Skip to content

Commit d65f966

Browse files
author
Boris Ulasevich
committed
8229971: Arm32: implementation for Thread-local handshakes
Reviewed-by: rehn, dsamersoff
1 parent c4b708b commit d65f966

10 files changed

+110
-56
lines changed

src/hotspot/cpu/arm/arm.ad

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
// Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
//
55
// This code is free software; you can redistribute it and/or modify it
@@ -351,10 +351,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
351351

352352
// If this does safepoint polling, then do it here
353353
if (do_polling() && ra_->C->is_method_compilation()) {
354-
// mov_slow here is usually one or two instruction
355-
__ mov_address(Rtemp, (address)os::get_polling_page());
356-
__ relocate(relocInfo::poll_return_type);
357-
__ ldr(Rtemp, Address(Rtemp));
354+
__ read_polling_page(Rtemp, relocInfo::poll_return_type);
358355
}
359356
}
360357

src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -285,23 +285,16 @@ int LIR_Assembler::emit_deopt_handler() {
285285
void LIR_Assembler::return_op(LIR_Opr result) {
286286
// Pop the frame before safepoint polling
287287
__ remove_frame(initial_frame_size_in_bytes());
288-
289-
// mov_slow here is usually one or two instruction
290-
__ mov_address(Rtemp, os::get_polling_page());
291-
__ relocate(relocInfo::poll_return_type);
292-
__ ldr(Rtemp, Address(Rtemp));
288+
__ read_polling_page(Rtemp, relocInfo::poll_return_type);
293289
__ ret();
294290
}
295291

296-
297292
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
298-
__ mov_address(Rtemp, os::get_polling_page());
299293
if (info != NULL) {
300294
add_debug_info_for_branch(info);
301295
}
302296
int offset = __ offset();
303-
__ relocate(relocInfo::poll_type);
304-
__ ldr(Rtemp, Address(Rtemp));
297+
__ read_polling_page(Rtemp, relocInfo::poll_type);
305298
return offset;
306299
}
307300

src/hotspot/cpu/arm/globalDefinitions_arm.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -62,4 +62,6 @@ const bool HaveVFP = true;
6262
#endif
6363
#endif
6464

65+
#define THREAD_LOCAL_POLL
66+
6567
#endif // CPU_ARM_GLOBALDEFINITIONS_ARM_HPP

src/hotspot/cpu/arm/interp_masm_arm.cpp

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
4242
#include "runtime/basicLock.hpp"
4343
#include "runtime/biasedLocking.hpp"
4444
#include "runtime/frame.inline.hpp"
45+
#include "runtime/safepointMechanism.hpp"
4546
#include "runtime/sharedRuntime.hpp"
4647

4748
//--------------------------------------------------------------------
@@ -556,7 +557,7 @@ void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) {
556557

557558
void InterpreterMacroAssembler::dispatch_base(TosState state,
558559
DispatchTableMode table_mode,
559-
bool verifyoop) {
560+
bool verifyoop, bool generate_poll) {
560561
if (VerifyActivationFrameSize) {
561562
Label L;
562563
sub(Rtemp, FP, SP);
@@ -571,6 +572,18 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
571572
interp_verify_oop(R0_tos, state, __FILE__, __LINE__);
572573
}
573574

575+
Label safepoint;
576+
address* const safepoint_table = Interpreter::safept_table(state);
577+
address* const table = Interpreter::dispatch_table(state);
578+
bool needs_thread_local_poll = generate_poll &&
579+
SafepointMechanism::uses_thread_local_poll() && table != safepoint_table;
580+
581+
if (needs_thread_local_poll) {
582+
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
583+
ldr(Rtemp, Address(Rthread, Thread::polling_page_offset()));
584+
tbnz(Rtemp, exact_log2(SafepointMechanism::poll_bit()), safepoint);
585+
}
586+
574587
if((state == itos) || (state == btos) || (state == ztos) || (state == ctos) || (state == stos)) {
575588
zap_high_non_significant_bits(R0_tos);
576589
}
@@ -600,12 +613,18 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
600613
indirect_jump(Address::indexed_ptr(Rtemp, R3_bytecode), Rtemp);
601614
}
602615

616+
if (needs_thread_local_poll) {
617+
bind(safepoint);
618+
lea(Rtemp, ExternalAddress((address)safepoint_table));
619+
indirect_jump(Address::indexed_ptr(Rtemp, R3_bytecode), Rtemp);
620+
}
621+
603622
nop(); // to avoid filling CPU pipeline with invalid instructions
604623
nop();
605624
}
606625

