Skip to content

Commit

Permalink
[GR-53920] Use hashed lookup in the secondary supers array.
Browse files Browse the repository at this point in the history
PullRequest: graal/17704
  • Loading branch information
mur47x111 committed Jun 5, 2024
2 parents bb21ab1 + 9f3cf28 commit ba9e6da
Show file tree
Hide file tree
Showing 17 changed files with 728 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.graal.compiler.hotspot.test;

import org.junit.Test;

public class SecondarySupersLookupTest extends HotSpotGraalCompilerTest {

interface I01 {
}

interface I02 extends I01 {
}

interface I03 extends I02 {
}

interface I04 extends I03 {
}

interface I05 extends I04 {
}

interface I06 extends I05 {
}

interface I07 extends I06 {
}

interface I08 extends I07 {
}

interface I09 extends I08 {
}

interface I10 extends I09 {
}

interface I11 extends I10 {
}

interface I12 extends I11 {
}

interface I13 extends I12 {
}

interface I14 extends I13 {
}

interface I15 extends I14 {
}

interface I16 extends I15 {
}

interface I17 extends I16 {
}

interface I18 extends I17 {
}

interface I19 extends I18 {
}

interface I20 extends I19 {
}

interface I21 extends I20 {
}

interface I22 extends I21 {
}

interface I23 extends I22 {
}

interface I24 extends I23 {
}

interface I25 extends I24 {
}

interface I26 extends I25 {
}

interface I27 extends I26 {
}

interface I28 extends I27 {
}

interface I29 extends I28 {
}

interface I30 extends I29 {
}

interface I31 extends I30 {
}

interface I32 extends I31 {
}

interface I33 extends I32 {
}

interface I34 extends I33 {
}

interface I35 extends I34 {
}

interface I36 extends I35 {
}

interface I37 extends I36 {
}

interface I38 extends I37 {
}

interface I39 extends I38 {
}

interface I40 extends I39 {
}

interface I41 extends I40 {
}

interface I42 extends I41 {
}

interface I43 extends I42 {
}

interface I44 extends I43 {
}

interface I45 extends I44 {
}

interface I46 extends I45 {
}

interface I47 extends I46 {
}

interface I48 extends I47 {
}

interface I49 extends I48 {
}

interface I50 extends I49 {
}

interface I51 extends I50 {
}

interface I52 extends I51 {
}

interface I53 extends I52 {
}

interface I54 extends I53 {
}

interface I55 extends I54 {
}

interface I56 extends I55 {
}

interface I57 extends I56 {
}

interface I58 extends I57 {
}

interface I59 extends I58 {
}

interface I60 extends I59 {
}

interface I61 extends I60 {
}

interface I62 extends I61 {
}

interface I63 extends I62 {
}

interface I64 extends I63 {
}

final Object obj01 = new I01() {
};
final Object obj08 = new I08() {
};
final Object obj34 = new I34() {
};
final Object obj60 = new I60() {
};
final Object obj64 = new I64() {
};

public static boolean instanceOfI01(Object o) {
return o instanceof I01;
}

@Test
public void testHashHitMiss() {
// hash miss
test("instanceOfI01", new Object());
// hash hit
test("instanceOfI01", obj01);
}

public static boolean instanceOfI08(Object o) {
return o instanceof I08;
}

public static boolean instanceOfI34(Object o) {
return o instanceof I34;
}

public static boolean instanceOfI60(Object o) {
return o instanceof I60;
}

@Test
public void testHashCollision() {
// hash collision, call into slow path, more than 64 secondary supers
test("instanceOfI01", obj64);
// I08, I34 and I60 have the same hash value because
// the hashing algorithm depends on the type name.
// hash collision, call into slow path, next slot hit
test("instanceOfI08", obj34);
// hash collision, next slot empty
test("instanceOfI34", obj08);
// hash collision, call into slow path, next slot miss
test("instanceOfI60", obj34);

// other tests for completion
test("instanceOfI08", obj60);
test("instanceOfI34", obj60);
test("instanceOfI60", obj08);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4837,6 +4837,14 @@ public final void testq(Register dst, AMD64Address src) {
AMD64RMOp.TEST.emit(this, OperandSize.QWORD, dst, src);
}

public final void btq(Register src, int imm8) {
prefixq(src);
emitByte(0x0F);
emitByte(0xBA);
emitModRM(4, src);
emitByte(imm8);
}

public final void btrq(Register src, int imm8) {
prefixq(src);
emitByte(0x0F);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
import jdk.graal.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
import jdk.graal.compiler.lir.amd64.AMD64Binary;
import jdk.graal.compiler.lir.amd64.AMD64BinaryConsumer;
import jdk.graal.compiler.lir.amd64.AMD64BitCountOp;
import jdk.graal.compiler.lir.amd64.AMD64BitSwapOp;
import jdk.graal.compiler.lir.amd64.AMD64ClearRegisterOp;
import jdk.graal.compiler.lir.amd64.AMD64ConvertFloatToIntegerOp;
Expand Down Expand Up @@ -1059,11 +1060,15 @@ public Value emitZeroExtend(Value inputVal, int fromBits, int toBits, boolean re
@Override
public Variable emitBitCount(Value value) {
Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AMD64Kind.DWORD));
assert ((AMD64Kind) value.getPlatformKind()).isInteger();
if (value.getPlatformKind() == AMD64Kind.QWORD) {
getLIRGen().append(new AMD64Unary.RMOp(POPCNT, QWORD, result, asAllocatable(value)));
if (getLIRGen().target().arch.getFeatures().contains(CPUFeature.POPCNT)) {
assert ((AMD64Kind) value.getPlatformKind()).isInteger();
if (value.getPlatformKind() == AMD64Kind.QWORD) {
getLIRGen().append(new AMD64Unary.RMOp(POPCNT, QWORD, result, asAllocatable(value)));
} else {
getLIRGen().append(new AMD64Unary.RMOp(POPCNT, DWORD, result, asAllocatable(value)));
}
} else {
getLIRGen().append(new AMD64Unary.RMOp(POPCNT, DWORD, result, asAllocatable(value)));
getLIRGen().append(new AMD64BitCountOp(getLIRGen(), result, asAllocatable(value)));
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import jdk.graal.compiler.lir.LabelRef;
import jdk.graal.compiler.lir.amd64.AMD64AddressValue;
import jdk.graal.compiler.lir.amd64.AMD64BinaryConsumer;
import jdk.graal.compiler.lir.amd64.AMD64ControlFlow;
import jdk.graal.compiler.lir.amd64.AMD64ControlFlow.TestBranchOp;
import jdk.graal.compiler.lir.amd64.AMD64ControlFlow.TestConstBranchOp;
import jdk.graal.compiler.lir.amd64.AMD64UnaryConsumer;
Expand Down Expand Up @@ -373,6 +374,21 @@ public ComplexMatchResult resetLowestSetBit(ValueNode a, ValueNode b) {
}
}

@MatchRule("(If (IntegerTest value Constant=a))")
public ComplexMatchResult testBitAndBranch(IfNode root, ValueNode value, ConstantNode a) {
long constant = a.asJavaConstant().asLong();
if (Long.bitCount(constant) == 1) {
return builder -> {
LabelRef trueDestination = getLIRBlock(root.trueSuccessor());
LabelRef falseDestination = getLIRBlock(root.falseSuccessor());
gen.append(new AMD64ControlFlow.BitTestAndBranchOp(trueDestination, falseDestination, gen.asAllocatable(operand(value)),
root.getTrueSuccessorProbability(), Long.numberOfTrailingZeros(constant)));
return null;
};
}
return null;
}

@MatchRule("(If (IntegerTest Read=access value))")
@MatchRule("(If (IntegerTest FloatingRead=access value))")
public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ public final int logMinObjAlignment() {
public final int superCheckOffsetOffset = getFieldOffset("Klass::_super_check_offset", Integer.class, "juint");
public final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*");
public final int secondarySupersOffset = getFieldOffset("Klass::_secondary_supers", Integer.class, "Array<Klass*>*");
public final int klassHashSlotOffset = getFieldOffset("Klass::_hash_slot", Integer.class, "uint8_t", 0, JDK >= 23);
public final int klassBitmapOffset = getFieldOffset("Klass::_bitmap", Integer.class, "uintx", 0, JDK >= 23);

// JDK-8186777
public final int classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import static jdk.graal.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER;
import static jdk.graal.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT;
import static jdk.graal.compiler.hotspot.stubs.ExceptionHandlerStub.EXCEPTION_HANDLER_FOR_PC;
import static jdk.graal.compiler.hotspot.stubs.LookUpSecondarySupersTableStub.LOOKUP_SECONDARY_SUPERS_TABLE_SLOW_PATH;
import static jdk.graal.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
import static jdk.graal.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
import static jdk.graal.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
Expand Down Expand Up @@ -120,6 +121,7 @@
import jdk.graal.compiler.hotspot.stubs.IntegerExactOverflowExceptionStub;
import jdk.graal.compiler.hotspot.stubs.IntrinsicStubsGen;
import jdk.graal.compiler.hotspot.stubs.LongExactOverflowExceptionStub;
import jdk.graal.compiler.hotspot.stubs.LookUpSecondarySupersTableStub;
import jdk.graal.compiler.hotspot.stubs.NegativeArraySizeExceptionStub;
import jdk.graal.compiler.hotspot.stubs.NullPointerExceptionStub;
import jdk.graal.compiler.hotspot.stubs.OutOfBoundsExceptionStub;
Expand Down Expand Up @@ -512,6 +514,9 @@ public void initialize(HotSpotProviders providers, OptionValues options) {
registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.ILLEGAL_ARGUMENT_EXCEPTION_ARGUMENT_IS_NOT_AN_ARRAY),
SAFEPOINT, HAS_SIDE_EFFECT, DESTROYS_ALL_CALLER_SAVE_REGISTERS, any())));

link(new LookUpSecondarySupersTableStub(options, providers,
registerStubCall(LOOKUP_SECONDARY_SUPERS_TABLE_SLOW_PATH, DESTROYS_ALL_CALLER_SAVE_REGISTERS)));

linkForeignCall(options, providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD);
linkForeignCall(options, providers, createDescriptor(REGISTER_FINALIZER, SAFEPOINT, HAS_SIDE_EFFECT, any()), c.registerFinalizerAddress, PREPEND_THREAD);
linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD);
Expand Down
Loading

0 comments on commit ba9e6da

Please sign in to comment.