Skip to content

Commit 0a0ff23

Browse files
committed
WIP: AOSCOS: LOONGARCH: Port of JEP 450: Compact Object Headers (Experimental)
Fixes: 44ec501 ("8305895: Implement JEP 450: Compact Object Headers (Experimental)") Fixes: ff12ff5 ("8340453: C2: Improve encoding of LoadNKlass for compact headers") Follow-up: 44ec501 ("8305895: Implement JEP 450: Compact Object Headers (Experimental)") Follow-up: ff12ff5 ("8340453: C2: Improve encoding of LoadNKlass for compact headers") Link: openjdk#20677 Link: openjdk#22203 Signed-off-by: Bingwu Zhang <[email protected]>
1 parent ea82ba4 commit 0a0ff23

8 files changed

+169
-83
lines changed

src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp

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

25172517
Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
25182518
Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
2519-
Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
2520-
Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
25212519

25222520
// test for null
25232521
if (flags & LIR_OpArrayCopy::src_null_check) {
@@ -2573,14 +2571,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
25732571
// We don't know the array types are compatible
25742572
if (basic_type != T_OBJECT) {
25752573
// Simple test for basic type arrays
2576-
if (UseCompressedClassPointers) {
2577-
__ ld_wu(tmp, src_klass_addr);
2578-
__ ld_wu(SCR1, dst_klass_addr);
2579-
} else {
2580-
__ ld_d(tmp, src_klass_addr);
2581-
__ ld_d(SCR1, dst_klass_addr);
2582-
}
2583-
__ bne_far(tmp, SCR1, *stub->entry());
2574+
__ cmp_klass(dst, src, tmp, SCR1, *stub->entry(), false, true);
25842575
} else {
25852576
// For object arrays, if src is a sub class of dst then we can
25862577
// safely do the copy.
@@ -2716,26 +2707,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
27162707
}
27172708

27182709
if (basic_type != T_OBJECT) {
2719-
2720-
if (UseCompressedClassPointers) {
2721-
__ ld_wu(SCR1, dst_klass_addr);
2722-
} else {
2723-
__ ld_d(SCR1, dst_klass_addr);
2724-
}
2725-
__ bne(tmp, SCR1, halt);
2726-
if (UseCompressedClassPointers) {
2727-
__ ld_wu(SCR1, src_klass_addr);
2728-
} else {
2729-
__ ld_d(SCR1, src_klass_addr);
2730-
}
2731-
__ beq(tmp, SCR1, known_ok);
2710+
__ cmp_klass_compressed(dst, tmp, SCR1, halt, false);
2711+
__ cmp_klass_compressed(src, tmp, SCR1, known_ok, true);
27322712
} else {
2733-
if (UseCompressedClassPointers) {
2734-
__ ld_wu(SCR1, dst_klass_addr);
2735-
} else {
2736-
__ ld_d(SCR1, dst_klass_addr);
2737-
}
2738-
__ beq(tmp, SCR1, known_ok);
2713+
__ cmp_klass_compressed(dst, tmp, SCR1, known_ok, true);
27392714
__ beq(src, dst, known_ok);
27402715
}
27412716
__ bind(halt);
@@ -2814,12 +2789,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
28142789
add_debug_info_for_null_check_here(info);
28152790
}
28162791

2817-
if (UseCompressedClassPointers) {
2818-
__ ld_wu(result, obj, oopDesc::klass_offset_in_bytes());
2819-
__ decode_klass_not_null(result);
2820-
} else {
2821-
__ ld_d(result, obj, oopDesc::klass_offset_in_bytes());
2822-
}
2792+
__ load_klass(result, obj);
28232793
}
28242794

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

src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ using MacroAssembler::null_check;
4646
Label& slow_case // continuation point if fast allocation fails
4747
);
4848

49-
void initialize_header(Register obj, Register klass, Register len, Register t1, Register t2);
49+
void initialize_header(Register obj, Register klass, Register len, Register t1);
5050
void initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1, Register t2);
5151

5252
// locking

src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "oops/arrayOop.hpp"
3434
#include "oops/markWord.hpp"
3535
#include "runtime/basicLock.hpp"
36+
#include "runtime/globals.hpp"
3637
#include "runtime/os.hpp"
3738
#include "runtime/sharedRuntime.hpp"
3839
#include "runtime/stubRoutines.hpp"
@@ -150,17 +151,21 @@ void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes,
150151
}
151152

