1.1 --- a/src/share/vm/opto/memnode.cpp Fri Feb 22 10:12:00 2013 -0800 1.2 +++ b/src/share/vm/opto/memnode.cpp Mon Feb 25 14:13:04 2013 +0100 1.3 @@ -320,6 +320,9 @@ 1.4 1.5 if (mem != old_mem) { 1.6 set_req(MemNode::Memory, mem); 1.7 + if (can_reshape && old_mem->outcnt() == 0) { 1.8 + igvn->_worklist.push(old_mem); 1.9 + } 1.10 if (phase->type( mem ) == Type::TOP) return NodeSentinel; 1.11 return this; 1.12 } 1.13 @@ -2319,9 +2322,9 @@ 1.14 if (ReduceFieldZeroing && /*can_reshape &&*/ 1.15 mem->is_Proj() && mem->in(0)->is_Initialize()) { 1.16 InitializeNode* init = mem->in(0)->as_Initialize(); 1.17 - intptr_t offset = init->can_capture_store(this, phase); 1.18 + intptr_t offset = init->can_capture_store(this, phase, can_reshape); 1.19 if (offset > 0) { 1.20 - Node* moved = init->capture_store(this, offset, phase); 1.21 + Node* moved = init->capture_store(this, offset, phase, can_reshape); 1.22 // If the InitializeNode captured me, it made a raw copy of me, 1.23 // and I need to disappear. 1.24 if (moved != NULL) { 1.25 @@ -3134,7 +3137,7 @@ 1.26 // an initialization. Returns zero if a check fails. 1.27 // On success, returns the (constant) offset to which the store applies, 1.28 // within the initialized memory. 1.29 -intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { 1.30 +intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape) { 1.31 const int FAIL = 0; 1.32 if (st->req() != MemNode::ValueIn + 1) 1.33 return FAIL; // an inscrutable StoreNode (card mark?) 1.34 @@ -3156,6 +3159,91 @@ 1.35 if (!detect_init_independence(val, true, complexity_count)) 1.36 return FAIL; // stored value must be 'simple enough' 1.37 1.38 + // The Store can be captured only if nothing after the allocation 1.39 + // and before the Store is using the memory location that the store 1.40 + // overwrites. 1.41 + bool failed = false; 1.42 + // If is_complete_with_arraycopy() is true the shape of the graph is 1.43 + // well defined and is safe so no need for extra checks. 1.44 + if (!is_complete_with_arraycopy()) { 1.45 + // We are going to look at each use of the memory state following 1.46 + // the allocation to make sure nothing reads the memory that the 1.47 + // Store writes. 1.48 + const TypePtr* t_adr = phase->type(adr)->isa_ptr(); 1.49 + int alias_idx = phase->C->get_alias_index(t_adr); 1.50 + ResourceMark rm; 1.51 + Unique_Node_List mems; 1.52 + mems.push(mem); 1.53 + Node* unique_merge = NULL; 1.54 + for (uint next = 0; next < mems.size(); ++next) { 1.55 + Node *m = mems.at(next); 1.56 + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) { 1.57 + Node *n = m->fast_out(j); 1.58 + if (n->outcnt() == 0) { 1.59 + continue; 1.60 + } 1.61 + if (n == st) { 1.62 + continue; 1.63 + } else if (n->in(0) != NULL && n->in(0) != ctl) { 1.64 + // If the control of this use is different from the control 1.65 + // of the Store which is right after the InitializeNode then 1.66 + // this node cannot be between the InitializeNode and the 1.67 + // Store. 1.68 + continue; 1.69 + } else if (n->is_MergeMem()) { 1.70 + if (n->as_MergeMem()->memory_at(alias_idx) == m) { 1.71 + // We can hit a MergeMemNode (that will likely go away 1.72 + // later) that is a direct use of the memory state 1.73 + // following the InitializeNode on the same slice as the 1.74 + // store node that we'd like to capture. We need to check 1.75 + // the uses of the MergeMemNode. 1.76 + mems.push(n); 1.77 + } 1.78 + } else if (n->is_Mem()) { 1.79 + Node* other_adr = n->in(MemNode::Address); 1.80 + if (other_adr == adr) { 1.81 + failed = true; 1.82 + break; 1.83 + } else { 1.84 + const TypePtr* other_t_adr = phase->type(other_adr)->isa_ptr(); 1.85 + if (other_t_adr != NULL) { 1.86 + int other_alias_idx = phase->C->get_alias_index(other_t_adr); 1.87 + if (other_alias_idx == alias_idx) { 1.88 + // A load from the same memory slice as the store right 1.89 + // after the InitializeNode. We check the control of the 1.90 + // object/array that is loaded from. If it's the same as 1.91 + // the store control then we cannot capture the store. 1.92 + assert(!n->is_Store(), "2 stores to same slice on same control?"); 1.93 + Node* base = other_adr; 1.94 + assert(base->is_AddP(), err_msg_res("should be addp but is %s", base->Name())); 1.95 + base = base->in(AddPNode::Base); 1.96 + if (base != NULL) { 1.97 + base = base->uncast(); 1.98 + if (base->is_Proj() && base->in(0) == alloc) { 1.99 + failed = true; 1.100 + break; 1.101 + } 1.102 + } 1.103 + } 1.104 + } 1.105 + } 1.106 + } else { 1.107 + failed = true; 1.108 + break; 1.109 + } 1.110 + } 1.111 + } 1.112 + } 1.113 + if (failed) { 1.114 + if (!can_reshape) { 1.115 + // We decided we couldn't capture the store during parsing. We 1.116 + // should try again during the next IGVN once the graph is 1.117 + // cleaner. 1.118 + phase->C->record_for_igvn(st); 1.119 + } 1.120 + return FAIL; 1.121 + } 1.122 + 1.123 return offset; // success 1.124 } 1.125 1.126 @@ -3266,11 +3354,11 @@ 1.127 // rawstore1 rawstore2) 1.128 // 1.129 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, 1.130 - PhaseTransform* phase) { 1.131 + PhaseTransform* phase, bool can_reshape) { 1.132 assert(stores_are_sane(phase), ""); 1.133 1.134 if (start < 0) return NULL; 1.135 - assert(can_capture_store(st, phase) == start, "sanity"); 1.136 + assert(can_capture_store(st, phase, can_reshape) == start, "sanity"); 1.137 1.138 Compile* C = phase->C; 1.139 int size_in_bytes = st->memory_size();