Skip to content

Commit 755621d

Browse files
committed
Fix truffle entry barrier on aaarch64
1 parent e077377 commit 755621d

File tree

2 files changed

+59
-46
lines changed

2 files changed

+59
-46
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/aarch64/shenandoah/AArch64HotSpotShenandoahLoadRefBarrierOp.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
*/
2525
package jdk.graal.compiler.hotspot.aarch64.shenandoah;
2626

27+
import static jdk.graal.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
28+
import static jdk.graal.compiler.lir.LIRInstruction.OperandFlag.REG;
29+
import static jdk.vm.ci.code.ValueUtil.asRegister;
30+
2731
import jdk.graal.compiler.asm.Label;
2832
import jdk.graal.compiler.asm.aarch64.AArch64Address;
2933
import jdk.graal.compiler.asm.aarch64.AArch64Assembler;
@@ -35,21 +39,17 @@
3539
import jdk.graal.compiler.hotspot.replacements.HotSpotReplacementsUtil;
3640
import jdk.graal.compiler.lir.LIRInstruction;
3741
import jdk.graal.compiler.lir.LIRInstructionClass;
42+
import jdk.graal.compiler.lir.LIRValueUtil;
3843
import jdk.graal.compiler.lir.SyncPort;
3944
import jdk.graal.compiler.lir.aarch64.AArch64AddressValue;
4045
import jdk.graal.compiler.lir.aarch64.AArch64Call;
4146
import jdk.graal.compiler.lir.aarch64.AArch64LIRInstruction;
4247
import jdk.graal.compiler.lir.asm.CompilationResultBuilder;
4348
import jdk.graal.compiler.nodes.gc.shenandoah.ShenandoahLoadRefBarrierNode;
44-
4549
import jdk.vm.ci.code.CallingConvention;
4650
import jdk.vm.ci.code.Register;
4751
import jdk.vm.ci.meta.AllocatableValue;
4852

