src/cpu/x86/vm/assembler_x86.cpp
Print this page
rev 2237 : [mq]: initial-intrinsification-changes
rev 2238 : [mq]: code-review-comments-vladimir
rev 2239 : [mq]: client_assertion_fauilure
*** 6888,6984 ****
//////////////////////////////////////////////////////////////////////////////////
#ifndef SERIALGC
void MacroAssembler::g1_write_barrier_pre(Register obj,
! #ifndef _LP64
Register thread,
- #endif
Register tmp,
! Register tmp2,
! bool tosca_live) {
! LP64_ONLY(Register thread = r15_thread;)
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_active()));
-
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_index()));
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_buf()));
! Label done;
! Label runtime;
!
! // if (!marking_in_progress) goto done;
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
cmpl(in_progress, 0);
} else {
assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
cmpb(in_progress, 0);
}
jcc(Assembler::equal, done);
! // if (x.f == NULL) goto done;
! #ifdef _LP64
! load_heap_oop(tmp2, Address(obj, 0));
! #else
! movptr(tmp2, Address(obj, 0));
! #endif
! cmpptr(tmp2, (int32_t) NULL_WORD);
jcc(Assembler::equal, done);
// Can we store original value in the thread's buffer?
! #ifdef _LP64
! movslq(tmp, index);
! cmpq(tmp, 0);
! #else
! cmpl(index, 0);
! #endif
! jcc(Assembler::equal, runtime);
! #ifdef _LP64
! subq(tmp, wordSize);
! movl(index, tmp);
! addq(tmp, buffer);
! #else
! subl(index, wordSize);
! movl(tmp, buffer);
! addl(tmp, index);
! #endif
! movptr(Address(tmp, 0), tmp2);
jmp(done);
bind(runtime);
// save the live input values
if(tosca_live) push(rax);
push(obj);
! #ifdef _LP64
! call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, r15_thread);
! #else
! push(thread);
! call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), tmp2, thread);
! pop(thread);
! #endif
pop(obj);
if(tosca_live) pop(rax);
- bind(done);
}
void MacroAssembler::g1_write_barrier_post(Register store_addr,
Register new_val,
- #ifndef _LP64
Register thread,
- #endif
Register tmp,
Register tmp2) {
- LP64_ONLY(Register thread = r15_thread;)
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
PtrQueue::byte_offset_of_index()));
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
PtrQueue::byte_offset_of_buf()));
BarrierSet* bs = Universe::heap()->barrier_set();
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
Label done;
Label runtime;
--- 6888,7024 ----
//////////////////////////////////////////////////////////////////////////////////
#ifndef SERIALGC
void MacroAssembler::g1_write_barrier_pre(Register obj,
! Register pre_val,
Register thread,
Register tmp,
! bool tosca_live,
! bool expand_call) {
!
! // If expand_call is true then we expand the call_VM_leaf macro
! // directly to skip generating the check by
! // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
!
! #ifdef _LP64
! assert(thread == r15_thread, "must be");
! #endif // _LP64
!
! Label done;
! Label runtime;
!
! assert(pre_val != noreg, "check this code");
!
! if (obj != noreg) {
! assert_different_registers(obj, pre_val, tmp);
! assert(pre_val != rax, "check this code");
! }
!
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_active()));
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_index()));
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_buf()));
! // Is marking active?
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
cmpl(in_progress, 0);
} else {
assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
cmpb(in_progress, 0);
}
jcc(Assembler::equal, done);
! // Do we need to load the previous value?
! if (obj != noreg) {
! load_heap_oop(pre_val, Address(obj, 0));
! }
!
! // Is the previous value null?
! cmpptr(pre_val, (int32_t) NULL_WORD);
jcc(Assembler::equal, done);
// Can we store original value in the thread's buffer?
+ // Is index == 0?
+ // (The index field is typed as size_t.)
! movptr(tmp, index); // tmp := *index_adr
! cmpptr(tmp, 0); // tmp == 0?
! jcc(Assembler::equal, runtime); // If yes, goto runtime
!
! subptr(tmp, wordSize); // tmp := tmp - wordSize
! movptr(index, tmp); // *index_adr := tmp
! addptr(tmp, buffer); // tmp := tmp + *buffer_adr
!
! // Record the previous value
! movptr(Address(tmp, 0), pre_val);
jmp(done);
+
bind(runtime);
// save the live input values
if(tosca_live) push(rax);
+
+ if (obj != noreg && obj != rax)
push(obj);
!
! if (pre_val != rax)
! push(pre_val);
!
! // Calling the runtime using the regular call_VM_leaf mechanism generates
! // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
! // that checks that the *(ebp+frame::interpreter_frame_last_sp) == NULL.
! //
! // If we care generating the pre-barrier without a frame (e.g. in the
! // intrinsified Reference.get() routine) then ebp might be pointing to
! // the caller frame and so this check will most likely fail at runtime.
! //
! // Expanding the call directly bypasses the generation of the check.
! // So when we do not have have a full interpreter frame on the stack
! // expand_call should be passed true.
!
! NOT_LP64( push(thread); )
!
! if (expand_call) {
! LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
! pass_arg1(this, thread);
! pass_arg0(this, pre_val);
! MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
! } else {
! call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
! }
!
! NOT_LP64( pop(thread); )
!
! // save the live input values
! if (pre_val != rax)
! pop(pre_val);
!
! if (obj != noreg && obj != rax)
pop(obj);
+
if(tosca_live) pop(rax);
+ bind(done);
}
void MacroAssembler::g1_write_barrier_post(Register store_addr,
Register new_val,
Register thread,
Register tmp,
Register tmp2) {
+ #ifdef _LP64
+ assert(thread == r15_thread, "must be");
+ #endif // _LP64
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
PtrQueue::byte_offset_of_index()));
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
PtrQueue::byte_offset_of_buf()));
+
BarrierSet* bs = Universe::heap()->barrier_set();
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
Label done;
Label runtime;
*** 7053,7063 ****
#endif
pop(new_val);
pop(store_addr);
bind(done);
-
}
#endif // SERIALGC
//////////////////////////////////////////////////////////////////////////////////
--- 7093,7102 ----