Skip to content

Commit

Permalink
Update (2025.02.19, 2nd)
Browse files Browse the repository at this point in the history
22096: [c2] Delete unused adjust for null_check position
35535: LA port of 8338383: Implement JEP 491: Synchronize Virtual Threads without Pinning
31020: LA port of 8305895: Implement JEP 450: Compact Object Headers (Experimental)
35534: LA port of 8343343: Misc crash dump improvements on more platforms after JDK-8294160
  • Loading branch information
loongson-jvm authored Feb 19, 2025
1 parent 5762af5 commit 08c4e0d
Show file tree
Hide file tree
Showing 23 changed files with 546 additions and 221 deletions.
7 changes: 7 additions & 0 deletions make/autoconf/jdk-options.m4
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
# questions.
#

#
# This file has been modified by Loongson Technology in 2025. These
# modifications are Copyright (c) 2025, Loongson Technology, and are made
# available on the same license terms set forth above.
#

################################################################################
# Set the debug level
# release: no debug information, all optimizations, no asserts.
Expand Down Expand Up @@ -719,6 +725,7 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE_COH],
test "x$OPENJDK_TARGET_CPU" != "xppc64" &&
test "x$OPENJDK_TARGET_CPU" != "xppc64le" &&
test "x$OPENJDK_TARGET_CPU" != "xriscv64" &&
test "x$OPENJDK_TARGET_CPU" != "xloongarch64" &&
test "x$OPENJDK_TARGET_CPU" != "xs390x"; then
AC_MSG_RESULT([no (compact object headers not supported for this platform)])
AVAILABLE=false
Expand Down
34 changes: 8 additions & 26 deletions src/hotspot/cpu/loongarch/c1_LIRAssembler_loongarch_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2573,7 +2573,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// 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(SCR1, dst);
} else if (UseCompressedClassPointers) {
__ ld_wu(tmp, src_klass_addr);
__ ld_wu(SCR1, dst_klass_addr);
} else {
Expand Down Expand Up @@ -2716,26 +2719,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
}

if (basic_type != T_OBJECT) {

if (UseCompressedClassPointers) {
__ ld_wu(SCR1, dst_klass_addr);
} else {
__ ld_d(SCR1, dst_klass_addr);
}
__ bne(tmp, SCR1, halt);
if (UseCompressedClassPointers) {
__ ld_wu(SCR1, src_klass_addr);
} else {
__ ld_d(SCR1, src_klass_addr);
}
__ beq(tmp, SCR1, known_ok);
__ cmp_klass_compressed(dst, tmp, SCR1, halt, false);
__ cmp_klass_compressed(src, tmp, SCR1, known_ok, true);
} else {
if (UseCompressedClassPointers) {
__ ld_wu(SCR1, dst_klass_addr);
} else {
__ ld_d(SCR1, dst_klass_addr);
}
__ beq(tmp, SCR1, known_ok);
__ cmp_klass_compressed(dst, tmp, SCR1, known_ok, true);
__ beq(src, dst, known_ok);
}
__ bind(halt);
Expand Down Expand Up @@ -2814,12 +2801,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) {
add_debug_info_for_null_check_here(info);
}

if (UseCompressedClassPointers) {
__ ld_wu(result, obj, oopDesc::klass_offset_in_bytes());
__ decode_klass_not_null(result);
} else {
__ ld_d(result, obj, oopDesc::klass_offset_in_bytes());
}
__ load_klass(result, obj);
}

void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
Expand Down
31 changes: 18 additions & 13 deletions src/hotspot/cpu/loongarch/c1_MacroAssembler_loongarch_64.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2024, Loongson Technology. All rights reserved.
* Copyright (c) 2021, 2025, Loongson Technology. 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 @@ -71,8 +71,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
// displaced header address in the object header - if it is not the same, get the
// object header instead
lea(SCR2, Address(obj, hdr_offset));
cmpxchg(Address(SCR2, 0), hdr, disp_hdr, SCR1, true, true /* acquire */, done);
// if the object header was the same, we're done
cmpxchg(Address(SCR2, 0), hdr, disp_hdr, SCR1, true, true /* acquire */, done);
// if the object header was not the same, it is now in the hdr register
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
//
Expand All @@ -94,10 +94,11 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
st_d(hdr, Address(disp_hdr, 0));
// otherwise we don't care about the result and handle locking via runtime call
bnez(hdr, slow_case);

// done
bind(done);
inc_held_monitor_count(SCR1);
}
increment(Address(TREG, JavaThread::held_monitor_count_offset()), 1);
return null_check_offset;
}

Expand Down Expand Up @@ -132,10 +133,11 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
} else {
cmpxchg(Address(obj, 0), disp_hdr, hdr, SCR2, false, true /* acquire */, done, &slow_case);
}

