Skip to content

Commit 6722f8b

Browse files
committed
PPC64 implementation of Compact Object Headers (JEP 450)
1 parent b289ef8 commit 6722f8b

File tree

9 files changed

+122
-66
lines changed

9 files changed

+122
-66
lines changed

make/autoconf/jdk-options.m4

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,9 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE_COH],
689689
AC_MSG_RESULT([no (CDS default archive generation is disabled)])
690690
AVAILABLE=false
691691
elif test "x$OPENJDK_TARGET_CPU" != "xx86_64" &&
692-
test "x$OPENJDK_TARGET_CPU" != "xaarch64"; then
692+
test "x$OPENJDK_TARGET_CPU" != "xaarch64" &&
693+
test "x$OPENJDK_TARGET_CPU" != "xppc64" &&
694+
test "x$OPENJDK_TARGET_CPU" != "xppc64le"; then
693695
AC_MSG_RESULT([no (compact object headers not supported for this platform)])
694696
AVAILABLE=false
695697
else

src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,16 +1976,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
19761976
// We don't know the array types are compatible.
19771977
if (basic_type != T_OBJECT) {
19781978
// Simple test for basic type arrays.
1979-
if (UseCompressedClassPointers) {
1980-
// We don't need decode because we just need to compare.
1981-
__ lwz(tmp, oopDesc::klass_offset_in_bytes(), src);
1982-
__ lwz(tmp2, oopDesc::klass_offset_in_bytes(), dst);
1983-
__ cmpw(CCR0, tmp, tmp2);
1984-
} else {
1985-
__ ld(tmp, oopDesc::klass_offset_in_bytes(), src);
1986-
__ ld(tmp2, oopDesc::klass_offset_in_bytes(), dst);
1987-
__ cmpd(CCR0, tmp, tmp2);
1988-
}
1979+
__ cmp_klasses_from_objects(CCR0, src, dst, tmp, tmp2);
19891980
__ beq(CCR0, cont);
19901981
} else {
19911982
// For object arrays, if src is a sub class of dst then we can
@@ -2108,39 +2099,15 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
21082099
// but not necessarily exactly of type default_type.
21092100
Label known_ok, halt;
21102101
metadata2reg(default_type->constant_encoding(), tmp);
2111-
if (UseCompressedClassPointers) {
2112-
// Tmp holds the default type. It currently comes uncompressed after the
2113-
// load of a constant, so encode it.
2114-
__ encode_klass_not_null(tmp);
2115-
// Load the raw value of the dst klass, since we will be comparing
2116-
// uncompressed values directly.
2117-
__ lwz(tmp2, oopDesc::klass_offset_in_bytes(), dst);
2118-
__ cmpw(CCR0, tmp, tmp2);
2119-
if (basic_type != T_OBJECT) {
2120-
__ bne(CCR0, halt);
2121-
// Load the raw value of the src klass.
2122-
__ lwz(tmp2, oopDesc::klass_offset_in_bytes(), src);
2123-
__ cmpw(CCR0, tmp, tmp2);
2124-
__ beq(CCR0, known_ok);
2125-
} else {
2126-
__ beq(CCR0, known_ok);
2127-
__ cmpw(CCR0, src, dst);
2128-
__ beq(CCR0, known_ok);
2129-
}
2102+
__ cmp_klass(CCR0, dst, tmp, R11_scratch1, R12_scratch2);
2103+
if (basic_type != T_OBJECT) {
2104+
__ bne(CCR0, halt);
2105+
__ cmp_klass(CCR0, src, tmp, R11_scratch1, R12_scratch2);
2106+
__ beq(CCR0, known_ok);
21302107
} else {
2131-
__ ld(tmp2, oopDesc::klass_offset_in_bytes(), dst);
2132-
__ cmpd(CCR0, tmp, tmp2);
2133-
if (basic_type != T_OBJECT) {
2134-
__ bne(CCR0, halt);
2135-
// Load the raw value of the src klass.
2136-
__ ld(tmp2, oopDesc::klass_offset_in_bytes(), src);
2137-
__ cmpd(CCR0, tmp, tmp2);
2138-
__ beq(CCR0, known_ok);
2139-
} else {
2140-
__ beq(CCR0, known_ok);
2141-
__ cmpd(CCR0, src, dst);
2142-
__ beq(CCR0, known_ok);
2143-
}
2108+
__ beq(CCR0, known_ok);
2109+
__ cmpw(CCR0, src, dst);
2110+
__ beq(CCR0, known_ok);
21442111
}
21452112
__ bind(halt);
21462113
__ stop("incorrect type information in arraycopy");
@@ -2717,12 +2684,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
27172684
}
27182685
}
27192686

