3470 Register pre_val,
3471 Register thread,
3472 Register tmp,
3473 bool tosca_live,
3474 bool expand_call) {
3475 // If expand_call is true then we expand the call_VM_leaf macro
3476 // directly to skip generating the check by
3477 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
3478
3479 assert(thread == rthread, "must be");
3480
3481 Label done;
3482 Label runtime;
3483
3484 assert(pre_val != noreg, "check this code");
3485
3486 if (obj != noreg)
3487 assert_different_registers(obj, pre_val, tmp);
3488
3489 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3490 PtrQueue::byte_offset_of_active()));
3491 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3492 PtrQueue::byte_offset_of_index()));
3493 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3494 PtrQueue::byte_offset_of_buf()));
3495
3496
3497 // Is marking active?
3498 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
3499 ldrw(tmp, in_progress);
3500 } else {
3501 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
3502 ldrb(tmp, in_progress);
3503 }
3504 cbzw(tmp, done);
3505
3506 // Do we need to load the previous value?
3507 if (obj != noreg) {
3508 load_heap_oop(pre_val, Address(obj, 0));
3509 }
3510
3511 // Is the previous value null?
3512 cbz(pre_val, done);
3513
3514 // Can we store original value in the thread's buffer?
3515 // Is index == 0?
3516 // (The index field is typed as size_t.)
3517
3518 ldr(tmp, index); // tmp := *index_adr
3519 cbz(tmp, runtime); // tmp == 0?
3520 // If yes, goto runtime
3521
3549 pass_arg1(this, thread);
3550 pass_arg0(this, pre_val);
3551 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
3552 } else {
3553 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
3554 }
3555
3556 pop(r0->bit(tosca_live) | obj->bit(obj != noreg) | pre_val->bit(true), sp);
3557
3558 bind(done);
3559 }
3560
3561 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3562 Register new_val,
3563 Register thread,
3564 Register tmp,
3565 Register tmp2) {
3566 assert(thread == rthread, "must be");
3567
3568 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3569 PtrQueue::byte_offset_of_index()));
3570 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3571 PtrQueue::byte_offset_of_buf()));
3572
3573 BarrierSet* bs = Universe::heap()->barrier_set();
3574 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3575 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3576
3577 Label done;
3578 Label runtime;
3579
3580 // Does store cross heap regions?
3581
3582 eor(tmp, store_addr, new_val);
3583 lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3584 cbz(tmp, done);
3585
3586 // crosses regions, storing NULL?
3587
3588 cbz(new_val, done);
3589
3590 // storing region crossing non-NULL, is card already dirty?
3591
|
3470 Register pre_val,
3471 Register thread,
3472 Register tmp,
3473 bool tosca_live,
3474 bool expand_call) {
3475 // If expand_call is true then we expand the call_VM_leaf macro
3476 // directly to skip generating the check by
3477 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
3478
3479 assert(thread == rthread, "must be");
3480
3481 Label done;
3482 Label runtime;
3483
3484 assert(pre_val != noreg, "check this code");
3485
3486 if (obj != noreg)
3487 assert_different_registers(obj, pre_val, tmp);
3488
3489 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3490 SATBMarkQueue::byte_offset_of_active()));
3491 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3492 SATBMarkQueue::byte_offset_of_index()));
3493 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3494 SATBMarkQueue::byte_offset_of_buf()));
3495
3496
3497 // Is marking active?
3498 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
3499 ldrw(tmp, in_progress);
3500 } else {
3501 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
3502 ldrb(tmp, in_progress);
3503 }
3504 cbzw(tmp, done);
3505
3506 // Do we need to load the previous value?
3507 if (obj != noreg) {
3508 load_heap_oop(pre_val, Address(obj, 0));
3509 }
3510
3511 // Is the previous value null?
3512 cbz(pre_val, done);
3513
3514 // Can we store original value in the thread's buffer?
3515 // Is index == 0?
3516 // (The index field is typed as size_t.)
3517
3518 ldr(tmp, index); // tmp := *index_adr
3519 cbz(tmp, runtime); // tmp == 0?
3520 // If yes, goto runtime
3521
3549 pass_arg1(this, thread);
3550 pass_arg0(this, pre_val);
3551 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
3552 } else {
3553 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
3554 }
3555
3556 pop(r0->bit(tosca_live) | obj->bit(obj != noreg) | pre_val->bit(true), sp);
3557
3558 bind(done);
3559 }
3560
3561 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3562 Register new_val,
3563 Register thread,
3564 Register tmp,
3565 Register tmp2) {
3566 assert(thread == rthread, "must be");
3567
3568 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3569 DirtyCardQueue::byte_offset_of_index()));
3570 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3571 DirtyCardQueue::byte_offset_of_buf()));
3572
3573 BarrierSet* bs = Universe::heap()->barrier_set();
3574 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3575 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3576
3577 Label done;
3578 Label runtime;
3579
3580 // Does store cross heap regions?
3581
3582 eor(tmp, store_addr, new_val);
3583 lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3584 cbz(tmp, done);
3585
3586 // crosses regions, storing NULL?
3587
3588 cbz(new_val, done);
3589
3590 // storing region crossing non-NULL, is card already dirty?
3591
|