[aarch64-port-dev ] Patch: safepoint polling
Andrew Haley
aph at redhat.com
Fri Jul 19 04:30:29 PDT 2013
If you want to debug without segfaults at every safepoint, you can use
-XX:-UseCompilerSafepoints . This doesn't work because you'll soon get an
infinite hang awaiting a safepoint. Fixed thusly.
Andrew.
diff -r 7ddc396907b4 src/cpu/aarch64/vm/aarch64_call.cpp
--- a/src/cpu/aarch64/vm/aarch64_call.cpp Thu Jul 18 15:13:13 2013 +0100
+++ b/src/cpu/aarch64/vm/aarch64_call.cpp Fri Jul 19 12:27:28 2013 +0100
@@ -481,30 +481,68 @@
}
}
+// Rather than take a segfault when the polling page is protected,
+// explicitly check for a safepoint in progress and if there is one,
+// fake a call to the handler as if a segfault had been caught.
+void LIR_Assembler::poll_for_safepoint(relocInfo::relocType rtype, CodeEmitInfo* info) {
+ __ mov(rscratch1, SafepointSynchronize::address_of_state());
+ __ ldrb(rscratch1, Address(rscratch1));
+ Label nope, poll;
+ __ cbz(rscratch1, nope);
+ __ block_comment("safepoint");
+ __ enter();
+ __ push(0x3, sp); // r0 & r1
+ __ push(0x3ffffffc, sp); // integer registers except lr & sp & r0 & r1
+ __ adr(r0, poll);
+ __ str(r0, Address(rthread, JavaThread::saved_exception_pc_offset()));
+ __ mov(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::get_poll_stub));
+ __ brx86(rscratch1, 1, 0, 1);
+ __ pop(0x3ffffffc, sp); // integer registers except lr & sp & r0 & r1
+ __ mov(rscratch1, r0);
+ __ pop(0x3, sp); // r0 & r1
+ __ leave();
+ __ br(rscratch1);
+ address polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
+ assert(os::is_poll_address(polling_page), "should be");
+ unsigned long off;
+ __ adrp(rscratch1, Address(polling_page, rtype), off);
+ __ bind(poll);
+ if (info)
+ add_debug_info_for_branch(info); // This isn't just debug info:
+ // it's the oop map
+ else
+ __ code_section()->relocate(pc(), rtype);
+ __ ldrw(zr, Address(rscratch1, off));
+ __ bind(nope);
+}
void LIR_Assembler::return_op(LIR_Opr result) {
assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,");
// Pop the stack before the safepoint code
__ remove_frame(initial_frame_size_in_bytes());
-
- bool result_is_oop = result->is_valid() ? result->is_oop() : false;
-
- address polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
- __ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
+ if (UseCompilerSafepoints) {
+ address polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
+ __ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
+ } else {
+ poll_for_safepoint(relocInfo::poll_return_type);
+ }
__ ret(lr);
}
-
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
address polling_page(os::get_polling_page()
+ (SafepointPollOffset % os::vm_page_size()));
- guarantee(info != NULL, "Shouldn't be NULL");
- assert(os::is_poll_address(polling_page), "should be");
- unsigned long off;
- __ adrp(rscratch1, Address(polling_page, relocInfo::poll_type), off);
- add_debug_info_for_branch(info); // This isn't just debug info:
- // it's the oop map
- __ ldrw(zr, Address(rscratch1, off));
+ if (UseCompilerSafepoints) {
+ guarantee(info != NULL, "Shouldn't be NULL");
+ assert(os::is_poll_address(polling_page), "should be");
+ unsigned long off;
+ __ adrp(rscratch1, Address(polling_page, relocInfo::poll_type), off);
+ add_debug_info_for_branch(info); // This isn't just debug info:
+ // it's the oop map
+ __ ldrw(zr, Address(rscratch1, off));
+ } else {
+ poll_for_safepoint(relocInfo::poll_type, info);
+ }
return __ offset();
}
More information about the aarch64-port-dev
mailing list