< prev index next >

src/cpu/x86/vm/stubGenerator_x86_64.cpp

Print this page

        

*** 23,32 **** --- 23,36 ---- */ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" + #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp" + #include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" + #include "gc_implementation/shenandoah/shenandoahHeap.hpp" + #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_x86.hpp" #include "oops/instanceOop.hpp" #include "oops/method.hpp" #include "oops/objArrayKlass.hpp"
*** 750,759 **** --- 754,852 ---- __ ret(0); return start; } + address generate_shenandoah_wb(bool c_abi, bool do_cset_test) { + StubCodeMark mark(this, "StubRoutines", "shenandoah_wb"); + address start = __ pc(); + + Label not_done; + + // We use RDI, which also serves as argument register for slow call. + // RAX always holds the src object ptr, except after the slow call and + // the cmpxchg, then it holds the result. + // R8 and RCX are used as temporary registers. + if (!c_abi) { + __ push(rdi); + __ push(r8); + } + + // Check for object beeing in the collection set. + // TODO: Can we use only 1 register here? + // The source object arrives here in rax. + // live: rax + // live: rdi + if (!c_abi) { + __ mov(rdi, rax); + } else { + if (rax != c_rarg0) { + __ mov(rax, c_rarg0); + } + } + if (do_cset_test) { + __ shrptr(rdi, ShenandoahHeapRegion::region_size_bytes_shift_jint()); + // live: r8 + __ movptr(r8, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr()); + __ movbool(r8, Address(r8, rdi, Address::times_1)); + // unlive: rdi + __ testbool(r8); + // unlive: r8 + __ jccb(Assembler::notZero, not_done); + + if (!c_abi) { + __ pop(r8); + __ pop(rdi); + } + __ ret(0); + + __ bind(not_done); + } + + if (!c_abi) { + __ push(rcx); + } + + if (!c_abi) { + __ push(rdx); + __ push(rdi); + __ push(rsi); + __ push(r8); + __ push(r9); + __ push(r10); + __ push(r11); + __ push(r12); + __ push(r13); + __ push(r14); + __ push(r15); + } + __ save_vector_registers(); + __ movptr(rdi, rax); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_JRT), rdi); + __ restore_vector_registers(); + if (!c_abi) { + __ pop(r15); + __ pop(r14); + __ pop(r13); + __ pop(r12); + __ pop(r11); + __ pop(r10); + __ pop(r9); + __ pop(r8); + __ pop(rsi); + __ pop(rdi); + __ pop(rdx); + + __ pop(rcx); + __ pop(r8); + __ pop(rdi); + } + __ ret(0); + + return start; + } + address generate_f2i_fixup() { StubCodeMark mark(this, "StubRoutines", "f2i_fixup"); Address inout(rsp, 5 * wordSize); // return address + 4 saves address start = __ pc();
*** 1181,1190 **** --- 1274,1284 ---- void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) { BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: + case BarrierSet::ShenandoahBarrierSet: // With G1, don't generate the call if we statically know that the target in uninitialized if (!dest_uninitialized) { __ pusha(); // push registers if (count == c_rarg0) { if (addr == c_rarg1) {
*** 1226,1235 **** --- 1320,1330 ---- assert_different_registers(start, count, scratch); BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCTLogging: + case BarrierSet::ShenandoahBarrierSet: { __ pusha(); // push registers (overkill) if (c_rarg0 == count) { // On win64 c_rarg0 == rcx assert_different_registers(c_rarg1, start); __ mov(c_rarg1, count);
*** 4047,4056 **** --- 4142,4155 ---- CAST_FROM_FN_PTR(address, SharedRuntime:: throw_NullPointerException_at_call)); // entry points that are platform specific + if (UseShenandoahGC && ShenandoahWriteBarrier) { + StubRoutines::x86::_shenandoah_wb = generate_shenandoah_wb(false, true); + StubRoutines::_shenandoah_wb_C = generate_shenandoah_wb(true, false); + } StubRoutines::x86::_f2i_fixup = generate_f2i_fixup(); StubRoutines::x86::_f2l_fixup = generate_f2l_fixup(); StubRoutines::x86::_d2i_fixup = generate_d2i_fixup(); StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
< prev index next >