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;