607-
void InterpreterMacroAssembler::dispatch_only(TosState state) {
608-
dispatch_base(state, DispatchDefault);
626+
void InterpreterMacroAssembler::dispatch_only(TosState state, bool generate_poll) {
627+
dispatch_base(state, DispatchDefault, true, generate_poll);
609628
}
610629

611630

@@ -617,10 +636,10 @@ void InterpreterMacroAssembler::dispatch_only_noverify(TosState state) {
617636
dispatch_base(state, DispatchNormal, false);
618637
}
619638

620-
void InterpreterMacroAssembler::dispatch_next(TosState state, int step) {
639+
void InterpreterMacroAssembler::dispatch_next(TosState state, int step, bool generate_poll) {
621640
// load next bytecode and advance Rbcp
622641
ldrb(R3_bytecode, Address(Rbcp, step, pre_indexed));
623-
dispatch_base(state, DispatchDefault);
642+
dispatch_base(state, DispatchDefault, true, generate_poll);
624643
}
625644

626645
void InterpreterMacroAssembler::narrow(Register result) {

src/hotspot/cpu/arm/interp_masm_arm.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
5454

5555
// base routine for all dispatches
5656
typedef enum { DispatchDefault, DispatchNormal } DispatchTableMode;
57-
void dispatch_base(TosState state, DispatchTableMode table_mode, bool verifyoop = true);
57+
void dispatch_base(TosState state, DispatchTableMode table_mode, bool verifyoop = true, bool generate_poll = false);
5858

5959
public:
6060
InterpreterMacroAssembler(CodeBuffer* code);
@@ -160,10 +160,10 @@ class InterpreterMacroAssembler: public MacroAssembler {
160160
// Dispatching
161161
void dispatch_prolog(TosState state, int step = 0);
162162
void dispatch_epilog(TosState state, int step = 0);
163-
void dispatch_only(TosState state); // dispatch by R3_bytecode
164-
void dispatch_only_normal(TosState state); // dispatch normal table by R3_bytecode
163+
void dispatch_only(TosState state, bool generate_poll = false); // dispatch by R3_bytecode
164+
void dispatch_only_normal(TosState state); // dispatch normal table by R3_bytecode
165165
void dispatch_only_noverify(TosState state);
166-
void dispatch_next(TosState state, int step = 0); // load R3_bytecode from [Rbcp + step] and dispatch by R3_bytecode
166+
void dispatch_next(TosState state, int step = 0, bool generate_poll = false); // load R3_bytecode from [Rbcp + step] and dispatch by R3_bytecode
167167

168168
// jump to an invoked target
169169
void prepare_to_jump_from_interpreted();

src/hotspot/cpu/arm/macroAssembler_arm.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -2053,4 +2053,32 @@ void MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch
20532053
bind(done);
20542054

20552055
}
2056+
2057+
void MacroAssembler::safepoint_poll(Register tmp1, Label& slow_path) {
2058+
if (SafepointMechanism::uses_thread_local_poll()) {
2059+
ldr_u32(tmp1, Address(Rthread, Thread::polling_page_offset()));
2060+
tst(tmp1, exact_log2(SafepointMechanism::poll_bit()));
2061+
b(slow_path, eq);
2062+
} else {
2063+
ldr_global_s32(tmp1, SafepointSynchronize::address_of_state());
2064+
cmp(tmp1, SafepointSynchronize::_not_synchronized);
2065+
b(slow_path, ne);
2066+
}
2067+
}
2068+
2069+
void MacroAssembler::get_polling_page(Register dest) {
2070+
if (SafepointMechanism::uses_thread_local_poll()) {
2071+
ldr(dest, Address(Rthread, Thread::polling_page_offset()));
2072+
} else {
2073+
mov_address(dest, os::get_polling_page());
2074+
}
2075+
}
2076+
2077+
void MacroAssembler::read_polling_page(Register dest, relocInfo::relocType rtype) {
2078+
get_polling_page(dest);
2079+
relocate(rtype);
2080+
ldr(dest, Address(dest));
2081+
}
2082+
2083+
20562084
#endif // COMPILER2

src/hotspot/cpu/arm/macroAssembler_arm.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1074,7 +1074,9 @@ class MacroAssembler: public Assembler {
10741074
void fast_unlock(Register obj, Register box, Register scratch, Register scratch2);
10751075
#endif
10761076

1077-
1077+
void safepoint_poll(Register tmp1, Label& slow_path);
1078+
void get_polling_page(Register dest);
1079+
void read_polling_page(Register dest, relocInfo::relocType rtype);
10781080
};
10791081

10801082

src/hotspot/cpu/arm/sharedRuntime_arm.cpp

+23-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
3434
#include "oops/compiledICHolder.hpp"
3535
#include "oops/klass.inline.hpp"
3636
#include "runtime/sharedRuntime.hpp"
37+
#include "runtime/safepointMechanism.hpp"
3738
#include "runtime/vframeArray.hpp"
3839
#include "utilities/align.hpp"
3940
#include "vmreg_arm.inline.hpp"
@@ -1219,20 +1220,18 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
12191220
}
12201221

12211222
// Do a safepoint check while thread is in transition state
1222-
InlinedAddress safepoint_state(SafepointSynchronize::address_of_state());
12231223
Label call_safepoint_runtime, return_to_java;
12241224
__ mov(Rtemp, _thread_in_native_trans);
1225-
__ ldr_literal(R2, safepoint_state);
12261225
__ str_32(Rtemp, Address(Rthread, JavaThread::thread_state_offset()));
12271226

12281227
// make sure the store is observed before reading the SafepointSynchronize state and further mem refs
12291228
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad | MacroAssembler::StoreStore), Rtemp);
12301229

