Skip to content

Commit 44ec501

Browse files
rkennkeSandhya ViswanathanTheRealMDoerrHamlin Litstuefe
committed
8305895: Implement JEP 450: Compact Object Headers (Experimental)
Co-authored-by: Sandhya Viswanathan <sviswanathan@openjdk.org> Co-authored-by: Martin Doerr <mdoerr@openjdk.org> Co-authored-by: Hamlin Li <mli@openjdk.org> Co-authored-by: Thomas Stuefe <stuefe@openjdk.org> Co-authored-by: Amit Kumar <amitkumar@openjdk.org> Co-authored-by: Stefan Karlsson <stefank@openjdk.org> Co-authored-by: Coleen Phillimore <coleenp@openjdk.org> Co-authored-by: Axel Boldt-Christmas <aboldtch@openjdk.org> Reviewed-by: coleenp, stefank, stuefe, phh, ihse, lmesnik, tschatzl, matsaave, rcastanedalo, vpaprotski, yzheng, egahlin
1 parent 6053962 commit 44ec501

File tree

218 files changed

+4348
-1627
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

218 files changed

+4348
-1627
lines changed

make/Images.gmk

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,16 @@ CDS_DUMP_FLAGS = -Xmx128M -Xms128M
132132
# Helper function for creating the CDS archives for the JDK and JRE
133133
#
134134
# Param1 - VM variant (e.g., server, client, zero, ...)
135-
# Param2 - _nocoops, or empty
135+
# Param2 - _nocoops, _coh, _nocoops_coh, or empty
136136
define CreateCDSArchive
137-
$1_$2_DUMP_EXTRA_ARG := $(if $(filter _nocoops, $2), -XX:-UseCompressedOops, )
138-
$1_$2_DUMP_TYPE := $(if $(filter _nocoops, $2), -NOCOOPS, )
137+
$1_$2_COOPS_OPTION := $(if $(findstring _nocoops, $2),-XX:-UseCompressedOops)
138+
# enable and also explicitly disable coh as needed.
139+
ifeq ($(call isTargetCpuBits, 64), true)
140+
$1_$2_COH_OPTION := -XX:+UnlockExperimentalVMOptions \
141+
$(if $(findstring _coh, $2),-XX:+UseCompactObjectHeaders,-XX:-UseCompactObjectHeaders)
142+
endif
143+
$1_$2_DUMP_EXTRA_ARG := $$($1_$2_COOPS_OPTION) $$($1_$2_COH_OPTION)
144+
$1_$2_DUMP_TYPE := $(if $(findstring _nocoops, $2),-NOCOOPS,)$(if $(findstring _coh, $2),-COH,)
139145

140146
# Only G1 supports dumping the shared heap, so explicitly use G1 if the JVM supports it.
141147
$1_$2_CDS_DUMP_FLAGS := $(CDS_DUMP_FLAGS) $(if $(filter g1gc, $(JVM_FEATURES_$1)), -XX:+UseG1GC)
@@ -190,6 +196,14 @@ ifeq ($(BUILD_CDS_ARCHIVE), true)
190196
$(foreach v, $(JVM_VARIANTS), \
191197
$(eval $(call CreateCDSArchive,$v,_nocoops)) \
192198
)
199+
ifeq ($(BUILD_CDS_ARCHIVE_COH), true)
200+
$(foreach v, $(JVM_VARIANTS), \
201+
$(eval $(call CreateCDSArchive,$v,_coh)) \
202+
)
203+
$(foreach v, $(JVM_VARIANTS), \
204+
$(eval $(call CreateCDSArchive,$v,_nocoops_coh)) \
205+
)
206+
endif
193207
endif
194208
endif
195209

make/autoconf/configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST
261261
JDKOPT_EXCLUDE_TRANSLATIONS
262262
JDKOPT_ENABLE_DISABLE_MANPAGES
263263
JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE
264+
JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE_COH
264265
JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT
265266
JDKOPT_SETUP_MACOSX_SIGNING
266267

make/autoconf/jdk-options.m4

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,37 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE],
673673
AC_SUBST(BUILD_CDS_ARCHIVE)
674674
])
675675