152153
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len,
153-
Register t1, Register t2) {
154+
Register t1) {
154155
assert_different_registers(obj, klass, len);
155-
// This assumes that all prototype bits fit in an int32_t
156-
li(t1, (int32_t)(intptr_t)markWord::prototype().value());
157-
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
158-
159-
if (UseCompressedClassPointers) { // Take care not to kill klass
160-
encode_klass_not_null(t1, klass);
161-
st_w(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
156+
if (UseCompactObjectHeaders) {
157+
ld_d(t1, Address(klass, Klass::prototype_header_offset()));
158+
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
162159
} else {
163-
st_d(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
160+
// This assumes that all prototype bits fit in an int32_t
161+
li(t1, (int32_t)(intptr_t)markWord::prototype().value());
162+
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
163+
if (UseCompressedClassPointers) { // Take care not to kill klass
164+
encode_klass_not_null(t1, klass);
165+
st_w(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
166+
} else {
167+
st_d(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
168+
}
164169
}
165170

166171
if (len->is_valid()) {
@@ -171,7 +176,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
171176
// Clear gap/first 4 bytes following the length field.
172177
st_w(R0, Address(obj, base_offset));
173178
}
174-
} else if (UseCompressedClassPointers) {
179+
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
175180
store_klass_gap(obj, R0);
176181
}
177182
}
@@ -221,7 +226,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
221226
"con_size_in_bytes is not multiple of alignment");
222227
const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
223228

224-
initialize_header(obj, klass, noreg, t1, t2);
229+
initialize_header(obj, klass, noreg, t1);
225230

226231
if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) {
227232
// clear rest of allocated space
@@ -272,7 +277,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
272277

273278
try_allocate(obj, arr_size, 0, t1, t2, slow_case);
274279

275-
initialize_header(obj, klass, len, t1, t2);
280+
initialize_header(obj, klass, len, t1);
276281

277282
// Align-up to word boundary, because we clear the 4 bytes potentially
278283
// following the length field in initialize_header().

src/hotspot/cpu/loongarch/compressedKlass_loongarch.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size
5757
result = reserve_address_space_for_zerobased_encoding(size, aslr);
5858
}
5959

60-
// Failing that, optimize for case (3) - a base with only bits set between [33-52)
60+
// Failing that, optimize for case (3) - a base with only bits set between [32-52)
6161
if (result == nullptr) {
62-
const uintptr_t from = nth_bit(32 + (optimize_for_zero_base ? LogKlassAlignmentInBytes : 0));
62+
const uintptr_t from = nth_bit(32);
6363
constexpr uintptr_t to = nth_bit(52);
6464
constexpr size_t alignment = nth_bit(32);
6565
result = reserve_address_space_X(from, to, size, alignment, aslr);

src/hotspot/cpu/loongarch/loongarch_64.ad

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4276,6 +4276,7 @@ instruct loadKlass(mRegP dst, memory mem) %{
42764276
// Load narrow Klass Pointer
42774277
instruct loadNKlass(mRegN dst, memory mem)
42784278
%{
4279+
predicate(!UseCompactObjectHeaders);
42794280
match(Set dst (LoadNKlass mem));
42804281

42814282
ins_cost(125);
@@ -4288,6 +4289,25 @@ instruct loadNKlass(mRegN dst, memory mem)
42884289
ins_pipe( ialu_load );
42894290
%}
42904291

4292+
instruct loadNKlassCompactHeaders(mRegN dst, memory mem)
4293+
%{
4294+
predicate(UseCompactObjectHeaders);
4295+
match(Set dst (LoadNKlass mem));
4296+
4297+
ins_cost(125);
4298+
format %{
4299+
"ld_wu $dst, $mem\t# compressed klass ptr, shifted\n\t"
4300+
"srli_d $dst, $dst, markWord::klass_shift_at_offset"
4301+
%}
4302+
4303+
ins_encode %{
4304+
__ ld_wu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
4305+
__ srli_d(as_Register($dst$$reg), as_Register($dst$$reg), (unsigned) markWord::klass_shift_at_offset);
4306+
%}
4307+
4308+
ins_pipe( ialu_load );
4309+
%}
4310+
42914311
instruct loadN2PKlass(mRegP dst, memory mem)
42924312
%{
42934313
match(Set dst (DecodeNKlass (LoadNKlass mem)));

src/hotspot/cpu/loongarch/macroAssembler_loongarch.cpp

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,49 @@ void MacroAssembler::wrap_label(Register r, Label &L, reg_addr_insn insn) {
492492
}
493493
}
494494

495+
void MacroAssembler::cmp_klass(Register obj1, Register obj2, Register tmp1,
496+
Register tmp2, Label &L, bool equal, bool far) {
497+
if (UseCompactObjectHeaders) {
498+
load_narrow_klass_compact(tmp1, obj1);
499+
load_narrow_klass_compact(tmp2, obj2);
500+
} else if (UseCompressedClassPointers) {
501+
ld_wu(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
502+
ld_wu(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));
503+
} else {
504+
ld_d(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
505+
ld_d(tmp1, Address(obj2, oopDesc::klass_offset_in_bytes()));
506+
}
507+
if (equal) {
508+
if (far) {
509+
beq_far(tmp1, tmp2, L);
510+
} else {
511+
beq(tmp1, tmp2, L);
512+
}
513+
} else {
514+
if (far) {
515+
bne_far(tmp1, tmp2, L);
516+
} else {
517+
bne(tmp1, tmp2, L);
518+
}
519+
}
520+
}
521+
522+
void MacroAssembler::cmp_klass_compressed(Register obj, Register klass,
523+
Register tmp1, Label &L, bool equal) {
524+
if (UseCompactObjectHeaders) {
525+
load_narrow_klass_compact(tmp1, obj);
526+
} else if (UseCompressedClassPointers) {
527+
ld_wu(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
528+
} else {
529+
ld_d(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
530+
}
531+
if (equal) {
532+
beq(tmp1, klass, L);
533+
} else {
534+
bne(tmp1, klass, L);
535+
}
536+
}
537+
495538
// Move an oop into a register.
496539
void MacroAssembler::movoop(Register dst, jobject obj) {
497540
int oop_index;
@@ -610,7 +653,10 @@ address MacroAssembler::ic_call(address entry, jint method_index) {
610653
}
611654

612655
int MacroAssembler::ic_check_size() {
613-
return 4 * 5;
656+
return 4 * (/* beq */ 1 + /* patchable jump(force patchable) */ 2 +
657+
/* load klass */
658+
(UseCompactObjectHeaders ? 3 /* load_narrow_klass_compact + 1 */
659+
: 2 /* ld + ld */));
614660
}
615661

616662
int MacroAssembler::ic_check(int end_alignment) {
@@ -626,7 +672,10 @@ int MacroAssembler::ic_check(int end_alignment) {
626672
align(end_alignment, offset() + ic_check_size());
627673
int uep_offset = offset();
628674

629-
if (UseCompressedClassPointers) {
675+
if (UseCompactObjectHeaders) {
676+
load_narrow_klass_compact(tmp1, receiver);
677+
ld_wu(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
678+
} else if (UseCompressedClassPointers) {
630679
ld_wu(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
631680
ld_wu(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
632681
} else {
@@ -2049,15 +2098,25 @@ void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod)
20492098

20502099
// for UseCompressedOops Option
20512100
void MacroAssembler::load_klass(Register dst, Register src) {
2052-
if(UseCompressedClassPointers){
2101+
if (UseCompactObjectHeaders) {
2102+
load_narrow_klass_compact(dst, src);
2103+
decode_klass_not_null(dst);
2104+
} else if (UseCompressedClassPointers) {
20532105
ld_wu(dst, Address(src, oopDesc::klass_offset_in_bytes()));
20542106
decode_klass_not_null(dst);
20552107
} else {
20562108
ld_d(dst, src, oopDesc::klass_offset_in_bytes());
20572109
}
20582110
}
20592111

2112+
void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
2113+
assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
2114+
ld_d(dst, Address(src, oopDesc::mark_offset_in_bytes()));
2115+
srli_d(dst, dst, markWord::klass_shift);
2116+
}
2117+
20602118
void MacroAssembler::store_klass(Register dst, Register src) {
2119+
assert(!UseCompactObjectHeaders, "not with compact headers");
20612120
if(UseCompressedClassPointers){
20622121
encode_klass_not_null(src);
20632122
st_w(src, dst, oopDesc::klass_offset_in_bytes());
@@ -2067,6 +2126,7 @@ void MacroAssembler::store_klass(Register dst, Register src) {
20672126
}
20682127

20692128
void MacroAssembler::store_klass_gap(Register dst, Register src) {
2129+
assert(!UseCompactObjectHeaders, "not with compact headers");
20702130
if (UseCompressedClassPointers) {
20712131
st_w(src, dst, oopDesc::klass_gap_offset_in_bytes());
20722132
}
@@ -2350,8 +2410,7 @@ void MacroAssembler::encode_klass_not_null(Register r) {
23502410
sub_d(r, r, AT);
23512411
}
23522412
if (CompressedKlassPointers::shift() != 0) {
2353-
assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2354-
srli_d(r, r, LogKlassAlignmentInBytes);
2413+
srli_d(r, r, CompressedKlassPointers::shift());
23552414
}
23562415
}
23572416

@@ -2368,13 +2427,11 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
23682427
li(dst, (int64_t)CompressedKlassPointers::base());
23692428
sub_d(dst, src, dst);
23702429
if (CompressedKlassPointers::shift() != 0) {
2371-
assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2372-
srli_d(dst, dst, LogKlassAlignmentInBytes);
2430+
srli_d(dst, dst, CompressedKlassPointers::shift());
23732431
}
23742432
} else {
23752433
if (CompressedKlassPointers::shift() != 0) {
2376-
assert (LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2377-
srli_d(dst, src, LogKlassAlignmentInBytes);
2434+
srli_d(dst, src, CompressedKlassPointers::shift());
23782435
} else {
23792436
move(dst, src);
23802437
}
@@ -2397,15 +2454,16 @@ void MacroAssembler::decode_klass_not_null(Register r) {
23972454
add_d(r, r, AT);
23982455
}
23992456
} else {
2400-
assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2401-
assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
2457+
assert(CompressedKlassPointers::shift() == Address::times_8,
2458+
"klass not aligned on 64bits?");
24022459
li(AT, (int64_t)CompressedKlassPointers::base());
24032460
alsl_d(r, r, AT, Address::times_8 - 1);
24042461
}
24052462
} else {
24062463
if (CompressedKlassPointers::shift() != 0) {
2407-
assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2408-
slli_d(r, r, LogKlassAlignmentInBytes);
2464+
assert(CompressedKlassPointers::shift() == Address::times_8,
2465+
"klass not aligned on 64bits?");
2466+
slli_d(r, r, CompressedKlassPointers::shift());
24092467
}
24102468
}
24112469
}
@@ -2428,15 +2486,16 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
24282486
add_d(dst, dst, src);
24292487
}
24302488
} else {
2431-
assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2432-
assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
2489+
assert(CompressedKlassPointers::shift() == Address::times_8,
2490+
"klass not aligned on 64bits?");
24332491
li(dst, (int64_t)CompressedKlassPointers::base());
24342492
alsl_d(dst, src, dst, Address::times_8 - 1);
24352493
}
24362494
} else {
24372495
if (CompressedKlassPointers::shift() != 0) {
2438-
assert(LogKlassAlignmentInBytes == CompressedKlassPointers::shift(), "decode alg wrong");
2439-
slli_d(dst, src, LogKlassAlignmentInBytes);
2496+
assert(CompressedKlassPointers::shift() == Address::times_8,
2497+
"klass not aligned on 64bits?");
2498+
slli_d(dst, src, CompressedKlassPointers::shift());
24402499
} else {
24412500
move(dst, src);
24422501
}

src/hotspot/cpu/loongarch/macroAssembler_loongarch.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,15 @@ class MacroAssembler: public Assembler {
277277

278278
// oop manipulations
279279
void load_klass(Register dst, Register src);
280+
// load narrow klass ptr from obj ptr (src) to dst, 2 insns
281+
void load_narrow_klass_compact(Register dst, Register src);
280282
void store_klass(Register dst, Register src);
283+
// compare if obj1 and obj2 has the same (or diff) klass ptr
284+
// and jump to L.
285+
void cmp_klass(Register obj1, Register obj2, Register tmp1, Register tmp2,
286+
Label &L, bool equal, bool far);
287+
void cmp_klass_compressed(Register obj, Register klass, Register tmp1,
288+
Label &L, bool equal);
281289

282290
void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
283291
Register tmp1, Register tmp2);
@@ -562,6 +570,7 @@ class MacroAssembler: public Assembler {
562570
static bool reachable_from_branch_short(jlong offs);
563571

564572
void patchable_jump_far(Register ra, jlong offs);
573+
// 2 insns if force_patchable, 1 insn if not
565574
void patchable_jump(address target, bool force_patchable = false);
566575
void patchable_call(address target, address call_size = 0);
567576

0 commit comments

Comments
 (0)