comparison src/cpu/x86/vm/c1_CodeStubs_x86.cpp @ 3249:e1162778c1c8

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer. Reviewed-by: kvn, iveresov, never, tonyp, dholmes
author johnc
date Thu, 07 Apr 2011 09:53:20 -0700
parents 32f7097f9d8f
children 59766fd005ff
comparison
equal deleted inserted replaced
3248:e6beb62de02d 3249:e1162778c1c8
462 462
463 ///////////////////////////////////////////////////////////////////////////// 463 /////////////////////////////////////////////////////////////////////////////
464 #ifndef SERIALGC 464 #ifndef SERIALGC
465 465
466 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { 466 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
467 467 // At this point we know that marking is in progress.
468 // At this point we know that marking is in progress 468 // If do_load() is true then we have to emit the
469 // load of the previous value; otherwise it has already
470 // been loaded into _pre_val.
469 471
470 __ bind(_entry); 472 __ bind(_entry);
471 assert(pre_val()->is_register(), "Precondition."); 473 assert(pre_val()->is_register(), "Precondition.");
472 474
473 Register pre_val_reg = pre_val()->as_register(); 475 Register pre_val_reg = pre_val()->as_register();
474 476
475 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); 477 if (do_load()) {
478 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
479 }
476 480
477 __ cmpptr(pre_val_reg, (int32_t) NULL_WORD); 481 __ cmpptr(pre_val_reg, (int32_t) NULL_WORD);
478 __ jcc(Assembler::equal, _continuation); 482 __ jcc(Assembler::equal, _continuation);
479 ce->store_parameter(pre_val()->as_register(), 0); 483 ce->store_parameter(pre_val()->as_register(), 0);
480 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id))); 484 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id)));
481 __ jmp(_continuation); 485 __ jmp(_continuation);
482 486
487 }
488
489 void G1UnsafeGetObjSATBBarrierStub::emit_code(LIR_Assembler* ce) {
490 // At this point we know that offset == referent_offset.
491 //
492 // So we might have to emit:
493 // if (src == null) goto continuation.
494 //
495 // and we definitely have to emit:
496 // if (klass(src).reference_type == REF_NONE) goto continuation
497 // if (!marking_active) goto continuation
498 // if (pre_val == null) goto continuation
499 // call pre_barrier(pre_val)
500 // goto continuation
501 //
502 __ bind(_entry);
503
504 assert(src()->is_register(), "sanity");
505 Register src_reg = src()->as_register();
506
507 if (gen_src_check()) {
508 // The original src operand was not a constant.
509 // Generate src == null?
510 __ cmpptr(src_reg, (int32_t) NULL_WORD);
511 __ jcc(Assembler::equal, _continuation);
512 }
513
514 // Generate src->_klass->_reference_type == REF_NONE)?
515 assert(tmp()->is_register(), "sanity");
516 Register tmp_reg = tmp()->as_register();
517
518 __ load_klass(tmp_reg, src_reg);
519
520 Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset_in_bytes() + sizeof(oopDesc));
521 __ cmpl(ref_type_adr, REF_NONE);
522 __ jcc(Assembler::equal, _continuation);
523
524 // Is marking active?
525 assert(thread()->is_register(), "precondition");
526 Register thread_reg = thread()->as_register();
527
528 Address in_progress(thread_reg, in_bytes(JavaThread::satb_mark_queue_offset() +
529 PtrQueue::byte_offset_of_active()));
530
531 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
532 __ cmpl(in_progress, 0);
533 } else {
534 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
535 __ cmpb(in_progress, 0);
536 }
537 __ jcc(Assembler::equal, _continuation);
538
539 // val == null?
540 assert(val()->is_register(), "Precondition.");
541 Register val_reg = val()->as_register();
542
543 __ cmpptr(val_reg, (int32_t) NULL_WORD);
544 __ jcc(Assembler::equal, _continuation);
545
546 ce->store_parameter(val()->as_register(), 0);
547 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id)));
548 __ jmp(_continuation);
483 } 549 }
484 550
485 jbyte* G1PostBarrierStub::_byte_map_base = NULL; 551 jbyte* G1PostBarrierStub::_byte_map_base = NULL;
486 552
487 jbyte* G1PostBarrierStub::byte_map_base_slow() { 553 jbyte* G1PostBarrierStub::byte_map_base_slow() {