< prev index next >

src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp

Print this page
rev 55404 : 8226197: Reducing G1?s CPU cost with simplified write post-barrier and disabling concurrent refinement
Summary: A prototype to add a mode for G1 to use a simplified write post-barrier. Guarded by new flag G1FastWriteBarrier.


 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
< prev index next >