284 __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
285 __ jcc(Assembler::equal, done);
286
287 // crosses regions, storing NULL?
288
289 __ cmpptr(new_val, (int32_t) NULL_WORD);
290 __ jcc(Assembler::equal, done);
291
292 // storing region crossing non-NULL, is card already dirty?
293
294 const Register card_addr = tmp;
295 const Register cardtable = tmp2;
296
297 __ movptr(card_addr, store_addr);
298 __ shrptr(card_addr, CardTable::card_shift);
299 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
300 // a valid address and therefore is not properly handled by the relocation code.
301 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
302 __ addptr(card_addr, cardtable);
303
304 __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
305 __ jcc(Assembler::equal, done);
306
307 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
308 __ cmpb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val());
309 __ jcc(Assembler::equal, done);
310
311
312 // storing a region crossing, non-NULL oop, card is clean.
313 // dirty card and log.
314
315 __ movb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val());
316
317 __ cmpl(queue_index, 0);
318 __ jcc(Assembler::equal, runtime);
319 __ subl(queue_index, wordSize);
320 __ movptr(tmp2, buffer);
321 #ifdef _LP64
322 __ movslq(rscratch1, queue_index);
323 __ addq(tmp2, rscratch1);
324 __ movq(Address(tmp2, 0), card_addr);
325 #else
326 __ addl(tmp2, queue_index);
327 __ movl(Address(tmp2, 0), card_addr);
328 #endif
329 __ jmp(done);
330
331 __ bind(runtime);
332 // save the live input values
333 __ push(store_addr);
334 __ push(new_val);
335 #ifdef _LP64
336 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, r15_thread);
337 #else
338 __ push(thread);
339 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
340 __ pop(thread);
341 #endif
342 __ pop(new_val);
343 __ pop(store_addr);
344
345 __ bind(done);
346 }
347
348 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
349 Address dst, Register val, Register tmp1, Register tmp2) {
350 bool in_heap = (decorators & IN_HEAP) != 0;
351 bool as_normal = (decorators & AS_NORMAL) != 0;
352 assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
353
354 bool needs_pre_barrier = as_normal;
355 bool needs_post_barrier = val != noreg && in_heap;
356
357 Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
358 Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
359 // flatten object address if needed
360 // We do it regardless of precise because we need the registers
361 if (dst.index() == noreg && dst.disp() == 0) {
362 if (dst.base() != tmp1) {
363 __ movptr(tmp1, dst.base());
532 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
533
534 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
535 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
536
537 __ push(rax);
538 __ push(rcx);
539
540 const Register cardtable = rax;
541 const Register card_addr = rcx;
542
543 __ load_parameter(0, card_addr);
544 __ shrptr(card_addr, CardTable::card_shift);
545 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
546 // a valid address and therefore is not properly handled by the relocation code.
547 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
548 __ addptr(card_addr, cardtable);
549
550 NOT_LP64(__ get_thread(thread);)
551
552 __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
553 __ jcc(Assembler::equal, done);
554
555 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
556 __ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
557 __ jcc(Assembler::equal, done);
558
559 // storing region crossing non-NULL, card is clean.
560 // dirty card and log.
561
562 __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
563
564 const Register tmp = rdx;
565 __ push(rdx);
566
567 __ movptr(tmp, queue_index);
568 __ testptr(tmp, tmp);
569 __ jcc(Assembler::zero, runtime);
570 __ subptr(tmp, wordSize);
571 __ movptr(queue_index, tmp);
572 __ addptr(tmp, buffer);
573 __ movptr(Address(tmp, 0), card_addr);
574 __ jmp(enqueued);
575
576 __ bind(runtime);
577
578 __ save_live_registers_no_oop_map(true);
579
580 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
581
582 __ restore_live_registers(true);
583
584 __ bind(enqueued);
585 __ pop(rdx);
586
587 __ bind(done);
588 __ pop(rcx);
589 __ pop(rax);
590
591 __ epilogue();
592 }
593
594 #undef __
595
596 #endif // COMPILER1
|
284 __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
285 __ jcc(Assembler::equal, done);
286
287 // crosses regions, storing NULL?
288
289 __ cmpptr(new_val, (int32_t) NULL_WORD);
290 __ jcc(Assembler::equal, done);
291
292 // storing region crossing non-NULL, is card already dirty?
293
294 const Register card_addr = tmp;
295 const Register cardtable = tmp2;
296
297 __ movptr(card_addr, store_addr);
298 __ shrptr(card_addr, CardTable::card_shift);
299 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
300 // a valid address and therefore is not properly handled by the relocation code.
301 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
302 __ addptr(card_addr, cardtable);
303
304 if (G1FastWriteBarrier) {
305 __ movb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val());
306 } else {
307 __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
308 __ jcc(Assembler::equal, done);
309
310 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
311 __ cmpb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val());
312 __ jcc(Assembler::equal, done);
313
314
315 // storing a region crossing, non-NULL oop, card is clean.
316 // dirty card and log.
317
318 __ movb(Address(card_addr, 0), (int)G1CardTable::dirty_card_val());
319
320 __ cmpl(queue_index, 0);
321 __ jcc(Assembler::equal, runtime);
322 __ subl(queue_index, wordSize);
323 __ movptr(tmp2, buffer);
324 #ifdef _LP64
325 __ movslq(rscratch1, queue_index);
326 __ addq(tmp2, rscratch1);
327 __ movq(Address(tmp2, 0), card_addr);
328 #else
329 __ addl(tmp2, queue_index);
330 __ movl(Address(tmp2, 0), card_addr);
331 #endif
332 __ jmp(done);
333
334 __ bind(runtime);
335 // save the live input values
336 __ push(store_addr);
337 __ push(new_val);
338 #ifdef _LP64
339 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, r15_thread);
340 #else
341 __ push(thread);
342 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
343 __ pop(thread);
344 #endif
345 __ pop(new_val);
346 __ pop(store_addr);
347 }
348
349 __ bind(done);
350 }
351
352 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
353 Address dst, Register val, Register tmp1, Register tmp2) {
354 bool in_heap = (decorators & IN_HEAP) != 0;
355 bool as_normal = (decorators & AS_NORMAL) != 0;
356 assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
357
358 bool needs_pre_barrier = as_normal;
359 bool needs_post_barrier = val != noreg && in_heap;
360
361 Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
362 Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
363 // flatten object address if needed
364 // We do it regardless of precise because we need the registers
365 if (dst.index() == noreg && dst.disp() == 0) {
366 if (dst.base() != tmp1) {
367 __ movptr(tmp1, dst.base());
536 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
537
538 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
539 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
540
541 __ push(rax);
542 __ push(rcx);
543
544 const Register cardtable = rax;
545 const Register card_addr = rcx;
546
547 __ load_parameter(0, card_addr);
548 __ shrptr(card_addr, CardTable::card_shift);
549 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
550 // a valid address and therefore is not properly handled by the relocation code.
551 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
552 __ addptr(card_addr, cardtable);
553
554 NOT_LP64(__ get_thread(thread);)
555
556 if (G1FastWriteBarrier) {
557 __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
558 } else {
559 __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
560 __ jcc(Assembler::equal, done);
561
562 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
563 __ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
564 __ jcc(Assembler::equal, done);
565
566 // storing region crossing non-NULL, card is clean.
567 // dirty card and log.
568
569 __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
570
571 const Register tmp = rdx;
572 __ push(rdx);
573
574 __ movptr(tmp, queue_index);
575 __ testptr(tmp, tmp);
576 __ jcc(Assembler::zero, runtime);
577 __ subptr(tmp, wordSize);
578 __ movptr(queue_index, tmp);
579 __ addptr(tmp, buffer);
580 __ movptr(Address(tmp, 0), card_addr);
581 __ jmp(enqueued);
582
583 __ bind(runtime);
584
585 __ save_live_registers_no_oop_map(true);
586
587 __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
588
589 __ restore_live_registers(true);
590
591 __ bind(enqueued);
592 __ pop(rdx);
593
594 __ bind(done);
595 }
596 __ pop(rcx);
597 __ pop(rax);
598
599 __ epilogue();
600 }
601
602 #undef __
603
604 #endif // COMPILER1
|