1.1 --- a/src/share/vm/opto/graphKit.cpp Thu Apr 28 14:00:13 2011 -0700 1.2 +++ b/src/share/vm/opto/graphKit.cpp Fri Apr 29 11:15:30 2011 -0700 1.3 @@ -1453,19 +1453,22 @@ 1.4 } 1.5 1.6 1.7 -void GraphKit::pre_barrier(Node* ctl, 1.8 +void GraphKit::pre_barrier(bool do_load, 1.9 + Node* ctl, 1.10 Node* obj, 1.11 Node* adr, 1.12 uint adr_idx, 1.13 Node* val, 1.14 const TypeOopPtr* val_type, 1.15 + Node* pre_val, 1.16 BasicType bt) { 1.17 + 1.18 BarrierSet* bs = Universe::heap()->barrier_set(); 1.19 set_control(ctl); 1.20 switch (bs->kind()) { 1.21 case BarrierSet::G1SATBCT: 1.22 case BarrierSet::G1SATBCTLogging: 1.23 - g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt); 1.24 + g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt); 1.25 break; 1.26 1.27 case BarrierSet::CardTableModRef: 1.28 @@ -1528,7 +1531,11 @@ 1.29 uint adr_idx = C->get_alias_index(adr_type); 1.30 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); 1.31 1.32 - pre_barrier(control(), obj, adr, adr_idx, val, val_type, bt); 1.33 + pre_barrier(true /* do_load */, 1.34 + control(), obj, adr, adr_idx, val, val_type, 1.35 + NULL /* pre_val */, 1.36 + bt); 1.37 + 1.38 Node* store = store_to_memory(control(), adr, val, bt, adr_idx); 1.39 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise); 1.40 return store; 1.41 @@ -3479,12 +3486,31 @@ 1.42 } 1.43 1.44 // G1 pre/post barriers 1.45 -void GraphKit::g1_write_barrier_pre(Node* obj, 1.46 +void GraphKit::g1_write_barrier_pre(bool do_load, 1.47 + Node* obj, 1.48 Node* adr, 1.49 uint alias_idx, 1.50 Node* val, 1.51 const TypeOopPtr* val_type, 1.52 + Node* pre_val, 1.53 BasicType bt) { 1.54 + 1.55 + // Some sanity checks 1.56 + // Note: val is unused in this routine. 1.57 + 1.58 + if (do_load) { 1.59 + // We need to generate the load of the previous value 1.60 + assert(obj != NULL, "must have a base"); 1.61 + assert(adr != NULL, "where are loading from?"); 1.62 + assert(pre_val == NULL, "loaded already?"); 1.63 + assert(val_type != NULL, "need a type"); 1.64 + } else { 1.65 + // In this case both val_type and alias_idx are unused. 1.66 + assert(pre_val != NULL, "must be loaded already"); 1.67 + assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here"); 1.68 + } 1.69 + assert(bt == T_OBJECT, "or we shouldn't be here"); 1.70 + 1.71 IdealKit ideal(this, true); 1.72 1.73 Node* tls = __ thread(); // ThreadLocalStorage 1.74 @@ -3506,32 +3532,28 @@ 1.75 PtrQueue::byte_offset_of_index()); 1.76 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652 1.77 PtrQueue::byte_offset_of_buf()); 1.78 + 1.79 // Now the actual pointers into the thread 1.80 - 1.81 - // set_control( ctl); 1.82 - 1.83 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset)); 1.84 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset)); 1.85 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset)); 1.86 1.87 // Now some of the values 1.88 - 1.89 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); 1.90 1.91 // if (!marking) 1.92 __ if_then(marking, BoolTest::ne, zero); { 1.93 Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); 1.94 1.95 - const Type* t1 = adr->bottom_type(); 1.96 - const Type* t2 = val->bottom_type(); 1.97 - 1.98 - Node* orig = __ load(no_ctrl, adr, val_type, bt, alias_idx); 1.99 - // if (orig != NULL) 1.100 - __ if_then(orig, BoolTest::ne, null()); { 1.101 - Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); 1.102 - 1.103 + if (do_load) { 1.104 // load original value 1.105 // alias_idx correct?? 1.106 + pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx); 1.107 + } 1.108 + 1.109 + // if (pre_val != NULL) 1.110 + __ if_then(pre_val, BoolTest::ne, null()); { 1.111 + Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); 1.112 1.113 // is the queue for this thread full? 1.114 __ if_then(index, BoolTest::ne, zero, likely); { 1.115 @@ -3545,10 +3567,9 @@ 1.116 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); 1.117 #endif 1.118 1.119 - // Now get the buffer location we will log the original value into and store it 1.120 + // Now get the buffer location we will log the previous value into and store it 1.121 Node *log_addr = __ AddP(no_base, buffer, next_indexX); 1.122 - __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw); 1.123 - 1.124 + __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw); 1.125 // update the index 1.126 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 1.127 1.128 @@ -3556,9 +3577,9 @@ 1.129 1.130 // logging buffer is full, call the runtime 1.131 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); 1.132 - __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, tls); 1.133 + __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", pre_val, tls); 1.134 } __ end_if(); // (!index) 1.135 - } __ end_if(); // (orig != NULL) 1.136 + } __ end_if(); // (pre_val != NULL) 1.137 } __ end_if(); // (!marking) 1.138 1.139 // Final sync IdealKit and GraphKit.