Skip to content

Commit d8ba227

Browse files
Matias Saavedra Silvacoleenp
Matias Saavedra Silva
authored andcommitted
8304069: ClassFileParser has ad-hoc hashtables
Reviewed-by: coleenp, dholmes
1 parent 9a8a60f commit d8ba227

File tree

1 file changed

+42
-101
lines changed

1 file changed

+42
-101
lines changed

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 42 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -771,52 +771,27 @@ class NameSigHash: public ResourceObj {
771771
public:
772772
const Symbol* _name; // name
773773
const Symbol* _sig; // signature
774-
NameSigHash* _next; // Next entry in hash table
775-
};
776-
777-
static const int HASH_ROW_SIZE = 256;
778774

779-
static unsigned int hash(const Symbol* name, const Symbol* sig) {
780-
unsigned int raw_hash = 0;
781-
raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2);
782-
raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize;
783-
784-
return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE;
785-
}
775+
static const int HASH_ROW_SIZE = 256;
786776

777+
NameSigHash(Symbol* name, Symbol* sig) :
778+
_name(name),
779+
_sig(sig) {}
787780

788-
static void initialize_hashtable(NameSigHash** table) {
789-
memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE);
790-
}
791-
// Return false if the name/sig combination is found in table.
792-
// Return true if no duplicate is found. And name/sig is added as a new entry in table.
793-
// The old format checker uses heap sort to find duplicates.
794-
// NOTE: caller should guarantee that GC doesn't happen during the life cycle
795-
// of table since we don't expect Symbol*'s to move.
796-
static bool put_after_lookup(const Symbol* name, const Symbol* sig, NameSigHash** table) {
797-
assert(name != nullptr, "name in constant pool is null");
798-
799-
// First lookup for duplicates
800-
int index = hash(name, sig);
801-
NameSigHash* entry = table[index];
802-
while (entry != nullptr) {
803-
if (entry->_name == name && entry->_sig == sig) {
804-
return false;
805-
}
806-
entry = entry->_next;
781+
static unsigned int hash(NameSigHash const& namesig) {
782+
return namesig._name->identity_hash() ^ namesig._sig->identity_hash();
807783
}
808784

809-
// No duplicate is found, allocate a new entry and fill it.
810-
entry = new NameSigHash();
811-
entry->_name = name;
812-
entry->_sig = sig;
813-
814-
// Insert into hash table
815-
entry->_next = table[index];
816-
table[index] = entry;
785+
static bool equals(NameSigHash const& e0, NameSigHash const& e1) {
786+
return (e0._name == e1._name) &&
787+
(e0._sig == e1._sig);
788+
}
789+
};
817790

818-
return true;
819-
}
791+
using NameSigHashtable = ResourceHashtable<NameSigHash, int,
792+
NameSigHash::HASH_ROW_SIZE,
793+
AnyObj::RESOURCE_AREA, mtInternal,
794+
&NameSigHash::hash, &NameSigHash::equals>;
820795

821796
// Side-effects: populates the _local_interfaces field
822797
void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
@@ -882,28 +857,17 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
882857

883858
// Check if there's any duplicates in interfaces
884859
ResourceMark rm(THREAD);
885-
NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,
886-
NameSigHash*,
887-
HASH_ROW_SIZE);
888-
initialize_hashtable(interface_names);
889-
bool dup = false;
890-
const Symbol* name = nullptr;
891-
{
892-
debug_only(NoSafepointVerifier nsv;)
893-
for (index = 0; index < itfs_len; index++) {
894-
const InstanceKlass* const k = _local_interfaces->at(index);
895-
name = k->name();
896-
// If no duplicates, add (name, nullptr) in hashtable interface_names.
897-
if (!put_after_lookup(name, nullptr, interface_names)) {
898-
dup = true;
899-
break;
900-
}
860+
// Set containing interface names
861+
ResourceHashtable<Symbol*, int>* interface_names = new ResourceHashtable<Symbol*, int>();
862+
for (index = 0; index < itfs_len; index++) {
863+
const InstanceKlass* const k = _local_interfaces->at(index);
864+
Symbol* interface_name = k->name();
865+
// If no duplicates, add (name, nullptr) in hashtable interface_names.
866+
if (!interface_names->put(interface_name, 0)) {
867+
classfile_parse_error("Duplicate interface name \"%s\" in class file %s",
868+
interface_name->as_C_string(), THREAD);
901869
}
902870
}
903-
if (dup) {
904-
classfile_parse_error("Duplicate interface name \"%s\" in class file %s",
905-
name->as_C_string(), THREAD);
906-
}
907871
}
908872
}
909873

