Skip to content

Commit

Permalink
Compact header riscv (#3)
Browse files Browse the repository at this point in the history
Implement compact headers on RISCV
---------

Co-authored-by: hamlin <[email protected]>
  • Loading branch information
rkennke and Hamlin-Li authored Oct 17, 2024
1 parent e4c0878 commit 1b907cc
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 60 deletions.
3 changes: 2 additions & 1 deletion make/autoconf/jdk-options.m4
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,8 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE_COH],
elif test "x$OPENJDK_TARGET_CPU" != "xx86_64" &&
test "x$OPENJDK_TARGET_CPU" != "xaarch64" &&
test "x$OPENJDK_TARGET_CPU" != "xppc64" &&
test "x$OPENJDK_TARGET_CPU" != "xppc64le"; then
test "x$OPENJDK_TARGET_CPU" != "xppc64le" &&
test "x$OPENJDK_TARGET_CPU" != "xriscv64"; then
AC_MSG_RESULT([no (compact object headers not supported for this platform)])
AVAILABLE=false
else
Expand Down
27 changes: 7 additions & 20 deletions src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe
// We don't know the array types are compatible
if (basic_type != T_OBJECT) {
// Simple test for basic type arrays
if (UseCompressedClassPointers) {
if (UseCompactObjectHeaders) {
__ load_narrow_klass_compact(tmp, src);
__ load_narrow_klass_compact(t0, dst);
} else if (UseCompressedClassPointers) {
__ lwu(tmp, Address(src, oopDesc::klass_offset_in_bytes()));
__ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
} else {
Expand Down Expand Up @@ -244,7 +247,6 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe
void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, ciArrayKlass *default_type, int flags) {
assert(default_type != nullptr, "null default_type!");
BasicType basic_type = default_type->element_type()->basic_type();

if (basic_type == T_ARRAY) { basic_type = T_OBJECT; }
if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
// Sanity check the known type with the incoming class. For the
Expand All @@ -261,25 +263,10 @@ void LIR_Assembler::arraycopy_assert(Register src, Register dst, Register tmp, c
}

if (basic_type != T_OBJECT) {
if (UseCompressedClassPointers) {
__ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
} else {
__ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
}
__ bne(tmp, t0, halt);
if (UseCompressedClassPointers) {
__ lwu(t0, Address(src, oopDesc::klass_offset_in_bytes()));
} else {
__ ld(t0, Address(src, oopDesc::klass_offset_in_bytes()));
}
__ beq(tmp, t0, known_ok);
__ cmp_klass_compressed(dst, tmp, t0, halt, false);
__ cmp_klass_compressed(src, tmp, t0, known_ok, true);
} else {
if (UseCompressedClassPointers) {
__ lwu(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
} else {
__ ld(t0, Address(dst, oopDesc::klass_offset_in_bytes()));
}
__ beq(tmp, t0, known_ok);
__ cmp_klass_compressed(dst, tmp, t0, known_ok, true);
__ beq(src, dst, known_ok);
}
__ bind(halt);
Expand Down
7 changes: 1 addition & 6 deletions src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1525,12 +1525,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
add_debug_info_for_null_check_here(info);
}

if (UseCompressedClassPointers) {
__ lwu(result, Address(obj, oopDesc::klass_offset_in_bytes()));
__ decode_klass_not_null(result);
} else {
__ ld(result, Address(obj, oopDesc::klass_offset_in_bytes()));
}
__ load_klass(result, obj);
}

void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
Expand Down
22 changes: 13 additions & 9 deletions src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,19 @@ void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, i

void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
assert_different_registers(obj, klass, len, tmp1, tmp2);
// This assumes that all prototype bits fitr in an int32_t
mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value());
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
// Todo UseCompactObjectHeaders
if (UseCompressedClassPointers) { // Take care not to kill klass
encode_klass_not_null(tmp1, klass, tmp2);
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
if (UseCompactObjectHeaders) {
ld(tmp1, Address(klass, Klass::prototype_header_offset()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
} else {
sd(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
// This assumes that all prototype bits fitr in an int32_t
mv(tmp1, checked_cast<int32_t>(markWord::prototype().value()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
if (UseCompressedClassPointers) { // Take care not to kill klass
encode_klass_not_null(tmp1, klass, tmp2);
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
} else {
sd(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
}
}

if (len->is_valid()) {
Expand All @@ -183,7 +187,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
// Clear gap/first 4 bytes following the length field.
sw(zr, Address(obj, base_offset));
}
} else if (UseCompressedClassPointers) {
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
store_klass_gap(obj, zr);
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3119,3 +3119,13 @@ void C2_MacroAssembler::extract_fp_v(FloatRegister dst, VectorRegister src, Basi
vfmv_f_s(dst, tmp);
}
}

void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Address src) {
// The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract
// obj-start, so that we can load from the object's mark-word instead. Usually the address
// comes as obj-start in obj and klass_offset_in_bytes in disp.
assert(UseCompactObjectHeaders, "must");
int offset = oopDesc::mark_offset_in_bytes() - oopDesc::klass_offset_in_bytes();
ld(dst, Address(src.base(), src.offset() + offset));
srli(dst, dst, markWord::klass_shift);
}
2 changes: 2 additions & 0 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,6 @@
void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp);
void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp);

void load_narrow_klass_compact_c2(Register dst, Address src);

#endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP
48 changes: 31 additions & 17 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2484,20 +2484,19 @@ void MacroAssembler::orptr(Address adr, RegisterOrConstant src, Register tmp1, R
sd(tmp1, adr);
}

void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp1, Register tmp2, Label &L) {
assert_different_registers(oop, trial_klass, tmp1, tmp2);
if (UseCompressedClassPointers) {
lwu(tmp1, Address(oop, oopDesc::klass_offset_in_bytes()));
if (CompressedKlassPointers::base() == nullptr) {
slli(tmp1, tmp1, CompressedKlassPointers::shift());
beq(trial_klass, tmp1, L);
return;
}
decode_klass_not_null(tmp1, tmp2);
void MacroAssembler::cmp_klass_compressed(Register oop, Register trial_klass, Register tmp, Label &L, bool equal) {
if (UseCompactObjectHeaders) {
load_narrow_klass_compact(tmp, oop);
} else if (UseCompressedClassPointers) {
lwu(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
} else {
ld(tmp1, Address(oop, oopDesc::klass_offset_in_bytes()));
ld(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
}
if (equal) {
beq(trial_klass, tmp, L);
} else {
bne(trial_klass, tmp, L);
}
beq(trial_klass, tmp1, L);
}

// Move an oop into a register.
Expand Down Expand Up @@ -2724,10 +2723,19 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
}
}

void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
ld(dst, Address(src, oopDesc::mark_offset_in_bytes()));
srli(dst, dst, markWord::klass_shift);
}

void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
assert_different_registers(dst, tmp);
assert_different_registers(src, tmp);
if (UseCompressedClassPointers) {
if (UseCompactObjectHeaders) {
load_narrow_klass_compact(dst, src);
decode_klass_not_null(dst, tmp);
} else if (UseCompressedClassPointers) {
lwu(dst, Address(src, oopDesc::klass_offset_in_bytes()));
decode_klass_not_null(dst, tmp);
} else {
Expand All @@ -2738,6 +2746,7 @@ void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
// FIXME: Should this be a store release? concurrent gcs assumes
// klass length is valid if klass field is not null.
assert(!UseCompactObjectHeaders, "not with compact headers");
if (UseCompressedClassPointers) {
encode_klass_not_null(src, tmp);
sw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
Expand All @@ -2747,6 +2756,7 @@ void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
}

void MacroAssembler::store_klass_gap(Register dst, Register src) {
assert(!UseCompactObjectHeaders, "not with compact headers");
if (UseCompressedClassPointers) {
// Store to klass gap in destination
sw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
Expand Down Expand Up @@ -2779,8 +2789,9 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src, Register
mv(xbase, (uintptr_t)CompressedKlassPointers::base());

if (CompressedKlassPointers::shift() != 0) {
assert_different_registers(t0, xbase);
shadd(dst, src, xbase, t0, CompressedKlassPointers::shift());
Register t = src == dst ? dst : t0;
assert_different_registers(t, xbase);
shadd(dst, src, xbase, t, CompressedKlassPointers::shift());
} else {
add(dst, xbase, src);
}
Expand Down Expand Up @@ -4313,7 +4324,7 @@ address MacroAssembler::ic_call(address entry, jint method_index) {
int MacroAssembler::ic_check_size() {
// No compressed
return (MacroAssembler::instruction_size * (2 /* 2 loads */ + 1 /* branch */)) +
far_branch_size();
far_branch_size() + (UseCompactObjectHeaders ? MacroAssembler::instruction_size * 1 : 0);
}

int MacroAssembler::ic_check(int end_alignment) {
Expand All @@ -4333,7 +4344,10 @@ int MacroAssembler::ic_check(int end_alignment) {
align(end_alignment, ic_check_size());
int uep_offset = offset();

if (UseCompressedClassPointers) {
if (UseCompactObjectHeaders) {
load_narrow_klass_compact(tmp1, receiver);
lwu(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
} else if (UseCompressedClassPointers) {
lwu(tmp1, Address(receiver, oopDesc::klass_offset_in_bytes()));
lwu(tmp2, Address(data, CompiledICData::speculated_klass_offset()));
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ class MacroAssembler: public Assembler {
void access_store_at(BasicType type, DecoratorSet decorators, Address dst,
Register val, Register tmp1, Register tmp2, Register tmp3);
void load_klass(Register dst, Register src, Register tmp = t0);
void load_narrow_klass_compact(Register dst, Register src);
void store_klass(Register dst, Register src, Register tmp = t0);
void cmp_klass(Register oop, Register trial_klass, Register tmp1, Register tmp2, Label &L);
void cmp_klass_compressed(Register oop, Register trial_klass, Register tmp, Label &L, bool equal);

void encode_klass_not_null(Register r, Register tmp = t0);
void decode_klass_not_null(Register r, Register tmp = t0);
Expand Down
16 changes: 16 additions & 0 deletions src/hotspot/cpu/riscv/riscv.ad
Original file line number Diff line number Diff line change
Expand Up @@ -4821,6 +4821,7 @@ instruct loadKlass(iRegPNoSp dst, memory mem)
// Load Narrow Klass Pointer
instruct loadNKlass(iRegNNoSp dst, memory mem)
%{
predicate(!UseCompactObjectHeaders);
match(Set dst (LoadNKlass mem));

ins_cost(LOAD_COST);
Expand All @@ -4833,6 +4834,21 @@ instruct loadNKlass(iRegNNoSp dst, memory mem)
ins_pipe(iload_reg_mem);
%}

instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory mem)
%{
predicate(UseCompactObjectHeaders);
match(Set dst (LoadNKlass mem));

ins_cost(LOAD_COST);
format %{ "lwu $dst, $mem\t# loadNKlass, compressed class ptr, #@loadNKlass" %}

ins_encode %{
__ load_narrow_klass_compact_c2(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp));
%}

ins_pipe(iload_reg_mem);
%}

// Load Float
instruct loadF(fRegF dst, memory mem)
%{
Expand Down
27 changes: 21 additions & 6 deletions src/hotspot/cpu/riscv/templateTable_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3565,12 +3565,22 @@ void TemplateTable::_new() {

// The object is initialized before the header. If the object size is
// zero, go directly to the header initialization.
__ sub(x13, x13, sizeof(oopDesc));
if (UseCompactObjectHeaders) {
assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned");
__ sub(x13, x13, oopDesc::base_offset_in_bytes());
} else {
__ sub(x13, x13, sizeof(oopDesc));
}
__ beqz(x13, initialize_header);

// Initialize object fields
{
__ add(x12, x10, sizeof(oopDesc));
if (UseCompactObjectHeaders) {
assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned");
__ add(x12, x10, oopDesc::base_offset_in_bytes());
} else {
__ add(x12, x10, sizeof(oopDesc));
}
Label loop;
__ bind(loop);
__ sd(zr, Address(x12));
Expand All @@ -3581,10 +3591,15 @@ void TemplateTable::_new() {

// initialize object hader only.
__ bind(initialize_header);
__ mv(t0, (intptr_t)markWord::prototype().value());
__ sd(t0, Address(x10, oopDesc::mark_offset_in_bytes()));
__ store_klass_gap(x10, zr); // zero klass gap for compressed oops
__ store_klass(x10, x14); // store klass last
if (UseCompactObjectHeaders) {
__ ld(t0, Address(x14, Klass::prototype_header_offset()));
__ sd(t0, Address(x10, oopDesc::mark_offset_in_bytes()));
} else {
__ mv(t0, (intptr_t)markWord::prototype().value());
__ sd(t0, Address(x10, oopDesc::mark_offset_in_bytes()));
__ store_klass_gap(x10, zr); // zero klass gap for compressed oops
__ store_klass(x10, x14); // store klass last
}

if (DTraceAllocProbes) {
// Trigger dtrace event for fastpath
Expand Down

0 comments on commit 1b907cc

Please sign in to comment.