8319859: Better symbol storage

Reviewed-by: rhalade, coleenp, matsaave, iklam
This commit is contained in:
David Holmes 2024-02-11 21:54:51 +00:00 committed by Jaikiran Pai
parent 227fc5e591
commit aea9a08beb
3 changed files with 17 additions and 2 deletions

View File

@ -344,8 +344,19 @@ Symbol* SymbolTable::lookup_common(const char* name,
return sym;
}
// Symbols should represent entities from the constant pool that are
// limited to 64K in length, but usage errors creep in allowing Symbols
// to be used for arbitrary strings. For debug builds we will assert if
// a string is too long, whereas product builds will truncate it.
Symbol* SymbolTable::new_symbol(const char* name, int len) {
assert(len <= Symbol::max_length(), "sanity");
assert(len <= Symbol::max_length(),
"String length %d exceeds the maximum Symbol length of %d", len, Symbol::max_length());
if (len > Symbol::max_length()) {
warning("A string \"%.80s ... %.80s\" exceeds the maximum Symbol "
"length of %d and has been truncated", name, (name + len - 80), Symbol::max_length());
len = Symbol::max_length();
}
unsigned int hash = hash_symbol(name, len, _alt_hash);
Symbol* sym = lookup_common(name, len, hash);
if (sym == nullptr) {
@ -485,6 +496,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa
for (int i = 0; i < names_count; i++) {
const char *name = names[i];
int len = lengths[i];
assert(len <= Symbol::max_length(), "must be - these come from the constant pool");
unsigned int hash = hashValues[i];
assert(lookup_shared(name, len, hash) == nullptr, "must have checked already");
Symbol* sym = do_add_if_needed(name, len, hash, is_permanent);
@ -494,6 +506,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa
}
Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool is_permanent) {
assert(len <= Symbol::max_length(), "caller should have ensured this");
SymbolTableLookup lookup(name, len, hash);
SymbolTableGet stg;
bool clean_hint = false;

View File

@ -54,6 +54,7 @@ uint32_t Symbol::pack_hash_and_refcount(short hash, int refcount) {
}
Symbol::Symbol(const u1* name, int length, int refcount) {
assert(length <= max_length(), "SymbolTable should have caught this!");
_hash_and_refcount = pack_hash_and_refcount((short)os::random(), refcount);
_length = (u2)length;
// _body[0..1] are allocated in the header just by coincidence in the current

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -130,6 +130,7 @@ class Symbol : public MetaspaceObj {
return (int)heap_word_size(byte_size(length));
}
// Constructor is private for use only by SymbolTable.
Symbol(const u1* name, int length, int refcount);
static short extract_hash(uint32_t value) { return (short)(value >> 16); }