Mercurial > hg > graal-compiler
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 } |