--- old/src/cpu/x86/vm/x86_64.ad 2015-08-12 14:09:03.000000000 +0200 +++ new/src/cpu/x86/vm/x86_64.ad 2015-08-12 14:09:03.000000000 +0200 @@ -938,7 +938,11 @@ st->print_cr("popq rbp"); if (do_polling() && C->is_method_compilation()) { st->print("\t"); - if (Assembler::is_polling_page_far()) { + if (ThreadLocalSafepoints) { + st->print_cr("testb $1, [r15]\t" + "# Safepoint: poll for GC\n\t"); + st->print_cr("je #slow_safepoint_runtime"); + } else if (Assembler::is_polling_page_far()) { st->print_cr("movq rscratch1, #polling_page_address\n\t" "testl rax, [rscratch1]\t" "# Safepoint: poll for GC"); @@ -987,7 +991,14 @@ if (do_polling() && C->is_method_compilation()) { MacroAssembler _masm(&cbuf); AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); - if (Assembler::is_polling_page_far()) { + if (ThreadLocalSafepoints) { + InternalAddress safepoint_pc(__ pc()); + Label dummy_label; + Label &code_stub = &cbuf == C->code_buffer() ? C->tls_table()->add_safepoint(safepoint_pc, true) : dummy_label; + __ relocate(relocInfo::poll_return_type); + __ testb(Address(r15_thread, Thread::yieldpoint_offset()), 2); + __ jcc(Assembler::equal, code_stub); + } else if (Assembler::is_polling_page_far()) { __ lea(rscratch1, polling_page); __ relocate(relocInfo::poll_return_type); __ testl(rax, Address(rscratch1, 0)); @@ -1005,7 +1016,7 @@ int MachEpilogNode::reloc() const { - return 2; // a large enough number + return 3; // a large enough number } const Pipeline* MachEpilogNode::pipeline() const @@ -11552,7 +11563,7 @@ // Safepoint Instructions instruct safePoint_poll(rFlagsReg cr) %{ - predicate(!Assembler::is_polling_page_far()); + predicate(!Assembler::is_polling_page_far() || ThreadLocalSafepoints); match(SafePoint); effect(KILL cr); @@ -11560,15 +11571,25 @@ "# Safepoint: poll for GC" %} ins_cost(125); ins_encode %{ - AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); - __ testl(rax, addr); + if (ThreadLocalSafepoints) { + Compile* C = ra_->C; + InternalAddress safepoint_pc(__ pc()); + Label dummy_label; + Label &code_stub = &cbuf == C->code_buffer() ? C->tls_table()->add_safepoint(safepoint_pc, false) : dummy_label; + __ relocate(relocInfo::poll_type); + __ testb(Address(r15_thread, Thread::yieldpoint_offset()), 1); + __ jcc(Assembler::equal, code_stub); + } else { + AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); + __ testl(rax, addr); + } %} ins_pipe(ialu_reg_mem); %} instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) %{ - predicate(Assembler::is_polling_page_far()); + predicate(Assembler::is_polling_page_far() && !ThreadLocalSafepoints); match(SafePoint poll); effect(KILL cr, USE poll);