49-
import static jdk.graal.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
50-
import static jdk.graal.compiler.lir.LIRInstruction.OperandFlag.REG;
51-
import static jdk.vm.ci.code.ValueUtil.asRegister;
52-
5353
/**
5454
* AArch64 backend for the Shenandoah load-reference barrier.
5555
*/
@@ -116,7 +116,11 @@ public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
116116
// @formatter:on
117117
public static void emitCode(GraalHotSpotVMConfig config, CompilationResultBuilder crb, AArch64MacroAssembler masm, LIRInstruction op, Register thread, Register result, Register object,
118118
AArch64Address loadAddress, ForeignCallLinkage callTarget, ShenandoahLoadRefBarrierNode.ReferenceStrength strength, boolean notNull) {
119-
try (AArch64MacroAssembler.ScratchRegister sc1 = masm.getScratchRegister()) {
119+
/*
120+
* The slow path uses both scratch registers so allocate them both here to catch any cases
121+
* where the caller might thing the scratch registers are free.
122+
*/
123+
try (AArch64MacroAssembler.ScratchRegister sc1 = masm.getScratchRegister(); AArch64MacroAssembler.ScratchRegister unused = masm.getScratchRegister()) {
120124
Register rscratch1 = sc1.getRegister();
121125

122126
Label done = new Label();
@@ -158,6 +162,7 @@ public static void emitCode(GraalHotSpotVMConfig config, CompilationResultBuilde
158162
try (AArch64MacroAssembler.ScratchRegister tmp1 = masm.getScratchRegister(); AArch64MacroAssembler.ScratchRegister tmp2 = masm.getScratchRegister()) {
159163
Register rtmp1 = tmp1.getRegister();
160164
Register rtmp2 = tmp2.getRegister();
165+
LIRValueUtil.differentRegisters(object, rtmp1, rtmp2);
161166
masm.bind(csetCheck);
162167
masm.mov(rtmp1, HotSpotReplacementsUtil.shenandoahGCCSetFastTestAddr(config));
163168
masm.lsr(64, rtmp2, object, HotSpotReplacementsUtil.shenandoahGCRegionSizeBytesShift(config));

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/aarch64/AArch64TruffleCallBoundaryInstrumentationFactory.java

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCall;
3030
import static jdk.vm.ci.meta.JavaKind.Object;
3131

32+
import java.util.List;
33+
3234
import jdk.graal.compiler.asm.Label;
3335
import jdk.graal.compiler.asm.aarch64.AArch64Address;
3436
import jdk.graal.compiler.asm.aarch64.AArch64MacroAssembler;
35-
import jdk.graal.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister;
3637
import jdk.graal.compiler.core.common.CompressEncoding;
3738
import jdk.graal.compiler.core.common.spi.ForeignCallLinkage;
39+
import jdk.graal.compiler.debug.GraalError;
3840
import jdk.graal.compiler.hotspot.GraalHotSpotVMConfig;
3941
import jdk.graal.compiler.hotspot.HotSpotGraalRuntime;
4042
import jdk.graal.compiler.hotspot.aarch64.AArch64HotSpotBackend;
@@ -49,6 +51,7 @@
4951
import jdk.graal.compiler.truffle.TruffleCompilerConfiguration;
5052
import jdk.graal.compiler.truffle.hotspot.TruffleCallBoundaryInstrumentationFactory;
5153
import jdk.graal.compiler.truffle.hotspot.TruffleEntryPointDecorator;
54+
import jdk.vm.ci.aarch64.AArch64;
5255
import jdk.vm.ci.code.Register;
5356

5457
@ServiceProvider(TruffleCallBoundaryInstrumentationFactory.class)
@@ -69,46 +72,51 @@ public void emitEntryPoint(CompilationResultBuilder crb, boolean beforeFrameSetu
6972
AArch64MacroAssembler masm = (AArch64MacroAssembler) crb.asm;
7073
AArch64HotSpotBackend.emitInvalidatePlaceholder(crb, masm);
7174

72-
try (ScratchRegister scratch = masm.getScratchRegister()) {
73-
Register thisRegister = crb.getCodeCache().getRegisterConfig().getCallingConventionRegisters(JavaCall, Object).get(0);
74-
Register spillRegister = scratch.getRegister();
75-
Label doProlog = new Label();
76-
if (config.useCompressedOops) {
77-
CompressEncoding encoding = config.getOopEncoding();
78-
AArch64Address address = AArch64Address.createImmediateAddress(32, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, thisRegister, installedCodeOffset);
79-
masm.ldr(32, spillRegister, address);
80-
Register base = encoding.hasBase() ? registers.getHeapBaseRegister() : null;
81-
AArch64HotSpotMove.UncompressPointer.emitUncompressCode(masm, spillRegister, spillRegister, base, encoding, true);
82-
if (config.gc == HotSpotGraalRuntime.HotSpotGC.Shenandoah) {
83-
Register thread = registers.getThreadRegister();
84-
ForeignCallLinkage callTarget = crb.getForeignCalls().lookupForeignCall(SHENANDOAH_LOAD_BARRIER);
85-
AArch64HotSpotShenandoahLoadRefBarrierOp.emitCode(config, crb, masm, null, thread, spillRegister, spillRegister, address, callTarget,
86-
ShenandoahLoadRefBarrierNode.ReferenceStrength.STRONG, false);
87-
}
88-
} else {
89-
AArch64Address address = AArch64Address.createImmediateAddress(64, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, thisRegister, installedCodeOffset);
90-
masm.ldr(64, spillRegister, address);
91-
if (config.gc == HotSpotGraalRuntime.HotSpotGC.Z) {
92-
ForeignCallLinkage callTarget = crb.getForeignCalls().lookupForeignCall(Z_LOAD_BARRIER);
93-
AArch64HotSpotZBarrierSetLIRGenerator.emitLoadBarrier(crb, masm, config, spillRegister, callTarget, address, null, false, false);
94-
}
95-
if (config.gc == HotSpotGraalRuntime.HotSpotGC.Shenandoah) {
96-
Register thread = registers.getThreadRegister();
97-
ForeignCallLinkage callTarget = crb.getForeignCalls().lookupForeignCall(SHENANDOAH_LOAD_BARRIER);
98-
AArch64HotSpotShenandoahLoadRefBarrierOp.emitCode(config, crb, masm, null, thread, spillRegister, spillRegister, address, callTarget,
99-
ShenandoahLoadRefBarrierNode.ReferenceStrength.STRONG, false);
100-
}
101-
}
102-
masm.ldr(64, spillRegister, AArch64Address.createImmediateAddress(64, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, spillRegister, entryPointOffset));
103-
masm.cbz(64, spillRegister, doProlog);
104-
if (!beforeFrameSetup) {
105-
// Must tear down the frame before jumping
106-
((AArch64HotSpotBackend.HotSpotFrameContext) crb.frameContext).leave(crb);
107-
}
108-
masm.jmp(spillRegister);
109-
masm.nop();
110-
masm.bind(doProlog);
75+
List<Register> callRegisters = crb.getCodeCache().getRegisterConfig().getCallingConventionRegisters(JavaCall, Object);
76+
Register thisRegister = callRegisters.get(0);
77+
/**
78+
* This path is complicated by the need for barriers which might have complex
79+
* implementations. In particular they may already be using the scratch registers so
80+
* choose other registers as temporaries. Since this is at the method entry and
81+
* non-argument registers should be freely available so use those instead.
82+
*/
83+
Register spillRegister = AArch64.r11;
84+
assert !callRegisters.contains(spillRegister) : spillRegister + " " + callRegisters;
85+
Label doProlog = new Label();
86+
AArch64Address address;
87+
if (config.useCompressedOops) {
88+
CompressEncoding encoding = config.getOopEncoding();
89+
address = AArch64Address.createImmediateAddress(32, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, thisRegister, installedCodeOffset);
90+
masm.ldr(32, spillRegister, address);
91+
Register base = encoding.hasBase() ? registers.getHeapBaseRegister() : null;
92+
AArch64HotSpotMove.UncompressPointer.emitUncompressCode(masm, spillRegister, spillRegister, base, encoding, true);
93+
} else {
94+
address = AArch64Address.createImmediateAddress(64, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, thisRegister, installedCodeOffset);
95+
masm.ldr(64, spillRegister, address);
96+
}
97+
if (config.gc == HotSpotGraalRuntime.HotSpotGC.Z) {
98+
GraalError.guarantee(!config.useCompressedOops, "only uncompressed oops");
99+
ForeignCallLinkage callTarget = crb.getForeignCalls().lookupForeignCall(Z_LOAD_BARRIER);
100+
AArch64HotSpotZBarrierSetLIRGenerator.emitLoadBarrier(crb, masm, config, spillRegister, callTarget, address, null, false, false);
101+
}
102+
if (config.gc == HotSpotGraalRuntime.HotSpotGC.Shenandoah) {
103+
Register objectRegister = AArch64.r12;
104+
assert !callRegisters.contains(objectRegister) : objectRegister + " " + callRegisters;
105+
Register thread = registers.getThreadRegister();
106+
ForeignCallLinkage callTarget = crb.getForeignCalls().lookupForeignCall(SHENANDOAH_LOAD_BARRIER);
107+
AArch64HotSpotShenandoahLoadRefBarrierOp.emitCode(config, crb, masm, null, thread, objectRegister, spillRegister, address, callTarget,
108+
ShenandoahLoadRefBarrierNode.ReferenceStrength.STRONG, false);
109+
masm.mov(64, spillRegister, objectRegister);
110+
}
111+
masm.ldr(64, spillRegister, AArch64Address.createImmediateAddress(64, AArch64Address.AddressingMode.IMMEDIATE_UNSIGNED_SCALED, spillRegister, entryPointOffset));
112+
masm.cbz(64, spillRegister, doProlog);
113+
if (!beforeFrameSetup) {
114+
// Must tear down the frame before jumping
115+
crb.frameContext.leave(crb);
111116
}
117+
masm.jmp(spillRegister);
118+
masm.nop();
119+
masm.bind(doProlog);
112120
}
113121
};
114122
}

0 commit comments

Comments
 (0)