comparison src/cpu/sparc/vm/c1_CodeStubs_sparc.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
406 406
407 /////////////////////////////////////////////////////////////////////////////////// 407 ///////////////////////////////////////////////////////////////////////////////////
408 #ifndef SERIALGC 408 #ifndef SERIALGC
409 409
410 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { 410 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
411 // At this point we know that marking is in progress.
412 // If do_load() is true then we have to emit the
413 // load of the previous value; otherwise it has already
414 // been loaded into _pre_val.
415
411 __ bind(_entry); 416 __ bind(_entry);
412 417
413 assert(pre_val()->is_register(), "Precondition."); 418 assert(pre_val()->is_register(), "Precondition.");
414
415 Register pre_val_reg = pre_val()->as_register(); 419 Register pre_val_reg = pre_val()->as_register();
416 420
417 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); 421 if (do_load()) {
422 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
423 }
424
418 if (__ is_in_wdisp16_range(_continuation)) { 425 if (__ is_in_wdisp16_range(_continuation)) {
419 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, 426 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
420 pre_val_reg, _continuation); 427 pre_val_reg, _continuation);
421 } else { 428 } else {
422 __ cmp(pre_val_reg, G0); 429 __ cmp(pre_val_reg, G0);
427 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id)); 434 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
428 __ delayed()->mov(pre_val_reg, G4); 435 __ delayed()->mov(pre_val_reg, G4);
429 __ br(Assembler::always, false, Assembler::pt, _continuation); 436 __ br(Assembler::always, false, Assembler::pt, _continuation);
430 __ delayed()->nop(); 437 __ delayed()->nop();
431 438
439 }
440
441 void G1UnsafeGetObjSATBBarrierStub::emit_code(LIR_Assembler* ce) {
442 // At this point we know that offset == referent_offset.
443 //
444 // So we might have to emit:
445 // if (src == null) goto continuation.
446 //
447 // and we definitely have to emit:
448 // if (klass(src).reference_type == REF_NONE) goto continuation
449 // if (!marking_active) goto continuation
450 // if (pre_val == null) goto continuation
451 // call pre_barrier(pre_val)
452 // goto continuation
453 //
454 __ bind(_entry);
455
456 assert(src()->is_register(), "sanity");
457 Register src_reg = src()->as_register();
458
459 if (gen_src_check()) {
460 // The original src operand was not a constant.
461 // Generate src == null?
462 if (__ is_in_wdisp16_range(_continuation)) {
463 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
464 src_reg, _continuation);
465 } else {
466 __ cmp(src_reg, G0);
467 __ brx(Assembler::equal, false, Assembler::pt, _continuation);
468 }
469 __ delayed()->nop();
470 }
471
472 // Generate src->_klass->_reference_type() == REF_NONE)?
473 assert(tmp()->is_register(), "sanity");
474 Register tmp_reg = tmp()->as_register();
475
476 __ load_klass(src_reg, tmp_reg);
477
478 Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset_in_bytes() + sizeof(oopDesc));
479 __ ld(ref_type_adr, tmp_reg);
480
481 if (__ is_in_wdisp16_range(_continuation)) {
482 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
483 tmp_reg, _continuation);
484 } else {
485 __ cmp(tmp_reg, G0);
486 __ brx(Assembler::equal, false, Assembler::pt, _continuation);
487 }
488 __ delayed()->nop();
489
490 // Is marking active?
491 assert(thread()->is_register(), "precondition");
492 Register thread_reg = thread()->as_register();
493
494 Address in_progress(thread_reg, in_bytes(JavaThread::satb_mark_queue_offset() +
495 PtrQueue::byte_offset_of_active()));
496
497 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
498 __ ld(in_progress, tmp_reg);
499 } else {
500 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
501 __ ldsb(in_progress, tmp_reg);
502 }
503 if (__ is_in_wdisp16_range(_continuation)) {
504 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
505 tmp_reg, _continuation);
506 } else {
507 __ cmp(tmp_reg, G0);
508 __ brx(Assembler::equal, false, Assembler::pt, _continuation);
509 }
510 __ delayed()->nop();
511
512 // val == null?
513 assert(val()->is_register(), "Precondition.");
514 Register val_reg = val()->as_register();
515
516 if (__ is_in_wdisp16_range(_continuation)) {
517 __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
518 val_reg, _continuation);
519 } else {
520 __ cmp(val_reg, G0);
521 __ brx(Assembler::equal, false, Assembler::pt, _continuation);
522 }
523 __ delayed()->nop();
524
525 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
526 __ delayed()->mov(val_reg, G4);
527 __ br(Assembler::always, false, Assembler::pt, _continuation);
528 __ delayed()->nop();
432 } 529 }
433 530
434 jbyte* G1PostBarrierStub::_byte_map_base = NULL; 531 jbyte* G1PostBarrierStub::_byte_map_base = NULL;
435 532
436 jbyte* G1PostBarrierStub::byte_map_base_slow() { 533 jbyte* G1PostBarrierStub::byte_map_base_slow() {