// done
bind(done);
dec_held_monitor_count(SCR1);
}
decrement(Address(TREG, JavaThread::held_monitor_count_offset()), 1);
}

// Defines obj, preserves var_size_in_bytes
Expand All @@ -152,15 +154,18 @@ void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes,
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len,
Register t1, Register t2) {
assert_different_registers(obj, klass, len);
// This assumes that all prototype bits fit in an int32_t
li(t1, (int32_t)(intptr_t)markWord::prototype().value());
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));

if (UseCompressedClassPointers) { // Take care not to kill klass
encode_klass_not_null(t1, klass);
st_w(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
if (UseCompactObjectHeaders) {
ld_d(t1, Address(klass, Klass::prototype_header_offset()));
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
} else {
st_d(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
li(t1, checked_cast<int32_t>(markWord::prototype().value()));
st_d(t1, Address(obj, oopDesc::mark_offset_in_bytes()));
if (UseCompressedClassPointers) { // Take care not to kill klass
encode_klass_not_null(t1, klass);
st_w(t1, Address(obj, oopDesc::klass_offset_in_bytes()));
} else {
st_d(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
}
}

if (len->is_valid()) {
Expand All @@ -171,7 +176,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
// Clear gap/first 4 bytes following the length field.
st_w(R0, Address(obj, base_offset));
}
} else if (UseCompressedClassPointers) {
} else if (UseCompressedClassPointers && !UseCompactObjectHeaders) {
store_klass_gap(obj, R0);
}
}
Expand Down
42 changes: 33 additions & 9 deletions src/hotspot/cpu/loongarch/c1_Runtime1_loongarch_64.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2024, Loongson Technology. All rights reserved.
* Copyright (c) 2021, 2025, Loongson Technology. 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 @@ -160,15 +160,15 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result,
}

enum return_state_t {
does_not_return, requires_return
does_not_return, requires_return, requires_pop_epilogue_return
};

// Implementation of StubFrame

class StubFrame: public StackObj {
private:
StubAssembler* _sasm;
bool _return_state;
return_state_t _return_state;

public:
StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments,
Expand All @@ -183,8 +183,16 @@ void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
enter();
}

void StubAssembler::epilogue() {
leave();
void StubAssembler::epilogue(bool use_pop) {
// Avoid using a leave instruction when this frame may
// have been frozen, since the current value of fp
// restored from the stub would be invalid. We still
// must restore the fp value saved on enter though.
if (use_pop) {
pop2(RA, FP);
} else {
leave();
}
jr(RA);
}

Expand All @@ -204,11 +212,12 @@ void StubFrame::load_argument(int offset_in_words, Register reg) {
}

StubFrame::~StubFrame() {
if (_return_state == requires_return) {
__ epilogue();
} else {
if (_return_state == does_not_return) {
__ should_not_reach_here();
} else {
__ epilogue(_return_state == requires_pop_epilogue_return);
}
_sasm = nullptr;
}

#undef __
Expand Down Expand Up @@ -256,6 +265,11 @@ static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
}
}

int sp_offset = cpu_reg_save_offsets[TREG->encoding()];
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
TREG->as_VMReg());

// fpu_regs
if (save_fpu_registers) {
for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
FloatRegister r = as_FloatRegister(i);
Expand Down Expand Up @@ -333,6 +347,16 @@ void Runtime1::initialize_pd() {
}
}

// return: offset in 64-bit words.
uint Runtime1::runtime_blob_current_thread_offset(frame f) {
CodeBlob* cb = f.cb();
assert(cb == Runtime1::blob_for(C1StubId::monitorenter_id) ||
cb == Runtime1::blob_for(C1StubId::monitorenter_nofpu_id), "must be");
assert(cb != nullptr && cb->is_runtime_stub(), "invalid frame");
int offset = cpu_reg_save_offsets[TREG->encoding()];
return offset / 2; // SP offsets are in halfwords
}

// target: the entry point of the method that creates and posts the exception oop
// has_argument: true if the exception needs arguments (passed in SCR1 and SCR2)

