Skip to content

Commit 5c3a564

Browse files
author
Andrew Haley
committed
Better
1 parent 903a38d commit 5c3a564

3 files changed

Lines changed: 53 additions & 38 deletions

File tree

src/hotspot/share/oops/klass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ uintx Klass::hash_secondary_supers(Array<Klass*>** secondaries_p, bool rewrite,
431431
if ((shift | delta) != 0) {
432432
Klass** a = secondaries->adr_at(0);
433433
// The `+1` here is because the probe limit in the Klass is
434-
// *inclusive*, but reverse takes a half-open interval. For
434+
// *inclusive*, but probing takes a half-open interval. For
435435
// example, if our probe limit is 3, we must probe the
436436
// interval [0, 4).
437437
int probe = shift - delta + 1;

src/hotspot/share/oops/klass.inline.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ inline bool Klass::lookup_secondary_supers_table(Klass* k) const {
128128
uint8_t slot = k->_hash_slot;
129129
uintx shifted_bitmap = bitmap << (highest_bit_number - slot);
130130

131-
// precond((int)population_count(bitmap) <= secondary_supers()->length());
131+
precond((int)population_count(bitmap) <= secondary_supers()->length());
132132

133133
// First check the bitmap to see if super_klass might be present. If
134134
// the bit is zero, we are certain that super_klass is not one of

test/micro/org/openjdk/bench/vm/lang/SecondarySupersLookup.java

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,17 @@
2525
import java.io.FileOutputStream;
2626
import java.io.IOException;
2727
import java.lang.classfile.*;
28-
import java.lang.classfile.constantpool.ClassEntry;
2928
import java.lang.constant.ClassDesc;
3029
import java.lang.constant.ConstantDescs;
3130
import java.lang.constant.MethodTypeDesc;
32-
import java.lang.invoke.*;
3331
import java.security.SecureClassLoader;
34-
import java.util.Arrays;
3532
import java.util.List;
36-
import java.util.Random;
3733
import java.util.concurrent.TimeUnit;
38-
import java.util.concurrent.atomic.AtomicReference;
3934
import java.util.function.Function;
40-
import java.util.stream.Stream;
4135
import org.openjdk.jmh.annotations.*;
4236
import org.openjdk.jmh.infra.*;
4337

4438
import static java.lang.classfile.ClassFile.*;
45-
import static java.lang.invoke.MethodType.methodType;
4639

4740

4841
@BenchmarkMode(Mode.AverageTime)
@@ -228,10 +221,10 @@ public Class<?>[] genClasses(Class<?>[] interfaces, int length) {
228221
return klasses;
229222
}
230223

231-
private static void genClassBody(ClassBuilder clb, List<ClassDesc> interfaceDesc) {
224+
private static void genClassBody(ClassBuilder clb, List<ClassDesc> interfaceDescriptors) {
232225
clb = clb.withFlags(ACC_PUBLIC);
233226
var cpool = clb.constantPool();
234-
var interfaceEntries = interfaceDesc.stream().map(cpool::classEntry).toList();
227+
var interfaceEntries = interfaceDescriptors.stream().map(cpool::classEntry).toList();
235228
var CD_AClass = ClassDesc.of(AClass.class.getName());
236229
clb.withSuperclass(CD_AClass)
237230
.withInterfaces(interfaceEntries)
@@ -268,12 +261,21 @@ private static void genClassBody(ClassBuilder clb, List<ClassDesc> interfaceDesc
268261
.aload(1)
269262
.instanceOf(ClassDesc.of("J"))
270263
.ireturn()
264+
))
265+
.withMethod("checkCast",
266+
MethodTypeDesc.of(ConstantDescs.CD_Object,
267+
ConstantDescs.CD_Object),
268+
ACC_PUBLIC,
269+
mb -> mb.withCode(cob -> cob
270+
.aload(1)
271+
.checkcast(interfaceEntries.get(interfaceEntries.size() - 1))
272+
.areturn()
271273
));
272274
}
273275

274-
private Class<?> genClass(List<ClassDesc> interfaceDesc, String name) {
276+
private Class<?> genClass(List<ClassDesc> interfaceDescriptors, String name) {
275277
byte[] bytes = ClassFile.of()
276-
.build(ClassDesc.of(name), clb -> genClassBody(clb, interfaceDesc));
278+
.build(ClassDesc.of(name), clb -> genClassBody(clb, interfaceDescriptors));
277279
return LOADER.defineClass(name, bytes);
278280
}
279281

@@ -284,13 +286,11 @@ private Class<?> genClass(Class<?>[] interfaces, String name) {
284286

285287
AClass testInstance;
286288
Object[] testInstances;
289+
public final static int TESTINSTANCES=10;
287290
Class<?> targetInterface;
288291

289292
Class testInterface;
290293

291-
static MethodHandles.Lookup lookup = MethodHandles.lookup();
292-
static MethodType mt = MethodType.methodType(boolean.class, Object.class);
293-
294294
@Setup
295295
public void init() throws Exception {
296296
LOADER = new MyLoader(AClass.class.getClassLoader());
@@ -304,12 +304,22 @@ public void init() throws Exception {
304304
Class<?> barf = genClass(interfaces, "Humongous");
305305
testInstance = (AClass)(barf.getConstructor().newInstance());
306306

307-
testInstances = new Object[20];
307+
testInstances = new Object[TESTINSTANCES];
308308
for (int i = 0; i < testInstances.length; i++) {
309309
testInstances[i] = genClass(interfaces, String.format("Humongous%02d", i))
310310
.getConstructor().newInstance();
311311
}
312312

313+
System.out.println("testInstance = " + testInstance);
314+
}
315+
316+
private static void test(Object obj, Class<?> cls, boolean expected) {
317+
if (cls.isInstance(obj) != expected) {
318+
throw new InternalError(obj.getClass() + " " + cls + " " + expected);
319+
}
320+
}
321+
322+
@Warmup public void warmup() {
313323
for (int i = 0; i < 20_000; i++) {
314324
testInterface = interfaces[i % interfaces.length];
315325
Class<?> s = getSuper(i);
@@ -322,30 +332,9 @@ public void init() throws Exception {
322332
test(obj07, s, s.isInstance(obj07));
323333
test(obj08, s, s.isInstance(obj08));
324334
test(obj09, s, s.isInstance(obj09));
325-
// testPositiveN();
326335
}
327-
328-
System.out.println("testInstance = " + testInstance);
329336
}
330337

331-
private static void test(Object obj, Class<?> cls, boolean expected) {
332-
if (cls.isInstance(obj) != expected) {
333-
throw new InternalError(obj.getClass() + " " + cls + " " + expected);
334-
}
335-
}
336-
337-
@Benchmark
338-
public void instanceOfPositive(Blackhole bh) {
339-
for (Object obj : testInstances) {
340-
bh.consume(testInstance.instanceOfPositive(obj));
341-
}
342-
}
343-
@Benchmark
344-
public void instanceOfNegative(Blackhole bh) {
345-
for (Object obj : testInstances) {
346-
bh.consume(testInstance.instanceOfNegative(obj));
347-
}
348-
}
349338
@Benchmark
350339
public void testPositive01() {
351340
test(obj01, I01.class, true);
@@ -487,11 +476,37 @@ public void testPositive01() {
487476
test(obj64, J.class, false);
488477
}
489478

479+
// Arbitrary-sized tests.
490480
@Benchmark public void testPositiveN() {
491481
test(testInstance, interfaces[interfaces.length - 1], true);
492482
}
493483
@Benchmark public void testNegativeN() {
494484
test(testInstance, J.class, false);
495485
}
496486

487+
// These invoke obj instanceof T. We use an array of testInstances
488+
// instead of a single instance to prevent C2 from removing our
489+
// lookup.
490+
@Benchmark
491+
@OperationsPerInvocation(TESTINSTANCES)
492+
public void checkCast(Blackhole bh) {
493+
for (Object obj : testInstances) {
494+
bh.consume(testInstance.checkCast(obj));
495+
}
496+
}
497+
@Benchmark
498+
@OperationsPerInvocation(TESTINSTANCES)
499+
public void instanceOfPositive(Blackhole bh) {
500+
for (Object obj : testInstances) {
501+
bh.consume(testInstance.instanceOfPositive(obj));
502+
}
503+
}
504+
@Benchmark
505+
@OperationsPerInvocation(TESTINSTANCES)
506+
public void instanceOfNegative(Blackhole bh) {
507+
for (Object obj : testInstances) {
508+
bh.consume(testInstance.instanceOfNegative(obj));
509+
}
510+
}
511+
497512
}

0 commit comments

Comments
 (0)