< prev index next >
src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp
Print this page
rev 50905 : Move Shenandoah stubs generation into ShenandoahBarrierSetAssembler
rev 50906 : [mq]: stubgen-v2.patch
*** 23,32 ****
--- 23,33 ----
#include "precompiled.hpp"
#include "gc/shenandoah/brooksPointer.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
+ #include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahRuntime.hpp"
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interp_masm.hpp"
*** 39,48 ****
--- 40,52 ----
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#endif
#define __ masm->
+ address ShenandoahBarrierSetAssembler::_shenandoah_wb = NULL;
+ address ShenandoahBarrierSetAssembler::_shenandoah_wb_C = NULL;
+
void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register src, Register dst, Register count) {
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
*** 836,840 ****
--- 840,959 ----
#undef __
#endif // COMPILER1
+ address ShenandoahBarrierSetAssembler::shenandoah_wb() {
+ assert(_shenandoah_wb != NULL, "need write barrier stub");
+ return _shenandoah_wb;
+ }
+
+ address ShenandoahBarrierSetAssembler::shenandoah_wb_C() {
+ assert(_shenandoah_wb_C != NULL, "need write barrier stub");
+ return _shenandoah_wb_C;
+ }
+
+ #define __ cgen->assembler()->
+
+ address ShenandoahBarrierSetAssembler::generate_shenandoah_wb(StubCodeGenerator* cgen, bool c_abi, bool do_cset_test) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(cgen, "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, ShenandoahRuntime::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;
+ }
+
+ #undef __
+
+ void ShenandoahBarrierSetAssembler::barrier_stubs_init() {
+ if (ShenandoahWriteBarrier || ShenandoahStoreValEnqueueBarrier) {
+ int stub_code_size = 1536;
+ ResourceMark rm;
+ BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size);
+ CodeBuffer buf(bb);
+ StubCodeGenerator cgen(&buf);
+ _shenandoah_wb = generate_shenandoah_wb(&cgen, false, true);
+ _shenandoah_wb_C = generate_shenandoah_wb(&cgen, true, !ShenandoahWriteBarrierCsetTestInIR);
+ }
+ }
< prev index next >