676+
################################################################################
677+
#
678+
# Enable or disable the default CDS archive generation for Compact Object Headers
679+
#
680+
AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE_COH],
681+
[
682+
UTIL_ARG_ENABLE(NAME: cds-archive-coh, DEFAULT: auto, RESULT: BUILD_CDS_ARCHIVE_COH,
683+
DESC: [enable generation of default CDS archives for compact object headers (requires --enable-cds-archive)],
684+
DEFAULT_DESC: [auto],
685+
CHECKING_MSG: [if default CDS archives for compact object headers should be generated],
686+
CHECK_AVAILABLE: [
687+
AC_MSG_CHECKING([if CDS archive with compact object headers is available])
688+
if test "x$BUILD_CDS_ARCHIVE" = "xfalse"; then
689+
AC_MSG_RESULT([no (CDS default archive generation is disabled)])
690+
AVAILABLE=false
691+
elif test "x$OPENJDK_TARGET_CPU" != "xx86_64" &&
692+
test "x$OPENJDK_TARGET_CPU" != "xaarch64" &&
693+
test "x$OPENJDK_TARGET_CPU" != "xppc64" &&
694+
test "x$OPENJDK_TARGET_CPU" != "xppc64le" &&
695+
test "x$OPENJDK_TARGET_CPU" != "xriscv64" &&
696+
test "x$OPENJDK_TARGET_CPU" != "xs390x"; then
697+
AC_MSG_RESULT([no (compact object headers not supported for this platform)])
698+
AVAILABLE=false
699+
else
700+
AC_MSG_RESULT([yes])
701+
AVAILABLE=true
702+
fi
703+
])
704+
AC_SUBST(BUILD_CDS_ARCHIVE_COH)
705+
])
706+
676707
################################################################################
677708
#
678709
# Enable the alternative CDS core region alignment

make/autoconf/spec.gmk.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ EXCLUDE_TRANSLATIONS := @EXCLUDE_TRANSLATIONS@
370370
BUILD_MANPAGES := @BUILD_MANPAGES@
371371

372372
BUILD_CDS_ARCHIVE := @BUILD_CDS_ARCHIVE@
373+
BUILD_CDS_ARCHIVE_COH := @BUILD_CDS_ARCHIVE_COH@
373374

374375
ENABLE_COMPATIBLE_CDS_ALIGNMENT := @ENABLE_COMPATIBLE_CDS_ALIGNMENT@
375376

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5756,6 +5756,10 @@ opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indInde
57565756
indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
57575757

57585758

