src/share/vm/opto/macro.cpp

changeset 3392
1dc233a8c7fe
parent 3391
069ab3f976d3
child 3396
d12a66fa3820
     1.1 --- a/src/share/vm/opto/macro.cpp	Wed Dec 07 11:35:03 2011 +0100
     1.2 +++ b/src/share/vm/opto/macro.cpp	Tue Dec 20 16:56:50 2011 +0100
     1.3 @@ -1088,6 +1088,12 @@
     1.4    Node* klass_node        = alloc->in(AllocateNode::KlassNode);
     1.5    Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
     1.6  
     1.7 +  Node* storestore = alloc->storestore();
     1.8 +  if (storestore != NULL) {
     1.9 +    // Break this link that is no longer useful and confuses register allocation
    1.10 +    storestore->set_req(MemBarNode::Precedent, top());
    1.11 +  }
    1.12 +
    1.13    assert(ctrl != NULL, "must have control");
    1.14    // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
    1.15    // they will not be used if "always_slow" is set
    1.16 @@ -1289,10 +1295,66 @@
    1.17                                     0, new_alloc_bytes, T_LONG);
    1.18      }
    1.19  
    1.20 +    InitializeNode* init = alloc->initialization();
    1.21      fast_oop_rawmem = initialize_object(alloc,
    1.22                                          fast_oop_ctrl, fast_oop_rawmem, fast_oop,
    1.23                                          klass_node, length, size_in_bytes);
    1.24  
    1.25 +    // If initialization is performed by an array copy, any required
    1.26 +    // MemBarStoreStore was already added. If the object does not
    1.27 +    // escape no need for a MemBarStoreStore. Otherwise we need a
    1.28 +    // MemBarStoreStore so that stores that initialize this object
    1.29 +    // can't be reordered with a subsequent store that makes this
    1.30 +    // object accessible by other threads.
    1.31 +    if (init == NULL || (!init->is_complete_with_arraycopy() && !init->does_not_escape())) {
    1.32 +      if (init == NULL || init->req() < InitializeNode::RawStores) {
    1.33 +        // No InitializeNode or no stores captured by zeroing
    1.34 +        // elimination. Simply add the MemBarStoreStore after object
    1.35 +        // initialization.
    1.36 +        MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot, fast_oop_rawmem);
    1.37 +        transform_later(mb);
    1.38 +
    1.39 +        mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
    1.40 +        mb->init_req(TypeFunc::Control, fast_oop_ctrl);
    1.41 +        fast_oop_ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control);
    1.42 +        transform_later(fast_oop_ctrl);
    1.43 +        fast_oop_rawmem = new (C, 1) ProjNode(mb,TypeFunc::Memory);
    1.44 +        transform_later(fast_oop_rawmem);
    1.45 +      } else {
    1.46 +        // Add the MemBarStoreStore after the InitializeNode so that
    1.47 +        // all stores performing the initialization that were moved
    1.48 +        // before the InitializeNode happen before the storestore
    1.49 +        // barrier.
    1.50 +
    1.51 +        Node* init_ctrl = init->proj_out(TypeFunc::Control);
    1.52 +        Node* init_mem = init->proj_out(TypeFunc::Memory);
    1.53 +
    1.54 +        MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
    1.55 +        transform_later(mb);
    1.56 +
    1.57 +        Node* ctrl = new (C, 1) ProjNode(init,TypeFunc::Control);
    1.58 +        transform_later(ctrl);
    1.59 +        Node* mem = new (C, 1) ProjNode(init,TypeFunc::Memory);
    1.60 +        transform_later(mem);
    1.61 +
    1.62 +        // The MemBarStoreStore depends on control and memory coming
    1.63 +        // from the InitializeNode
    1.64 +        mb->init_req(TypeFunc::Memory, mem);
    1.65 +        mb->init_req(TypeFunc::Control, ctrl);
    1.66 +
    1.67 +        ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control);
    1.68 +        transform_later(ctrl);
    1.69 +        mem = new (C, 1) ProjNode(mb,TypeFunc::Memory);
    1.70 +        transform_later(mem);
    1.71 +
    1.72 +        // All nodes that depended on the InitializeNode for control
    1.73 +        // and memory must now depend on the MemBarNode that itself
    1.74 +        // depends on the InitializeNode
    1.75 +        _igvn.replace_node(init_ctrl, ctrl);
    1.76 +        _igvn.replace_node(init_mem, mem);
    1.77 +      }
    1.78 +    }
    1.79 +
    1.80      if (C->env()->dtrace_extended_probes()) {
    1.81        // Slow-path call
    1.82        int size = TypeFunc::Parms + 2;

mercurial