comparison src/share/vm/opto/graphKit.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 9dc311b8473e
children 92add02409c9
comparison
equal deleted inserted replaced
3248:e6beb62de02d 3249:e1162778c1c8
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
1455 1455
1456 return st; 1456 return st;
1457 } 1457 }
1458 1458
1459 1459
1460 void GraphKit::pre_barrier(Node* ctl, 1460 void GraphKit::pre_barrier(bool do_load,
1461 Node* ctl,
1461 Node* obj, 1462 Node* obj,
1462 Node* adr, 1463 Node* adr,
1463 uint adr_idx, 1464 uint adr_idx,
1464 Node* val, 1465 Node* val,
1465 const TypeOopPtr* val_type, 1466 const TypeOopPtr* val_type,
1467 Node* pre_val,
1466 BasicType bt) { 1468 BasicType bt) {
1469
1467 BarrierSet* bs = Universe::heap()->barrier_set(); 1470 BarrierSet* bs = Universe::heap()->barrier_set();
1468 set_control(ctl); 1471 set_control(ctl);
1469 switch (bs->kind()) { 1472 switch (bs->kind()) {
1470 case BarrierSet::G1SATBCT: 1473 case BarrierSet::G1SATBCT:
1471 case BarrierSet::G1SATBCTLogging: 1474 case BarrierSet::G1SATBCTLogging:
1472 g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt); 1475 g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt);
1473 break; 1476 break;
1474 1477
1475 case BarrierSet::CardTableModRef: 1478 case BarrierSet::CardTableModRef:
1476 case BarrierSet::CardTableExtension: 1479 case BarrierSet::CardTableExtension:
1477 case BarrierSet::ModRef: 1480 case BarrierSet::ModRef:
1530 assert(bt == T_OBJECT, "sanity"); 1533 assert(bt == T_OBJECT, "sanity");
1531 assert(val != NULL, "not dead path"); 1534 assert(val != NULL, "not dead path");
1532 uint adr_idx = C->get_alias_index(adr_type); 1535 uint adr_idx = C->get_alias_index(adr_type);
1533 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); 1536 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
1534 1537
1535 pre_barrier(control(), obj, adr, adr_idx, val, val_type, bt); 1538 pre_barrier(true /* do_load */,
1539 control(), obj, adr, adr_idx, val, val_type,
1540 NULL /* pre_val */,
1541 bt);
1542
1536 Node* store = store_to_memory(control(), adr, val, bt, adr_idx); 1543 Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
1537 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise); 1544 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
1538 return store; 1545 return store;
1539 } 1546 }
1540 1547
3463 // Final sync IdealKit and GraphKit. 3470 // Final sync IdealKit and GraphKit.
3464 sync_kit(ideal); 3471 sync_kit(ideal);
3465 } 3472 }
3466 3473
3467 // G1 pre/post barriers 3474 // G1 pre/post barriers
3468 void GraphKit::g1_write_barrier_pre(Node* obj, 3475 void GraphKit::g1_write_barrier_pre(bool do_load,
3476 Node* obj,
3469 Node* adr, 3477 Node* adr,
3470 uint alias_idx, 3478 uint alias_idx,
3471 Node* val, 3479 Node* val,
3472 const TypeOopPtr* val_type, 3480 const TypeOopPtr* val_type,
3481 Node* pre_val,
3473 BasicType bt) { 3482 BasicType bt) {
3483
3484 // Some sanity checks
3485 // Note: val is unused in this routine.
3486
3487 if (do_load) {
3488 // We need to generate the load of the previous value
3489 assert(obj != NULL, "must have a base");
3490 assert(adr != NULL, "where are loading from?");
3491 assert(pre_val == NULL, "loaded already?");
3492 assert(val_type != NULL, "need a type");
3493 } else {
3494 // In this case both val_type and alias_idx are unused.
3495 assert(pre_val != NULL, "must be loaded already");
3496 assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");
3497 }
3498 assert(bt == T_OBJECT, "or we shouldn't be here");
3499
3474 IdealKit ideal(gvn(), control(), merged_memory(), true); 3500 IdealKit ideal(gvn(), control(), merged_memory(), true);
3475 3501
3476 Node* tls = __ thread(); // ThreadLocalStorage 3502 Node* tls = __ thread(); // ThreadLocalStorage
3477 3503
3478 Node* no_ctrl = NULL; 3504 Node* no_ctrl = NULL;
3490 PtrQueue::byte_offset_of_active()); 3516 PtrQueue::byte_offset_of_active());
3491 const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656 3517 const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656
3492 PtrQueue::byte_offset_of_index()); 3518 PtrQueue::byte_offset_of_index());
3493 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652 3519 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652
3494 PtrQueue::byte_offset_of_buf()); 3520 PtrQueue::byte_offset_of_buf());
3521
3495 // Now the actual pointers into the thread 3522 // Now the actual pointers into the thread
3496
3497 // set_control( ctl);
3498
3499 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset)); 3523 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
3500 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset)); 3524 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
3501 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset)); 3525 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
3502 3526
3503 // Now some of the values 3527 // Now some of the values
3504
3505 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); 3528 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
3506 3529
3507 // if (!marking) 3530 // if (!marking)
3508 __ if_then(marking, BoolTest::ne, zero); { 3531 __ if_then(marking, BoolTest::ne, zero); {
3509 Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); 3532 Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
3510 3533
3511 const Type* t1 = adr->bottom_type(); 3534 if (do_load) {
3512 const Type* t2 = val->bottom_type();
3513
3514 Node* orig = __ load(no_ctrl, adr, val_type, bt, alias_idx);
3515 // if (orig != NULL)
3516 __ if_then(orig, BoolTest::ne, null()); {
3517 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
3518
3519 // load original value 3535 // load original value
3520 // alias_idx correct?? 3536 // alias_idx correct??
3537 pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx);
3538 }
3539
3540 // if (pre_val != NULL)
3541 __ if_then(pre_val, BoolTest::ne, null()); {
3542 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
3521 3543
3522 // is the queue for this thread full? 3544 // is the queue for this thread full?
3523 __ if_then(index, BoolTest::ne, zero, likely); { 3545 __ if_then(index, BoolTest::ne, zero, likely); {
3524 3546
3525 // decrement the index 3547 // decrement the index
3529 // We could refine the type for what it's worth 3551 // We could refine the type for what it's worth
3530 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); 3552 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
3531 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); 3553 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
3532 #endif 3554 #endif
3533 3555
3534 // Now get the buffer location we will log the original value into and store it 3556 // Now get the buffer location we will log the previous value into and store it
3535 Node *log_addr = __ AddP(no_base, buffer, next_indexX); 3557 Node *log_addr = __ AddP(no_base, buffer, next_indexX);
3536 __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw); 3558 __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw);
3537
3538 // update the index 3559 // update the index
3539 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 3560 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
3540 3561
3541 } __ else_(); { 3562 } __ else_(); {
3542 3563
3543 // logging buffer is full, call the runtime 3564 // logging buffer is full, call the runtime
3544 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); 3565 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
3545 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, tls); 3566 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", pre_val, tls);
3546 } __ end_if(); // (!index) 3567 } __ end_if(); // (!index)
3547 } __ end_if(); // (orig != NULL) 3568 } __ end_if(); // (pre_val != NULL)
3548 } __ end_if(); // (!marking) 3569 } __ end_if(); // (!marking)
3549 3570
3550 // Final sync IdealKit and GraphKit. 3571 // Final sync IdealKit and GraphKit.
3551 sync_kit(ideal); 3572 sync_kit(ideal);
3552 } 3573 }