2720-
if (UseCompressedClassPointers) {
2721-
__ lwz(result, oopDesc::klass_offset_in_bytes(), obj);
2722-
__ decode_klass_not_null(result);
2723-
} else {
2724-
__ ld(result, oopDesc::klass_offset_in_bytes(), obj);
2725-
}
2687+
__ load_klass(result, obj);
27262688
}
27272689

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

src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,19 @@ void C1_MacroAssembler::try_allocate(
197197

198198
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
199199
assert_different_registers(obj, klass, len, t1, t2);
200-
load_const_optimized(t1, (intx)markWord::prototype().value());
201-
std(t1, oopDesc::mark_offset_in_bytes(), obj);
202-
store_klass(obj, klass);
200+
201+
if (UseCompactObjectHeaders) {
202+
ld(t1, in_bytes(Klass::prototype_header_offset()), klass);
203+
std(t1, oopDesc::mark_offset_in_bytes(), obj);
204+
} else {
205+
load_const_optimized(t1, (intx)markWord::prototype().value());
206+
std(t1, oopDesc::mark_offset_in_bytes(), obj);
207+
store_klass(obj, klass);
208+
}
209+
203210
if (len->is_valid()) {
204211
stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
205-
} else if (UseCompressedClassPointers) {
212+
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
206213
// Otherwise length is in the class gap.
207214
store_klass_gap(obj);
208215
}

src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ void C2_MacroAssembler::fast_unlock_lightweight(ConditionRegister flag, Register
4747
compiler_fast_unlock_lightweight_object(flag, obj, box, tmp1, tmp2, tmp3);
4848
}
4949

50+
void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Register obj, int disp) {
51+
// Note: Don't clobber obj anywhere in that method!
52+
53+
// The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
54+
// obj-start, so that we can load from the object's mark-word instead.
55+
ld(dst, disp - oopDesc::klass_offset_in_bytes(), obj);
56+
srdi(dst, dst, markWord::klass_shift);
57+
}
58+
5059
// Intrinsics for CompactStrings
5160

5261
// Compress char[] to byte[] by compressing 16 bytes at once.

src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
void fast_unlock_lightweight(ConditionRegister flag, Register obj, Register box,
3535
Register tmp1, Register tmp2, Register tmp3);
3636

37+
void load_narrow_klass_compact_c2(Register dst, Register obj, int disp);
38+
3739
// Intrinsics for CompactStrings
3840
// Compress char[] to byte[] by compressing 16 bytes at once.
3941
void string_compress_16(Register src, Register dst, Register cnt,

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,9 @@ int MacroAssembler::ic_check_size() {
12181218
num_ins = 7;
12191219
if (!implicit_null_checks_available) num_ins += 2;
12201220
}
1221+
1222+
if (UseCompactObjectHeaders) num_ins++;
1223+
12211224
return num_ins * BytesPerInstWord;
12221225
}
12231226