1231-
__ ldr_s32(R2, Address(R2));
1230+
__ safepoint_poll(R2, call_safepoint_runtime);
12321231
__ ldr_u32(R3, Address(Rthread, JavaThread::suspend_flags_offset()));
1233-
__ cmp(R2, SafepointSynchronize::_not_synchronized);
1234-
__ cond_cmp(R3, 0, eq);
1232+
__ cmp(R3, 0);
12351233
__ b(call_safepoint_runtime, ne);
1234+
12361235
__ bind(return_to_java);
12371236

12381237
// Perform thread state transition and reguard stack yellow pages if needed
@@ -1303,8 +1302,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
13031302
pop_result_registers(masm, ret_type);
13041303
__ b(return_to_java);
13051304

1306-
__ bind_literal(safepoint_state);
1307-
13081305
// Reguard stack pages. Save native results around a call to C runtime.
13091306
__ bind(reguard);
13101307
push_result_registers(masm, ret_type);
@@ -1806,15 +1803,29 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
18061803
oop_maps->add_gc_map(pc_offset, map);
18071804
__ reset_last_Java_frame(Rtemp); // Rtemp free since scratched by far call
18081805

1809-
// Check for pending exception
1810-
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
1811-
__ cmp(Rtemp, 0);
1812-
18131806
if (!cause_return) {
1807+
if (SafepointMechanism::uses_thread_local_poll()) {
1808+
// If our stashed return pc was modified by the runtime we avoid touching it
1809+
__ ldr(R3_tmp, Address(Rthread, JavaThread::saved_exception_pc_offset()));
1810+
__ ldr(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize));
1811+
__ cmp(R2_tmp, R3_tmp);
1812+
// Adjust return pc forward to step over the safepoint poll instruction
1813+
__ add(R2_tmp, R2_tmp, 4, eq);
1814+
__ str(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize), eq);
1815+
}
1816+
1817+
// Check for pending exception
1818+
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
1819+
__ cmp(Rtemp, 0);
1820+
18141821
RegisterSaver::restore_live_registers(masm, false);
18151822
__ pop(PC, eq);
18161823
__ pop(Rexception_pc);
18171824
} else {
1825+
// Check for pending exception
1826+
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
1827+
__ cmp(Rtemp, 0);
1828+
18181829
RegisterSaver::restore_live_registers(masm);
18191830
__ bx(LR, eq);
18201831
__ mov(Rexception_pc, LR);

src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -959,8 +959,6 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
959959
// Force this write out before the read below
960960
__ membar(MacroAssembler::StoreLoad, Rtemp);
961961

962-
__ ldr_global_s32(Rtemp, SafepointSynchronize::address_of_state());
963-
964962
// Protect the return value in the interleaved code: save it to callee-save registers.
965963
__ mov(Rsaved_result_lo, R0);
966964
__ mov(Rsaved_result_hi, R1);
@@ -973,12 +971,16 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
973971
#endif // __ABI_HARD__
974972

975973
{
976-
__ ldr_u32(R3, Address(Rthread, JavaThread::suspend_flags_offset()));
977-
__ cmp(Rtemp, SafepointSynchronize::_not_synchronized);
978-
__ cond_cmp(R3, 0, eq);
974+
Label call, skip_call;
975+
__ safepoint_poll(Rtemp, call);
976+
__ ldr_u32(R3, Address(Rthread, JavaThread::suspend_flags_offset()));
977+
__ cmp(R3, 0);
978+
__ b(skip_call, eq);
979+
__ bind(call);
980+
__ mov(R0, Rthread);
981+
__ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), relocInfo::none);
982+
__ bind(skip_call);
979983

980-
__ mov(R0, Rthread, ne);
981-
__ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), relocInfo::none, ne);
982984
#if R9_IS_SCRATCHED
983985
__ restore_method();
984986
#endif

0 commit comments

Comments
 (0)