5759+
opclass memory_noindex(indirect,
5760+
indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5761+
indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5762+
57595763
// iRegIorL2I is used for src inputs in rules for 32 bit int (I)
57605764
// operations. it allows the src to be either an iRegI or a (ConvL2I
57615765
// iRegL). in the latter case the l2i normally planted for a ConvL2I
@@ -6682,7 +6686,7 @@ instruct loadKlass(iRegPNoSp dst, memory8 mem)
66826686
instruct loadNKlass(iRegNNoSp dst, memory4 mem)
66836687
%{
66846688
match(Set dst (LoadNKlass mem));
6685-
predicate(!needs_acquiring_load(n));
6689+
predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
66866690

66876691
ins_cost(4 * INSN_COST);
66886692
format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
@@ -6692,6 +6696,20 @@ instruct loadNKlass(iRegNNoSp dst, memory4 mem)
66926696
ins_pipe(iload_reg_mem);
66936697
%}
66946698

6699+
instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem)
6700+
%{
6701+
match(Set dst (LoadNKlass mem));
6702+
predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6703+
6704+
ins_cost(4 * INSN_COST);
6705+
format %{ "load_narrow_klass_compact $dst, $mem\t# compressed class ptr" %}
6706+
ins_encode %{
6707+
assert($mem$$index$$Register == noreg, "must not have indexed address");
6708+
__ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
6709+
%}
6710+
ins_pipe(iload_reg_mem);
6711+
%}
6712+
66956713
// Load Float
66966714
instruct loadF(vRegF dst, memory4 mem)
66976715
%{

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,8 +2243,6 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
22432243

22442244
Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
22452245
Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
2246-
Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
2247-
Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
22482246

22492247
// test for null
22502248
if (flags & LIR_OpArrayCopy::src_null_check) {
@@ -2305,15 +2303,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
23052303
// We don't know the array types are compatible
23062304
if (basic_type != T_OBJECT) {
23072305
// Simple test for basic type arrays
2308-
if (UseCompressedClassPointers) {
2309-
__ ldrw(tmp, src_klass_addr);
2310-
__ ldrw(rscratch1, dst_klass_addr);
2311-
__ cmpw(tmp, rscratch1);
2312-
} else {
2313-
__ ldr(tmp, src_klass_addr);
2314-
__ ldr(rscratch1, dst_klass_addr);
2315-
__ cmp(tmp, rscratch1);
2316-
}
2306+
__ cmp_klasses_from_objects(src, dst, tmp, rscratch1);
23172307
__ br(Assembler::NE, *stub->entry());
23182308
} else {
23192309
// For object arrays, if src is a sub class of dst then we can
@@ -2435,36 +2425,14 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
24352425
// but not necessarily exactly of type default_type.
24362426
Label known_ok, halt;
24372427
__ mov_metadata(tmp, default_type->constant_encoding());
2438-
if (UseCompressedClassPointers) {
2439-
__ encode_klass_not_null(tmp);
2440-
}
24412428

24422429
if (basic_type != T_OBJECT) {
2443-
2444-
if (UseCompressedClassPointers) {
2445-
__ ldrw(rscratch1, dst_klass_addr);
2446-
__ cmpw(tmp, rscratch1);
2447-
} else {
2448-
__ ldr(rscratch1, dst_klass_addr);
2449-
__ cmp(tmp, rscratch1);
2450-
}
2430+
__ cmp_klass(dst, tmp, rscratch1);
24512431
__ br(Assembler::NE, halt);
2452-
if (UseCompressedClassPointers) {
2453-
__ ldrw(rscratch1, src_klass_addr);
2454-
__ cmpw(tmp, rscratch1);
2455-
} else {
2456-
__ ldr(rscratch1, src_klass_addr);
2457-
__ cmp(tmp, rscratch1);
2458-
}
2432+
__ cmp_klass(src, tmp, rscratch1);
24592433
__ br(Assembler::EQ, known_ok);
24602434
} else {
2461-
if (UseCompressedClassPointers) {
2462-
__ ldrw(rscratch1, dst_klass_addr);
2463-
__ cmpw(tmp, rscratch1);
2464-
} else {
2465-
__ ldr(rscratch1, dst_klass_addr);
2466-
__ cmp(tmp, rscratch1);
2467-
}
2435+
__ cmp_klass(dst, tmp, rscratch1);
24682436
__ br(Assembler::EQ, known_ok);
24692437
__ cmp(src, dst);
24702438
__ br(Assembler::EQ, known_ok);
@@ -2547,12 +2515,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
25472515
add_debug_info_for_null_check_here(info);
25482516
}
25492517

2550-
if (UseCompressedClassPointers) {
2551-
__ ldrw(result, Address (obj, oopDesc::klass_offset_in_bytes()));
2552-
__ decode_klass_not_null(result);
2553-
} else {
2554-
__ ldr(result, Address (obj, oopDesc::klass_offset_in_bytes()));
2555-
}
2518+
__ load_klass(result, obj);
25562519
}
25572520

25582521
void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,19 @@ void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, i
175175

176176
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
177177
assert_different_registers(obj, klass, len);
178-
// This assumes that all prototype bits fit in an int32_t
179-
mov(t1, (int32_t)(intptr_t)markWord::prototype().value());
180-
str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
181178

182-
if (UseCompressedClassPointers) { // Take care not to kill klass
183-
encode_klass_not_null(t1, klass);
184-
strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
179+
if (UseCompactObjectHeaders) {
180+
ldr(t1, Address(klass, Klass::prototype_header_offset()));
181+
str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
185182
} else {
186-
str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
183+
mov(t1, checked_cast<int32_t>(markWord::prototype().value()));
184+
str(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
185+
if (UseCompressedClassPointers) { // Take care not to kill klass
186+
encode_klass_not_null(t1, klass);
187+
strw(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
188+
} else {
189+
str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
190+
}
187191
}
188192

189193
if (len->is_valid()) {
@@ -194,7 +198,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
194198
// Clear gap/first 4 bytes following the length field.
195199
strw(zr, Address(obj, base_offset));
196200
}
197-
} else if (UseCompressedClassPointers) {
201+
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
198202
store_klass_gap(obj, zr);
199203
}
200204
}

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2689,3 +2689,12 @@ bool C2_MacroAssembler::in_scratch_emit_size() {
26892689
}
26902690
return MacroAssembler::in_scratch_emit_size();
26912691
}
2692+
2693+
void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Register obj, int disp) {
2694+
// Note: Don't clobber obj anywhere in that method!
2695+
2696+
// The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
2697+
// obj-start, so that we can load from the object's mark-word instead.
2698+
ldr(dst, Address(obj, disp - oopDesc::klass_offset_in_bytes()));
2699+
lsr(dst, dst, markWord::klass_shift);
2700+
}

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,6 @@
186186
void vector_signum_sve(FloatRegister dst, FloatRegister src, FloatRegister zero,
187187
FloatRegister one, FloatRegister vtmp, PRegister pgtmp, SIMD_RegVariant T);
188188

189+
void load_narrow_klass_compact_c2(Register dst, Register obj, int disp);
190+
189191
#endif // CPU_AARCH64_C2_MACROASSEMBLER_AARCH64_HPP

src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,3 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size
117117

118118
return result;
119119
}
120-
121-
void CompressedKlassPointers::initialize(address addr, size_t len) {
122-
constexpr uintptr_t unscaled_max = nth_bit(32);
123-
assert(len <= unscaled_max, "Klass range larger than 32 bits?");
124-
125-
// Shift is always 0 on aarch64.
126-
_shift = 0;
127-
128-
// On aarch64, we don't bother with zero-based encoding (base=0 shift>0).
129-
address const end = addr + len;
130-
_base = (end <= (address)unscaled_max) ? nullptr : addr;
131-
132-
// Remember the Klass range:
133-
_klass_range_start = addr;
134-
_klass_range_end = addr + len;
135-
}

0 commit comments

Comments
 (0)