Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8299730: Add trivial call linker option #771

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
142 changes: 76 additions & 66 deletions src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp
Expand Up @@ -47,6 +47,7 @@ class DowncallStubGenerator : public StubCodeGenerator {

bool _needs_return_buffer;
int _captured_state_mask;
bool _needs_transition;

int _frame_complete;
int _frame_size_slots;
Expand All @@ -60,7 +61,8 @@ class DowncallStubGenerator : public StubCodeGenerator {
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask)
int captured_state_mask,
bool needs_transition)
: StubCodeGenerator(buffer, PrintMethodHandleStubs),
_signature(signature),
_num_args(num_args),
Expand All @@ -70,6 +72,7 @@ class DowncallStubGenerator : public StubCodeGenerator {
_output_registers(output_registers),
_needs_return_buffer(needs_return_buffer),
_captured_state_mask(captured_state_mask),
_needs_transition(needs_transition),
_frame_complete(0),
_frame_size_slots(0),
_oop_maps(NULL) {
Expand Down Expand Up @@ -99,12 +102,14 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
int locs_size = 64;
CodeBuffer code("nep_invoker_blob", native_invoker_code_size, locs_size);
DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi,
input_registers, output_registers,
needs_return_buffer, captured_state_mask);
needs_return_buffer, captured_state_mask,
needs_transition);
g.generate();
code.log_section_sizes("nep_invoker_blob");

Expand Down Expand Up @@ -161,7 +166,7 @@ void DowncallStubGenerator::generate() {
assert(_abi._shadow_space_bytes == 0, "not expecting shadow space on AArch64");
allocated_frame_size += arg_shuffle.out_arg_bytes();

bool should_save_return_value = !_needs_return_buffer;
bool should_save_return_value = !_needs_return_buffer && _needs_transition;
RegSpiller out_reg_spiller(_output_registers);
int spill_offset = -1;

Expand Down Expand Up @@ -189,7 +194,7 @@ void DowncallStubGenerator::generate() {
_frame_size_slots = align_up(framesize + (allocated_frame_size >> LogBytesPerInt), 4);
assert(is_even(_frame_size_slots/2), "sp not 16-byte aligned");

_oop_maps = new OopMapSet();
_oop_maps = _needs_transition ? new OopMapSet() : nullptr;
address start = __ pc();

__ enter();
Expand All @@ -199,15 +204,17 @@ void DowncallStubGenerator::generate() {

_frame_complete = __ pc() - start;

address the_pc = __ pc();
__ set_last_Java_frame(sp, rfp, the_pc, tmp1);
OopMap* map = new OopMap(_frame_size_slots, 0);
_oop_maps->add_gc_map(the_pc - start, map);
if (_needs_transition) {
address the_pc = __ pc();
__ set_last_Java_frame(sp, rfp, the_pc, tmp1);
OopMap* map = new OopMap(_frame_size_slots, 0);
_oop_maps->add_gc_map(the_pc - start, map);

// State transition
__ mov(tmp1, _thread_in_native);
__ lea(tmp2, Address(rthread, JavaThread::thread_state_offset()));
__ stlrw(tmp1, tmp2);
// State transition
__ mov(tmp1, _thread_in_native);
__ lea(tmp2, Address(rthread, JavaThread::thread_state_offset()));
__ stlrw(tmp1, tmp2);
}

__ block_comment("{ argument shuffle");
arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes, locs);
Expand Down Expand Up @@ -255,85 +262,88 @@ void DowncallStubGenerator::generate() {

//////////////////////////////////////////////////////////////////////////////

__ mov(tmp1, _thread_in_native_trans);
__ strw(tmp1, Address(rthread, JavaThread::thread_state_offset()));

// Force this write out before the read below
if (!UseSystemMemoryBarrier) {
__ membar(Assembler::LoadLoad | Assembler::LoadStore |
Assembler::StoreLoad | Assembler::StoreStore);
}

__ verify_sve_vector_length(tmp1);

Label L_after_safepoint_poll;
Label L_safepoint_poll_slow_path;
Label L_reguard;
Label L_after_reguard;
if (_needs_transition) {
__ mov(tmp1, _thread_in_native_trans);
__ strw(tmp1, Address(rthread, JavaThread::thread_state_offset()));

// Force this write out before the read below
if (!UseSystemMemoryBarrier) {
__ membar(Assembler::LoadLoad | Assembler::LoadStore |
Assembler::StoreLoad | Assembler::StoreStore);
}

__ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */, tmp1);
__ verify_sve_vector_length(tmp1);

__ ldrw(tmp1, Address(rthread, JavaThread::suspend_flags_offset()));
__ cbnzw(tmp1, L_safepoint_poll_slow_path);
__ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */, tmp1);

__ bind(L_after_safepoint_poll);
__ ldrw(tmp1, Address(rthread, JavaThread::suspend_flags_offset()));
__ cbnzw(tmp1, L_safepoint_poll_slow_path);

// change thread state
__ mov(tmp1, _thread_in_Java);
__ lea(tmp2, Address(rthread, JavaThread::thread_state_offset()));
__ stlrw(tmp1, tmp2);
__ bind(L_after_safepoint_poll);

__ block_comment("reguard stack check");
Label L_reguard;
Label L_after_reguard;
__ ldrb(tmp1, Address(rthread, JavaThread::stack_guard_state_offset()));
__ cmpw(tmp1, StackOverflow::stack_guard_yellow_reserved_disabled);
__ br(Assembler::EQ, L_reguard);
__ bind(L_after_reguard);
// change thread state
__ mov(tmp1, _thread_in_Java);
__ lea(tmp2, Address(rthread, JavaThread::thread_state_offset()));
__ stlrw(tmp1, tmp2);

__ block_comment("reguard stack check");
__ ldrb(tmp1, Address(rthread, JavaThread::stack_guard_state_offset()));
__ cmpw(tmp1, StackOverflow::stack_guard_yellow_reserved_disabled);
__ br(Assembler::EQ, L_reguard);
__ bind(L_after_reguard);

__ reset_last_Java_frame(true);
__ reset_last_Java_frame(true);
}

__ leave(); // required for proper stackwalking of RuntimeStub frame
__ ret(lr);

//////////////////////////////////////////////////////////////////////////////

__ block_comment("{ L_safepoint_poll_slow_path");
__ bind(L_safepoint_poll_slow_path);
if (_needs_transition) {
__ block_comment("{ L_safepoint_poll_slow_path");
__ bind(L_safepoint_poll_slow_path);

if (should_save_return_value) {
// Need to save the native result registers around any runtime calls.
out_reg_spiller.generate_spill(_masm, spill_offset);
}
if (should_save_return_value) {
// Need to save the native result registers around any runtime calls.
out_reg_spiller.generate_spill(_masm, spill_offset);
}

__ mov(c_rarg0, rthread);
assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
__ lea(tmp1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
__ blr(tmp1);
__ mov(c_rarg0, rthread);
assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area");
__ lea(tmp1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
__ blr(tmp1);

if (should_save_return_value) {
out_reg_spiller.generate_fill(_masm, spill_offset);
}
if (should_save_return_value) {
out_reg_spiller.generate_fill(_masm, spill_offset);
}

__ b(L_after_safepoint_poll);
__ block_comment("} L_safepoint_poll_slow_path");
__ b(L_after_safepoint_poll);
__ block_comment("} L_safepoint_poll_slow_path");

//////////////////////////////////////////////////////////////////////////////

__ block_comment("{ L_reguard");
__ bind(L_reguard);
__ block_comment("{ L_reguard");
__ bind(L_reguard);

if (should_save_return_value) {
out_reg_spiller.generate_spill(_masm, spill_offset);
}
if (should_save_return_value) {
out_reg_spiller.generate_spill(_masm, spill_offset);
}

__ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), tmp1);
__ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), tmp1);

