src/share/vm/opto/graphKit.cpp

changeset 1286
fc4be448891f
parent 1262
bf3489cc0aa0
child 1335
9987d9d5eb0e
     1.1 --- a/src/share/vm/opto/graphKit.cpp	Wed Jul 15 13:37:35 2009 -0700
     1.2 +++ b/src/share/vm/opto/graphKit.cpp	Thu Jul 16 14:10:42 2009 -0700
     1.3 @@ -1373,11 +1373,12 @@
     1.4    return st;
     1.5  }
     1.6  
     1.7 +
     1.8  void GraphKit::pre_barrier(Node* ctl,
     1.9                             Node* obj,
    1.10                             Node* adr,
    1.11 -                           uint adr_idx,
    1.12 -                           Node *val,
    1.13 +                           uint  adr_idx,
    1.14 +                           Node* val,
    1.15                             const TypeOopPtr* val_type,
    1.16                             BasicType bt) {
    1.17    BarrierSet* bs = Universe::heap()->barrier_set();
    1.18 @@ -1385,7 +1386,7 @@
    1.19    switch (bs->kind()) {
    1.20      case BarrierSet::G1SATBCT:
    1.21      case BarrierSet::G1SATBCTLogging:
    1.22 -        g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt);
    1.23 +      g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt);
    1.24        break;
    1.25  
    1.26      case BarrierSet::CardTableModRef:
    1.27 @@ -1404,8 +1405,8 @@
    1.28                              Node* store,
    1.29                              Node* obj,
    1.30                              Node* adr,
    1.31 -                            uint adr_idx,
    1.32 -                            Node *val,
    1.33 +                            uint  adr_idx,
    1.34 +                            Node* val,
    1.35                              BasicType bt,
    1.36                              bool use_precise) {
    1.37    BarrierSet* bs = Universe::heap()->barrier_set();
    1.38 @@ -1413,7 +1414,7 @@
    1.39    switch (bs->kind()) {
    1.40      case BarrierSet::G1SATBCT:
    1.41      case BarrierSet::G1SATBCTLogging:
    1.42 -        g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
    1.43 +      g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
    1.44        break;
    1.45  
    1.46      case BarrierSet::CardTableModRef:
    1.47 @@ -1431,42 +1432,36 @@
    1.48    }
    1.49  }
    1.50  
    1.51 -Node* GraphKit::store_oop_to_object(Node* ctl,
    1.52 -                                    Node* obj,
    1.53 -                                    Node* adr,
    1.54 -                                    const TypePtr* adr_type,
    1.55 -                                    Node *val,
    1.56 -                                    const TypeOopPtr* val_type,
    1.57 -                                    BasicType bt) {
    1.58 +Node* GraphKit::store_oop(Node* ctl,
    1.59 +                          Node* obj,
    1.60 +                          Node* adr,
    1.61 +                          const TypePtr* adr_type,
    1.62 +                          Node* val,
    1.63 +                          const TypeOopPtr* val_type,
    1.64 +                          BasicType bt,
    1.65 +                          bool use_precise) {
    1.66 +
    1.67 +  set_control(ctl);
    1.68 +  if (stopped()) return top(); // Dead path ?
    1.69 +
    1.70 +  assert(bt == T_OBJECT, "sanity");
    1.71 +  assert(val != NULL, "not dead path");
    1.72    uint adr_idx = C->get_alias_index(adr_type);
    1.73 -  Node* store;
    1.74 -  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
    1.75 -  store = store_to_memory(control(), adr, val, bt, adr_idx);
    1.76 -  post_barrier(control(), store, obj, adr, adr_idx, val, bt, false);
    1.77 +  assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
    1.78 +
    1.79 +  pre_barrier(control(), obj, adr, adr_idx, val, val_type, bt);
    1.80 +  Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
    1.81 +  post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
    1.82    return store;
    1.83  }
    1.84  
    1.85 -Node* GraphKit::store_oop_to_array(Node* ctl,
    1.86 -                                   Node* obj,
    1.87 -                                   Node* adr,
    1.88 -                                   const TypePtr* adr_type,
    1.89 -                                   Node *val,
    1.90 -                                   const TypeOopPtr* val_type,
    1.91 -                                   BasicType bt) {
    1.92 -  uint adr_idx = C->get_alias_index(adr_type);
    1.93 -  Node* store;
    1.94 -  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
    1.95 -  store = store_to_memory(control(), adr, val, bt, adr_idx);
    1.96 -  post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
    1.97 -  return store;
    1.98 -}
    1.99 -
   1.100 +// Could be an array or object we don't know at compile time (unsafe ref.)
   1.101  Node* GraphKit::store_oop_to_unknown(Node* ctl,
   1.102 -                                     Node* obj,
   1.103 -                                     Node* adr,
   1.104 -                                     const TypePtr* adr_type,
   1.105 -                                     Node *val,
   1.106 -                                     BasicType bt) {
   1.107 +                             Node* obj,   // containing obj
   1.108 +                             Node* adr,  // actual adress to store val at
   1.109 +                             const TypePtr* adr_type,
   1.110 +                             Node* val,
   1.111 +                             BasicType bt) {
   1.112    Compile::AliasType* at = C->alias_type(adr_type);
   1.113    const TypeOopPtr* val_type = NULL;
   1.114    if (adr_type->isa_instptr()) {
   1.115 @@ -1485,12 +1480,7 @@
   1.116    if (val_type == NULL) {
   1.117      val_type = TypeInstPtr::BOTTOM;
   1.118    }
   1.119 -
   1.120 -  uint adr_idx = at->index();
   1.121 -  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
   1.122 -  Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
   1.123 -  post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
   1.124 -  return store;
   1.125 +  return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true);
   1.126  }
   1.127  
   1.128  
   1.129 @@ -1804,93 +1794,6 @@
   1.130  }
   1.131  
   1.132  
   1.133 -//------------------------------store_barrier----------------------------------
   1.134 -// Insert a write-barrier store.  This is to let generational GC work; we have
   1.135 -// to flag all oop-stores before the next GC point.
   1.136 -void GraphKit::write_barrier_post(Node* oop_store, Node* obj, Node* adr,
   1.137 -                                  Node* val, bool use_precise) {
   1.138 -  // No store check needed if we're storing a NULL or an old object
   1.139 -  // (latter case is probably a string constant). The concurrent
   1.140 -  // mark sweep garbage collector, however, needs to have all nonNull
   1.141 -  // oop updates flagged via card-marks.
   1.142 -  if (val != NULL && val->is_Con()) {
   1.143 -    // must be either an oop or NULL
   1.144 -    const Type* t = val->bottom_type();
   1.145 -    if (t == TypePtr::NULL_PTR || t == Type::TOP)
   1.146 -      // stores of null never (?) need barriers
   1.147 -      return;
   1.148 -    ciObject* con = t->is_oopptr()->const_oop();
   1.149 -    if (con != NULL
   1.150 -        && con->is_perm()
   1.151 -        && Universe::heap()->can_elide_permanent_oop_store_barriers())
   1.152 -      // no store barrier needed, because no old-to-new ref created
   1.153 -      return;
   1.154 -  }
   1.155 -
   1.156 -  if (use_ReduceInitialCardMarks()
   1.157 -      && obj == just_allocated_object(control())) {
   1.158 -    // We can skip marks on a freshly-allocated object.
   1.159 -    // Keep this code in sync with do_eager_card_mark in runtime.cpp.
   1.160 -    // That routine eagerly marks the occasional object which is produced
   1.161 -    // by the slow path, so that we don't have to do it here.
   1.162 -    return;
   1.163 -  }
   1.164 -
   1.165 -  if (!use_precise) {
   1.166 -    // All card marks for a (non-array) instance are in one place:
   1.167 -    adr = obj;
   1.168 -  }
   1.169 -  // (Else it's an array (or unknown), and we want more precise card marks.)
   1.170 -  assert(adr != NULL, "");
   1.171 -
   1.172 -  // Get the alias_index for raw card-mark memory
   1.173 -  int adr_type = Compile::AliasIdxRaw;
   1.174 -  // Convert the pointer to an int prior to doing math on it
   1.175 -  Node* cast = _gvn.transform(new (C, 2) CastP2XNode(control(), adr));
   1.176 -  // Divide by card size
   1.177 -  assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
   1.178 -         "Only one we handle so far.");
   1.179 -  CardTableModRefBS* ct =
   1.180 -    (CardTableModRefBS*)(Universe::heap()->barrier_set());
   1.181 -  Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
   1.182 -  // We store into a byte array, so do not bother to left-shift by zero
   1.183 -  Node *c = byte_map_base_node();
   1.184 -  // Combine
   1.185 -  Node *sb_ctl = control();
   1.186 -  Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b ));
   1.187 -  Node *sb_val = _gvn.intcon(0);
   1.188 -  // Smash zero into card
   1.189 -  if( !UseConcMarkSweepGC ) {
   1.190 -    BasicType bt = T_BYTE;
   1.191 -    store_to_memory(sb_ctl, sb_adr, sb_val, bt, adr_type);
   1.192 -  } else {
   1.193 -    // Specialized path for CM store barrier
   1.194 -    cms_card_mark( sb_ctl, sb_adr, sb_val, oop_store);
   1.195 -  }
   1.196 -}
   1.197 -
   1.198 -// Specialized path for CMS store barrier
   1.199 -void GraphKit::cms_card_mark(Node* ctl, Node* adr, Node* val, Node *oop_store) {
   1.200 -  BasicType bt = T_BYTE;
   1.201 -  int adr_idx = Compile::AliasIdxRaw;
   1.202 -  Node* mem = memory(adr_idx);
   1.203 -
   1.204 -  // The type input is NULL in PRODUCT builds
   1.205 -  const TypePtr* type = NULL;
   1.206 -  debug_only(type = C->get_adr_type(adr_idx));
   1.207 -
   1.208 -  // Add required edge to oop_store, optimizer does not support precedence edges.
   1.209 -  // Convert required edge to precedence edge before allocation.
   1.210 -  Node *store = _gvn.transform( new (C, 5) StoreCMNode(ctl, mem, adr, type, val, oop_store) );
   1.211 -  set_memory(store, adr_idx);
   1.212 -
   1.213 -  // For CMS, back-to-back card-marks can only remove the first one
   1.214 -  // and this requires DU info.  Push on worklist for optimizer.
   1.215 -  if (mem->req() > MemNode::Address && adr == mem->in(MemNode::Address))
   1.216 -    record_for_igvn(store);
   1.217 -}
   1.218 -
   1.219 -
   1.220  void GraphKit::round_double_arguments(ciMethod* dest_method) {
   1.221    // (Note:  TypeFunc::make has a cache that makes this fast.)
   1.222    const TypeFunc* tf    = TypeFunc::make(dest_method);
   1.223 @@ -3215,6 +3118,79 @@
   1.224    return NULL;
   1.225  }
   1.226  
   1.227 +//----------------------------- store barriers ----------------------------
   1.228 +#define __ ideal.
   1.229 +
   1.230 +void GraphKit::sync_kit(IdealKit& ideal) {
   1.231 +  // Final sync IdealKit and graphKit.
   1.232 +  __ drain_delay_transform();
   1.233 +  set_all_memory(__ merged_memory());
   1.234 +  set_control(__ ctrl());
   1.235 +}
   1.236 +
   1.237 +// vanilla/CMS post barrier
   1.238 +// Insert a write-barrier store.  This is to let generational GC work; we have
   1.239 +// to flag all oop-stores before the next GC point.
   1.240 +void GraphKit::write_barrier_post(Node* oop_store,
   1.241 +                                  Node* obj,
   1.242 +                                  Node* adr,
   1.243 +                                  Node* val,
   1.244 +                                  bool use_precise) {
   1.245 +  // No store check needed if we're storing a NULL or an old object
   1.246 +  // (latter case is probably a string constant). The concurrent
   1.247 +  // mark sweep garbage collector, however, needs to have all nonNull
   1.248 +  // oop updates flagged via card-marks.
   1.249 +  if (val != NULL && val->is_Con()) {
   1.250 +    // must be either an oop or NULL
   1.251 +    const Type* t = val->bottom_type();
   1.252 +    if (t == TypePtr::NULL_PTR || t == Type::TOP)
   1.253 +      // stores of null never (?) need barriers
   1.254 +      return;
   1.255 +    ciObject* con = t->is_oopptr()->const_oop();
   1.256 +    if (con != NULL
   1.257 +        && con->is_perm()
   1.258 +        && Universe::heap()->can_elide_permanent_oop_store_barriers())
   1.259 +      // no store barrier needed, because no old-to-new ref created
   1.260 +      return;
   1.261 +  }
   1.262 +
   1.263 +  if (!use_precise) {
   1.264 +    // All card marks for a (non-array) instance are in one place:
   1.265 +    adr = obj;
   1.266 +  }
   1.267 +  // (Else it's an array (or unknown), and we want more precise card marks.)
   1.268 +  assert(adr != NULL, "");
   1.269 +
   1.270 +  IdealKit ideal(gvn(), control(), merged_memory(), true);
   1.271 +
   1.272 +  // Convert the pointer to an int prior to doing math on it
   1.273 +  Node* cast = __ CastPX(__ ctrl(), adr);
   1.274 +
   1.275 +  // Divide by card size
   1.276 +  assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
   1.277 +         "Only one we handle so far.");
   1.278 +  Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
   1.279 +
   1.280 +  // Combine card table base and card offset
   1.281 +  Node* card_adr = __ AddP(__ top(), byte_map_base_node(), card_offset );
   1.282 +
   1.283 +  // Get the alias_index for raw card-mark memory
   1.284 +  int adr_type = Compile::AliasIdxRaw;
   1.285 +  // Smash zero into card
   1.286 +  Node*   zero = __ ConI(0);
   1.287 +  BasicType bt = T_BYTE;
   1.288 +  if( !UseConcMarkSweepGC ) {
   1.289 +    __ store(__ ctrl(), card_adr, zero, bt, adr_type);
   1.290 +  } else {
   1.291 +    // Specialized path for CM store barrier
   1.292 +    __ storeCM(__ ctrl(), card_adr, zero, oop_store, bt, adr_type);
   1.293 +  }
   1.294 +
   1.295 +  // Final sync IdealKit and GraphKit.
   1.296 +  sync_kit(ideal);
   1.297 +}
   1.298 +
   1.299 +// G1 pre/post barriers
   1.300  void GraphKit::g1_write_barrier_pre(Node* obj,
   1.301                                      Node* adr,
   1.302                                      uint alias_idx,
   1.303 @@ -3222,10 +3198,8 @@
   1.304                                      const TypeOopPtr* val_type,
   1.305                                      BasicType bt) {
   1.306    IdealKit ideal(gvn(), control(), merged_memory(), true);
   1.307 -#define __ ideal.
   1.308 -  __ declares_done();
   1.309 -
   1.310 -  Node* thread = __ thread();
   1.311 +
   1.312 +  Node* tls = __ thread(); // ThreadLocalStorage
   1.313  
   1.314    Node* no_ctrl = NULL;
   1.315    Node* no_base = __ top();
   1.316 @@ -3248,9 +3222,9 @@
   1.317  
   1.318    // set_control( ctl);
   1.319  
   1.320 -  Node* marking_adr = __ AddP(no_base, thread, __ ConX(marking_offset));
   1.321 -  Node* buffer_adr  = __ AddP(no_base, thread, __ ConX(buffer_offset));
   1.322 -  Node* index_adr   = __ AddP(no_base, thread, __ ConX(index_offset));
   1.323 +  Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
   1.324 +  Node* buffer_adr  = __ AddP(no_base, tls, __ ConX(buffer_offset));
   1.325 +  Node* index_adr   = __ AddP(no_base, tls, __ ConX(index_offset));
   1.326  
   1.327    // Now some of the values
   1.328  
   1.329 @@ -3278,55 +3252,52 @@
   1.330          Node* next_index = __ SubI(index,  __ ConI(sizeof(intptr_t)));
   1.331          Node* next_indexX = next_index;
   1.332  #ifdef _LP64
   1.333 -          // We could refine the type for what it's worth
   1.334 -          // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
   1.335 -          next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
   1.336 -#endif // _LP64
   1.337 +        // We could refine the type for what it's worth
   1.338 +        // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
   1.339 +        next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
   1.340 +#endif
   1.341  
   1.342          // Now get the buffer location we will log the original value into and store it
   1.343 -
   1.344          Node *log_addr = __ AddP(no_base, buffer, next_indexX);
   1.345 -        // __ store(__ ctrl(), log_addr, orig, T_OBJECT, C->get_alias_index(TypeOopPtr::BOTTOM));
   1.346          __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw);
   1.347  
   1.348 -
   1.349          // update the index
   1.350 -        // __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
   1.351 -        // This is a hack to force this store to occur before the oop store that is coming up
   1.352 -        __ store(__ ctrl(), index_adr, next_index, T_INT, C->get_alias_index(TypeOopPtr::BOTTOM));
   1.353 +        __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
   1.354  
   1.355        } __ else_(); {
   1.356  
   1.357          // logging buffer is full, call the runtime
   1.358          const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
   1.359 -        // __ make_leaf_call(tf, OptoRuntime::g1_wb_pre_Java(), "g1_wb_pre", orig, thread);
   1.360 -        __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, thread);
   1.361 -      } __ end_if();
   1.362 -    } __ end_if();
   1.363 -  } __ end_if();
   1.364 -
   1.365 -  __ drain_delay_transform();
   1.366 -  set_control( __ ctrl());
   1.367 -  set_all_memory( __ merged_memory());
   1.368 -
   1.369 -#undef __
   1.370 +        __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, tls);
   1.371 +      } __ end_if();  // (!index)
   1.372 +    } __ end_if();  // (orig != NULL)
   1.373 +  } __ end_if();  // (!marking)
   1.374 +
   1.375 +  // Final sync IdealKit and GraphKit.
   1.376 +  sync_kit(ideal);
   1.377  }
   1.378  
   1.379  //
   1.380  // Update the card table and add card address to the queue
   1.381  //
   1.382 -void GraphKit::g1_mark_card(IdealKit* ideal, Node* card_adr, Node* store,  Node* index, Node* index_adr, Node* buffer, const TypeFunc* tf) {
   1.383 -#define __ ideal->
   1.384 +void GraphKit::g1_mark_card(IdealKit& ideal,
   1.385 +                            Node* card_adr,
   1.386 +                            Node* oop_store,
   1.387 +                            Node* index,
   1.388 +                            Node* index_adr,
   1.389 +                            Node* buffer,
   1.390 +                            const TypeFunc* tf) {
   1.391 +
   1.392    Node* zero = __ ConI(0);
   1.393    Node* no_base = __ top();
   1.394    BasicType card_bt = T_BYTE;
   1.395    // Smash zero into card. MUST BE ORDERED WRT TO STORE
   1.396 -  __ storeCM(__ ctrl(), card_adr, zero, store, card_bt, Compile::AliasIdxRaw);
   1.397 +  __ storeCM(__ ctrl(), card_adr, zero, oop_store, card_bt, Compile::AliasIdxRaw);
   1.398  
   1.399    //  Now do the queue work
   1.400    __ if_then(index, BoolTest::ne, zero); {
   1.401  
   1.402 -    Node* next_index = __ SubI(index,  __ ConI(sizeof(intptr_t)));
   1.403 +    Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t)));
   1.404      Node* next_indexX = next_index;
   1.405  #ifdef _LP64
   1.406      // We could refine the type for what it's worth
   1.407 @@ -3341,10 +3312,10 @@
   1.408    } __ else_(); {
   1.409      __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
   1.410    } __ end_if();
   1.411 -#undef __
   1.412 +
   1.413  }
   1.414  
   1.415 -void GraphKit::g1_write_barrier_post(Node* store,
   1.416 +void GraphKit::g1_write_barrier_post(Node* oop_store,
   1.417                                       Node* obj,
   1.418                                       Node* adr,
   1.419                                       uint alias_idx,
   1.420 @@ -3369,10 +3340,8 @@
   1.421    assert(adr != NULL, "");
   1.422  
   1.423    IdealKit ideal(gvn(), control(), merged_memory(), true);
   1.424 -#define __ ideal.
   1.425 -  __ declares_done();
   1.426 -
   1.427 -  Node* thread = __ thread();
   1.428 +
   1.429 +  Node* tls = __ thread(); // ThreadLocalStorage
   1.430  
   1.431    Node* no_ctrl = NULL;
   1.432    Node* no_base = __ top();
   1.433 @@ -3394,8 +3363,8 @@
   1.434  
   1.435    // Pointers into the thread
   1.436  
   1.437 -  Node* buffer_adr = __ AddP(no_base, thread, __ ConX(buffer_offset));
   1.438 -  Node* index_adr =  __ AddP(no_base, thread, __ ConX(index_offset));
   1.439 +  Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
   1.440 +  Node* index_adr =  __ AddP(no_base, tls, __ ConX(index_offset));
   1.441  
   1.442    // Now some values
   1.443  
   1.444 @@ -3404,18 +3373,14 @@
   1.445  
   1.446  
   1.447    // Convert the store obj pointer to an int prior to doing math on it
   1.448 -  // Use addr not obj gets accurate card marks
   1.449 -
   1.450 -  // Node* cast = __ CastPX(no_ctrl, adr /* obj */);
   1.451 -
   1.452    // Must use ctrl to prevent "integerized oop" existing across safepoint
   1.453 -  Node* cast =  __ CastPX(__ ctrl(), ( use_precise ? adr : obj ));
   1.454 +  Node* cast =  __ CastPX(__ ctrl(), adr);
   1.455  
   1.456    // Divide pointer by card size
   1.457    Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
   1.458  
   1.459    // Combine card table base and card offset
   1.460 -  Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
   1.461 +  Node* card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
   1.462  
   1.463    // If we know the value being stored does it cross regions?
   1.464  
   1.465 @@ -3439,18 +3404,17 @@
   1.466          Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
   1.467  
   1.468          __ if_then(card_val, BoolTest::ne, zero); {
   1.469 -          g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf);
   1.470 +          g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
   1.471          } __ end_if();
   1.472        } __ end_if();
   1.473      } __ end_if();
   1.474    } else {
   1.475 -    g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf);
   1.476 +    // Object.clone() instrinsic uses this path.
   1.477 +    g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
   1.478    }
   1.479  
   1.480 -
   1.481 -  __ drain_delay_transform();
   1.482 -  set_control( __ ctrl());
   1.483 -  set_all_memory( __ merged_memory());
   1.484 +  // Final sync IdealKit and GraphKit.
   1.485 +  sync_kit(ideal);
   1.486 +}
   1.487  #undef __
   1.488  
   1.489 -}

mercurial