@@ -771,52 +771,27 @@ class NameSigHash: public ResourceObj {
771
771
public:
772
772
const Symbol* _name; // name
773
773
const Symbol* _sig; // signature
774
- NameSigHash* _next; // Next entry in hash table
775
- };
776
-
777
- static const int HASH_ROW_SIZE = 256 ;
778
774
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 ;
786
776
777
+ NameSigHash (Symbol* name, Symbol* sig) :
778
+ _name (name),
779
+ _sig (sig) {}
787
780
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 ();
807
783
}
808
784
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
+ };
817
790
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>;
820
795
821
796
// Side-effects: populates the _local_interfaces field
822
797
void ClassFileParser::parse_interfaces (const ClassFileStream* const stream,
@@ -882,28 +857,17 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
882
857
883
858
// Check if there's any duplicates in interfaces
884
859
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);
901
869
}
902
870
}
903
- if (dup ) {
904
- classfile_parse_error (" Duplicate interface name \" %s\" in class file %s" ,
905
- name->as_C_string (), THREAD);
906
- }
907
871
}
908
872
}
909
873
@@ -1621,28 +1585,17 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
1621
1585
if (_need_verify && length > 1 ) {
1622
1586
// Check duplicated fields
1623
1587
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);
1640
1597
}
1641
1598
}
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
- }
1646
1599
}
1647
1600
}
1648
1601
@@ -2871,29 +2824,17 @@ void ClassFileParser::parse_methods(const ClassFileStream* const cfs,
2871
2824
if (_need_verify && length > 1 ) {
2872
2825
// Check duplicated methods
2873
2826
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);
2891
2836
}
2892
2837
}
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
- }
2897
2838
}
2898
2839
}
2899
2840
}
0 commit comments