@@ -1621,28 +1585,17 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
16211585
if (_need_verify && length > 1) {
16221586
// Check duplicated fields
16231587
ResourceMark rm(THREAD);
1624-
NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
1625-
THREAD, NameSigHash*, HASH_ROW_SIZE);
1626-
initialize_hashtable(names_and_sigs);
1627-
bool dup = false;
1628-
const Symbol* name = nullptr;
1629-
const Symbol* sig = nullptr;
1630-
{
1631-
debug_only(NoSafepointVerifier nsv;)
1632-
for (int i = 0; i < _temp_field_info->length(); i++) {
1633-
name = _temp_field_info->adr_at(i)->name(_cp);
1634-
sig = _temp_field_info->adr_at(i)->signature(_cp);
1635-
// If no duplicates, add name/signature in hashtable names_and_sigs.
1636-
if (!put_after_lookup(name, sig, names_and_sigs)) {
1637-
dup = true;
1638-
break;
1639-
}
1588+
// Set containing name-signature pairs
1589+
NameSigHashtable* names_and_sigs = new NameSigHashtable();
1590+
for (int i = 0; i < _temp_field_info->length(); i++) {
1591+
NameSigHash name_and_sig(_temp_field_info->adr_at(i)->name(_cp),
1592+
_temp_field_info->adr_at(i)->signature(_cp));
1593+
// If no duplicates, add name/signature in hashtable names_and_sigs.
1594+
if(!names_and_sigs->put(name_and_sig, 0)) {
1595+
classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s",
1596+
name_and_sig._name->as_C_string(), name_and_sig._sig->as_klass_external_name(), THREAD);
16401597
}
16411598
}
1642-
if (dup) {
1643-
classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s",
1644-
name->as_C_string(), sig->as_klass_external_name(), THREAD);
1645-
}
16461599
}
16471600
}
16481601

@@ -2871,29 +2824,17 @@ void ClassFileParser::parse_methods(const ClassFileStream* const cfs,
28712824
if (_need_verify && length > 1) {
28722825
// Check duplicated methods
28732826
ResourceMark rm(THREAD);
2874-
NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
2875-
THREAD, NameSigHash*, HASH_ROW_SIZE);
2876-
initialize_hashtable(names_and_sigs);
2877-
bool dup = false;
2878-
const Symbol* name = nullptr;
2879-
const Symbol* sig = nullptr;
2880-
{
2881-
debug_only(NoSafepointVerifier nsv;)
2882-
for (int i = 0; i < length; i++) {
2883-
const Method* const m = _methods->at(i);
2884-
name = m->name();
2885-
sig = m->signature();
2886-
// If no duplicates, add name/signature in hashtable names_and_sigs.
2887-
if (!put_after_lookup(name, sig, names_and_sigs)) {
2888-
dup = true;
2889-
break;
2890-
}
2827+
// Set containing name-signature pairs
2828+
NameSigHashtable* names_and_sigs = new NameSigHashtable();
2829+
for (int i = 0; i < length; i++) {
2830+
const Method* const m = _methods->at(i);
2831+
NameSigHash name_and_sig(m->name(), m->signature());
2832+
// If no duplicates, add name/signature in hashtable names_and_sigs.
2833+
if(!names_and_sigs->put(name_and_sig, 0)) {
2834+
classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s",
2835+
name_and_sig._name->as_C_string(), name_and_sig._sig->as_klass_external_name(), THREAD);
28912836
}
28922837
}
2893-
if (dup) {
2894-
classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s",
2895-
name->as_C_string(), sig->as_klass_external_name(), THREAD);
2896-
}
28972838
}
28982839
}
28992840
}

0 commit comments

Comments
 (0)