@@ -1245,7 +1248,9 @@ int MacroAssembler::ic_check(int end_alignment) {
12451248
if (use_trap_based_null_check) {
12461249
trap_null_check(receiver);
12471250
}
1248-
if (UseCompressedClassPointers) {
1251+
if (UseCompactObjectHeaders) {
1252+
load_narrow_klass_compact(tmp1, receiver);
1253+
} else if (UseCompressedClassPointers) {
12491254
lwz(tmp1, oopDesc::klass_offset_in_bytes(), receiver);
12501255
} else {
12511256
ld(tmp1, oopDesc::klass_offset_in_bytes(), receiver);
@@ -3239,6 +3244,7 @@ Register MacroAssembler::encode_klass_not_null(Register dst, Register src) {
32393244
}
32403245

32413246
void MacroAssembler::store_klass(Register dst_oop, Register klass, Register ck) {
3247+
assert(!UseCompactObjectHeaders, "not with compact headers");
32423248
if (UseCompressedClassPointers) {
32433249
Register compressedKlass = encode_klass_not_null(ck, klass);
32443250
stw(compressedKlass, oopDesc::klass_offset_in_bytes(), dst_oop);
@@ -3248,12 +3254,13 @@ void MacroAssembler::store_klass(Register dst_oop, Register klass, Register ck)
32483254
}
32493255

32503256
void MacroAssembler::store_klass_gap(Register dst_oop, Register val) {
3257+
assert(!UseCompactObjectHeaders, "not with compact headers");
32513258
if (UseCompressedClassPointers) {
32523259
if (val == noreg) {
32533260
val = R0;
32543261
li(val, 0);
32553262
}
3256-
stw(val, oopDesc::klass_gap_offset_in_bytes(), dst_oop); // klass gap if compressed
3263+
stw(val, oopDesc::klass_gap_offset_in_bytes(), dst_oop);
32573264
}
32583265
}
32593266

@@ -3294,15 +3301,60 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
32943301
}
32953302

32963303
void MacroAssembler::load_klass(Register dst, Register src) {
3297-
if (UseCompressedClassPointers) {
3304+
if (UseCompactObjectHeaders) {
3305+
load_narrow_klass_compact(dst, src);
3306+
decode_klass_not_null(dst);
3307+
} else if (UseCompressedClassPointers) {
32983308
lwz(dst, oopDesc::klass_offset_in_bytes(), src);
3299-
// Attention: no null check here!
3300-
decode_klass_not_null(dst, dst);
3309+
decode_klass_not_null(dst);
33013310
} else {
33023311
ld(dst, oopDesc::klass_offset_in_bytes(), src);
33033312
}
33043313
}
33053314

3315+
// Loads the obj's Klass* into dst.
3316+
// Preserves all registers (incl src, rscratch1 and rscratch2).
3317+
// Input:
3318+
// src - the oop we want to load the klass from.
3319+
// dst - output nklass.
3320+
void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
3321+
assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
3322+
ld(dst, oopDesc::mark_offset_in_bytes(), src);
3323+
srdi(dst, dst, markWord::klass_shift);
3324+
}
3325+
3326+
void MacroAssembler::cmp_klass(ConditionRegister dst, Register obj, Register klass, Register tmp, Register tmp2) {
3327+
assert_different_registers(obj, klass, tmp);
3328+
if (UseCompressedClassPointers) {
3329+
if (UseCompactObjectHeaders) {
3330+
load_narrow_klass_compact(tmp, obj);
3331+
} else {
3332+
lwz(tmp, oopDesc::klass_offset_in_bytes(), obj);
3333+
}
3334+
Register encoded_klass = encode_klass_not_null(tmp2, klass);
3335+
cmpw(dst, tmp, encoded_klass);
3336+
} else {
3337+
ld(tmp, oopDesc::klass_offset_in_bytes(), obj);
3338+
cmpd(dst, tmp, klass);
3339+
}
3340+
}
3341+
3342+
void MacroAssembler::cmp_klasses_from_objects(ConditionRegister dst, Register obj1, Register obj2, Register tmp1, Register tmp2) {
3343+
if (UseCompactObjectHeaders) {
3344+
load_narrow_klass_compact(tmp1, obj1);
3345+
load_narrow_klass_compact(tmp2, obj2);
3346+
cmpw(dst, tmp1, tmp2);
3347+
} else if (UseCompressedClassPointers) {
3348+
lwz(tmp1, oopDesc::klass_offset_in_bytes(), obj1);
3349+
lwz(tmp2, oopDesc::klass_offset_in_bytes(), obj2);
3350+
cmpw(dst, tmp1, tmp2);
3351+
} else {
3352+
ld(tmp1, oopDesc::klass_offset_in_bytes(), obj1);
3353+
ld(tmp2, oopDesc::klass_offset_in_bytes(), obj2);
3354+
cmpd(dst, tmp1, tmp2);
3355+
}
3356+
}
3357+
33063358
void MacroAssembler::load_klass_check_null(Register dst, Register src, Label* is_null) {
33073359
null_check(src, oopDesc::klass_offset_in_bytes(), is_null);
33083360
load_klass(dst, src);

src/hotspot/cpu/ppc/macroAssembler_ppc.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,9 @@ class MacroAssembler: public Assembler {
757757

758758
// Load/Store klass oop from klass field. Compress.
759759
void load_klass(Register dst, Register src);
760+
void load_narrow_klass_compact(Register dst, Register src);
761+
void cmp_klass(ConditionRegister dst, Register obj, Register klass, Register tmp, Register tmp2);
762+
void cmp_klasses_from_objects(ConditionRegister dst, Register obj1, Register obj2, Register tmp1, Register tmp2);
760763
void load_klass_check_null(Register dst, Register src, Label* is_null = nullptr);
761764
void store_klass(Register dst_oop, Register klass, Register tmp = R0);
762765
void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.

src/hotspot/cpu/ppc/ppc.ad

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5500,6 +5500,7 @@ instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{
55005500
// Load compressed klass pointer.
55015501
instruct loadNKlass(iRegNdst dst, memory mem) %{
55025502
match(Set dst (LoadNKlass mem));
5503+
predicate(!UseCompactObjectHeaders);
55035504
ins_cost(MEMORY_REF_COST);
55045505

55055506
format %{ "LWZ $dst, $mem \t// compressed klass ptr" %}
@@ -5508,6 +5509,20 @@ instruct loadNKlass(iRegNdst dst, memory mem) %{
55085509
ins_pipe(pipe_class_memory);
55095510
%}
55105511

5512+
instruct loadNKlassCompactHeaders(iRegNdst dst, memory mem) %{
5513+
match(Set dst (LoadNKlass mem));
5514+
predicate(UseCompactObjectHeaders);
5515+
ins_cost(MEMORY_REF_COST);
5516+
5517+
format %{ "load_narrow_klass_compact $dst, $mem \t// compressed class ptr" %}
5518+
size(8);
5519+
ins_encode %{
5520+
assert($mem$$index$$Register == R0, "must not have indexed address: %s[%s]", $mem$$base$$Register.name(), $mem$$index$$Register.name());
5521+
__ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp);
5522+
%}
5523+
ins_pipe(pipe_class_memory);
5524+
%}
5525+
55115526
// Load Klass Pointer
55125527
instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
55135528
match(Set dst (LoadKlass mem));

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3840,8 +3840,9 @@ void TemplateTable::_new() {
38403840
// Init1: Zero out newly allocated memory.
38413841
// Initialize remaining object fields.
38423842
Register Rbase = Rtags;
3843-
__ addi(Rinstance_size, Rinstance_size, 7 - (int)sizeof(oopDesc));
3844-
__ addi(Rbase, RallocatedObject, sizeof(oopDesc));
3843+
int header_size = oopDesc::header_size() * HeapWordSize;
3844+
__ addi(Rinstance_size, Rinstance_size, 7 - header_size);
3845+
__ addi(Rbase, RallocatedObject, header_size);
38453846
__ srdi(Rinstance_size, Rinstance_size, 3);
38463847

38473848
// Clear out object skipping header. Takes also care of the zero length case.
@@ -3851,12 +3852,15 @@ void TemplateTable::_new() {
38513852
// --------------------------------------------------------------------------
38523853
// Init2: Initialize the header: mark, klass
38533854
// Init mark.
3854-
__ load_const_optimized(Rscratch, markWord::prototype().value(), R0);
3855-
__ std(Rscratch, oopDesc::mark_offset_in_bytes(), RallocatedObject);
3856-
3857-
// Init klass.
3858-
__ store_klass_gap(RallocatedObject);
3859-
__ store_klass(RallocatedObject, RinstanceKlass, Rscratch); // klass (last for cms)
3855+
if (UseCompactObjectHeaders) {
3856+
__ ld(Rscratch, in_bytes(Klass::prototype_header_offset()), RinstanceKlass);
3857+
__ std(Rscratch, oopDesc::mark_offset_in_bytes(), RallocatedObject);
3858+
} else {
3859+
__ load_const_optimized(Rscratch, markWord::prototype().value(), R0);
3860+
__ std(Rscratch, oopDesc::mark_offset_in_bytes(), RallocatedObject);
3861+
__ store_klass_gap(RallocatedObject);
3862+
__ store_klass(RallocatedObject, RinstanceKlass, Rscratch);
3863+
}
38603864

38613865
// Check and trigger dtrace event.
38623866
if (DTraceAllocProbes) {

0 commit comments

Comments
 (0)