Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JDK-8339796] Adapt JDK-8305895: Implement JEP 450: Compact Object Headers #9915

Open
wants to merge 2 commits into
base: galahad
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

"COMMENT.jdks": "When adding or removing JDKs keep in sync with JDKs in ci/common.jsonnet",
"jdks": {
"galahad-jdk": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24+19-2105", "platformspecific": true, "extrabundles": ["static-libs"]},
"galahad-jdk": {"name": "jpg-jdk", "version": "24", "build_id": "2024-09-27-1322328.yudi.zheng.jdk", "platformspecific": true, "extrabundles": ["static-libs"]},

"oraclejdk17": {"name": "jpg-jdk", "version": "17.0.7", "build_id": "jdk-17.0.7+8", "platformspecific": true, "extrabundles": ["static-libs"]},
"labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.7+4-jvmci-23.1-b02", "platformspecific": true },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigAccess {
GraalHotSpotVMConfig(HotSpotVMConfigStore store) {
super(store);

assert narrowKlassShift <= logKlassAlignment : Assertions.errorMessageContext("narrowKlassShift", narrowKlassShift, "logKlassAlignment", logKlassAlignment);
int logMinObjAlignment = logMinObjAlignment();
assert narrowOopShift <= logMinObjAlignment : Assertions.errorMessageContext("narrowOopShift", narrowOopShift, "logMinObjAlignment", logMinObjAlignment);
oopEncoding = new CompressEncoding(narrowOopBase, narrowOopShift);
Expand Down Expand Up @@ -187,6 +186,11 @@ public long gcTotalCollectionsAddress() {
// Compressed Oops related values.
public final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
public final boolean useCompressedClassPointers = getFlag("UseCompressedClassPointers", Boolean.class);
// JDK-8305895 allows storing the compressed class pointer in the upper 22 bits of the mark
// word. This runtime optimization is guarded by the flag UseCompactObjectHeaders. It depends
// on compressed class pointers, meaning that if useCompactObjectHeaders is true,
// useCompressedClassPointers is certainly true.
public final boolean useCompactObjectHeaders = getFlag("UseCompactObjectHeaders", Boolean.class, false, JDK >= 24);

public final long narrowOopBase = getFieldValue("CompilerToVM::Data::Universe_narrow_oop_base", Long.class, "address");
public final int narrowOopShift = getFieldValue("CompilerToVM::Data::Universe_narrow_oop_shift", Integer.class, "int");
Expand All @@ -199,15 +203,15 @@ public final int logMinObjAlignment() {
public final int narrowKlassSize = getFieldValue("CompilerToVM::Data::sizeof_narrowKlass", Integer.class, "int");
public final long narrowKlassBase = getFieldValue("CompilerToVM::Data::Universe_narrow_klass_base", Long.class, "address");
public final int narrowKlassShift = getFieldValue("CompilerToVM::Data::Universe_narrow_klass_shift", Integer.class, "int");
public final int logKlassAlignment = getConstant("LogKlassAlignmentInBytes", Integer.class);

public final int stackShadowPages = getFlag("StackShadowPages", Integer.class);
public final int vmPageSize = getFieldValue("CompilerToVM::Data::vm_page_size", Integer.class, "size_t");

public final int softwarePrefetchHintDistance = getFlag("SoftwarePrefetchHintDistance", Integer.class, -1, "aarch64".equals(osArch));

public final int markOffset = getFieldOffset("oopDesc::_mark", Integer.class, markWord);
public final int hubOffset = getFieldOffset("oopDesc::_metadata._klass", Integer.class, "Klass*");
// TODO remove before merge
public final int hubOffset = useCompactObjectHeaders ? 0xBAADCAFE : getFieldOffset("oopDesc::_metadata._klass", Integer.class, "Klass*");

public final int superCheckOffsetOffset = getFieldOffset("Klass::_super_check_offset", Integer.class, "juint");
public final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*");
Expand Down Expand Up @@ -238,12 +242,17 @@ public final int logMinObjAlignment() {

public final int arrayOopDescSize = getFieldValue("CompilerToVM::Data::sizeof_arrayOopDesc", Integer.class, "int");

public final int arrayLengthOffsetInBytes = getFieldValue("CompilerToVM::Data::arrayOopDesc_length_offset_in_bytes", Integer.class, "int", -1, JDK >= 24);

/**
* The offset of the array length word in an array object's header.
*
* See {@code arrayOopDesc::length_offset_in_bytes()}.
*/
public final int arrayOopDescLengthOffset() {
if (JDK >= 24) {
return arrayLengthOffsetInBytes;
}
return useCompressedClassPointers ? hubOffset + narrowKlassSize : arrayOopDescSize;
}

Expand Down Expand Up @@ -348,9 +357,22 @@ public int threadLastJavaFpOffset() {
public final int frameInterpreterFrameSenderSpOffset = getConstant("frame::interpreter_frame_sender_sp_offset", Integer.class, 0, osArch.equals("amd64"));
public final int frameInterpreterFrameLastSpOffset = getConstant("frame::interpreter_frame_last_sp_offset", Integer.class, 0, osArch.equals("amd64"));

public final int lockMaskInPlace = getConstant("markWord::lock_mask_in_place", Integer.class);
public final long markWordLockMaskInPlace = getConstant("markWord::lock_mask_in_place", Long.class);
public final long markWordHashMask = getConstant("markWord::hash_mask", Long.class);

public final long markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Long.class);
public final long markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Long.class);

// Mark word right shift to get identity hash code.
public final int markWordHashCodeShift = getConstant("markWord::hash_shift", Integer.class);
// Mark word right shift to get compressed klass pointer
public final int markWordKlassShift = getConstant("markWord::klass_shift", Integer.class, 0, JDK >= 24);

// The following three constants are declared as 64 bits uintptr_t, but known to be 32 bits
public final int unlockedValue = getConstant("markWord::unlocked_value", Integer.class);
public final int monitorValue = getConstant("markWord::monitor_value", Integer.class);
// Identity hash code value when uninitialized.
public final int uninitializedIdentityHashCodeValue = getConstant("markWord::no_hash", Integer.class);

// This field has no type in vmStructs.cpp
public final int objectMonitorOwner = getFieldOffset("ObjectMonitor::_owner", Integer.class, null);
Expand All @@ -359,26 +381,9 @@ public int threadLastJavaFpOffset() {
public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*");
public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "JavaThread*");

public final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class);
public final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class);

public long defaultPrototypeMarkWord() {
return this.markWordNoHashInPlace | this.markWordNoLockInPlace;
}

/**
* Mark word right shift to get identity hash code.
*/
public final int identityHashCodeShift = getConstant("markWord::hash_shift", Integer.class);

public final int contEntry = getFieldOffset("JavaThread::_cont_entry", Integer.class, "ContinuationEntry*", -1, JDK >= 24);
public final int pinCount = getFieldOffset("ContinuationEntry::_pin_count", Integer.class, "uint32_t", -1, JDK >= 24);

/**
* Identity hash code value when uninitialized.
*/
public final int uninitializedIdentityHashCodeValue = getConstant("markWord::no_hash", Integer.class);

public final int methodCompiledEntryOffset = getFieldOffset("Method::_from_compiled_entry", Integer.class, "address");

public final int compilationLevelFullOptimization = getConstant("CompLevel_full_optimization", Integer.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
Expand Down Expand Up @@ -419,15 +419,18 @@ private void emitCodePrefix(CompilationResultBuilder crb, ResolvedJavaMethod ins
CallingConvention cc = regConfig.getCallingConvention(HotSpotCallingConventionType.JavaCallee, null, parameterTypes, this);
Register receiver = asRegister(cc.getArgument(0));
int size = config.useCompressedClassPointers ? 32 : 64;
AArch64Address klassAddress = masm.makeAddress(size, receiver, config.hubOffset);
if (config.icSpeculatedKlassOffset == Integer.MAX_VALUE) {
crb.recordMark(HotSpotMarkId.UNVERIFIED_ENTRY);
Register klass = rscratch1;
if (config.useCompressedClassPointers) {
masm.ldr(32, klass, klassAddress);
if (config.useCompactObjectHeaders) {
((AArch64HotSpotMacroAssembler) masm).loadCompactClassPointer(klass, receiver);
} else {
masm.ldr(size, klass, masm.makeAddress(size, receiver, config.hubOffset));
}
AArch64HotSpotMove.decodeKlassPointer(masm, klass, klass, config.getKlassEncoding());
} else {
masm.ldr(64, klass, klassAddress);
masm.ldr(size, klass, masm.makeAddress(size, receiver, config.hubOffset));
}
// c1_LIRAssembler_aarch64.cpp: const Register IC_Klass = rscratch2;
Register inlineCacheKlass = AArch64HotSpotRegisterConfig.inlineCacheRegister;
Expand All @@ -436,7 +439,6 @@ private void emitCodePrefix(CompilationResultBuilder crb, ResolvedJavaMethod ins
masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, verifiedStub);
AArch64Call.directJmp(crb, masm, getForeignCalls().lookupForeignCall(IC_MISS_HANDLER));
} else {

// JDK-8322630 (removed ICStubs)
Register data = AArch64HotSpotRegisterConfig.inlineCacheRegister;
Register tmp1 = rscratch1;
Expand All @@ -445,16 +447,24 @@ private void emitCodePrefix(CompilationResultBuilder crb, ResolvedJavaMethod ins

// Size of IC check sequence checked with a guarantee below.
int inlineCacheCheckSize = AArch64Call.isNearCall(icMissHandler) ? 20 : 32;
if (config.useCompactObjectHeaders) {
// Extra instruction for shifting
inlineCacheCheckSize += 4;
}
masm.align(config.codeEntryAlignment, masm.position() + inlineCacheCheckSize);

int startICCheck = masm.position();
crb.recordMark(HotSpotMarkId.UNVERIFIED_ENTRY);
AArch64Address icSpeculatedKlass = masm.makeAddress(size, data, config.icSpeculatedKlassOffset);

masm.ldr(size, tmp1, klassAddress);
if (config.useCompactObjectHeaders) {
((AArch64HotSpotMacroAssembler) masm).loadCompactClassPointer(tmp1, receiver);
} else {
masm.ldr(size, tmp1, masm.makeAddress(size, receiver, config.hubOffset));
}

masm.ldr(size, tmp2, icSpeculatedKlass);
masm.cmp(size, tmp1, tmp2);

masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, verifiedStub);
AArch64Call.directJmp(crb, masm, icMissHandler);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 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
Expand Down Expand Up @@ -29,6 +29,7 @@
import jdk.graal.compiler.asm.aarch64.AArch64Assembler;
import jdk.graal.compiler.asm.aarch64.AArch64MacroAssembler;
import jdk.graal.compiler.core.common.CompressEncoding;
import jdk.graal.compiler.debug.GraalError;
import jdk.graal.compiler.hotspot.GraalHotSpotVMConfig;
import jdk.graal.compiler.lir.aarch64.AArch64Move;
import jdk.vm.ci.aarch64.AArch64;
Expand Down Expand Up @@ -81,23 +82,24 @@ public void verifyOop(Register value, Register tmp, Register tmp2, boolean compr
cbz(compressed ? 32 : 64, value, ok);
}

AArch64Address hubAddress;
int hubSize = config.useCompressedClassPointers ? 32 : 64;
Register object = value;
if (compressed) {
CompressEncoding encoding = config.getOopEncoding();
mov(32, tmp, value);
AArch64Move.UncompressPointerOp.emitUncompressCode(this, tmp, tmp, encoding, true, heapBaseRegister, false);
hubAddress = makeAddress(hubSize, tmp, config.hubOffset);
} else {
hubAddress = makeAddress(hubSize, value, config.hubOffset);
object = tmp;
}

// Load the class
if (config.useCompressedClassPointers) {
ldr(32, tmp, hubAddress);
if (config.useCompactObjectHeaders) {
loadCompactClassPointer(tmp, object);
} else {
ldr(32, tmp, makeAddress(32, object, config.hubOffset));
}
AArch64HotSpotMove.decodeKlassPointer(this, tmp, tmp, config.getKlassEncoding());
} else {
ldr(64, tmp, hubAddress);
ldr(64, tmp, makeAddress(64, object, config.hubOffset));
}
// Klass::_super_check_offset
ldr(32, tmp2, makeAddress(32, tmp, config.superCheckOffsetOffset));
Expand Down Expand Up @@ -127,4 +129,9 @@ public void verifyHeapBase() {
}
}

public void loadCompactClassPointer(Register result, Register receiver) {
GraalError.guarantee(config.useCompactObjectHeaders, "Load class pointer from markWord only when UseCompactObjectHeaders is on");
ldr(64, result, makeAddress(64, receiver, config.markOffset));
lsr(64, result, result, config.markWordKlassShift);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationRes
JavaType[] parameterTypes = {providers.getMetaAccess().lookupJavaType(Object.class)};
CallingConvention cc = regConfig.getCallingConvention(HotSpotCallingConventionType.JavaCallee, null, parameterTypes, this);
Register receiver = asRegister(cc.getArgument(0));
AMD64Address src = new AMD64Address(receiver, config.hubOffset);
int before;
if (config.icSpeculatedKlassOffset == Integer.MAX_VALUE) {
crb.recordMark(HotSpotMarkId.UNVERIFIED_ENTRY);
Expand All @@ -347,18 +346,23 @@ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationRes
if (config.useCompressedClassPointers) {
Register register = r10;
Register heapBase = providers.getRegisters().getHeapBaseRegister();
AMD64HotSpotMove.decodeKlassPointer(asm, register, heapBase, src, config);
if (config.useCompactObjectHeaders) {
((AMD64HotSpotMacroAssembler) asm).loadCompactClassPointer(register, receiver);
} else {
asm.movl(register, new AMD64Address(receiver, config.hubOffset));
}
AMD64HotSpotMove.decodeKlassPointer(asm, register, heapBase, config);
if (config.narrowKlassBase != 0) {
// The heap base register was destroyed above, so restore it
if (config.narrowOopBase == 0L) {
asm.xorq(heapBase, heapBase);
asm.xorl(heapBase, heapBase);
} else {
asm.movq(heapBase, config.narrowOopBase);
}
}
before = asm.cmpqAndJcc(inlineCacheKlass, register, ConditionFlag.NotEqual, null, false);
} else {
before = asm.cmpqAndJcc(inlineCacheKlass, src, ConditionFlag.NotEqual, null, false);
before = asm.cmpqAndJcc(inlineCacheKlass, new AMD64Address(receiver, config.hubOffset), ConditionFlag.NotEqual, null, false);
}
crb.recordDirectCall(before, asm.position(), getForeignCalls().lookupForeignCall(IC_MISS_HANDLER), null);
} else {
Expand All @@ -376,6 +380,10 @@ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationRes
*/
inlineCacheCheckSize += 3 + 3;
}
if (config.useCompactObjectHeaders) {
// 4 bytes for extra shift instruction, 1 byte less for 0-displacement address
inlineCacheCheckSize += 3;
}
asm.align(config.codeEntryAlignment, asm.position() + inlineCacheCheckSize);

int startICCheck = asm.position();
Expand All @@ -384,10 +392,14 @@ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationRes

AMD64BaseAssembler.OperandSize size;
if (config.useCompressedClassPointers) {
asm.movl(temp, src);
if (config.useCompactObjectHeaders) {
((AMD64HotSpotMacroAssembler) asm).loadCompactClassPointer(temp, receiver);
} else {
asm.movl(temp, new AMD64Address(receiver, config.hubOffset));
}
size = AMD64BaseAssembler.OperandSize.DWORD;
} else {
asm.movptr(temp, src);
asm.movptr(temp, new AMD64Address(receiver, config.hubOffset));
size = AMD64BaseAssembler.OperandSize.QWORD;
}
before = asm.cmpAndJcc(size, temp, icSpeculatedKlass, ConditionFlag.NotEqual, null, false);
Expand Down
Loading