Skip to content

Commit 83b3607

Browse files
D-D-HVladimir Ivanov
authored andcommitted
8266642: improve ResolvedMethodTable hash function
Reviewed-by: vlivanov, coleenp
1 parent 1c7a131 commit 83b3607

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

src/hotspot/share/classfile/classLoaderData.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ class ClassLoaderData : public CHeapObj<mtClass> {
325325
const char* loader_name_and_id() const;
326326
Symbol* name_and_id() const { return _name_and_id; }
327327

328+
unsigned identity_hash() const {
329+
return (unsigned)((uintptr_t)this >> 3);
330+
}
331+
328332
JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
329333
};
330334

src/hotspot/share/prims/resolvedMethodTable.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "precompiled.hpp"
26+
#include "classfile/classLoaderData.hpp"
2627
#include "classfile/javaClasses.hpp"
2728
#include "gc/shared/oopStorage.inline.hpp"
2829
#include "gc/shared/oopStorageSet.hpp"
@@ -53,7 +54,8 @@ static const size_t GROW_HINT = 32;
5354
static const size_t ResolvedMethodTableSizeLog = 10;
5455

5556
unsigned int method_hash(const Method* method) {
56-
unsigned int hash = method->klass_name()->identity_hash();
57+
unsigned int hash = method->method_holder()->class_loader_data()->identity_hash();
58+
hash = (hash * 31) ^ method->klass_name()->identity_hash();
5759
hash = (hash * 31) ^ method->name()->identity_hash();
5860
hash = (hash * 31) ^ method->signature()->identity_hash();
5961
return hash;

test/hotspot/jtreg/runtime/MemberName/ResolvedMethodTableHash.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ private MethodHandle generate(String className) throws ReflectiveOperationExcept
4848
return MethodHandles.publicLookup().findStatic(cls, "m", MethodType.methodType(void.class));
4949
}
5050

51+
private MethodHandle generateWithSameName() throws ReflectiveOperationException {
52+
byte[] buf = new byte[100];
53+
int size = writeClass(buf, "MH$$");
54+
// use different classloader instances to load the classes with the same name
55+
Class<?> cls = new ResolvedMethodTableHash().defineClass(null, buf, 0, size);
56+
return MethodHandles.publicLookup().findStatic(cls, "m", MethodType.methodType(void.class));
57+
}
58+
5159
// Produce a class file with the given name and a single method:
5260
// public static native void m();
5361
private int writeClass(byte[] buf, String className) {
@@ -82,7 +90,12 @@ public static void main(String[] args) throws Exception {
8290
int count = args.length > 0 ? Integer.parseInt(args[0]) : 200000;
8391

8492
for (int i = 0; i < count; i++) {
85-
handles.add(generator.generate("MH$" + i));
93+
// prevents metaspace oom
94+
if (i % 20 != 0) {
95+
handles.add(generator.generate("MH$" + i));
96+
} else {
97+
handles.add(generator.generateWithSameName());
98+
}
8699
if (i % 1000 == 0) {
87100
System.out.println("Generated " + i + " handles");
88101
}

0 commit comments

Comments
 (0)