if (should_save_return_value) {
out_reg_spiller.generate_fill(_masm, spill_offset);
}
if (should_save_return_value) {
out_reg_spiller.generate_fill(_masm, spill_offset);
}

__ b(L_after_reguard);
__ b(L_after_reguard);

__ block_comment("} L_reguard");
__ block_comment("} L_reguard");
}

//////////////////////////////////////////////////////////////////////////////

Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/arm/downcallLinker_arm.cpp
Expand Up @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
Unimplemented();
return nullptr;
}
3 changes: 2 additions & 1 deletion src/hotspot/cpu/ppc/downcallLinker_ppc.cpp
Expand Up @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
Unimplemented();
return nullptr;
}
3 changes: 2 additions & 1 deletion src/hotspot/cpu/riscv/downcallLinker_riscv.cpp
Expand Up @@ -100,7 +100,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
int locs_size = 64;
CodeBuffer code("nep_invoker_blob", native_invoker_code_size, locs_size);
DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi,
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/s390/downcallLinker_s390.cpp
Expand Up @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
Unimplemented();
return nullptr;
}
3 changes: 2 additions & 1 deletion src/hotspot/cpu/x86/downcallLinker_x86_32.cpp
Expand Up @@ -31,7 +31,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
const GrowableArray<VMStorage>& input_registers,
const GrowableArray<VMStorage>& output_registers,
bool needs_return_buffer,
int captured_state_mask) {
int captured_state_mask,
bool needs_transition) {
Unimplemented();
return nullptr;
}