Expand Down Expand Up @@ -860,7 +884,7 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
// fall through
case C1StubId::monitorenter_id:
{
StubFrame f(sasm, "monitorenter", dont_gc_arguments);
StubFrame f(sasm, "monitorenter", dont_gc_arguments, requires_pop_epilogue_return);
OopMap* map = save_live_registers(sasm, save_fpu_registers);

// Called with store_parameter and not C abi
Expand Down
52 changes: 34 additions & 18 deletions src/hotspot/cpu/loongarch/c2_MacroAssembler_loongarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@
#endif

// using the cr register as the bool result: 0 for failed; others success.
void C2_MacroAssembler::fast_lock_c2(Register oop, Register box, Register flag,
Register disp_hdr, Register tmp) {
void C2_MacroAssembler::fast_lock_c2(Register oop, Register box,
Register flag, Register disp_hdr,
Register tmp, Register tmp2) {
Label cont;
Label object_has_monitor;
Label count, no_count;

assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
assert_different_registers(oop, box, tmp, disp_hdr, flag);
assert_different_registers(oop, box, flag, disp_hdr, tmp, tmp2);

// Load markWord from object into displaced_header.
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
Expand Down Expand Up @@ -103,13 +104,12 @@ void C2_MacroAssembler::fast_lock_c2(Register oop, Register box, Register flag,
// Handle existing monitor.
bind(object_has_monitor);

// The object's monitor m is unlocked if m->owner is null,
// otherwise m->owner may contain a thread or a stack address.
//
// Try to CAS m->owner from null to current thread.
// Try to CAS owner (no owner => current thread's _lock_id).
Register tid = tmp2;
ld_d(tid, Address(TREG, JavaThread::lock_id_offset()));
move(AT, R0);
addi_d(tmp, disp_hdr, in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value);
cmpxchg(Address(tmp, 0), AT, TREG, flag, true, true /* acquire */);
cmpxchg(Address(tmp, 0), AT, tid, flag, true, true /* acquire */);

// Store a non-null value into the box to avoid looking like a re-entrant
// lock. The fast-path monitor unlock code checks for
Expand All @@ -120,7 +120,7 @@ void C2_MacroAssembler::fast_lock_c2(Register oop, Register box, Register flag,

bnez(flag, cont); // CAS success means locking succeeded

bne(AT, TREG, cont); // Check for recursive locking
bne(AT, tid, cont); // Check for recursive locking

// Recursive lock case
li(flag, 1);
Expand All @@ -132,7 +132,9 @@ void C2_MacroAssembler::fast_lock_c2(Register oop, Register box, Register flag,
beqz(flag, no_count);

bind(count);
increment(Address(TREG, JavaThread::held_monitor_count_offset()), 1);
if (LockingMode == LM_LEGACY) {
inc_held_monitor_count(SCR1);
}

bind(no_count);
}
Expand Down Expand Up @@ -231,14 +233,19 @@ void C2_MacroAssembler::fast_unlock_c2(Register oop, Register box, Register flag
beqz(flag, no_count);

bind(count);
decrement(Address(TREG, JavaThread::held_monitor_count_offset()), 1);
if (LockingMode == LM_LEGACY) {
dec_held_monitor_count(SCR1);
}

bind(no_count);
}

void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Register flag, Register tmp1, Register tmp2, Register tmp3) {
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box,
Register flag, Register tmp1,
Register tmp2, Register tmp3,
Register tmp4) {
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
assert_different_registers(obj, box, tmp1, tmp2, tmp3, flag);
assert_different_registers(obj, box, flag, tmp1, tmp2, tmp3, tmp4);

// Handle inflated monitor.
Label inflated;
Expand Down Expand Up @@ -352,13 +359,15 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
// Compute owner address.
lea(tmp2_owner_addr, owner_address);

// Try to CAS owner (no owner => current thread's _lock_id).
Register tid = tmp4;
ld_d(tid, Address(TREG, JavaThread::lock_id_offset()));
move(tmp3_owner, R0);
// CAS owner (null => current thread).
cmpxchg(Address(tmp2_owner_addr, 0), tmp3_owner, TREG, flag, true, true /* acquire */);
cmpxchg(Address(tmp2_owner_addr, 0), tmp3_owner, tid, flag, true, true /* acquire */);
bnez(flag, locked);

// Check if recursive.
bne(tmp3_owner, TREG, slow_path);
bne(tmp3_owner, tid, slow_path);

// Recursive.
increment(recursions_address, 1);
Expand All @@ -372,7 +381,6 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
bind(locked);
// Set flag != 0
li(flag, 1);
increment(Address(TREG, JavaThread::held_monitor_count_offset()), 1);

#ifdef ASSERT
// Check that locked label is reached with flag != 0.
Expand Down Expand Up @@ -535,7 +543,6 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, Regi
bind(unlocked);
// Set flag != 0
li(flag, 1);
decrement(Address(TREG, JavaThread::held_monitor_count_offset()), 1);

#ifdef ASSERT
// Check that unlocked label is reached with flag != 0.
Expand Down Expand Up @@ -2552,3 +2559,12 @@ void C2_MacroAssembler::arrays_hashcode_elload(Register dst, Address src, BasicT
ShouldNotReachHere();
}
}

void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Register obj, int disp) {
// Note: Don't clobber obj anywhere in that method!

// 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.
ld_d(dst, Address(obj, disp - oopDesc::klass_offset_in_bytes()));
srli_d(dst, dst, markWord::klass_shift);
}
Loading

0 comments on commit 08c4e0d

Please sign in to comment.