Mercurial > hg > graal-compiler
annotate src/share/vm/opto/memnode.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | a92cdbac8b9e |
children | 670a74b863fc |
rev | line source |
---|---|
0 | 1 /* |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1100
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1100
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1100
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "compiler/compileLog.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "oops/objArrayKlass.hpp" | |
30 #include "opto/addnode.hpp" | |
31 #include "opto/cfgnode.hpp" | |
32 #include "opto/compile.hpp" | |
33 #include "opto/connode.hpp" | |
34 #include "opto/loopnode.hpp" | |
35 #include "opto/machnode.hpp" | |
36 #include "opto/matcher.hpp" | |
37 #include "opto/memnode.hpp" | |
38 #include "opto/mulnode.hpp" | |
39 #include "opto/phaseX.hpp" | |
40 #include "opto/regmask.hpp" | |
41 | |
0 | 42 // Portions of code courtesy of Clifford Click |
43 | |
44 // Optimization - Graph Style | |
45 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
46 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
47 |
0 | 48 //============================================================================= |
49 uint MemNode::size_of() const { return sizeof(*this); } | |
50 | |
51 const TypePtr *MemNode::adr_type() const { | |
52 Node* adr = in(Address); | |
53 const TypePtr* cross_check = NULL; | |
54 DEBUG_ONLY(cross_check = _adr_type); | |
55 return calculate_adr_type(adr->bottom_type(), cross_check); | |
56 } | |
57 | |
58 #ifndef PRODUCT | |
59 void MemNode::dump_spec(outputStream *st) const { | |
60 if (in(Address) == NULL) return; // node is dead | |
61 #ifndef ASSERT | |
62 // fake the missing field | |
63 const TypePtr* _adr_type = NULL; | |
64 if (in(Address) != NULL) | |
65 _adr_type = in(Address)->bottom_type()->isa_ptr(); | |
66 #endif | |
67 dump_adr_type(this, _adr_type, st); | |
68 | |
69 Compile* C = Compile::current(); | |
70 if( C->alias_type(_adr_type)->is_volatile() ) | |
71 st->print(" Volatile!"); | |
72 } | |
73 | |
74 void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st) { | |
75 st->print(" @"); | |
76 if (adr_type == NULL) { | |
77 st->print("NULL"); | |
78 } else { | |
79 adr_type->dump_on(st); | |
80 Compile* C = Compile::current(); | |
81 Compile::AliasType* atp = NULL; | |
82 if (C->have_alias_type(adr_type)) atp = C->alias_type(adr_type); | |
83 if (atp == NULL) | |
84 st->print(", idx=?\?;"); | |
85 else if (atp->index() == Compile::AliasIdxBot) | |
86 st->print(", idx=Bot;"); | |
87 else if (atp->index() == Compile::AliasIdxTop) | |
88 st->print(", idx=Top;"); | |
89 else if (atp->index() == Compile::AliasIdxRaw) | |
90 st->print(", idx=Raw;"); | |
91 else { | |
92 ciField* field = atp->field(); | |
93 if (field) { | |
94 st->print(", name="); | |
95 field->print_name_on(st); | |
96 } | |
97 st->print(", idx=%d;", atp->index()); | |
98 } | |
99 } | |
100 } | |
101 | |
102 extern void print_alias_types(); | |
103 | |
104 #endif | |
105 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
106 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
107 const TypeOopPtr *tinst = t_adr->isa_oopptr(); |
223 | 108 if (tinst == NULL || !tinst->is_known_instance_field()) |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
109 return mchain; // don't try to optimize non-instance types |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
110 uint instance_id = tinst->instance_id(); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
111 Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
112 Node *prev = NULL; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
113 Node *result = mchain; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
114 while (prev != result) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
115 prev = result; |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
116 if (result == start_mem) |
605 | 117 break; // hit one of our sentinels |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
118 // skip over a call which does not affect this memory slice |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
119 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
120 Node *proj_in = result->in(0); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
121 if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { |
605 | 122 break; // hit one of our sentinels |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
123 } else if (proj_in->is_Call()) { |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
124 CallNode *call = proj_in->as_Call(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
125 if (!call->may_modify(t_adr, phase)) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
126 result = call->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
127 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
128 } else if (proj_in->is_Initialize()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
129 AllocateNode* alloc = proj_in->as_Initialize()->allocation(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
130 // Stop if this is the initialization for the object instance which |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
131 // which contains this memory slice, otherwise skip over it. |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
132 if (alloc != NULL && alloc->_idx != instance_id) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
133 result = proj_in->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
134 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
135 } else if (proj_in->is_MemBar()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
136 result = proj_in->in(TypeFunc::Memory); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
137 } else { |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
138 assert(false, "unexpected projection"); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
139 } |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
140 } else if (result->is_ClearArray()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
141 if (!ClearArrayNode::step_through(&result, instance_id, phase)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
142 // Can not bypass initialization of the instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
143 // we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
144 break; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
145 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
146 // Otherwise skip it (the call updated 'result' value). |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
147 } else if (result->is_MergeMem()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
148 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
149 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
150 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
151 return result; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
152 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
153 |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
154 Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
155 const TypeOopPtr *t_oop = t_adr->isa_oopptr(); |
223 | 156 bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field(); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
157 PhaseIterGVN *igvn = phase->is_IterGVN(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
158 Node *result = mchain; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
159 result = optimize_simple_memory_chain(result, t_adr, phase); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
160 if (is_instance && igvn != NULL && result->is_Phi()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
161 PhiNode *mphi = result->as_Phi(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
162 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
163 const TypePtr *t = mphi->adr_type(); |
163 | 164 if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || |
223 | 165 t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && |
247 | 166 t->is_oopptr()->cast_to_exactness(true) |
167 ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) | |
168 ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
169 // clone the Phi with our address type |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
170 result = mphi->split_out_instance(t_adr, igvn); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
171 } else { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
172 assert(phase->C->get_alias_index(t) == phase->C->get_alias_index(t_adr), "correct memory chain"); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
173 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
174 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
175 return result; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
176 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
177 |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
178 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
179 uint alias_idx = phase->C->get_alias_index(tp); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
180 Node *mem = mmem; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
181 #ifdef ASSERT |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
182 { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
183 // Check that current type is consistent with the alias index used during graph construction |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
184 assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
185 bool consistent = adr_check == NULL || adr_check->empty() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
186 phase->C->must_alias(adr_check, alias_idx ); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
187 // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
188 if( !consistent && adr_check != NULL && !adr_check->empty() && |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
189 tp->isa_aryptr() && tp->offset() == Type::OffsetBot && |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
190 adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
191 ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
192 adr_check->offset() == oopDesc::klass_offset_in_bytes() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
193 adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
194 // don't assert if it is dead code. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
195 consistent = true; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
196 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
197 if( !consistent ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
198 st->print("alias_idx==%d, adr_check==", alias_idx); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
199 if( adr_check == NULL ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
200 st->print("NULL"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
201 } else { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
202 adr_check->dump(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
203 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
204 st->cr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
205 print_alias_types(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
206 assert(consistent, "adr_check must match alias idx"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
207 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
208 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
209 #endif |
1815 | 210 // TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
211 // means an array I have not precisely typed yet. Do not do any |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
212 // alias stuff with it any time soon. |
1815 | 213 const TypeOopPtr *toop = tp->isa_oopptr(); |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
214 if( tp->base() != Type::AnyPtr && |
1815 | 215 !(toop && |
216 toop->klass() != NULL && | |
217 toop->klass()->is_java_lang_Object() && | |
218 toop->offset() == Type::OffsetBot) ) { | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
219 // compress paths and change unreachable cycles to TOP |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
220 // If not, we can update the input infinitely along a MergeMem cycle |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
221 // Equivalent code in PhiNode::Ideal |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
222 Node* m = phase->transform(mmem); |
605 | 223 // If transformed to a MergeMem, get the desired slice |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
224 // Otherwise the returned node represents memory for every slice |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
225 mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
226 // Update input if it is progress over what we have now |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
227 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
228 return mem; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
229 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
230 |
0 | 231 //--------------------------Ideal_common--------------------------------------- |
232 // Look for degenerate control and memory inputs. Bypass MergeMem inputs. | |
233 // Unhook non-raw memories from complete (macro-expanded) initializations. | |
234 Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { | |
235 // If our control input is a dead region, kill all below the region | |
236 Node *ctl = in(MemNode::Control); | |
237 if (ctl && remove_dead_region(phase, can_reshape)) | |
238 return this; | |
305 | 239 ctl = in(MemNode::Control); |
240 // Don't bother trying to transform a dead node | |
241 if( ctl && ctl->is_top() ) return NodeSentinel; | |
0 | 242 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
243 PhaseIterGVN *igvn = phase->is_IterGVN(); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
244 // Wait if control on the worklist. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
245 if (ctl && can_reshape && igvn != NULL) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
246 Node* bol = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
247 Node* cmp = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
248 if (ctl->in(0)->is_If()) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
249 assert(ctl->is_IfTrue() || ctl->is_IfFalse(), "sanity"); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
250 bol = ctl->in(0)->in(1); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
251 if (bol->is_Bool()) |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
252 cmp = ctl->in(0)->in(1)->in(1); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
253 } |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
254 if (igvn->_worklist.member(ctl) || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
255 (bol != NULL && igvn->_worklist.member(bol)) || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
256 (cmp != NULL && igvn->_worklist.member(cmp)) ) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
257 // This control path may be dead. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
258 // Delay this memory node transformation until the control is processed. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
259 phase->is_IterGVN()->_worklist.push(this); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
260 return NodeSentinel; // caller will return NULL |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
261 } |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
262 } |
0 | 263 // Ignore if memory is dead, or self-loop |
264 Node *mem = in(MemNode::Memory); | |
265 if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL | |
266 assert( mem != this, "dead loop in MemNode::Ideal" ); | |
267 | |
268 Node *address = in(MemNode::Address); | |
269 const Type *t_adr = phase->type( address ); | |
270 if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL | |
271 | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
272 if( can_reshape && igvn != NULL && |
1826
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1815
diff
changeset
|
273 (igvn->_worklist.member(address) || |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1815
diff
changeset
|
274 igvn->_worklist.size() > 0 && (phase->type(address) != adr_type())) ) { |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
275 // The address's base and type may change when the address is processed. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
276 // Delay this mem node transformation until the address is processed. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
277 phase->is_IterGVN()->_worklist.push(this); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
278 return NodeSentinel; // caller will return NULL |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
279 } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
280 |
1062
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
281 // Do NOT remove or optimize the next lines: ensure a new alias index |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
282 // is allocated for an oop pointer type before Escape Analysis. |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
283 // Note: C++ will not remove it since the call has side effect. |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
284 if ( t_adr->isa_oopptr() ) { |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
285 int alias_idx = phase->C->get_alias_index(t_adr->is_ptr()); |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
286 } |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
287 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
288 #ifdef ASSERT |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
289 Node* base = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
290 if (address->is_AddP()) |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
291 base = address->in(AddPNode::Base); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
292 assert(base == NULL || t_adr->isa_rawptr() || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
293 !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?"); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
294 #endif |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
295 |
0 | 296 // Avoid independent memory operations |
297 Node* old_mem = mem; | |
298 | |
36 | 299 // The code which unhooks non-raw memories from complete (macro-expanded) |
300 // initializations was removed. After macro-expansion all stores catched | |
301 // by Initialize node became raw stores and there is no information | |
302 // which memory slices they modify. So it is unsafe to move any memory | |
303 // operation above these stores. Also in most cases hooked non-raw memories | |
304 // were already unhooked by using information from detect_ptr_independence() | |
305 // and find_previous_store(). | |
0 | 306 |
307 if (mem->is_MergeMem()) { | |
308 MergeMemNode* mmem = mem->as_MergeMem(); | |
309 const TypePtr *tp = t_adr->is_ptr(); | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
310 |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
311 mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty); |
0 | 312 } |
313 | |
314 if (mem != old_mem) { | |
315 set_req(MemNode::Memory, mem); | |
305 | 316 if (phase->type( mem ) == Type::TOP) return NodeSentinel; |
0 | 317 return this; |
318 } | |
319 | |
320 // let the subclass continue analyzing... | |
321 return NULL; | |
322 } | |
323 | |
324 // Helper function for proving some simple control dominations. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
325 // Attempt to prove that all control inputs of 'dom' dominate 'sub'. |
0 | 326 // Already assumes that 'dom' is available at 'sub', and that 'sub' |
327 // is not a constant (dominated by the method's StartNode). | |
328 // Used by MemNode::find_previous_store to prove that the | |
329 // control input of a memory operation predates (dominates) | |
330 // an allocation it wants to look past. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
331 bool MemNode::all_controls_dominate(Node* dom, Node* sub) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
332 if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
333 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
334 |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
335 // Check 'dom'. Skip Proj and CatchProj nodes. |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
336 dom = dom->find_exact_control(dom); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
337 if (dom == NULL || dom->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
338 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
339 |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
340 if (dom == sub) { |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
341 // For the case when, for example, 'sub' is Initialize and the original |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
342 // 'dom' is Proj node of the 'sub'. |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
343 return false; |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
344 } |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
345 |
155
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
346 if (dom->is_Con() || dom->is_Start() || dom->is_Root() || dom == sub) |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
347 return true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
348 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
349 // 'dom' dominates 'sub' if its control edge and control edges |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
350 // of all its inputs dominate or equal to sub's control edge. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
351 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
352 // Currently 'sub' is either Allocate, Initialize or Start nodes. |
163 | 353 // Or Region for the check in LoadNode::Ideal(); |
354 // 'sub' should have sub->in(0) != NULL. | |
355 assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() || | |
356 sub->is_Region(), "expecting only these nodes"); | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
357 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
358 // Get control edge of 'sub'. |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
359 Node* orig_sub = sub; |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
360 sub = sub->find_exact_control(sub->in(0)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
361 if (sub == NULL || sub->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
362 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
363 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
364 assert(sub->is_CFG(), "expecting control"); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
365 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
366 if (sub == dom) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
367 return true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
368 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
369 if (sub->is_Start() || sub->is_Root()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
370 return false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
371 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
372 { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
373 // Check all control edges of 'dom'. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
374 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
375 ResourceMark rm; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
376 Arena* arena = Thread::current()->resource_area(); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
377 Node_List nlist(arena); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
378 Unique_Node_List dom_list(arena); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
379 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
380 dom_list.push(dom); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
381 bool only_dominating_controls = false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
382 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
383 for (uint next = 0; next < dom_list.size(); next++) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
384 Node* n = dom_list.at(next); |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
385 if (n == orig_sub) |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
386 return false; // One of dom's inputs dominated by sub. |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
387 if (!n->is_CFG() && n->pinned()) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
388 // Check only own control edge for pinned non-control nodes. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
389 n = n->find_exact_control(n->in(0)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
390 if (n == NULL || n->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
391 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
392 assert(n->is_CFG(), "expecting control"); |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
393 dom_list.push(n); |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
394 } else if (n->is_Con() || n->is_Start() || n->is_Root()) { |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
395 only_dominating_controls = true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
396 } else if (n->is_CFG()) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
397 if (n->dominates(sub, nlist)) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
398 only_dominating_controls = true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
399 else |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
400 return false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
401 } else { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
402 // First, own control edge. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
403 Node* m = n->find_exact_control(n->in(0)); |
155
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
404 if (m != NULL) { |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
405 if (m->is_top()) |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
406 return false; // Conservative answer for dead code |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
407 dom_list.push(m); |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
408 } |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
409 // Now, the rest of edges. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
410 uint cnt = n->req(); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
411 for (uint i = 1; i < cnt; i++) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
412 m = n->find_exact_control(n->in(i)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
413 if (m == NULL || m->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
414 continue; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
415 dom_list.push(m); |
0 | 416 } |
417 } | |
418 } | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
419 return only_dominating_controls; |
0 | 420 } |
421 } | |
422 | |
423 //---------------------detect_ptr_independence--------------------------------- | |
424 // Used by MemNode::find_previous_store to prove that two base | |
425 // pointers are never equal. | |
426 // The pointers are accompanied by their associated allocations, | |
427 // if any, which have been previously discovered by the caller. | |
428 bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1, | |
429 Node* p2, AllocateNode* a2, | |
430 PhaseTransform* phase) { | |
431 // Attempt to prove that these two pointers cannot be aliased. | |
432 // They may both manifestly be allocations, and they should differ. | |
433 // Or, if they are not both allocations, they can be distinct constants. | |
434 // Otherwise, one is an allocation and the other a pre-existing value. | |
435 if (a1 == NULL && a2 == NULL) { // neither an allocation | |
436 return (p1 != p2) && p1->is_Con() && p2->is_Con(); | |
437 } else if (a1 != NULL && a2 != NULL) { // both allocations | |
438 return (a1 != a2); | |
439 } else if (a1 != NULL) { // one allocation a1 | |
440 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
441 return all_controls_dominate(p2, a1); |
0 | 442 } else { //(a2 != NULL) // one allocation a2 |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
443 return all_controls_dominate(p1, a2); |
0 | 444 } |
445 return false; | |
446 } | |
447 | |
448 | |
449 // The logic for reordering loads and stores uses four steps: | |
450 // (a) Walk carefully past stores and initializations which we | |
451 // can prove are independent of this load. | |
452 // (b) Observe that the next memory state makes an exact match | |
453 // with self (load or store), and locate the relevant store. | |
454 // (c) Ensure that, if we were to wire self directly to the store, | |
455 // the optimizer would fold it up somehow. | |
456 // (d) Do the rewiring, and return, depending on some other part of | |
457 // the optimizer to fold up the load. | |
458 // This routine handles steps (a) and (b). Steps (c) and (d) are | |
459 // specific to loads and stores, so they are handled by the callers. | |
460 // (Currently, only LoadNode::Ideal has steps (c), (d). More later.) | |
461 // | |
462 Node* MemNode::find_previous_store(PhaseTransform* phase) { | |
463 Node* ctrl = in(MemNode::Control); | |
464 Node* adr = in(MemNode::Address); | |
465 intptr_t offset = 0; | |
466 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
467 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, phase); | |
468 | |
469 if (offset == Type::OffsetBot) | |
470 return NULL; // cannot unalias unless there are precise offsets | |
471 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
472 const TypeOopPtr *addr_t = adr->bottom_type()->isa_oopptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
473 |
0 | 474 intptr_t size_in_bytes = memory_size(); |
475 | |
476 Node* mem = in(MemNode::Memory); // start searching here... | |
477 | |
478 int cnt = 50; // Cycle limiter | |
479 for (;;) { // While we can dance past unrelated stores... | |
480 if (--cnt < 0) break; // Caught in cycle or a complicated dance? | |
481 | |
482 if (mem->is_Store()) { | |
483 Node* st_adr = mem->in(MemNode::Address); | |
484 intptr_t st_offset = 0; | |
485 Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_offset); | |
486 if (st_base == NULL) | |
487 break; // inscrutable pointer | |
488 if (st_offset != offset && st_offset != Type::OffsetBot) { | |
489 const int MAX_STORE = BytesPerLong; | |
490 if (st_offset >= offset + size_in_bytes || | |
491 st_offset <= offset - MAX_STORE || | |
492 st_offset <= offset - mem->as_Store()->memory_size()) { | |
493 // Success: The offsets are provably independent. | |
494 // (You may ask, why not just test st_offset != offset and be done? | |
495 // The answer is that stores of different sizes can co-exist | |
496 // in the same sequence of RawMem effects. We sometimes initialize | |
497 // a whole 'tile' of array elements with a single jint or jlong.) | |
498 mem = mem->in(MemNode::Memory); | |
499 continue; // (a) advance through independent store memory | |
500 } | |
501 } | |
502 if (st_base != base && | |
503 detect_ptr_independence(base, alloc, | |
504 st_base, | |
505 AllocateNode::Ideal_allocation(st_base, phase), | |
506 phase)) { | |
507 // Success: The bases are provably independent. | |
508 mem = mem->in(MemNode::Memory); | |
509 continue; // (a) advance through independent store memory | |
510 } | |
511 | |
512 // (b) At this point, if the bases or offsets do not agree, we lose, | |
513 // since we have not managed to prove 'this' and 'mem' independent. | |
514 if (st_base == base && st_offset == offset) { | |
515 return mem; // let caller handle steps (c), (d) | |
516 } | |
517 | |
518 } else if (mem->is_Proj() && mem->in(0)->is_Initialize()) { | |
519 InitializeNode* st_init = mem->in(0)->as_Initialize(); | |
520 AllocateNode* st_alloc = st_init->allocation(); | |
521 if (st_alloc == NULL) | |
522 break; // something degenerated | |
523 bool known_identical = false; | |
524 bool known_independent = false; | |
525 if (alloc == st_alloc) | |
526 known_identical = true; | |
527 else if (alloc != NULL) | |
528 known_independent = true; | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
529 else if (all_controls_dominate(this, st_alloc)) |
0 | 530 known_independent = true; |
531 | |
532 if (known_independent) { | |
533 // The bases are provably independent: Either they are | |
534 // manifestly distinct allocations, or else the control | |
535 // of this load dominates the store's allocation. | |
536 int alias_idx = phase->C->get_alias_index(adr_type()); | |
537 if (alias_idx == Compile::AliasIdxRaw) { | |
538 mem = st_alloc->in(TypeFunc::Memory); | |
539 } else { | |
540 mem = st_init->memory(alias_idx); | |
541 } | |
542 continue; // (a) advance through independent store memory | |
543 } | |
544 | |
545 // (b) at this point, if we are not looking at a store initializing | |
546 // the same allocation we are loading from, we lose. | |
547 if (known_identical) { | |
548 // From caller, can_see_stored_value will consult find_captured_store. | |
549 return mem; // let caller handle steps (c), (d) | |
550 } | |
551 | |
223 | 552 } else if (addr_t != NULL && addr_t->is_known_instance_field()) { |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
553 // Can't use optimize_simple_memory_chain() since it needs PhaseGVN. |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
554 if (mem->is_Proj() && mem->in(0)->is_Call()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
555 CallNode *call = mem->in(0)->as_Call(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
556 if (!call->may_modify(addr_t, phase)) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
557 mem = call->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
558 continue; // (a) advance through independent call memory |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
559 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
560 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
561 mem = mem->in(0)->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
562 continue; // (a) advance through independent MemBar memory |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
563 } else if (mem->is_ClearArray()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
564 if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
565 // (the call updated 'mem' value) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
566 continue; // (a) advance through independent allocation memory |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
567 } else { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
568 // Can not bypass initialization of the instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
569 // we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
570 return mem; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
571 } |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
572 } else if (mem->is_MergeMem()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
573 int alias_idx = phase->C->get_alias_index(adr_type()); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
574 mem = mem->as_MergeMem()->memory_at(alias_idx); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
575 continue; // (a) advance through independent MergeMem memory |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
576 } |
0 | 577 } |
578 | |
579 // Unless there is an explicit 'continue', we must bail out here, | |
580 // because 'mem' is an inscrutable memory state (e.g., a call). | |
581 break; | |
582 } | |
583 | |
584 return NULL; // bail out | |
585 } | |
586 | |
587 //----------------------calculate_adr_type------------------------------------- | |
588 // Helper function. Notices when the given type of address hits top or bottom. | |
589 // Also, asserts a cross-check of the type against the expected address type. | |
590 const TypePtr* MemNode::calculate_adr_type(const Type* t, const TypePtr* cross_check) { | |
591 if (t == Type::TOP) return NULL; // does not touch memory any more? | |
592 #ifdef PRODUCT | |
593 cross_check = NULL; | |
594 #else | |
595 if (!VerifyAliases || is_error_reported() || Node::in_dump()) cross_check = NULL; | |
596 #endif | |
597 const TypePtr* tp = t->isa_ptr(); | |
598 if (tp == NULL) { | |
599 assert(cross_check == NULL || cross_check == TypePtr::BOTTOM, "expected memory type must be wide"); | |
600 return TypePtr::BOTTOM; // touches lots of memory | |
601 } else { | |
602 #ifdef ASSERT | |
603 // %%%% [phh] We don't check the alias index if cross_check is | |
604 // TypeRawPtr::BOTTOM. Needs to be investigated. | |
605 if (cross_check != NULL && | |
606 cross_check != TypePtr::BOTTOM && | |
607 cross_check != TypeRawPtr::BOTTOM) { | |
608 // Recheck the alias index, to see if it has changed (due to a bug). | |
609 Compile* C = Compile::current(); | |
610 assert(C->get_alias_index(cross_check) == C->get_alias_index(tp), | |
611 "must stay in the original alias category"); | |
612 // The type of the address must be contained in the adr_type, | |
613 // disregarding "null"-ness. | |
614 // (We make an exception for TypeRawPtr::BOTTOM, which is a bit bucket.) | |
615 const TypePtr* tp_notnull = tp->join(TypePtr::NOTNULL)->is_ptr(); | |
616 assert(cross_check->meet(tp_notnull) == cross_check, | |
617 "real address must not escape from expected memory type"); | |
618 } | |
619 #endif | |
620 return tp; | |
621 } | |
622 } | |
623 | |
624 //------------------------adr_phi_is_loop_invariant---------------------------- | |
625 // A helper function for Ideal_DU_postCCP to check if a Phi in a counted | |
626 // loop is loop invariant. Make a quick traversal of Phi and associated | |
627 // CastPP nodes, looking to see if they are a closed group within the loop. | |
628 bool MemNode::adr_phi_is_loop_invariant(Node* adr_phi, Node* cast) { | |
629 // The idea is that the phi-nest must boil down to only CastPP nodes | |
630 // with the same data. This implies that any path into the loop already | |
631 // includes such a CastPP, and so the original cast, whatever its input, | |
632 // must be covered by an equivalent cast, with an earlier control input. | |
633 ResourceMark rm; | |
634 | |
635 // The loop entry input of the phi should be the unique dominating | |
636 // node for every Phi/CastPP in the loop. | |
637 Unique_Node_List closure; | |
638 closure.push(adr_phi->in(LoopNode::EntryControl)); | |
639 | |
640 // Add the phi node and the cast to the worklist. | |
641 Unique_Node_List worklist; | |
642 worklist.push(adr_phi); | |
643 if( cast != NULL ){ | |
644 if( !cast->is_ConstraintCast() ) return false; | |
645 worklist.push(cast); | |
646 } | |
647 | |
648 // Begin recursive walk of phi nodes. | |
649 while( worklist.size() ){ | |
650 // Take a node off the worklist | |
651 Node *n = worklist.pop(); | |
652 if( !closure.member(n) ){ | |
653 // Add it to the closure. | |
654 closure.push(n); | |
655 // Make a sanity check to ensure we don't waste too much time here. | |
656 if( closure.size() > 20) return false; | |
657 // This node is OK if: | |
658 // - it is a cast of an identical value | |
659 // - or it is a phi node (then we add its inputs to the worklist) | |
660 // Otherwise, the node is not OK, and we presume the cast is not invariant | |
661 if( n->is_ConstraintCast() ){ | |
662 worklist.push(n->in(1)); | |
663 } else if( n->is_Phi() ) { | |
664 for( uint i = 1; i < n->req(); i++ ) { | |
665 worklist.push(n->in(i)); | |
666 } | |
667 } else { | |
668 return false; | |
669 } | |
670 } | |
671 } | |
672 | |
673 // Quit when the worklist is empty, and we've found no offending nodes. | |
674 return true; | |
675 } | |
676 | |
677 //------------------------------Ideal_DU_postCCP------------------------------- | |
678 // Find any cast-away of null-ness and keep its control. Null cast-aways are | |
679 // going away in this pass and we need to make this memory op depend on the | |
680 // gating null check. | |
163 | 681 Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { |
682 return Ideal_common_DU_postCCP(ccp, this, in(MemNode::Address)); | |
683 } | |
0 | 684 |
685 // I tried to leave the CastPP's in. This makes the graph more accurate in | |
686 // some sense; we get to keep around the knowledge that an oop is not-null | |
687 // after some test. Alas, the CastPP's interfere with GVN (some values are | |
688 // the regular oop, some are the CastPP of the oop, all merge at Phi's which | |
689 // cannot collapse, etc). This cost us 10% on SpecJVM, even when I removed | |
690 // some of the more trivial cases in the optimizer. Removing more useless | |
691 // Phi's started allowing Loads to illegally float above null checks. I gave | |
692 // up on this approach. CNC 10/20/2000 | |
163 | 693 // This static method may be called not from MemNode (EncodePNode calls it). |
694 // Only the control edge of the node 'n' might be updated. | |
695 Node *MemNode::Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ) { | |
0 | 696 Node *skipped_cast = NULL; |
697 // Need a null check? Regular static accesses do not because they are | |
698 // from constant addresses. Array ops are gated by the range check (which | |
699 // always includes a NULL check). Just check field ops. | |
163 | 700 if( n->in(MemNode::Control) == NULL ) { |
0 | 701 // Scan upwards for the highest location we can place this memory op. |
702 while( true ) { | |
703 switch( adr->Opcode() ) { | |
704 | |
705 case Op_AddP: // No change to NULL-ness, so peek thru AddP's | |
706 adr = adr->in(AddPNode::Base); | |
707 continue; | |
708 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
709 case Op_DecodeN: // No change to NULL-ness, so peek thru |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
710 adr = adr->in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
711 continue; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
712 |
0 | 713 case Op_CastPP: |
714 // If the CastPP is useless, just peek on through it. | |
715 if( ccp->type(adr) == ccp->type(adr->in(1)) ) { | |
716 // Remember the cast that we've peeked though. If we peek | |
717 // through more than one, then we end up remembering the highest | |
718 // one, that is, if in a loop, the one closest to the top. | |
719 skipped_cast = adr; | |
720 adr = adr->in(1); | |
721 continue; | |
722 } | |
723 // CastPP is going away in this pass! We need this memory op to be | |
724 // control-dependent on the test that is guarding the CastPP. | |
163 | 725 ccp->hash_delete(n); |
726 n->set_req(MemNode::Control, adr->in(0)); | |
727 ccp->hash_insert(n); | |
728 return n; | |
0 | 729 |
730 case Op_Phi: | |
731 // Attempt to float above a Phi to some dominating point. | |
732 if (adr->in(0) != NULL && adr->in(0)->is_CountedLoop()) { | |
733 // If we've already peeked through a Cast (which could have set the | |
734 // control), we can't float above a Phi, because the skipped Cast | |
735 // may not be loop invariant. | |
736 if (adr_phi_is_loop_invariant(adr, skipped_cast)) { | |
737 adr = adr->in(1); | |
738 continue; | |
739 } | |
740 } | |
741 | |
742 // Intentional fallthrough! | |
743 | |
744 // No obvious dominating point. The mem op is pinned below the Phi | |
745 // by the Phi itself. If the Phi goes away (no true value is merged) | |
746 // then the mem op can float, but not indefinitely. It must be pinned | |
747 // behind the controls leading to the Phi. | |
748 case Op_CheckCastPP: | |
749 // These usually stick around to change address type, however a | |
750 // useless one can be elided and we still need to pick up a control edge | |
751 if (adr->in(0) == NULL) { | |
752 // This CheckCastPP node has NO control and is likely useless. But we | |
753 // need check further up the ancestor chain for a control input to keep | |
754 // the node in place. 4959717. | |
755 skipped_cast = adr; | |
756 adr = adr->in(1); | |
757 continue; | |
758 } | |
163 | 759 ccp->hash_delete(n); |
760 n->set_req(MemNode::Control, adr->in(0)); | |
761 ccp->hash_insert(n); | |
762 return n; | |
0 | 763 |
764 // List of "safe" opcodes; those that implicitly block the memory | |
765 // op below any null check. | |
766 case Op_CastX2P: // no null checks on native pointers | |
767 case Op_Parm: // 'this' pointer is not null | |
768 case Op_LoadP: // Loading from within a klass | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
769 case Op_LoadN: // Loading from within a klass |
0 | 770 case Op_LoadKlass: // Loading from within a klass |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
771 case Op_LoadNKlass: // Loading from within a klass |
0 | 772 case Op_ConP: // Loading from a klass |
163 | 773 case Op_ConN: // Loading from a klass |
0 | 774 case Op_CreateEx: // Sucking up the guts of an exception oop |
775 case Op_Con: // Reading from TLS | |
776 case Op_CMoveP: // CMoveP is pinned | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
777 case Op_CMoveN: // CMoveN is pinned |
0 | 778 break; // No progress |
779 | |
780 case Op_Proj: // Direct call to an allocation routine | |
781 case Op_SCMemProj: // Memory state from store conditional ops | |
782 #ifdef ASSERT | |
783 { | |
784 assert(adr->as_Proj()->_con == TypeFunc::Parms, "must be return value"); | |
785 const Node* call = adr->in(0); | |
163 | 786 if (call->is_CallJava()) { |
787 const CallJavaNode* call_java = call->as_CallJava(); | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
788 const TypeTuple *r = call_java->tf()->range(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
789 assert(r->cnt() > TypeFunc::Parms, "must return value"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
790 const Type* ret_type = r->field_at(TypeFunc::Parms); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
791 assert(ret_type && ret_type->isa_ptr(), "must return pointer"); |
0 | 792 // We further presume that this is one of |
793 // new_instance_Java, new_array_Java, or | |
794 // the like, but do not assert for this. | |
795 } else if (call->is_Allocate()) { | |
796 // similar case to new_instance_Java, etc. | |
797 } else if (!call->is_CallLeaf()) { | |
798 // Projections from fetch_oop (OSR) are allowed as well. | |
799 ShouldNotReachHere(); | |
800 } | |
801 } | |
802 #endif | |
803 break; | |
804 default: | |
805 ShouldNotReachHere(); | |
806 } | |
807 break; | |
808 } | |
809 } | |
810 | |
811 return NULL; // No progress | |
812 } | |
813 | |
814 | |
815 //============================================================================= | |
816 uint LoadNode::size_of() const { return sizeof(*this); } | |
817 uint LoadNode::cmp( const Node &n ) const | |
818 { return !Type::cmp( _type, ((LoadNode&)n)._type ); } | |
819 const Type *LoadNode::bottom_type() const { return _type; } | |
820 uint LoadNode::ideal_reg() const { | |
821 return Matcher::base2reg[_type->base()]; | |
822 } | |
823 | |
824 #ifndef PRODUCT | |
825 void LoadNode::dump_spec(outputStream *st) const { | |
826 MemNode::dump_spec(st); | |
827 if( !Verbose && !WizardMode ) { | |
828 // standard dump does this in Verbose and WizardMode | |
829 st->print(" #"); _type->dump_on(st); | |
830 } | |
831 } | |
832 #endif | |
833 | |
1609 | 834 #ifdef ASSERT |
835 //----------------------------is_immutable_value------------------------------- | |
836 // Helper function to allow a raw load without control edge for some cases | |
837 bool LoadNode::is_immutable_value(Node* adr) { | |
838 return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() && | |
839 adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && | |
840 (adr->in(AddPNode::Offset)->find_intptr_t_con(-1) == | |
841 in_bytes(JavaThread::osthread_offset()))); | |
842 } | |
843 #endif | |
0 | 844 |
845 //----------------------------LoadNode::make----------------------------------- | |
846 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
847 Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
848 Compile* C = gvn.C; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
849 |
0 | 850 // sanity check the alias category against the created node type |
851 assert(!(adr_type->isa_oopptr() && | |
852 adr_type->offset() == oopDesc::klass_offset_in_bytes()), | |
853 "use LoadKlassNode instead"); | |
854 assert(!(adr_type->isa_aryptr() && | |
855 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), | |
856 "use LoadRangeNode instead"); | |
1609 | 857 // Check control edge of raw loads |
858 assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw || | |
859 // oop will be recorded in oop map if load crosses safepoint | |
860 rt->isa_oopptr() || is_immutable_value(adr), | |
861 "raw memory operations should have control edge"); | |
0 | 862 switch (bt) { |
624 | 863 case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
864 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
865 case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
866 case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
867 case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
868 case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
869 case T_FLOAT: return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
870 case T_DOUBLE: return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
871 case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() ); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
872 case T_OBJECT: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
873 #ifdef _LP64 |
163 | 874 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
875 Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
876 return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr()); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
877 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
878 #endif |
163 | 879 { |
880 assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop"); | |
881 return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr()); | |
882 } | |
0 | 883 } |
884 ShouldNotReachHere(); | |
885 return (LoadNode*)NULL; | |
886 } | |
887 | |
888 LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) { | |
889 bool require_atomic = true; | |
890 return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic); | |
891 } | |
892 | |
893 | |
894 | |
895 | |
896 //------------------------------hash------------------------------------------- | |
897 uint LoadNode::hash() const { | |
898 // unroll addition of interesting fields | |
899 return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address); | |
900 } | |
901 | |
902 //---------------------------can_see_stored_value------------------------------ | |
903 // This routine exists to make sure this set of tests is done the same | |
904 // everywhere. We need to make a coordinated change: first LoadNode::Ideal | |
905 // will change the graph shape in a way which makes memory alive twice at the | |
906 // same time (uses the Oracle model of aliasing), then some | |
907 // LoadXNode::Identity will fold things back to the equivalence-class model | |
908 // of aliasing. | |
909 Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { | |
910 Node* ld_adr = in(MemNode::Address); | |
911 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
912 const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
913 Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
914 if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
915 atp->field() != NULL && !atp->field()->is_volatile()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
916 uint alias_idx = atp->index(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
917 bool final = atp->field()->is_final(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
918 Node* result = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
919 Node* current = st; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
920 // Skip through chains of MemBarNodes checking the MergeMems for |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
921 // new states for the slice of this load. Stop once any other |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
922 // kind of node is encountered. Loads from final memory can skip |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
923 // through any kind of MemBar but normal loads shouldn't skip |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
924 // through MemBarAcquire since the could allow them to move out of |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
925 // a synchronized region. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
926 while (current->is_Proj()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
927 int opc = current->in(0)->Opcode(); |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
928 if ((final && (opc == Op_MemBarAcquire || opc == Op_MemBarAcquireLock)) || |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
929 opc == Op_MemBarRelease || opc == Op_MemBarCPUOrder || |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
930 opc == Op_MemBarReleaseLock) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
931 Node* mem = current->in(0)->in(TypeFunc::Memory); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
932 if (mem->is_MergeMem()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
933 MergeMemNode* merge = mem->as_MergeMem(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
934 Node* new_st = merge->memory_at(alias_idx); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
935 if (new_st == merge->base_memory()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
936 // Keep searching |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
937 current = merge->base_memory(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
938 continue; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
939 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
940 // Save the new memory state for the slice and fall through |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
941 // to exit. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
942 result = new_st; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
943 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
944 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
945 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
946 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
947 if (result != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
948 st = result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
949 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
950 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
951 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
952 |
0 | 953 // Loop around twice in the case Load -> Initialize -> Store. |
954 // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) | |
955 for (int trip = 0; trip <= 1; trip++) { | |
956 | |
957 if (st->is_Store()) { | |
958 Node* st_adr = st->in(MemNode::Address); | |
959 if (!phase->eqv(st_adr, ld_adr)) { | |
960 // Try harder before giving up... Match raw and non-raw pointers. | |
961 intptr_t st_off = 0; | |
962 AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off); | |
963 if (alloc == NULL) return NULL; | |
964 intptr_t ld_off = 0; | |
965 AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off); | |
966 if (alloc != allo2) return NULL; | |
967 if (ld_off != st_off) return NULL; | |
968 // At this point we have proven something like this setup: | |
969 // A = Allocate(...) | |
970 // L = LoadQ(, AddP(CastPP(, A.Parm),, #Off)) | |
971 // S = StoreQ(, AddP(, A.Parm , #Off), V) | |
972 // (Actually, we haven't yet proven the Q's are the same.) | |
973 // In other words, we are loading from a casted version of | |
974 // the same pointer-and-offset that we stored to. | |
975 // Thus, we are able to replace L by V. | |
976 } | |
977 // Now prove that we have a LoadQ matched to a StoreQ, for some Q. | |
978 if (store_Opcode() != st->Opcode()) | |
979 return NULL; | |
980 return st->in(MemNode::ValueIn); | |
981 } | |
982 | |
983 intptr_t offset = 0; // scratch | |
984 | |
985 // A load from a freshly-created object always returns zero. | |
986 // (This can happen after LoadNode::Ideal resets the load's memory input | |
987 // to find_captured_store, which returned InitializeNode::zero_memory.) | |
988 if (st->is_Proj() && st->in(0)->is_Allocate() && | |
989 st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) && | |
990 offset >= st->in(0)->as_Allocate()->minimum_header_size()) { | |
991 // return a zero value for the load's basic type | |
992 // (This is one of the few places where a generic PhaseTransform | |
993 // can create new nodes. Think of it as lazily manifesting | |
994 // virtually pre-existing constants.) | |
995 return phase->zerocon(memory_type()); | |
996 } | |
997 | |
998 // A load from an initialization barrier can match a captured store. | |
999 if (st->is_Proj() && st->in(0)->is_Initialize()) { | |
1000 InitializeNode* init = st->in(0)->as_Initialize(); | |
1001 AllocateNode* alloc = init->allocation(); | |
1002 if (alloc != NULL && | |
1003 alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) { | |
1004 // examine a captured store value | |
1005 st = init->find_captured_store(offset, memory_size(), phase); | |
1006 if (st != NULL) | |
1007 continue; // take one more trip around | |
1008 } | |
1009 } | |
1010 | |
1011 break; | |
1012 } | |
1013 | |
1014 return NULL; | |
1015 } | |
1016 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1017 //----------------------is_instance_field_load_with_local_phi------------------ |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1018 bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1019 if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1020 in(MemNode::Address)->is_AddP() ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1021 const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1022 // Only instances. |
223 | 1023 if( t_oop != NULL && t_oop->is_known_instance_field() && |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1024 t_oop->offset() != Type::OffsetBot && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1025 t_oop->offset() != Type::OffsetTop) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1026 return true; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1027 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1028 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1029 return false; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1030 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1031 |
0 | 1032 //------------------------------Identity--------------------------------------- |
1033 // Loads are identity if previous store is to same address | |
1034 Node *LoadNode::Identity( PhaseTransform *phase ) { | |
1035 // If the previous store-maker is the right kind of Store, and the store is | |
1036 // to the same address, then we are equal to the value stored. | |
1037 Node* mem = in(MemNode::Memory); | |
1038 Node* value = can_see_stored_value(mem, phase); | |
1039 if( value ) { | |
1040 // byte, short & char stores truncate naturally. | |
1041 // A load has to load the truncated value which requires | |
1042 // some sort of masking operation and that requires an | |
1043 // Ideal call instead of an Identity call. | |
1044 if (memory_size() < BytesPerInt) { | |
1045 // If the input to the store does not fit with the load's result type, | |
1046 // it must be truncated via an Ideal call. | |
1047 if (!phase->type(value)->higher_equal(phase->type(this))) | |
1048 return this; | |
1049 } | |
1050 // (This works even when value is a Con, but LoadNode::Value | |
1051 // usually runs first, producing the singleton type of the Con.) | |
1052 return value; | |
1053 } | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1054 |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1055 // Search for an existing data phi which was generated before for the same |
605 | 1056 // instance's field to avoid infinite generation of phis in a loop. |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1057 Node *region = mem->in(0); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1058 if (is_instance_field_load_with_local_phi(region)) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1059 const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1060 int this_index = phase->C->get_alias_index(addr_t); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1061 int this_offset = addr_t->offset(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1062 int this_id = addr_t->is_oopptr()->instance_id(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1063 const Type* this_type = bottom_type(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1064 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1065 Node* phi = region->fast_out(i); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1066 if (phi->is_Phi() && phi != mem && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1067 phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1068 return phi; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1069 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1070 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1071 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1072 |
0 | 1073 return this; |
1074 } | |
1075 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1076 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1077 // Returns true if the AliasType refers to the field that holds the |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1078 // cached box array. Currently only handles the IntegerCache case. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1079 static bool is_autobox_cache(Compile::AliasType* atp) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1080 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1081 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1082 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1083 if (field->name() == ciSymbol::cache_field_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1084 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1085 klass == ciSymbol::java_lang_Integer_IntegerCache()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1086 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1087 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1088 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1089 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1090 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1091 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1092 // Fetch the base value in the autobox array |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1093 static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1094 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1095 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1096 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1097 if (field->name() == ciSymbol::cache_field_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1098 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1099 klass == ciSymbol::java_lang_Integer_IntegerCache()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1100 assert(field->is_constant(), "what?"); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1101 ciObjArray* array = field->constant_value().as_object()->as_obj_array(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1102 // Fetch the box object at the base of the array and get its value |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1103 ciInstance* box = array->obj_at(0)->as_instance(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1104 ciInstanceKlass* ik = box->klass()->as_instance_klass(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1105 if (ik->nof_nonstatic_fields() == 1) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1106 // This should be true nonstatic_field_at requires calling |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1107 // nof_nonstatic_fields so check it anyway |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1108 ciConstant c = box->field_value(ik->nonstatic_field_at(0)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1109 cache_offset = c.as_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1110 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1111 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1112 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1113 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1114 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1115 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1116 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1117 // Returns true if the AliasType refers to the value field of an |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1118 // autobox object. Currently only handles Integer. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1119 static bool is_autobox_object(Compile::AliasType* atp) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1120 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1121 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1122 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1123 if (field->name() == ciSymbol::value_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1124 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1125 klass == ciSymbol::java_lang_Integer()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1126 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1127 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1128 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1129 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1130 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1131 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1132 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1133 // We're loading from an object which has autobox behaviour. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1134 // If this object is result of a valueOf call we'll have a phi |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1135 // merging a newly allocated object and a load from the cache. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1136 // We want to replace this load with the original incoming |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1137 // argument to the valueOf call. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1138 Node* LoadNode::eliminate_autobox(PhaseGVN* phase) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1139 Node* base = in(Address)->in(AddPNode::Base); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1140 if (base->is_Phi() && base->req() == 3) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1141 AllocateNode* allocation = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1142 int allocation_index = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1143 int load_index = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1144 for (uint i = 1; i < base->req(); i++) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1145 allocation = AllocateNode::Ideal_allocation(base->in(i), phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1146 if (allocation != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1147 allocation_index = i; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1148 load_index = 3 - allocation_index; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1149 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1150 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1151 } |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1152 bool has_load = ( allocation != NULL && |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1153 (base->in(load_index)->is_Load() || |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1154 base->in(load_index)->is_DecodeN() && |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1155 base->in(load_index)->in(1)->is_Load()) ); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1156 if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1157 // Push the loads from the phi that comes from valueOf up |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1158 // through it to allow elimination of the loads and the recovery |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1159 // of the original value. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1160 Node* mem_phi = in(Memory); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1161 Node* offset = in(Address)->in(AddPNode::Offset); |
553 | 1162 Node* region = base->in(0); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1163 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1164 Node* in1 = clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1165 Node* in1_addr = in1->in(Address)->clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1166 in1_addr->set_req(AddPNode::Base, base->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1167 in1_addr->set_req(AddPNode::Address, base->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1168 in1_addr->set_req(AddPNode::Offset, offset); |
553 | 1169 in1->set_req(0, region->in(allocation_index)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1170 in1->set_req(Address, in1_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1171 in1->set_req(Memory, mem_phi->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1172 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1173 Node* in2 = clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1174 Node* in2_addr = in2->in(Address)->clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1175 in2_addr->set_req(AddPNode::Base, base->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1176 in2_addr->set_req(AddPNode::Address, base->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1177 in2_addr->set_req(AddPNode::Offset, offset); |
553 | 1178 in2->set_req(0, region->in(load_index)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1179 in2->set_req(Address, in2_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1180 in2->set_req(Memory, mem_phi->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1181 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1182 in1_addr = phase->transform(in1_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1183 in1 = phase->transform(in1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1184 in2_addr = phase->transform(in2_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1185 in2 = phase->transform(in2); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1186 |
553 | 1187 PhiNode* result = PhiNode::make_blank(region, this); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1188 result->set_req(allocation_index, in1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1189 result->set_req(load_index, in2); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1190 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1191 } |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1192 } else if (base->is_Load() || |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1193 base->is_DecodeN() && base->in(1)->is_Load()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1194 if (base->is_DecodeN()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1195 // Get LoadN node which loads cached Integer object |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1196 base = base->in(1); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1197 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1198 // Eliminate the load of Integer.value for integers from the cache |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1199 // array by deriving the value from the index into the array. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1200 // Capture the offset of the load and then reverse the computation. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1201 Node* load_base = base->in(Address)->in(AddPNode::Base); |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1202 if (load_base->is_DecodeN()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1203 // Get LoadN node which loads IntegerCache.cache field |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1204 load_base = load_base->in(1); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1205 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1206 if (load_base != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1207 Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type()); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1208 intptr_t cache_offset; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1209 int shift = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1210 Node* cache = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1211 if (is_autobox_cache(atp)) { |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
1212 shift = exact_log2(type2aelembytes(T_OBJECT)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1213 cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1214 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1215 if (cache != NULL && base->in(Address)->is_AddP()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1216 Node* elements[4]; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1217 int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1218 int cache_low; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1219 if (count > 0 && fetch_autobox_base(atp, cache_low)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1220 int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1221 // Add up all the offsets making of the address of the load |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1222 Node* result = elements[0]; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1223 for (int i = 1; i < count; i++) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1224 result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i])); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1225 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1226 // Remove the constant offset from the address and then |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1227 // remove the scaling of the offset to recover the original index. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1228 result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset))); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1229 if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1230 // Peel the shift off directly but wrap it in a dummy node |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1231 // since Ideal can't return existing nodes |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1232 result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1233 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1234 result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1235 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1236 #ifdef _LP64 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1237 result = new (phase->C, 2) ConvL2INode(phase->transform(result)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1238 #endif |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1239 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1240 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1241 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1242 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1243 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1244 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1245 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1246 |
163 | 1247 //------------------------------split_through_phi------------------------------ |
1248 // Split instance field load through Phi. | |
1249 Node *LoadNode::split_through_phi(PhaseGVN *phase) { | |
1250 Node* mem = in(MemNode::Memory); | |
1251 Node* address = in(MemNode::Address); | |
1252 const TypePtr *addr_t = phase->type(address)->isa_ptr(); | |
1253 const TypeOopPtr *t_oop = addr_t->isa_oopptr(); | |
1254 | |
1255 assert(mem->is_Phi() && (t_oop != NULL) && | |
223 | 1256 t_oop->is_known_instance_field(), "invalide conditions"); |
163 | 1257 |
1258 Node *region = mem->in(0); | |
1259 if (region == NULL) { | |
1260 return NULL; // Wait stable graph | |
1261 } | |
1262 uint cnt = mem->req(); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1263 for (uint i = 1; i < cnt; i++) { |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1264 Node* rc = region->in(i); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1265 if (rc == NULL || phase->type(rc) == Type::TOP) |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1266 return NULL; // Wait stable graph |
163 | 1267 Node *in = mem->in(i); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1268 if (in == NULL) { |
163 | 1269 return NULL; // Wait stable graph |
1270 } | |
1271 } | |
1272 // Check for loop invariant. | |
1273 if (cnt == 3) { | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1274 for (uint i = 1; i < cnt; i++) { |
163 | 1275 Node *in = mem->in(i); |
1276 Node* m = MemNode::optimize_memory_chain(in, addr_t, phase); | |
1277 if (m == mem) { | |
1278 set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi. | |
1279 return this; | |
1280 } | |
1281 } | |
1282 } | |
1283 // Split through Phi (see original code in loopopts.cpp). | |
1284 assert(phase->C->have_alias_type(addr_t), "instance should have alias type"); | |
1285 | |
1286 // Do nothing here if Identity will find a value | |
1287 // (to avoid infinite chain of value phis generation). | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1288 if (!phase->eqv(this, this->Identity(phase))) |
163 | 1289 return NULL; |
1290 | |
1291 // Skip the split if the region dominates some control edge of the address. | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1292 if (!MemNode::all_controls_dominate(address, region)) |
163 | 1293 return NULL; |
1294 | |
1295 const Type* this_type = this->bottom_type(); | |
1296 int this_index = phase->C->get_alias_index(addr_t); | |
1297 int this_offset = addr_t->offset(); | |
1298 int this_iid = addr_t->is_oopptr()->instance_id(); | |
1299 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
1300 Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1301 for (uint i = 1; i < region->req(); i++) { |
163 | 1302 Node *x; |
1303 Node* the_clone = NULL; | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1304 if (region->in(i) == phase->C->top()) { |
163 | 1305 x = phase->C->top(); // Dead path? Use a dead data op |
1306 } else { | |
1307 x = this->clone(); // Else clone up the data op | |
1308 the_clone = x; // Remember for possible deletion. | |
1309 // Alter data node to use pre-phi inputs | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1310 if (this->in(0) == region) { |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1311 x->set_req(0, region->in(i)); |
163 | 1312 } else { |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1313 x->set_req(0, NULL); |
163 | 1314 } |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1315 for (uint j = 1; j < this->req(); j++) { |
163 | 1316 Node *in = this->in(j); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1317 if (in->is_Phi() && in->in(0) == region) |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1318 x->set_req(j, in->in(i)); // Use pre-Phi input for the clone |
163 | 1319 } |
1320 } | |
1321 // Check for a 'win' on some paths | |
1322 const Type *t = x->Value(igvn); | |
1323 | |
1324 bool singleton = t->singleton(); | |
1325 | |
1326 // See comments in PhaseIdealLoop::split_thru_phi(). | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1327 if (singleton && t == Type::TOP) { |
163 | 1328 singleton &= region->is_Loop() && (i != LoopNode::EntryControl); |
1329 } | |
1330 | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1331 if (singleton) { |
163 | 1332 x = igvn->makecon(t); |
1333 } else { | |
1334 // We now call Identity to try to simplify the cloned node. | |
1335 // Note that some Identity methods call phase->type(this). | |
1336 // Make sure that the type array is big enough for | |
1337 // our new node, even though we may throw the node away. | |
1338 // (This tweaking with igvn only works because x is a new node.) | |
1339 igvn->set_type(x, t); | |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1340 // If x is a TypeNode, capture any more-precise type permanently into Node |
605 | 1341 // otherwise it will be not updated during igvn->transform since |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1342 // igvn->type(x) is set to x->Value() already. |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1343 x->raise_bottom_type(t); |
163 | 1344 Node *y = x->Identity(igvn); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1345 if (y != x) { |
163 | 1346 x = y; |
1347 } else { | |
1348 y = igvn->hash_find(x); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1349 if (y) { |
163 | 1350 x = y; |
1351 } else { | |
1352 // Else x is a new node we are keeping | |
1353 // We do not need register_new_node_with_optimizer | |
1354 // because set_type has already been called. | |
1355 igvn->_worklist.push(x); | |
1356 } | |
1357 } | |
1358 } | |
1359 if (x != the_clone && the_clone != NULL) | |
1360 igvn->remove_dead_node(the_clone); | |
1361 phi->set_req(i, x); | |
1362 } | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1363 // Record Phi |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1364 igvn->register_new_node_with_optimizer(phi); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1365 return phi; |
163 | 1366 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1367 |
0 | 1368 //------------------------------Ideal------------------------------------------ |
1369 // If the load is from Field memory and the pointer is non-null, we can | |
1370 // zero out the control input. | |
1371 // If the offset is constant and the base is an object allocation, | |
1372 // try to hook me up to the exact initializing store. | |
1373 Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1374 Node* p = MemNode::Ideal_common(phase, can_reshape); | |
1375 if (p) return (p == NodeSentinel) ? NULL : p; | |
1376 | |
1377 Node* ctrl = in(MemNode::Control); | |
1378 Node* address = in(MemNode::Address); | |
1379 | |
1380 // Skip up past a SafePoint control. Cannot do this for Stores because | |
1381 // pointer stores & cardmarks must stay on the same side of a SafePoint. | |
1382 if( ctrl != NULL && ctrl->Opcode() == Op_SafePoint && | |
1383 phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw ) { | |
1384 ctrl = ctrl->in(0); | |
1385 set_req(MemNode::Control,ctrl); | |
1386 } | |
1387 | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1388 intptr_t ignore = 0; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1389 Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1390 if (base != NULL |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1391 && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1392 // Check for useless control edge in some common special cases |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1393 if (in(MemNode::Control) != NULL |
0 | 1394 && phase->type(base)->higher_equal(TypePtr::NOTNULL) |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
1395 && all_controls_dominate(base, phase->C->start())) { |
0 | 1396 // A method-invariant, non-null address (constant or 'this' argument). |
1397 set_req(MemNode::Control, NULL); | |
1398 } | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1399 |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1400 if (EliminateAutoBox && can_reshape) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1401 assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null"); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1402 Compile::AliasType* atp = phase->C->alias_type(adr_type()); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1403 if (is_autobox_object(atp)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1404 Node* result = eliminate_autobox(phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1405 if (result != NULL) return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1406 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1407 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1408 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1409 |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1410 Node* mem = in(MemNode::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1411 const TypePtr *addr_t = phase->type(address)->isa_ptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1412 |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1413 if (addr_t != NULL) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1414 // try to optimize our memory input |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1415 Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1416 if (opt_mem != mem) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1417 set_req(MemNode::Memory, opt_mem); |
305 | 1418 if (phase->type( opt_mem ) == Type::TOP) return NULL; |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1419 return this; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1420 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1421 const TypeOopPtr *t_oop = addr_t->isa_oopptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1422 if (can_reshape && opt_mem->is_Phi() && |
223 | 1423 (t_oop != NULL) && t_oop->is_known_instance_field()) { |
163 | 1424 // Split instance field load through Phi. |
1425 Node* result = split_through_phi(phase); | |
1426 if (result != NULL) return result; | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1427 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1428 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1429 |
0 | 1430 // Check for prior store with a different base or offset; make Load |
1431 // independent. Skip through any number of them. Bail out if the stores | |
1432 // are in an endless dead cycle and report no progress. This is a key | |
1433 // transform for Reflection. However, if after skipping through the Stores | |
1434 // we can't then fold up against a prior store do NOT do the transform as | |
1435 // this amounts to using the 'Oracle' model of aliasing. It leaves the same | |
1436 // array memory alive twice: once for the hoisted Load and again after the | |
1437 // bypassed Store. This situation only works if EVERYBODY who does | |
1438 // anti-dependence work knows how to bypass. I.e. we need all | |
1439 // anti-dependence checks to ask the same Oracle. Right now, that Oracle is | |
1440 // the alias index stuff. So instead, peek through Stores and IFF we can | |
1441 // fold up, do so. | |
1442 Node* prev_mem = find_previous_store(phase); | |
1443 // Steps (a), (b): Walk past independent stores to find an exact match. | |
1444 if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) { | |
1445 // (c) See if we can fold up on the spot, but don't fold up here. | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1446 // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or |
0 | 1447 // just return a prior value, which is done by Identity calls. |
1448 if (can_see_stored_value(prev_mem, phase)) { | |
1449 // Make ready for step (d): | |
1450 set_req(MemNode::Memory, prev_mem); | |
1451 return this; | |
1452 } | |
1453 } | |
1454 | |
1455 return NULL; // No further progress | |
1456 } | |
1457 | |
1458 // Helper to recognize certain Klass fields which are invariant across | |
1459 // some group of array types (e.g., int[] or all T[] where T < Object). | |
1460 const Type* | |
1461 LoadNode::load_array_final_field(const TypeKlassPtr *tkls, | |
1462 ciKlass* klass) const { | |
1463 if (tkls->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1464 // The field is Klass::_modifier_flags. Return its (constant) value. | |
1465 // (Folds up the 2nd indirection in aClassConstant.getModifiers().) | |
1466 assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); | |
1467 return TypeInt::make(klass->modifier_flags()); | |
1468 } | |
1469 if (tkls->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1470 // The field is Klass::_access_flags. Return its (constant) value. | |
1471 // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) | |
1472 assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); | |
1473 return TypeInt::make(klass->access_flags()); | |
1474 } | |
1475 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1476 // The field is Klass::_layout_helper. Return its constant value if known. | |
1477 assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); | |
1478 return TypeInt::make(klass->layout_helper()); | |
1479 } | |
1480 | |
1481 // No match. | |
1482 return NULL; | |
1483 } | |
1484 | |
1485 //------------------------------Value----------------------------------------- | |
1486 const Type *LoadNode::Value( PhaseTransform *phase ) const { | |
1487 // Either input is TOP ==> the result is TOP | |
1488 Node* mem = in(MemNode::Memory); | |
1489 const Type *t1 = phase->type(mem); | |
1490 if (t1 == Type::TOP) return Type::TOP; | |
1491 Node* adr = in(MemNode::Address); | |
1492 const TypePtr* tp = phase->type(adr)->isa_ptr(); | |
1493 if (tp == NULL || tp->empty()) return Type::TOP; | |
1494 int off = tp->offset(); | |
1495 assert(off != Type::OffsetTop, "case covered by TypePtr::empty"); | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1496 Compile* C = phase->C; |
0 | 1497 |
1498 // Try to guess loaded type from pointer type | |
1499 if (tp->base() == Type::AryPtr) { | |
1500 const Type *t = tp->is_aryptr()->elem(); | |
1501 // Don't do this for integer types. There is only potential profit if | |
1502 // the element type t is lower than _type; that is, for int types, if _type is | |
1503 // more restrictive than t. This only happens here if one is short and the other | |
1504 // char (both 16 bits), and in those cases we've made an intentional decision | |
1505 // to use one kind of load over the other. See AndINode::Ideal and 4965907. | |
1506 // Also, do not try to narrow the type for a LoadKlass, regardless of offset. | |
1507 // | |
1508 // Yes, it is possible to encounter an expression like (LoadKlass p1:(AddP x x 8)) | |
1509 // where the _gvn.type of the AddP is wider than 8. This occurs when an earlier | |
1510 // copy p0 of (AddP x x 8) has been proven equal to p1, and the p0 has been | |
1511 // subsumed by p1. If p1 is on the worklist but has not yet been re-transformed, | |
1512 // it is possible that p1 will have a type like Foo*[int+]:NotNull*+any. | |
1513 // In fact, that could have been the original type of p1, and p1 could have | |
1514 // had an original form like p1:(AddP x x (LShiftL quux 3)), where the | |
1515 // expression (LShiftL quux 3) independently optimized to the constant 8. | |
1516 if ((t->isa_int() == NULL) && (t->isa_long() == NULL) | |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1517 && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { |
0 | 1518 // t might actually be lower than _type, if _type is a unique |
1519 // concrete subclass of abstract class t. | |
1520 // Make sure the reference is not into the header, by comparing | |
1521 // the offset against the offset of the start of the array's data. | |
1522 // Different array types begin at slightly different offsets (12 vs. 16). | |
1523 // We choose T_BYTE as an example base type that is least restrictive | |
1524 // as to alignment, which will therefore produce the smallest | |
1525 // possible base offset. | |
1526 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); | |
1527 if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header? | |
1528 const Type* jt = t->join(_type); | |
1529 // In any case, do not allow the join, per se, to empty out the type. | |
1530 if (jt->empty() && !t->empty()) { | |
1531 // This can happen if a interface-typed array narrows to a class type. | |
1532 jt = _type; | |
1533 } | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1534 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1535 if (EliminateAutoBox && adr->is_AddP()) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1536 // The pointers in the autobox arrays are always non-null |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1537 Node* base = adr->in(AddPNode::Base); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1538 if (base != NULL && |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1539 !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) { |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1540 Compile::AliasType* atp = C->alias_type(base->adr_type()); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1541 if (is_autobox_cache(atp)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1542 return jt->join(TypePtr::NOTNULL)->is_ptr(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1543 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1544 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1545 } |
0 | 1546 return jt; |
1547 } | |
1548 } | |
1549 } else if (tp->base() == Type::InstPtr) { | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1550 ciEnv* env = C->env(); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1551 const TypeInstPtr* tinst = tp->is_instptr(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1552 ciKlass* klass = tinst->klass(); |
0 | 1553 assert( off != Type::OffsetBot || |
1554 // arrays can be cast to Objects | |
1555 tp->is_oopptr()->klass()->is_java_lang_Object() || | |
1556 // unsafe field access may not have a constant offset | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1557 C->has_unsafe_access(), |
0 | 1558 "Field accesses must be precise" ); |
1559 // For oop loads, we expect the _type to be precise | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1560 if (klass == env->String_klass() && |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1561 adr->is_AddP() && off != Type::OffsetBot) { |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1562 // For constant Strings treat the final fields as compile time constants. |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1563 Node* base = adr->in(AddPNode::Base); |
1766
02f0a9b6f654
6969586: OptimizeStringConcat: SIGSEGV in LoadNode::Value()
never
parents:
1609
diff
changeset
|
1564 const TypeOopPtr* t = phase->type(base)->isa_oopptr(); |
02f0a9b6f654
6969586: OptimizeStringConcat: SIGSEGV in LoadNode::Value()
never
parents:
1609
diff
changeset
|
1565 if (t != NULL && t->singleton()) { |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1566 ciField* field = env->String_klass()->get_field_by_offset(off, false); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1567 if (field != NULL && field->is_final()) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1568 ciObject* string = t->const_oop(); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1569 ciConstant constant = string->as_instance()->field_value(field); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1570 if (constant.basic_type() == T_INT) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1571 return TypeInt::make(constant.as_int()); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1572 } else if (constant.basic_type() == T_ARRAY) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1573 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2320
diff
changeset
|
1574 return TypeNarrowOop::make_from_constant(constant.as_object(), true); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1575 } else { |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2320
diff
changeset
|
1576 return TypeOopPtr::make_from_constant(constant.as_object(), true); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1577 } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1578 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1579 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1580 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1581 } |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1582 // Optimizations for constant objects |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1583 ciObject* const_oop = tinst->const_oop(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1584 if (const_oop != NULL) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1585 // For constant CallSites treat the target field as a compile time constant. |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1586 if (const_oop->is_call_site()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1587 ciCallSite* call_site = const_oop->as_call_site(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1588 ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1589 if (field != NULL && field->is_call_site_target()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1590 ciMethodHandle* target = call_site->get_target(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1591 if (target != NULL) { // just in case |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1592 ciConstant constant(T_OBJECT, target); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1593 const Type* t; |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1594 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1595 t = TypeNarrowOop::make_from_constant(constant.as_object(), true); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1596 } else { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1597 t = TypeOopPtr::make_from_constant(constant.as_object(), true); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1598 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1599 // Add a dependence for invalidation of the optimization. |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1600 if (!call_site->is_constant_call_site()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1601 C->dependencies()->assert_call_site_target_value(call_site, target); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1602 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1603 return t; |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1604 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1605 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1606 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1607 } |
0 | 1608 } else if (tp->base() == Type::KlassPtr) { |
1609 assert( off != Type::OffsetBot || | |
1610 // arrays can be cast to Objects | |
1611 tp->is_klassptr()->klass()->is_java_lang_Object() || | |
1612 // also allow array-loading from the primary supertype | |
1613 // array during subtype checks | |
1614 Opcode() == Op_LoadKlass, | |
1615 "Field accesses must be precise" ); | |
1616 // For klass/static loads, we expect the _type to be precise | |
1617 } | |
1618 | |
1619 const TypeKlassPtr *tkls = tp->isa_klassptr(); | |
1620 if (tkls != NULL && !StressReflectiveCode) { | |
1621 ciKlass* klass = tkls->klass(); | |
1622 if (klass->is_loaded() && tkls->klass_is_exact()) { | |
1623 // We are loading a field from a Klass metaobject whose identity | |
1624 // is known at compile time (the type is "exact" or "precise"). | |
1625 // Check for fields we know are maintained as constants by the VM. | |
1626 if (tkls->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1627 // The field is Klass::_super_check_offset. Return its (constant) value. | |
1628 // (Folds up type checking code.) | |
1629 assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset"); | |
1630 return TypeInt::make(klass->super_check_offset()); | |
1631 } | |
1632 // Compute index into primary_supers array | |
1633 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); | |
1634 // Check for overflowing; use unsigned compare to handle the negative case. | |
1635 if( depth < ciKlass::primary_super_limit() ) { | |
1636 // The field is an element of Klass::_primary_supers. Return its (constant) value. | |
1637 // (Folds up type checking code.) | |
1638 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); | |
1639 ciKlass *ss = klass->super_of_depth(depth); | |
1640 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; | |
1641 } | |
1642 const Type* aift = load_array_final_field(tkls, klass); | |
1643 if (aift != NULL) return aift; | |
1644 if (tkls->offset() == in_bytes(arrayKlass::component_mirror_offset()) + (int)sizeof(oopDesc) | |
1645 && klass->is_array_klass()) { | |
1646 // The field is arrayKlass::_component_mirror. Return its (constant) value. | |
1647 // (Folds up aClassConstant.getComponentType, common in Arrays.copyOf.) | |
1648 assert(Opcode() == Op_LoadP, "must load an oop from _component_mirror"); | |
1649 return TypeInstPtr::make(klass->as_array_klass()->component_mirror()); | |
1650 } | |
1651 if (tkls->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1652 // The field is Klass::_java_mirror. Return its (constant) value. | |
1653 // (Folds up the 2nd indirection in anObjConstant.getClass().) | |
1654 assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror"); | |
1655 return TypeInstPtr::make(klass->java_mirror()); | |
1656 } | |
1657 } | |
1658 | |
1659 // We can still check if we are loading from the primary_supers array at a | |
1660 // shallow enough depth. Even though the klass is not exact, entries less | |
1661 // than or equal to its super depth are correct. | |
1662 if (klass->is_loaded() ) { | |
1663 ciType *inner = klass->klass(); | |
1664 while( inner->is_obj_array_klass() ) | |
1665 inner = inner->as_obj_array_klass()->base_element_type(); | |
1666 if( inner->is_instance_klass() && | |
1667 !inner->as_instance_klass()->flags().is_interface() ) { | |
1668 // Compute index into primary_supers array | |
1669 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); | |
1670 // Check for overflowing; use unsigned compare to handle the negative case. | |
1671 if( depth < ciKlass::primary_super_limit() && | |
1672 depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case | |
1673 // The field is an element of Klass::_primary_supers. Return its (constant) value. | |
1674 // (Folds up type checking code.) | |
1675 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); | |
1676 ciKlass *ss = klass->super_of_depth(depth); | |
1677 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; | |
1678 } | |
1679 } | |
1680 } | |
1681 | |
1682 // If the type is enough to determine that the thing is not an array, | |
1683 // we can give the layout_helper a positive interval type. | |
1684 // This will help short-circuit some reflective code. | |
1685 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc) | |
1686 && !klass->is_array_klass() // not directly typed as an array | |
1687 && !klass->is_interface() // specifically not Serializable & Cloneable | |
1688 && !klass->is_java_lang_Object() // not the supertype of all T[] | |
1689 ) { | |
1690 // Note: When interfaces are reliable, we can narrow the interface | |
1691 // test to (klass != Serializable && klass != Cloneable). | |
1692 assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); | |
1693 jint min_size = Klass::instance_layout_helper(oopDesc::header_size(), false); | |
1694 // The key property of this type is that it folds up tests | |
1695 // for array-ness, since it proves that the layout_helper is positive. | |
1696 // Thus, a generic value like the basic object layout helper works fine. | |
1697 return TypeInt::make(min_size, max_jint, Type::WidenMin); | |
1698 } | |
1699 } | |
1700 | |
1701 // If we are loading from a freshly-allocated object, produce a zero, | |
1702 // if the load is provably beyond the header of the object. | |
1703 // (Also allow a variable load from a fresh array to produce zero.) | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1704 const TypeOopPtr *tinst = tp->isa_oopptr(); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1705 bool is_instance = (tinst != NULL) && tinst->is_known_instance_field(); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1706 if (ReduceFieldZeroing || is_instance) { |
0 | 1707 Node* value = can_see_stored_value(mem,phase); |
1708 if (value != NULL && value->is_Con()) | |
1709 return value->bottom_type(); | |
1710 } | |
1711 | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1712 if (is_instance) { |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1713 // If we have an instance type and our memory input is the |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1714 // programs's initial memory state, there is no matching store, |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1715 // so just return a zero of the appropriate type |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1716 Node *mem = in(MemNode::Memory); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1717 if (mem->is_Parm() && mem->in(0)->is_Start()) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1718 assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1719 return Type::get_zero_type(_type->basic_type()); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1720 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1721 } |
0 | 1722 return _type; |
1723 } | |
1724 | |
1725 //------------------------------match_edge------------------------------------- | |
1726 // Do we Match on this edge index or not? Match only the address. | |
1727 uint LoadNode::match_edge(uint idx) const { | |
1728 return idx == MemNode::Address; | |
1729 } | |
1730 | |
1731 //--------------------------LoadBNode::Ideal-------------------------------------- | |
1732 // | |
1733 // If the previous store is to the same address as this load, | |
1734 // and the value stored was larger than a byte, replace this load | |
1735 // with the value stored truncated to a byte. If no truncation is | |
1736 // needed, the replacement is done in LoadNode::Identity(). | |
1737 // | |
1738 Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1739 Node* mem = in(MemNode::Memory); | |
1740 Node* value = can_see_stored_value(mem,phase); | |
1741 if( value && !phase->type(value)->higher_equal( _type ) ) { | |
1742 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(24)) ); | |
1743 return new (phase->C, 3) RShiftINode(result, phase->intcon(24)); | |
1744 } | |
1745 // Identity call will handle the case where truncation is not needed. | |
1746 return LoadNode::Ideal(phase, can_reshape); | |
1747 } | |
1748 | |
624 | 1749 //--------------------------LoadUBNode::Ideal------------------------------------- |
1750 // | |
1751 // If the previous store is to the same address as this load, | |
1752 // and the value stored was larger than a byte, replace this load | |
1753 // with the value stored truncated to a byte. If no truncation is | |
1754 // needed, the replacement is done in LoadNode::Identity(). | |
1755 // | |
1756 Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) { | |
1757 Node* mem = in(MemNode::Memory); | |
1758 Node* value = can_see_stored_value(mem, phase); | |
1759 if (value && !phase->type(value)->higher_equal(_type)) | |
1760 return new (phase->C, 3) AndINode(value, phase->intcon(0xFF)); | |
1761 // Identity call will handle the case where truncation is not needed. | |
1762 return LoadNode::Ideal(phase, can_reshape); | |
1763 } | |
1764 | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1765 //--------------------------LoadUSNode::Ideal------------------------------------- |
0 | 1766 // |
1767 // If the previous store is to the same address as this load, | |
1768 // and the value stored was larger than a char, replace this load | |
1769 // with the value stored truncated to a char. If no truncation is | |
1770 // needed, the replacement is done in LoadNode::Identity(). | |
1771 // | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1772 Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
0 | 1773 Node* mem = in(MemNode::Memory); |
1774 Node* value = can_see_stored_value(mem,phase); | |
1775 if( value && !phase->type(value)->higher_equal( _type ) ) | |
1776 return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF)); | |
1777 // Identity call will handle the case where truncation is not needed. | |
1778 return LoadNode::Ideal(phase, can_reshape); | |
1779 } | |
1780 | |
1781 //--------------------------LoadSNode::Ideal-------------------------------------- | |
1782 // | |
1783 // If the previous store is to the same address as this load, | |
1784 // and the value stored was larger than a short, replace this load | |
1785 // with the value stored truncated to a short. If no truncation is | |
1786 // needed, the replacement is done in LoadNode::Identity(). | |
1787 // | |
1788 Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1789 Node* mem = in(MemNode::Memory); | |
1790 Node* value = can_see_stored_value(mem,phase); | |
1791 if( value && !phase->type(value)->higher_equal( _type ) ) { | |
1792 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(16)) ); | |
1793 return new (phase->C, 3) RShiftINode(result, phase->intcon(16)); | |
1794 } | |
1795 // Identity call will handle the case where truncation is not needed. | |
1796 return LoadNode::Ideal(phase, can_reshape); | |
1797 } | |
1798 | |
1799 //============================================================================= | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1800 //----------------------------LoadKlassNode::make------------------------------ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1801 // Polymorphic factory method: |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1802 Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1803 Compile* C = gvn.C; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1804 Node *ctl = NULL; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1805 // sanity check the alias category against the created node type |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1806 const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr(); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1807 assert(adr_type != NULL, "expecting TypeOopPtr"); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1808 #ifdef _LP64 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1809 if (adr_type->is_ptr_to_narrowoop()) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
1810 Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
1811 return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr()); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1812 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1813 #endif |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1814 assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1815 return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1816 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1817 |
0 | 1818 //------------------------------Value------------------------------------------ |
1819 const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1820 return klass_value_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1821 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1822 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1823 const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const { |
0 | 1824 // Either input is TOP ==> the result is TOP |
1825 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
1826 if (t1 == Type::TOP) return Type::TOP; | |
1827 Node *adr = in(MemNode::Address); | |
1828 const Type *t2 = phase->type( adr ); | |
1829 if (t2 == Type::TOP) return Type::TOP; | |
1830 const TypePtr *tp = t2->is_ptr(); | |
1831 if (TypePtr::above_centerline(tp->ptr()) || | |
1832 tp->ptr() == TypePtr::Null) return Type::TOP; | |
1833 | |
1834 // Return a more precise klass, if possible | |
1835 const TypeInstPtr *tinst = tp->isa_instptr(); | |
1836 if (tinst != NULL) { | |
1837 ciInstanceKlass* ik = tinst->klass()->as_instance_klass(); | |
1838 int offset = tinst->offset(); | |
1839 if (ik == phase->C->env()->Class_klass() | |
1840 && (offset == java_lang_Class::klass_offset_in_bytes() || | |
1841 offset == java_lang_Class::array_klass_offset_in_bytes())) { | |
1842 // We are loading a special hidden field from a Class mirror object, | |
1843 // the field which points to the VM's Klass metaobject. | |
1844 ciType* t = tinst->java_mirror_type(); | |
1845 // java_mirror_type returns non-null for compile-time Class constants. | |
1846 if (t != NULL) { | |
1847 // constant oop => constant klass | |
1848 if (offset == java_lang_Class::array_klass_offset_in_bytes()) { | |
1849 return TypeKlassPtr::make(ciArrayKlass::make(t)); | |
1850 } | |
1851 if (!t->is_klass()) { | |
1852 // a primitive Class (e.g., int.class) has NULL for a klass field | |
1853 return TypePtr::NULL_PTR; | |
1854 } | |
1855 // (Folds up the 1st indirection in aClassConstant.getModifiers().) | |
1856 return TypeKlassPtr::make(t->as_klass()); | |
1857 } | |
1858 // non-constant mirror, so we can't tell what's going on | |
1859 } | |
1860 if( !ik->is_loaded() ) | |
1861 return _type; // Bail out if not loaded | |
1862 if (offset == oopDesc::klass_offset_in_bytes()) { | |
1863 if (tinst->klass_is_exact()) { | |
1864 return TypeKlassPtr::make(ik); | |
1865 } | |
1866 // See if we can become precise: no subklasses and no interface | |
1867 // (Note: We need to support verified interfaces.) | |
1868 if (!ik->is_interface() && !ik->has_subklass()) { | |
1869 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1870 // Add a dependence; if any subclass added we need to recompile | |
1871 if (!ik->is_final()) { | |
1872 // %%% should use stronger assert_unique_concrete_subtype instead | |
1873 phase->C->dependencies()->assert_leaf_type(ik); | |
1874 } | |
1875 // Return precise klass | |
1876 return TypeKlassPtr::make(ik); | |
1877 } | |
1878 | |
1879 // Return root of possible klass | |
1880 return TypeKlassPtr::make(TypePtr::NotNull, ik, 0/*offset*/); | |
1881 } | |
1882 } | |
1883 | |
1884 // Check for loading klass from an array | |
1885 const TypeAryPtr *tary = tp->isa_aryptr(); | |
1886 if( tary != NULL ) { | |
1887 ciKlass *tary_klass = tary->klass(); | |
1888 if (tary_klass != NULL // can be NULL when at BOTTOM or TOP | |
1889 && tary->offset() == oopDesc::klass_offset_in_bytes()) { | |
1890 if (tary->klass_is_exact()) { | |
1891 return TypeKlassPtr::make(tary_klass); | |
1892 } | |
1893 ciArrayKlass *ak = tary->klass()->as_array_klass(); | |
1894 // If the klass is an object array, we defer the question to the | |
1895 // array component klass. | |
1896 if( ak->is_obj_array_klass() ) { | |
1897 assert( ak->is_loaded(), "" ); | |
1898 ciKlass *base_k = ak->as_obj_array_klass()->base_element_klass(); | |
1899 if( base_k->is_loaded() && base_k->is_instance_klass() ) { | |
1900 ciInstanceKlass* ik = base_k->as_instance_klass(); | |
1901 // See if we can become precise: no subklasses and no interface | |
1902 if (!ik->is_interface() && !ik->has_subklass()) { | |
1903 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1904 // Add a dependence; if any subclass added we need to recompile | |
1905 if (!ik->is_final()) { | |
1906 phase->C->dependencies()->assert_leaf_type(ik); | |
1907 } | |
1908 // Return precise array klass | |
1909 return TypeKlassPtr::make(ak); | |
1910 } | |
1911 } | |
1912 return TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); | |
1913 } else { // Found a type-array? | |
1914 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1915 assert( ak->is_type_array_klass(), "" ); | |
1916 return TypeKlassPtr::make(ak); // These are always precise | |
1917 } | |
1918 } | |
1919 } | |
1920 | |
1921 // Check for loading klass from an array klass | |
1922 const TypeKlassPtr *tkls = tp->isa_klassptr(); | |
1923 if (tkls != NULL && !StressReflectiveCode) { | |
1924 ciKlass* klass = tkls->klass(); | |
1925 if( !klass->is_loaded() ) | |
1926 return _type; // Bail out if not loaded | |
1927 if( klass->is_obj_array_klass() && | |
1928 (uint)tkls->offset() == objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)) { | |
1929 ciKlass* elem = klass->as_obj_array_klass()->element_klass(); | |
1930 // // Always returning precise element type is incorrect, | |
1931 // // e.g., element type could be object and array may contain strings | |
1932 // return TypeKlassPtr::make(TypePtr::Constant, elem, 0); | |
1933 | |
1934 // The array's TypeKlassPtr was declared 'precise' or 'not precise' | |
1935 // according to the element type's subclassing. | |
1936 return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/); | |
1937 } | |
1938 if( klass->is_instance_klass() && tkls->klass_is_exact() && | |
1939 (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) { | |
1940 ciKlass* sup = klass->as_instance_klass()->super(); | |
1941 // The field is Klass::_super. Return its (constant) value. | |
1942 // (Folds up the 2nd indirection in aClassConstant.getSuperClass().) | |
1943 return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR; | |
1944 } | |
1945 } | |
1946 | |
1947 // Bailout case | |
1948 return LoadNode::Value(phase); | |
1949 } | |
1950 | |
1951 //------------------------------Identity--------------------------------------- | |
1952 // To clean up reflective code, simplify k.java_mirror.as_klass to plain k. | |
1953 // Also feed through the klass in Allocate(...klass...)._klass. | |
1954 Node* LoadKlassNode::Identity( PhaseTransform *phase ) { | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1955 return klass_identity_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1956 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1957 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1958 Node* LoadNode::klass_identity_common(PhaseTransform *phase ) { |
0 | 1959 Node* x = LoadNode::Identity(phase); |
1960 if (x != this) return x; | |
1961 | |
1962 // Take apart the address into an oop and and offset. | |
1963 // Return 'this' if we cannot. | |
1964 Node* adr = in(MemNode::Address); | |
1965 intptr_t offset = 0; | |
1966 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
1967 if (base == NULL) return this; | |
1968 const TypeOopPtr* toop = phase->type(adr)->isa_oopptr(); | |
1969 if (toop == NULL) return this; | |
1970 | |
1971 // We can fetch the klass directly through an AllocateNode. | |
1972 // This works even if the klass is not constant (clone or newArray). | |
1973 if (offset == oopDesc::klass_offset_in_bytes()) { | |
1974 Node* allocated_klass = AllocateNode::Ideal_klass(base, phase); | |
1975 if (allocated_klass != NULL) { | |
1976 return allocated_klass; | |
1977 } | |
1978 } | |
1979 | |
1980 // Simplify k.java_mirror.as_klass to plain k, where k is a klassOop. | |
1981 // Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass. | |
1982 // See inline_native_Class_query for occurrences of these patterns. | |
1983 // Java Example: x.getClass().isAssignableFrom(y) | |
1984 // Java Example: Array.newInstance(x.getClass().getComponentType(), n) | |
1985 // | |
1986 // This improves reflective code, often making the Class | |
1987 // mirror go completely dead. (Current exception: Class | |
1988 // mirrors may appear in debug info, but we could clean them out by | |
1989 // introducing a new debug info operator for klassOop.java_mirror). | |
1990 if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass() | |
1991 && (offset == java_lang_Class::klass_offset_in_bytes() || | |
1992 offset == java_lang_Class::array_klass_offset_in_bytes())) { | |
1993 // We are loading a special hidden field from a Class mirror, | |
1994 // the field which points to its Klass or arrayKlass metaobject. | |
1995 if (base->is_Load()) { | |
1996 Node* adr2 = base->in(MemNode::Address); | |
1997 const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr(); | |
1998 if (tkls != NULL && !tkls->empty() | |
1999 && (tkls->klass()->is_instance_klass() || | |
2000 tkls->klass()->is_array_klass()) | |
2001 && adr2->is_AddP() | |
2002 ) { | |
2003 int mirror_field = Klass::java_mirror_offset_in_bytes(); | |
2004 if (offset == java_lang_Class::array_klass_offset_in_bytes()) { | |
2005 mirror_field = in_bytes(arrayKlass::component_mirror_offset()); | |
2006 } | |
2007 if (tkls->offset() == mirror_field + (int)sizeof(oopDesc)) { | |
2008 return adr2->in(AddPNode::Base); | |
2009 } | |
2010 } | |
2011 } | |
2012 } | |
2013 | |
2014 return this; | |
2015 } | |
2016 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2017 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2018 //------------------------------Value------------------------------------------ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2019 const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2020 const Type *t = klass_value_common(phase); |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2021 if (t == Type::TOP) |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2022 return t; |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2023 |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2024 return t->make_narrowoop(); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2025 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2026 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2027 //------------------------------Identity--------------------------------------- |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2028 // To clean up reflective code, simplify k.java_mirror.as_klass to narrow k. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2029 // Also feed through the klass in Allocate(...klass...)._klass. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2030 Node* LoadNKlassNode::Identity( PhaseTransform *phase ) { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2031 Node *x = klass_identity_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2032 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2033 const Type *t = phase->type( x ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2034 if( t == Type::TOP ) return x; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2035 if( t->isa_narrowoop()) return x; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2036 |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2037 return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop())); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2038 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2039 |
0 | 2040 //------------------------------Value----------------------------------------- |
2041 const Type *LoadRangeNode::Value( PhaseTransform *phase ) const { | |
2042 // Either input is TOP ==> the result is TOP | |
2043 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
2044 if( t1 == Type::TOP ) return Type::TOP; | |
2045 Node *adr = in(MemNode::Address); | |
2046 const Type *t2 = phase->type( adr ); | |
2047 if( t2 == Type::TOP ) return Type::TOP; | |
2048 const TypePtr *tp = t2->is_ptr(); | |
2049 if (TypePtr::above_centerline(tp->ptr())) return Type::TOP; | |
2050 const TypeAryPtr *tap = tp->isa_aryptr(); | |
2051 if( !tap ) return _type; | |
2052 return tap->size(); | |
2053 } | |
2054 | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2055 //-------------------------------Ideal--------------------------------------- |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2056 // Feed through the length in AllocateArray(...length...)._length. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2057 Node *LoadRangeNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2058 Node* p = MemNode::Ideal_common(phase, can_reshape); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2059 if (p) return (p == NodeSentinel) ? NULL : p; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2060 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2061 // Take apart the address into an oop and and offset. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2062 // Return 'this' if we cannot. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2063 Node* adr = in(MemNode::Address); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2064 intptr_t offset = 0; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2065 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2066 if (base == NULL) return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2067 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2068 if (tary == NULL) return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2069 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2070 // We can fetch the length directly through an AllocateArrayNode. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2071 // This works even if the length is not constant (clone or newArray). |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2072 if (offset == arrayOopDesc::length_offset_in_bytes()) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2073 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2074 if (alloc != NULL) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2075 Node* allocated_length = alloc->Ideal_length(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2076 Node* len = alloc->make_ideal_length(tary, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2077 if (allocated_length != len) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2078 // New CastII improves on this. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2079 return len; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2080 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2081 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2082 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2083 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2084 return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2085 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2086 |
0 | 2087 //------------------------------Identity--------------------------------------- |
2088 // Feed through the length in AllocateArray(...length...)._length. | |
2089 Node* LoadRangeNode::Identity( PhaseTransform *phase ) { | |
2090 Node* x = LoadINode::Identity(phase); | |
2091 if (x != this) return x; | |
2092 | |
2093 // Take apart the address into an oop and and offset. | |
2094 // Return 'this' if we cannot. | |
2095 Node* adr = in(MemNode::Address); | |
2096 intptr_t offset = 0; | |
2097 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
2098 if (base == NULL) return this; | |
2099 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr(); | |
2100 if (tary == NULL) return this; | |
2101 | |
2102 // We can fetch the length directly through an AllocateArrayNode. | |
2103 // This works even if the length is not constant (clone or newArray). | |
2104 if (offset == arrayOopDesc::length_offset_in_bytes()) { | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2105 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2106 if (alloc != NULL) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2107 Node* allocated_length = alloc->Ideal_length(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2108 // Do not allow make_ideal_length to allocate a CastII node. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2109 Node* len = alloc->make_ideal_length(tary, phase, false); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2110 if (allocated_length == len) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2111 // Return allocated_length only if it would not be improved by a CastII. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2112 return allocated_length; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2113 } |
0 | 2114 } |
2115 } | |
2116 | |
2117 return this; | |
2118 | |
2119 } | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2120 |
0 | 2121 //============================================================================= |
2122 //---------------------------StoreNode::make----------------------------------- | |
2123 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2124 StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2125 Compile* C = gvn.C; |
1609 | 2126 assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw || |
2127 ctl != NULL, "raw memory operations should have control edge"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2128 |
0 | 2129 switch (bt) { |
2130 case T_BOOLEAN: | |
2131 case T_BYTE: return new (C, 4) StoreBNode(ctl, mem, adr, adr_type, val); | |
2132 case T_INT: return new (C, 4) StoreINode(ctl, mem, adr, adr_type, val); | |
2133 case T_CHAR: | |
2134 case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val); | |
2135 case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val); | |
2136 case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val); | |
2137 case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val); | |
2138 case T_ADDRESS: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2139 case T_OBJECT: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2140 #ifdef _LP64 |
163 | 2141 if (adr->bottom_type()->is_ptr_to_narrowoop() || |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2142 (UseCompressedOops && val->bottom_type()->isa_klassptr() && |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2143 adr->bottom_type()->isa_rawptr())) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2144 val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2145 return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2146 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2147 #endif |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2148 { |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2149 return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2150 } |
0 | 2151 } |
2152 ShouldNotReachHere(); | |
2153 return (StoreNode*)NULL; | |
2154 } | |
2155 | |
2156 StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) { | |
2157 bool require_atomic = true; | |
2158 return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic); | |
2159 } | |
2160 | |
2161 | |
2162 //--------------------------bottom_type---------------------------------------- | |
2163 const Type *StoreNode::bottom_type() const { | |
2164 return Type::MEMORY; | |
2165 } | |
2166 | |
2167 //------------------------------hash------------------------------------------- | |
2168 uint StoreNode::hash() const { | |
2169 // unroll addition of interesting fields | |
2170 //return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address) + (uintptr_t)in(ValueIn); | |
2171 | |
2172 // Since they are not commoned, do not hash them: | |
2173 return NO_HASH; | |
2174 } | |
2175 | |
2176 //------------------------------Ideal------------------------------------------ | |
2177 // Change back-to-back Store(, p, x) -> Store(m, p, y) to Store(m, p, x). | |
2178 // When a store immediately follows a relevant allocation/initialization, | |
2179 // try to capture it into the initialization, or hoist it above. | |
2180 Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
2181 Node* p = MemNode::Ideal_common(phase, can_reshape); | |
2182 if (p) return (p == NodeSentinel) ? NULL : p; | |
2183 | |
2184 Node* mem = in(MemNode::Memory); | |
2185 Node* address = in(MemNode::Address); | |
2186 | |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2187 // Back-to-back stores to same address? Fold em up. Generally |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2188 // unsafe if I have intervening uses... Also disallowed for StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2189 // since they must follow each StoreP operation. Redundant StoreCMs |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2190 // are eliminated just before matching in final_graph_reshape. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2191 if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address) && |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2192 mem->Opcode() != Op_StoreCM) { |
0 | 2193 // Looking at a dead closed cycle of memory? |
2194 assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal"); | |
2195 | |
2196 assert(Opcode() == mem->Opcode() || | |
2197 phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw, | |
2198 "no mismatched stores, except on raw memory"); | |
2199 | |
2200 if (mem->outcnt() == 1 && // check for intervening uses | |
2201 mem->as_Store()->memory_size() <= this->memory_size()) { | |
2202 // If anybody other than 'this' uses 'mem', we cannot fold 'mem' away. | |
2203 // For example, 'mem' might be the final state at a conditional return. | |
2204 // Or, 'mem' might be used by some node which is live at the same time | |
2205 // 'this' is live, which might be unschedulable. So, require exactly | |
2206 // ONE user, the 'this' store, until such time as we clone 'mem' for | |
2207 // each of 'mem's uses (thus making the exactly-1-user-rule hold true). | |
2208 if (can_reshape) { // (%%% is this an anachronism?) | |
2209 set_req_X(MemNode::Memory, mem->in(MemNode::Memory), | |
2210 phase->is_IterGVN()); | |
2211 } else { | |
2212 // It's OK to do this in the parser, since DU info is always accurate, | |
2213 // and the parser always refers to nodes via SafePointNode maps. | |
2214 set_req(MemNode::Memory, mem->in(MemNode::Memory)); | |
2215 } | |
2216 return this; | |
2217 } | |
2218 } | |
2219 | |
2220 // Capture an unaliased, unconditional, simple store into an initializer. | |
2221 // Or, if it is independent of the allocation, hoist it above the allocation. | |
2222 if (ReduceFieldZeroing && /*can_reshape &&*/ | |
2223 mem->is_Proj() && mem->in(0)->is_Initialize()) { | |
2224 InitializeNode* init = mem->in(0)->as_Initialize(); | |
2225 intptr_t offset = init->can_capture_store(this, phase); | |
2226 if (offset > 0) { | |
2227 Node* moved = init->capture_store(this, offset, phase); | |
2228 // If the InitializeNode captured me, it made a raw copy of me, | |
2229 // and I need to disappear. | |
2230 if (moved != NULL) { | |
2231 // %%% hack to ensure that Ideal returns a new node: | |
2232 mem = MergeMemNode::make(phase->C, mem); | |
2233 return mem; // fold me away | |
2234 } | |
2235 } | |
2236 } | |
2237 | |
2238 return NULL; // No further progress | |
2239 } | |
2240 | |
2241 //------------------------------Value----------------------------------------- | |
2242 const Type *StoreNode::Value( PhaseTransform *phase ) const { | |
2243 // Either input is TOP ==> the result is TOP | |
2244 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
2245 if( t1 == Type::TOP ) return Type::TOP; | |
2246 const Type *t2 = phase->type( in(MemNode::Address) ); | |
2247 if( t2 == Type::TOP ) return Type::TOP; | |
2248 const Type *t3 = phase->type( in(MemNode::ValueIn) ); | |
2249 if( t3 == Type::TOP ) return Type::TOP; | |
2250 return Type::MEMORY; | |
2251 } | |
2252 | |
2253 //------------------------------Identity--------------------------------------- | |
2254 // Remove redundant stores: | |
2255 // Store(m, p, Load(m, p)) changes to m. | |
2256 // Store(, p, x) -> Store(m, p, x) changes to Store(m, p, x). | |
2257 Node *StoreNode::Identity( PhaseTransform *phase ) { | |
2258 Node* mem = in(MemNode::Memory); | |
2259 Node* adr = in(MemNode::Address); | |
2260 Node* val = in(MemNode::ValueIn); | |
2261 | |
2262 // Load then Store? Then the Store is useless | |
2263 if (val->is_Load() && | |
2264 phase->eqv_uncast( val->in(MemNode::Address), adr ) && | |
2265 phase->eqv_uncast( val->in(MemNode::Memory ), mem ) && | |
2266 val->as_Load()->store_Opcode() == Opcode()) { | |
2267 return mem; | |
2268 } | |
2269 | |
2270 // Two stores in a row of the same value? | |
2271 if (mem->is_Store() && | |
2272 phase->eqv_uncast( mem->in(MemNode::Address), adr ) && | |
2273 phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) && | |
2274 mem->Opcode() == Opcode()) { | |
2275 return mem; | |
2276 } | |
2277 | |
2278 // Store of zero anywhere into a freshly-allocated object? | |
2279 // Then the store is useless. | |
2280 // (It must already have been captured by the InitializeNode.) | |
2281 if (ReduceFieldZeroing && phase->type(val)->is_zero_type()) { | |
2282 // a newly allocated object is already all-zeroes everywhere | |
2283 if (mem->is_Proj() && mem->in(0)->is_Allocate()) { | |
2284 return mem; | |
2285 } | |
2286 | |
2287 // the store may also apply to zero-bits in an earlier object | |
2288 Node* prev_mem = find_previous_store(phase); | |
2289 // Steps (a), (b): Walk past independent stores to find an exact match. | |
2290 if (prev_mem != NULL) { | |
2291 Node* prev_val = can_see_stored_value(prev_mem, phase); | |
2292 if (prev_val != NULL && phase->eqv(prev_val, val)) { | |
2293 // prev_val and val might differ by a cast; it would be good | |
2294 // to keep the more informative of the two. | |
2295 return mem; | |
2296 } | |
2297 } | |
2298 } | |
2299 | |
2300 return this; | |
2301 } | |
2302 | |
2303 //------------------------------match_edge------------------------------------- | |
2304 // Do we Match on this edge index or not? Match only memory & value | |
2305 uint StoreNode::match_edge(uint idx) const { | |
2306 return idx == MemNode::Address || idx == MemNode::ValueIn; | |
2307 } | |
2308 | |
2309 //------------------------------cmp-------------------------------------------- | |
2310 // Do not common stores up together. They generally have to be split | |
2311 // back up anyways, so do not bother. | |
2312 uint StoreNode::cmp( const Node &n ) const { | |
2313 return (&n == this); // Always fail except on self | |
2314 } | |
2315 | |
2316 //------------------------------Ideal_masked_input----------------------------- | |
2317 // Check for a useless mask before a partial-word store | |
2318 // (StoreB ... (AndI valIn conIa) ) | |
2319 // If (conIa & mask == mask) this simplifies to | |
2320 // (StoreB ... (valIn) ) | |
2321 Node *StoreNode::Ideal_masked_input(PhaseGVN *phase, uint mask) { | |
2322 Node *val = in(MemNode::ValueIn); | |
2323 if( val->Opcode() == Op_AndI ) { | |
2324 const TypeInt *t = phase->type( val->in(2) )->isa_int(); | |
2325 if( t && t->is_con() && (t->get_con() & mask) == mask ) { | |
2326 set_req(MemNode::ValueIn, val->in(1)); | |
2327 return this; | |
2328 } | |
2329 } | |
2330 return NULL; | |
2331 } | |
2332 | |
2333 | |
2334 //------------------------------Ideal_sign_extended_input---------------------- | |
2335 // Check for useless sign-extension before a partial-word store | |
2336 // (StoreB ... (RShiftI _ (LShiftI _ valIn conIL ) conIR) ) | |
2337 // If (conIL == conIR && conIR <= num_bits) this simplifies to | |
2338 // (StoreB ... (valIn) ) | |
2339 Node *StoreNode::Ideal_sign_extended_input(PhaseGVN *phase, int num_bits) { | |
2340 Node *val = in(MemNode::ValueIn); | |
2341 if( val->Opcode() == Op_RShiftI ) { | |
2342 const TypeInt *t = phase->type( val->in(2) )->isa_int(); | |
2343 if( t && t->is_con() && (t->get_con() <= num_bits) ) { | |
2344 Node *shl = val->in(1); | |
2345 if( shl->Opcode() == Op_LShiftI ) { | |
2346 const TypeInt *t2 = phase->type( shl->in(2) )->isa_int(); | |
2347 if( t2 && t2->is_con() && (t2->get_con() == t->get_con()) ) { | |
2348 set_req(MemNode::ValueIn, shl->in(1)); | |
2349 return this; | |
2350 } | |
2351 } | |
2352 } | |
2353 } | |
2354 return NULL; | |
2355 } | |
2356 | |
2357 //------------------------------value_never_loaded----------------------------------- | |
2358 // Determine whether there are any possible loads of the value stored. | |
2359 // For simplicity, we actually check if there are any loads from the | |
2360 // address stored to, not just for loads of the value stored by this node. | |
2361 // | |
2362 bool StoreNode::value_never_loaded( PhaseTransform *phase) const { | |
2363 Node *adr = in(Address); | |
2364 const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr(); | |
2365 if (adr_oop == NULL) | |
2366 return false; | |
223 | 2367 if (!adr_oop->is_known_instance_field()) |
0 | 2368 return false; // if not a distinct instance, there may be aliases of the address |
2369 for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) { | |
2370 Node *use = adr->fast_out(i); | |
2371 int opc = use->Opcode(); | |
2372 if (use->is_Load() || use->is_LoadStore()) { | |
2373 return false; | |
2374 } | |
2375 } | |
2376 return true; | |
2377 } | |
2378 | |
2379 //============================================================================= | |
2380 //------------------------------Ideal------------------------------------------ | |
2381 // If the store is from an AND mask that leaves the low bits untouched, then | |
2382 // we can skip the AND operation. If the store is from a sign-extension | |
2383 // (a left shift, then right shift) we can skip both. | |
2384 Node *StoreBNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2385 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFF); | |
2386 if( progress != NULL ) return progress; | |
2387 | |
2388 progress = StoreNode::Ideal_sign_extended_input(phase, 24); | |
2389 if( progress != NULL ) return progress; | |
2390 | |
2391 // Finally check the default case | |
2392 return StoreNode::Ideal(phase, can_reshape); | |
2393 } | |
2394 | |
2395 //============================================================================= | |
2396 //------------------------------Ideal------------------------------------------ | |
2397 // If the store is from an AND mask that leaves the low bits untouched, then | |
2398 // we can skip the AND operation | |
2399 Node *StoreCNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2400 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFFFF); | |
2401 if( progress != NULL ) return progress; | |
2402 | |
2403 progress = StoreNode::Ideal_sign_extended_input(phase, 16); | |
2404 if( progress != NULL ) return progress; | |
2405 | |
2406 // Finally check the default case | |
2407 return StoreNode::Ideal(phase, can_reshape); | |
2408 } | |
2409 | |
2410 //============================================================================= | |
2411 //------------------------------Identity--------------------------------------- | |
2412 Node *StoreCMNode::Identity( PhaseTransform *phase ) { | |
2413 // No need to card mark when storing a null ptr | |
2414 Node* my_store = in(MemNode::OopStore); | |
2415 if (my_store->is_Store()) { | |
2416 const Type *t1 = phase->type( my_store->in(MemNode::ValueIn) ); | |
2417 if( t1 == TypePtr::NULL_PTR ) { | |
2418 return in(MemNode::Memory); | |
2419 } | |
2420 } | |
2421 return this; | |
2422 } | |
2423 | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2424 //============================================================================= |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2425 //------------------------------Ideal--------------------------------------- |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2426 Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){ |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2427 Node* progress = StoreNode::Ideal(phase, can_reshape); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2428 if (progress != NULL) return progress; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2429 |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2430 Node* my_store = in(MemNode::OopStore); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2431 if (my_store->is_MergeMem()) { |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2432 Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx()); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2433 set_req(MemNode::OopStore, mem); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2434 return this; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2435 } |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2436 |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2437 return NULL; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2438 } |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2439 |
0 | 2440 //------------------------------Value----------------------------------------- |
2441 const Type *StoreCMNode::Value( PhaseTransform *phase ) const { | |
43 | 2442 // Either input is TOP ==> the result is TOP |
2443 const Type *t = phase->type( in(MemNode::Memory) ); | |
2444 if( t == Type::TOP ) return Type::TOP; | |
2445 t = phase->type( in(MemNode::Address) ); | |
2446 if( t == Type::TOP ) return Type::TOP; | |
2447 t = phase->type( in(MemNode::ValueIn) ); | |
2448 if( t == Type::TOP ) return Type::TOP; | |
0 | 2449 // If extra input is TOP ==> the result is TOP |
43 | 2450 t = phase->type( in(MemNode::OopStore) ); |
2451 if( t == Type::TOP ) return Type::TOP; | |
0 | 2452 |
2453 return StoreNode::Value( phase ); | |
2454 } | |
2455 | |
2456 | |
2457 //============================================================================= | |
2458 //----------------------------------SCMemProjNode------------------------------ | |
2459 const Type * SCMemProjNode::Value( PhaseTransform *phase ) const | |
2460 { | |
2461 return bottom_type(); | |
2462 } | |
2463 | |
2464 //============================================================================= | |
2465 LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : Node(5) { | |
2466 init_req(MemNode::Control, c ); | |
2467 init_req(MemNode::Memory , mem); | |
2468 init_req(MemNode::Address, adr); | |
2469 init_req(MemNode::ValueIn, val); | |
2470 init_req( ExpectedIn, ex ); | |
2471 init_class_id(Class_LoadStore); | |
2472 | |
2473 } | |
2474 | |
2475 //============================================================================= | |
2476 //-------------------------------adr_type-------------------------------------- | |
2477 // Do we Match on this edge index or not? Do not match memory | |
2478 const TypePtr* ClearArrayNode::adr_type() const { | |
2479 Node *adr = in(3); | |
2480 return MemNode::calculate_adr_type(adr->bottom_type()); | |
2481 } | |
2482 | |
2483 //------------------------------match_edge------------------------------------- | |
2484 // Do we Match on this edge index or not? Do not match memory | |
2485 uint ClearArrayNode::match_edge(uint idx) const { | |
2486 return idx > 1; | |
2487 } | |
2488 | |
2489 //------------------------------Identity--------------------------------------- | |
2490 // Clearing a zero length array does nothing | |
2491 Node *ClearArrayNode::Identity( PhaseTransform *phase ) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2492 return phase->type(in(2))->higher_equal(TypeX::ZERO) ? in(1) : this; |
0 | 2493 } |
2494 | |
2495 //------------------------------Idealize--------------------------------------- | |
2496 // Clearing a short array is faster with stores | |
2497 Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2498 const int unit = BytesPerLong; | |
2499 const TypeX* t = phase->type(in(2))->isa_intptr_t(); | |
2500 if (!t) return NULL; | |
2501 if (!t->is_con()) return NULL; | |
2502 intptr_t raw_count = t->get_con(); | |
2503 intptr_t size = raw_count; | |
2504 if (!Matcher::init_array_count_is_in_bytes) size *= unit; | |
2505 // Clearing nothing uses the Identity call. | |
2506 // Negative clears are possible on dead ClearArrays | |
2507 // (see jck test stmt114.stmt11402.val). | |
2508 if (size <= 0 || size % unit != 0) return NULL; | |
2509 intptr_t count = size / unit; | |
2510 // Length too long; use fast hardware clear | |
2511 if (size > Matcher::init_array_short_size) return NULL; | |
2512 Node *mem = in(1); | |
2513 if( phase->type(mem)==Type::TOP ) return NULL; | |
2514 Node *adr = in(3); | |
2515 const Type* at = phase->type(adr); | |
2516 if( at==Type::TOP ) return NULL; | |
2517 const TypePtr* atp = at->isa_ptr(); | |
2518 // adjust atp to be the correct array element address type | |
2519 if (atp == NULL) atp = TypePtr::BOTTOM; | |
2520 else atp = atp->add_offset(Type::OffsetBot); | |
2521 // Get base for derived pointer purposes | |
2522 if( adr->Opcode() != Op_AddP ) Unimplemented(); | |
2523 Node *base = adr->in(1); | |
2524 | |
2525 Node *zero = phase->makecon(TypeLong::ZERO); | |
2526 Node *off = phase->MakeConX(BytesPerLong); | |
2527 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); | |
2528 count--; | |
2529 while( count-- ) { | |
2530 mem = phase->transform(mem); | |
2531 adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off)); | |
2532 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); | |
2533 } | |
2534 return mem; | |
2535 } | |
2536 | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2537 //----------------------------step_through---------------------------------- |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2538 // Return allocation input memory edge if it is different instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2539 // or itself if it is the one we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2540 bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2541 Node* n = *np; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2542 assert(n->is_ClearArray(), "sanity"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2543 intptr_t offset; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2544 AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2545 // This method is called only before Allocate nodes are expanded during |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2546 // macro nodes expansion. Before that ClearArray nodes are only generated |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2547 // in LibraryCallKit::generate_arraycopy() which follows allocations. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2548 assert(alloc != NULL, "should have allocation"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2549 if (alloc->_idx == instance_id) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2550 // Can not bypass initialization of the instance we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2551 return false; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2552 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2553 // Otherwise skip it. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2554 InitializeNode* init = alloc->initialization(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2555 if (init != NULL) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2556 *np = init->in(TypeFunc::Memory); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2557 else |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2558 *np = alloc->in(TypeFunc::Memory); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2559 return true; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2560 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2561 |
0 | 2562 //----------------------------clear_memory------------------------------------- |
2563 // Generate code to initialize object storage to zero. | |
2564 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2565 intptr_t start_offset, | |
2566 Node* end_offset, | |
2567 PhaseGVN* phase) { | |
2568 Compile* C = phase->C; | |
2569 intptr_t offset = start_offset; | |
2570 | |
2571 int unit = BytesPerLong; | |
2572 if ((offset % unit) != 0) { | |
2573 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset)); | |
2574 adr = phase->transform(adr); | |
2575 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2576 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); |
0 | 2577 mem = phase->transform(mem); |
2578 offset += BytesPerInt; | |
2579 } | |
2580 assert((offset % unit) == 0, ""); | |
2581 | |
2582 // Initialize the remaining stuff, if any, with a ClearArray. | |
2583 return clear_memory(ctl, mem, dest, phase->MakeConX(offset), end_offset, phase); | |
2584 } | |
2585 | |
2586 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2587 Node* start_offset, | |
2588 Node* end_offset, | |
2589 PhaseGVN* phase) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2590 if (start_offset == end_offset) { |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2591 // nothing to do |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2592 return mem; |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2593 } |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2594 |
0 | 2595 Compile* C = phase->C; |
2596 int unit = BytesPerLong; | |
2597 Node* zbase = start_offset; | |
2598 Node* zend = end_offset; | |
2599 | |
2600 // Scale to the unit required by the CPU: | |
2601 if (!Matcher::init_array_count_is_in_bytes) { | |
2602 Node* shift = phase->intcon(exact_log2(unit)); | |
2603 zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) ); | |
2604 zend = phase->transform( new(C,3) URShiftXNode(zend, shift) ); | |
2605 } | |
2606 | |
2607 Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) ); | |
2608 Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); | |
2609 | |
2610 // Bulk clear double-words | |
2611 Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) ); | |
2612 mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr); | |
2613 return phase->transform(mem); | |
2614 } | |
2615 | |
2616 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2617 intptr_t start_offset, | |
2618 intptr_t end_offset, | |
2619 PhaseGVN* phase) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2620 if (start_offset == end_offset) { |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2621 // nothing to do |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2622 return mem; |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2623 } |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2624 |
0 | 2625 Compile* C = phase->C; |
2626 assert((end_offset % BytesPerInt) == 0, "odd end offset"); | |
2627 intptr_t done_offset = end_offset; | |
2628 if ((done_offset % BytesPerLong) != 0) { | |
2629 done_offset -= BytesPerInt; | |
2630 } | |
2631 if (done_offset > start_offset) { | |
2632 mem = clear_memory(ctl, mem, dest, | |
2633 start_offset, phase->MakeConX(done_offset), phase); | |
2634 } | |
2635 if (done_offset < end_offset) { // emit the final 32-bit store | |
2636 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset)); | |
2637 adr = phase->transform(adr); | |
2638 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2639 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); |
0 | 2640 mem = phase->transform(mem); |
2641 done_offset += BytesPerInt; | |
2642 } | |
2643 assert(done_offset == end_offset, ""); | |
2644 return mem; | |
2645 } | |
2646 | |
2647 //============================================================================= | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2648 // Do not match memory edge. |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2649 uint StrIntrinsicNode::match_edge(uint idx) const { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2650 return idx == 2 || idx == 3; |
681 | 2651 } |
2652 | |
2653 //------------------------------Ideal------------------------------------------ | |
2654 // Return a node which is more "ideal" than the current node. Strip out | |
2655 // control copies | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2656 Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2657 if (remove_dead_region(phase, can_reshape)) return this; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2658 |
2417 | 2659 if (can_reshape) { |
2660 Node* mem = phase->transform(in(MemNode::Memory)); | |
2661 // If transformed to a MergeMem, get the desired slice | |
2662 uint alias_idx = phase->C->get_alias_index(adr_type()); | |
2663 mem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(alias_idx) : mem; | |
2664 if (mem != in(MemNode::Memory)) { | |
2665 set_req(MemNode::Memory, mem); | |
2666 return this; | |
2667 } | |
2668 } | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2669 return NULL; |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
2670 } |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
2671 |
0 | 2672 //============================================================================= |
2673 MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent) | |
2674 : MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)), | |
2675 _adr_type(C->get_adr_type(alias_idx)) | |
2676 { | |
2677 init_class_id(Class_MemBar); | |
2678 Node* top = C->top(); | |
2679 init_req(TypeFunc::I_O,top); | |
2680 init_req(TypeFunc::FramePtr,top); | |
2681 init_req(TypeFunc::ReturnAdr,top); | |
2682 if (precedent != NULL) | |
2683 init_req(TypeFunc::Parms, precedent); | |
2684 } | |
2685 | |
2686 //------------------------------cmp-------------------------------------------- | |
2687 uint MemBarNode::hash() const { return NO_HASH; } | |
2688 uint MemBarNode::cmp( const Node &n ) const { | |
2689 return (&n == this); // Always fail except on self | |
2690 } | |
2691 | |
2692 //------------------------------make------------------------------------------- | |
2693 MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { | |
2694 int len = Precedent + (pn == NULL? 0: 1); | |
2695 switch (opcode) { | |
2696 case Op_MemBarAcquire: return new(C, len) MemBarAcquireNode(C, atp, pn); | |
2697 case Op_MemBarRelease: return new(C, len) MemBarReleaseNode(C, atp, pn); | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
2698 case Op_MemBarAcquireLock: return new(C, len) MemBarAcquireLockNode(C, atp, pn); |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
2699 case Op_MemBarReleaseLock: return new(C, len) MemBarReleaseLockNode(C, atp, pn); |
0 | 2700 case Op_MemBarVolatile: return new(C, len) MemBarVolatileNode(C, atp, pn); |
2701 case Op_MemBarCPUOrder: return new(C, len) MemBarCPUOrderNode(C, atp, pn); | |
2702 case Op_Initialize: return new(C, len) InitializeNode(C, atp, pn); | |
2703 default: ShouldNotReachHere(); return NULL; | |
2704 } | |
2705 } | |
2706 | |
2707 //------------------------------Ideal------------------------------------------ | |
2708 // Return a node which is more "ideal" than the current node. Strip out | |
2709 // control copies | |
2710 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2711 if (remove_dead_region(phase, can_reshape)) return this; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2712 |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2713 // Eliminate volatile MemBars for scalar replaced objects. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2714 if (can_reshape && req() == (Precedent+1) && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2715 (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2716 // Volatile field loads and stores. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2717 Node* my_mem = in(MemBarNode::Precedent); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2718 if (my_mem != NULL && my_mem->is_Mem()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2719 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2720 // Check for scalar replaced object reference. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2721 if( t_oop != NULL && t_oop->is_known_instance_field() && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2722 t_oop->offset() != Type::OffsetBot && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2723 t_oop->offset() != Type::OffsetTop) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2724 // Replace MemBar projections by its inputs. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2725 PhaseIterGVN* igvn = phase->is_IterGVN(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2726 igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2727 igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2728 // Must return either the original node (now dead) or a new node |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2729 // (Do not return a top here, since that would break the uniqueness of top.) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2730 return new (phase->C, 1) ConINode(TypeInt::ZERO); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2731 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2732 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2733 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2734 return NULL; |
0 | 2735 } |
2736 | |
2737 //------------------------------Value------------------------------------------ | |
2738 const Type *MemBarNode::Value( PhaseTransform *phase ) const { | |
2739 if( !in(0) ) return Type::TOP; | |
2740 if( phase->type(in(0)) == Type::TOP ) | |
2741 return Type::TOP; | |
2742 return TypeTuple::MEMBAR; | |
2743 } | |
2744 | |
2745 //------------------------------match------------------------------------------ | |
2746 // Construct projections for memory. | |
2747 Node *MemBarNode::match( const ProjNode *proj, const Matcher *m ) { | |
2748 switch (proj->_con) { | |
2749 case TypeFunc::Control: | |
2750 case TypeFunc::Memory: | |
2751 return new (m->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); | |
2752 } | |
2753 ShouldNotReachHere(); | |
2754 return NULL; | |
2755 } | |
2756 | |
2757 //===========================InitializeNode==================================== | |
2758 // SUMMARY: | |
2759 // This node acts as a memory barrier on raw memory, after some raw stores. | |
2760 // The 'cooked' oop value feeds from the Initialize, not the Allocation. | |
2761 // The Initialize can 'capture' suitably constrained stores as raw inits. | |
2762 // It can coalesce related raw stores into larger units (called 'tiles'). | |
2763 // It can avoid zeroing new storage for memory units which have raw inits. | |
2764 // At macro-expansion, it is marked 'complete', and does not optimize further. | |
2765 // | |
2766 // EXAMPLE: | |
2767 // The object 'new short[2]' occupies 16 bytes in a 32-bit machine. | |
2768 // ctl = incoming control; mem* = incoming memory | |
2769 // (Note: A star * on a memory edge denotes I/O and other standard edges.) | |
2770 // First allocate uninitialized memory and fill in the header: | |
2771 // alloc = (Allocate ctl mem* 16 #short[].klass ...) | |
2772 // ctl := alloc.Control; mem* := alloc.Memory* | |
2773 // rawmem = alloc.Memory; rawoop = alloc.RawAddress | |
2774 // Then initialize to zero the non-header parts of the raw memory block: | |
2775 // init = (Initialize alloc.Control alloc.Memory* alloc.RawAddress) | |
2776 // ctl := init.Control; mem.SLICE(#short[*]) := init.Memory | |
2777 // After the initialize node executes, the object is ready for service: | |
2778 // oop := (CheckCastPP init.Control alloc.RawAddress #short[]) | |
2779 // Suppose its body is immediately initialized as {1,2}: | |
2780 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1) | |
2781 // store2 = (StoreC init.Control store1 (+ oop 14) 2) | |
2782 // mem.SLICE(#short[*]) := store2 | |
2783 // | |
2784 // DETAILS: | |
2785 // An InitializeNode collects and isolates object initialization after | |
2786 // an AllocateNode and before the next possible safepoint. As a | |
2787 // memory barrier (MemBarNode), it keeps critical stores from drifting | |
2788 // down past any safepoint or any publication of the allocation. | |
2789 // Before this barrier, a newly-allocated object may have uninitialized bits. | |
2790 // After this barrier, it may be treated as a real oop, and GC is allowed. | |
2791 // | |
2792 // The semantics of the InitializeNode include an implicit zeroing of | |
2793 // the new object from object header to the end of the object. | |
2794 // (The object header and end are determined by the AllocateNode.) | |
2795 // | |
2796 // Certain stores may be added as direct inputs to the InitializeNode. | |
2797 // These stores must update raw memory, and they must be to addresses | |
2798 // derived from the raw address produced by AllocateNode, and with | |
2799 // a constant offset. They must be ordered by increasing offset. | |
2800 // The first one is at in(RawStores), the last at in(req()-1). | |
2801 // Unlike most memory operations, they are not linked in a chain, | |
2802 // but are displayed in parallel as users of the rawmem output of | |
2803 // the allocation. | |
2804 // | |
2805 // (See comments in InitializeNode::capture_store, which continue | |
2806 // the example given above.) | |
2807 // | |
2808 // When the associated Allocate is macro-expanded, the InitializeNode | |
2809 // may be rewritten to optimize collected stores. A ClearArrayNode | |
2810 // may also be created at that point to represent any required zeroing. | |
2811 // The InitializeNode is then marked 'complete', prohibiting further | |
2812 // capturing of nearby memory operations. | |
2813 // | |
2814 // During macro-expansion, all captured initializations which store | |
605 | 2815 // constant values of 32 bits or smaller are coalesced (if advantageous) |
0 | 2816 // into larger 'tiles' 32 or 64 bits. This allows an object to be |
2817 // initialized in fewer memory operations. Memory words which are | |
2818 // covered by neither tiles nor non-constant stores are pre-zeroed | |
2819 // by explicit stores of zero. (The code shape happens to do all | |
2820 // zeroing first, then all other stores, with both sequences occurring | |
2821 // in order of ascending offsets.) | |
2822 // | |
2823 // Alternatively, code may be inserted between an AllocateNode and its | |
2824 // InitializeNode, to perform arbitrary initialization of the new object. | |
2825 // E.g., the object copying intrinsics insert complex data transfers here. | |
2826 // The initialization must then be marked as 'complete' disable the | |
2827 // built-in zeroing semantics and the collection of initializing stores. | |
2828 // | |
2829 // While an InitializeNode is incomplete, reads from the memory state | |
2830 // produced by it are optimizable if they match the control edge and | |
2831 // new oop address associated with the allocation/initialization. | |
2832 // They return a stored value (if the offset matches) or else zero. | |
2833 // A write to the memory state, if it matches control and address, | |
2834 // and if it is to a constant offset, may be 'captured' by the | |
2835 // InitializeNode. It is cloned as a raw memory operation and rewired | |
2836 // inside the initialization, to the raw oop produced by the allocation. | |
2837 // Operations on addresses which are provably distinct (e.g., to | |
2838 // other AllocateNodes) are allowed to bypass the initialization. | |
2839 // | |
2840 // The effect of all this is to consolidate object initialization | |
2841 // (both arrays and non-arrays, both piecewise and bulk) into a | |
2842 // single location, where it can be optimized as a unit. | |
2843 // | |
2844 // Only stores with an offset less than TrackedInitializationLimit words | |
2845 // will be considered for capture by an InitializeNode. This puts a | |
2846 // reasonable limit on the complexity of optimized initializations. | |
2847 | |
2848 //---------------------------InitializeNode------------------------------------ | |
2849 InitializeNode::InitializeNode(Compile* C, int adr_type, Node* rawoop) | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3902
diff
changeset
|
2850 : _is_complete(Incomplete), |
0 | 2851 MemBarNode(C, adr_type, rawoop) |
2852 { | |
2853 init_class_id(Class_Initialize); | |
2854 | |
2855 assert(adr_type == Compile::AliasIdxRaw, "only valid atp"); | |
2856 assert(in(RawAddress) == rawoop, "proper init"); | |
2857 // Note: allocation() can be NULL, for secondary initialization barriers | |
2858 } | |
2859 | |
2860 // Since this node is not matched, it will be processed by the | |
2861 // register allocator. Declare that there are no constraints | |
2862 // on the allocation of the RawAddress edge. | |
2863 const RegMask &InitializeNode::in_RegMask(uint idx) const { | |
2864 // This edge should be set to top, by the set_complete. But be conservative. | |
2865 if (idx == InitializeNode::RawAddress) | |
2866 return *(Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]); | |
2867 return RegMask::Empty; | |
2868 } | |
2869 | |
2870 Node* InitializeNode::memory(uint alias_idx) { | |
2871 Node* mem = in(Memory); | |
2872 if (mem->is_MergeMem()) { | |
2873 return mem->as_MergeMem()->memory_at(alias_idx); | |
2874 } else { | |
2875 // incoming raw memory is not split | |
2876 return mem; | |
2877 } | |
2878 } | |
2879 | |
2880 bool InitializeNode::is_non_zero() { | |
2881 if (is_complete()) return false; | |
2882 remove_extra_zeroes(); | |
2883 return (req() > RawStores); | |
2884 } | |
2885 | |
2886 void InitializeNode::set_complete(PhaseGVN* phase) { | |
2887 assert(!is_complete(), "caller responsibility"); | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3902
diff
changeset
|
2888 _is_complete = Complete; |
0 | 2889 |
2890 // After this node is complete, it contains a bunch of | |
2891 // raw-memory initializations. There is no need for | |
2892 // it to have anything to do with non-raw memory effects. | |
2893 // Therefore, tell all non-raw users to re-optimize themselves, | |
2894 // after skipping the memory effects of this initialization. | |
2895 PhaseIterGVN* igvn = phase->is_IterGVN(); | |
2896 if (igvn) igvn->add_users_to_worklist(this); | |
2897 } | |
2898 | |
2899 // convenience function | |
2900 // return false if the init contains any stores already | |
2901 bool AllocateNode::maybe_set_complete(PhaseGVN* phase) { | |
2902 InitializeNode* init = initialization(); | |
2903 if (init == NULL || init->is_complete()) return false; | |
2904 init->remove_extra_zeroes(); | |
2905 // for now, if this allocation has already collected any inits, bail: | |
2906 if (init->is_non_zero()) return false; | |
2907 init->set_complete(phase); | |
2908 return true; | |
2909 } | |
2910 | |
2911 void InitializeNode::remove_extra_zeroes() { | |
2912 if (req() == RawStores) return; | |
2913 Node* zmem = zero_memory(); | |
2914 uint fill = RawStores; | |
2915 for (uint i = fill; i < req(); i++) { | |
2916 Node* n = in(i); | |
2917 if (n->is_top() || n == zmem) continue; // skip | |
2918 if (fill < i) set_req(fill, n); // compact | |
2919 ++fill; | |
2920 } | |
2921 // delete any empty spaces created: | |
2922 while (fill < req()) { | |
2923 del_req(fill); | |
2924 } | |
2925 } | |
2926 | |
2927 // Helper for remembering which stores go with which offsets. | |
2928 intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) { | |
2929 if (!st->is_Store()) return -1; // can happen to dead code via subsume_node | |
2930 intptr_t offset = -1; | |
2931 Node* base = AddPNode::Ideal_base_and_offset(st->in(MemNode::Address), | |
2932 phase, offset); | |
2933 if (base == NULL) return -1; // something is dead, | |
2934 if (offset < 0) return -1; // dead, dead | |
2935 return offset; | |
2936 } | |
2937 | |
2938 // Helper for proving that an initialization expression is | |
2939 // "simple enough" to be folded into an object initialization. | |
2940 // Attempts to prove that a store's initial value 'n' can be captured | |
2941 // within the initialization without creating a vicious cycle, such as: | |
2942 // { Foo p = new Foo(); p.next = p; } | |
2943 // True for constants and parameters and small combinations thereof. | |
2944 bool InitializeNode::detect_init_independence(Node* n, | |
2945 bool st_is_pinned, | |
2946 int& count) { | |
2947 if (n == NULL) return true; // (can this really happen?) | |
2948 if (n->is_Proj()) n = n->in(0); | |
2949 if (n == this) return false; // found a cycle | |
2950 if (n->is_Con()) return true; | |
2951 if (n->is_Start()) return true; // params, etc., are OK | |
2952 if (n->is_Root()) return true; // even better | |
2953 | |
2954 Node* ctl = n->in(0); | |
2955 if (ctl != NULL && !ctl->is_top()) { | |
2956 if (ctl->is_Proj()) ctl = ctl->in(0); | |
2957 if (ctl == this) return false; | |
2958 | |
2959 // If we already know that the enclosing memory op is pinned right after | |
2960 // the init, then any control flow that the store has picked up | |
2961 // must have preceded the init, or else be equal to the init. | |
2962 // Even after loop optimizations (which might change control edges) | |
2963 // a store is never pinned *before* the availability of its inputs. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
2964 if (!MemNode::all_controls_dominate(n, this)) |
0 | 2965 return false; // failed to prove a good control |
2966 | |
2967 } | |
2968 | |
2969 // Check data edges for possible dependencies on 'this'. | |
2970 if ((count += 1) > 20) return false; // complexity limit | |
2971 for (uint i = 1; i < n->req(); i++) { | |
2972 Node* m = n->in(i); | |
2973 if (m == NULL || m == n || m->is_top()) continue; | |
2974 uint first_i = n->find_edge(m); | |
2975 if (i != first_i) continue; // process duplicate edge just once | |
2976 if (!detect_init_independence(m, st_is_pinned, count)) { | |
2977 return false; | |
2978 } | |
2979 } | |
2980 | |
2981 return true; | |
2982 } | |
2983 | |
2984 // Here are all the checks a Store must pass before it can be moved into | |
2985 // an initialization. Returns zero if a check fails. | |
2986 // On success, returns the (constant) offset to which the store applies, | |
2987 // within the initialized memory. | |
2988 intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { | |
2989 const int FAIL = 0; | |
2990 if (st->req() != MemNode::ValueIn + 1) | |
2991 return FAIL; // an inscrutable StoreNode (card mark?) | |
2992 Node* ctl = st->in(MemNode::Control); | |
2993 if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this)) | |
2994 return FAIL; // must be unconditional after the initialization | |
2995 Node* mem = st->in(MemNode::Memory); | |
2996 if (!(mem->is_Proj() && mem->in(0) == this)) | |
2997 return FAIL; // must not be preceded by other stores | |
2998 Node* adr = st->in(MemNode::Address); | |
2999 intptr_t offset; | |
3000 AllocateNode* alloc = AllocateNode::Ideal_allocation(adr, phase, offset); | |
3001 if (alloc == NULL) | |
3002 return FAIL; // inscrutable address | |
3003 if (alloc != allocation()) | |
3004 return FAIL; // wrong allocation! (store needs to float up) | |
3005 Node* val = st->in(MemNode::ValueIn); | |
3006 int complexity_count = 0; | |
3007 if (!detect_init_independence(val, true, complexity_count)) | |
3008 return FAIL; // stored value must be 'simple enough' | |
3009 | |
3010 return offset; // success | |
3011 } | |
3012 | |
3013 // Find the captured store in(i) which corresponds to the range | |
3014 // [start..start+size) in the initialized object. | |
3015 // If there is one, return its index i. If there isn't, return the | |
3016 // negative of the index where it should be inserted. | |
3017 // Return 0 if the queried range overlaps an initialization boundary | |
3018 // or if dead code is encountered. | |
3019 // If size_in_bytes is zero, do not bother with overlap checks. | |
3020 int InitializeNode::captured_store_insertion_point(intptr_t start, | |
3021 int size_in_bytes, | |
3022 PhaseTransform* phase) { | |
3023 const int FAIL = 0, MAX_STORE = BytesPerLong; | |
3024 | |
3025 if (is_complete()) | |
3026 return FAIL; // arraycopy got here first; punt | |
3027 | |
3028 assert(allocation() != NULL, "must be present"); | |
3029 | |
3030 // no negatives, no header fields: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3031 if (start < (intptr_t) allocation()->minimum_header_size()) return FAIL; |
0 | 3032 |
3033 // after a certain size, we bail out on tracking all the stores: | |
3034 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); | |
3035 if (start >= ti_limit) return FAIL; | |
3036 | |
3037 for (uint i = InitializeNode::RawStores, limit = req(); ; ) { | |
3038 if (i >= limit) return -(int)i; // not found; here is where to put it | |
3039 | |
3040 Node* st = in(i); | |
3041 intptr_t st_off = get_store_offset(st, phase); | |
3042 if (st_off < 0) { | |
3043 if (st != zero_memory()) { | |
3044 return FAIL; // bail out if there is dead garbage | |
3045 } | |
3046 } else if (st_off > start) { | |
3047 // ...we are done, since stores are ordered | |
3048 if (st_off < start + size_in_bytes) { | |
3049 return FAIL; // the next store overlaps | |
3050 } | |
3051 return -(int)i; // not found; here is where to put it | |
3052 } else if (st_off < start) { | |
3053 if (size_in_bytes != 0 && | |
3054 start < st_off + MAX_STORE && | |
3055 start < st_off + st->as_Store()->memory_size()) { | |
3056 return FAIL; // the previous store overlaps | |
3057 } | |
3058 } else { | |
3059 if (size_in_bytes != 0 && | |
3060 st->as_Store()->memory_size() != size_in_bytes) { | |
3061 return FAIL; // mismatched store size | |
3062 } | |
3063 return i; | |
3064 } | |
3065 | |
3066 ++i; | |
3067 } | |
3068 } | |
3069 | |
3070 // Look for a captured store which initializes at the offset 'start' | |
3071 // with the given size. If there is no such store, and no other | |
3072 // initialization interferes, then return zero_memory (the memory | |
3073 // projection of the AllocateNode). | |
3074 Node* InitializeNode::find_captured_store(intptr_t start, int size_in_bytes, | |
3075 PhaseTransform* phase) { | |
3076 assert(stores_are_sane(phase), ""); | |
3077 int i = captured_store_insertion_point(start, size_in_bytes, phase); | |
3078 if (i == 0) { | |
3079 return NULL; // something is dead | |
3080 } else if (i < 0) { | |
3081 return zero_memory(); // just primordial zero bits here | |
3082 } else { | |
3083 Node* st = in(i); // here is the store at this position | |
3084 assert(get_store_offset(st->as_Store(), phase) == start, "sanity"); | |
3085 return st; | |
3086 } | |
3087 } | |
3088 | |
3089 // Create, as a raw pointer, an address within my new object at 'offset'. | |
3090 Node* InitializeNode::make_raw_address(intptr_t offset, | |
3091 PhaseTransform* phase) { | |
3092 Node* addr = in(RawAddress); | |
3093 if (offset != 0) { | |
3094 Compile* C = phase->C; | |
3095 addr = phase->transform( new (C, 4) AddPNode(C->top(), addr, | |
3096 phase->MakeConX(offset)) ); | |
3097 } | |
3098 return addr; | |
3099 } | |
3100 | |
3101 // Clone the given store, converting it into a raw store | |
3102 // initializing a field or element of my new object. | |
3103 // Caller is responsible for retiring the original store, | |
3104 // with subsume_node or the like. | |
3105 // | |
3106 // From the example above InitializeNode::InitializeNode, | |
3107 // here are the old stores to be captured: | |
3108 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1) | |
3109 // store2 = (StoreC init.Control store1 (+ oop 14) 2) | |
3110 // | |
3111 // Here is the changed code; note the extra edges on init: | |
3112 // alloc = (Allocate ...) | |
3113 // rawoop = alloc.RawAddress | |
3114 // rawstore1 = (StoreC alloc.Control alloc.Memory (+ rawoop 12) 1) | |
3115 // rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2) | |
3116 // init = (Initialize alloc.Control alloc.Memory rawoop | |
3117 // rawstore1 rawstore2) | |
3118 // | |
3119 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, | |
3120 PhaseTransform* phase) { | |
3121 assert(stores_are_sane(phase), ""); | |
3122 | |
3123 if (start < 0) return NULL; | |
3124 assert(can_capture_store(st, phase) == start, "sanity"); | |
3125 | |
3126 Compile* C = phase->C; | |
3127 int size_in_bytes = st->memory_size(); | |
3128 int i = captured_store_insertion_point(start, size_in_bytes, phase); | |
3129 if (i == 0) return NULL; // bail out | |
3130 Node* prev_mem = NULL; // raw memory for the captured store | |
3131 if (i > 0) { | |
3132 prev_mem = in(i); // there is a pre-existing store under this one | |
3133 set_req(i, C->top()); // temporarily disconnect it | |
3134 // See StoreNode::Ideal 'st->outcnt() == 1' for the reason to disconnect. | |
3135 } else { | |
3136 i = -i; // no pre-existing store | |
3137 prev_mem = zero_memory(); // a slice of the newly allocated object | |
3138 if (i > InitializeNode::RawStores && in(i-1) == prev_mem) | |
3139 set_req(--i, C->top()); // reuse this edge; it has been folded away | |
3140 else | |
3141 ins_req(i, C->top()); // build a new edge | |
3142 } | |
3143 Node* new_st = st->clone(); | |
3144 new_st->set_req(MemNode::Control, in(Control)); | |
3145 new_st->set_req(MemNode::Memory, prev_mem); | |
3146 new_st->set_req(MemNode::Address, make_raw_address(start, phase)); | |
3147 new_st = phase->transform(new_st); | |
3148 | |
3149 // At this point, new_st might have swallowed a pre-existing store | |
3150 // at the same offset, or perhaps new_st might have disappeared, | |
3151 // if it redundantly stored the same value (or zero to fresh memory). | |
3152 | |
3153 // In any case, wire it in: | |
3154 set_req(i, new_st); | |
3155 | |
3156 // The caller may now kill the old guy. | |
3157 DEBUG_ONLY(Node* check_st = find_captured_store(start, size_in_bytes, phase)); | |
3158 assert(check_st == new_st || check_st == NULL, "must be findable"); | |
3159 assert(!is_complete(), ""); | |
3160 return new_st; | |
3161 } | |
3162 | |
3163 static bool store_constant(jlong* tiles, int num_tiles, | |
3164 intptr_t st_off, int st_size, | |
3165 jlong con) { | |
3166 if ((st_off & (st_size-1)) != 0) | |
3167 return false; // strange store offset (assume size==2**N) | |
3168 address addr = (address)tiles + st_off; | |
3169 assert(st_off >= 0 && addr+st_size <= (address)&tiles[num_tiles], "oob"); | |
3170 switch (st_size) { | |
3171 case sizeof(jbyte): *(jbyte*) addr = (jbyte) con; break; | |
3172 case sizeof(jchar): *(jchar*) addr = (jchar) con; break; | |
3173 case sizeof(jint): *(jint*) addr = (jint) con; break; | |
3174 case sizeof(jlong): *(jlong*) addr = (jlong) con; break; | |
3175 default: return false; // strange store size (detect size!=2**N here) | |
3176 } | |
3177 return true; // return success to caller | |
3178 } | |
3179 | |
3180 // Coalesce subword constants into int constants and possibly | |
3181 // into long constants. The goal, if the CPU permits, | |
3182 // is to initialize the object with a small number of 64-bit tiles. | |
3183 // Also, convert floating-point constants to bit patterns. | |
3184 // Non-constants are not relevant to this pass. | |
3185 // | |
3186 // In terms of the running example on InitializeNode::InitializeNode | |
3187 // and InitializeNode::capture_store, here is the transformation | |
3188 // of rawstore1 and rawstore2 into rawstore12: | |
3189 // alloc = (Allocate ...) | |
3190 // rawoop = alloc.RawAddress | |
3191 // tile12 = 0x00010002 | |
3192 // rawstore12 = (StoreI alloc.Control alloc.Memory (+ rawoop 12) tile12) | |
3193 // init = (Initialize alloc.Control alloc.Memory rawoop rawstore12) | |
3194 // | |
3195 void | |
3196 InitializeNode::coalesce_subword_stores(intptr_t header_size, | |
3197 Node* size_in_bytes, | |
3198 PhaseGVN* phase) { | |
3199 Compile* C = phase->C; | |
3200 | |
3201 assert(stores_are_sane(phase), ""); | |
3202 // Note: After this pass, they are not completely sane, | |
3203 // since there may be some overlaps. | |
3204 | |
3205 int old_subword = 0, old_long = 0, new_int = 0, new_long = 0; | |
3206 | |
3207 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); | |
3208 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, ti_limit); | |
3209 size_limit = MIN2(size_limit, ti_limit); | |
3210 size_limit = align_size_up(size_limit, BytesPerLong); | |
3211 int num_tiles = size_limit / BytesPerLong; | |
3212 | |
3213 // allocate space for the tile map: | |
3214 const int small_len = DEBUG_ONLY(true ? 3 :) 30; // keep stack frames small | |
3215 jlong tiles_buf[small_len]; | |
3216 Node* nodes_buf[small_len]; | |
3217 jlong inits_buf[small_len]; | |
3218 jlong* tiles = ((num_tiles <= small_len) ? &tiles_buf[0] | |
3219 : NEW_RESOURCE_ARRAY(jlong, num_tiles)); | |
3220 Node** nodes = ((num_tiles <= small_len) ? &nodes_buf[0] | |
3221 : NEW_RESOURCE_ARRAY(Node*, num_tiles)); | |
3222 jlong* inits = ((num_tiles <= small_len) ? &inits_buf[0] | |
3223 : NEW_RESOURCE_ARRAY(jlong, num_tiles)); | |
3224 // tiles: exact bitwise model of all primitive constants | |
3225 // nodes: last constant-storing node subsumed into the tiles model | |
3226 // inits: which bytes (in each tile) are touched by any initializations | |
3227 | |
3228 //// Pass A: Fill in the tile model with any relevant stores. | |
3229 | |
3230 Copy::zero_to_bytes(tiles, sizeof(tiles[0]) * num_tiles); | |
3231 Copy::zero_to_bytes(nodes, sizeof(nodes[0]) * num_tiles); | |
3232 Copy::zero_to_bytes(inits, sizeof(inits[0]) * num_tiles); | |
3233 Node* zmem = zero_memory(); // initially zero memory state | |
3234 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { | |
3235 Node* st = in(i); | |
3236 intptr_t st_off = get_store_offset(st, phase); | |
3237 | |
3238 // Figure out the store's offset and constant value: | |
3239 if (st_off < header_size) continue; //skip (ignore header) | |
3240 if (st->in(MemNode::Memory) != zmem) continue; //skip (odd store chain) | |
3241 int st_size = st->as_Store()->memory_size(); | |
3242 if (st_off + st_size > size_limit) break; | |
3243 | |
3244 // Record which bytes are touched, whether by constant or not. | |
3245 if (!store_constant(inits, num_tiles, st_off, st_size, (jlong) -1)) | |
3246 continue; // skip (strange store size) | |
3247 | |
3248 const Type* val = phase->type(st->in(MemNode::ValueIn)); | |
3249 if (!val->singleton()) continue; //skip (non-con store) | |
3250 BasicType type = val->basic_type(); | |
3251 | |
3252 jlong con = 0; | |
3253 switch (type) { | |
3254 case T_INT: con = val->is_int()->get_con(); break; | |
3255 case T_LONG: con = val->is_long()->get_con(); break; | |
3256 case T_FLOAT: con = jint_cast(val->getf()); break; | |
3257 case T_DOUBLE: con = jlong_cast(val->getd()); break; | |
3258 default: continue; //skip (odd store type) | |
3259 } | |
3260 | |
3261 if (type == T_LONG && Matcher::isSimpleConstant64(con) && | |
3262 st->Opcode() == Op_StoreL) { | |
3263 continue; // This StoreL is already optimal. | |
3264 } | |
3265 | |
3266 // Store down the constant. | |
3267 store_constant(tiles, num_tiles, st_off, st_size, con); | |
3268 | |
3269 intptr_t j = st_off >> LogBytesPerLong; | |
3270 | |
3271 if (type == T_INT && st_size == BytesPerInt | |
3272 && (st_off & BytesPerInt) == BytesPerInt) { | |
3273 jlong lcon = tiles[j]; | |
3274 if (!Matcher::isSimpleConstant64(lcon) && | |
3275 st->Opcode() == Op_StoreI) { | |
3276 // This StoreI is already optimal by itself. | |
3277 jint* intcon = (jint*) &tiles[j]; | |
3278 intcon[1] = 0; // undo the store_constant() | |
3279 | |
3280 // If the previous store is also optimal by itself, back up and | |
3281 // undo the action of the previous loop iteration... if we can. | |
3282 // But if we can't, just let the previous half take care of itself. | |
3283 st = nodes[j]; | |
3284 st_off -= BytesPerInt; | |
3285 con = intcon[0]; | |
3286 if (con != 0 && st != NULL && st->Opcode() == Op_StoreI) { | |
3287 assert(st_off >= header_size, "still ignoring header"); | |
3288 assert(get_store_offset(st, phase) == st_off, "must be"); | |
3289 assert(in(i-1) == zmem, "must be"); | |
3290 DEBUG_ONLY(const Type* tcon = phase->type(st->in(MemNode::ValueIn))); | |
3291 assert(con == tcon->is_int()->get_con(), "must be"); | |
3292 // Undo the effects of the previous loop trip, which swallowed st: | |
3293 intcon[0] = 0; // undo store_constant() | |
3294 set_req(i-1, st); // undo set_req(i, zmem) | |
3295 nodes[j] = NULL; // undo nodes[j] = st | |
3296 --old_subword; // undo ++old_subword | |
3297 } | |
3298 continue; // This StoreI is already optimal. | |
3299 } | |
3300 } | |
3301 | |
3302 // This store is not needed. | |
3303 set_req(i, zmem); | |
3304 nodes[j] = st; // record for the moment | |
3305 if (st_size < BytesPerLong) // something has changed | |
3306 ++old_subword; // includes int/float, but who's counting... | |
3307 else ++old_long; | |
3308 } | |
3309 | |
3310 if ((old_subword + old_long) == 0) | |
3311 return; // nothing more to do | |
3312 | |
3313 //// Pass B: Convert any non-zero tiles into optimal constant stores. | |
3314 // Be sure to insert them before overlapping non-constant stores. | |
3315 // (E.g., byte[] x = { 1,2,y,4 } => x[int 0] = 0x01020004, x[2]=y.) | |
3316 for (int j = 0; j < num_tiles; j++) { | |
3317 jlong con = tiles[j]; | |
3318 jlong init = inits[j]; | |
3319 if (con == 0) continue; | |
3320 jint con0, con1; // split the constant, address-wise | |
3321 jint init0, init1; // split the init map, address-wise | |
3322 { union { jlong con; jint intcon[2]; } u; | |
3323 u.con = con; | |
3324 con0 = u.intcon[0]; | |
3325 con1 = u.intcon[1]; | |
3326 u.con = init; | |
3327 init0 = u.intcon[0]; | |
3328 init1 = u.intcon[1]; | |
3329 } | |
3330 | |
3331 Node* old = nodes[j]; | |
3332 assert(old != NULL, "need the prior store"); | |
3333 intptr_t offset = (j * BytesPerLong); | |
3334 | |
3335 bool split = !Matcher::isSimpleConstant64(con); | |
3336 | |
3337 if (offset < header_size) { | |
3338 assert(offset + BytesPerInt >= header_size, "second int counts"); | |
3339 assert(*(jint*)&tiles[j] == 0, "junk in header"); | |
3340 split = true; // only the second word counts | |
3341 // Example: int a[] = { 42 ... } | |
3342 } else if (con0 == 0 && init0 == -1) { | |
3343 split = true; // first word is covered by full inits | |
3344 // Example: int a[] = { ... foo(), 42 ... } | |
3345 } else if (con1 == 0 && init1 == -1) { | |
3346 split = true; // second word is covered by full inits | |
3347 // Example: int a[] = { ... 42, foo() ... } | |
3348 } | |
3349 | |
3350 // Here's a case where init0 is neither 0 nor -1: | |
3351 // byte a[] = { ... 0,0,foo(),0, 0,0,0,42 ... } | |
3352 // Assuming big-endian memory, init0, init1 are 0x0000FF00, 0x000000FF. | |
3353 // In this case the tile is not split; it is (jlong)42. | |
3354 // The big tile is stored down, and then the foo() value is inserted. | |
3355 // (If there were foo(),foo() instead of foo(),0, init0 would be -1.) | |
3356 | |
3357 Node* ctl = old->in(MemNode::Control); | |
3358 Node* adr = make_raw_address(offset, phase); | |
3359 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
3360 | |
3361 // One or two coalesced stores to plop down. | |
3362 Node* st[2]; | |
3363 intptr_t off[2]; | |
3364 int nst = 0; | |
3365 if (!split) { | |
3366 ++new_long; | |
3367 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3368 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3369 phase->longcon(con), T_LONG); |
3370 } else { | |
3371 // Omit either if it is a zero. | |
3372 if (con0 != 0) { | |
3373 ++new_int; | |
3374 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3375 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3376 phase->intcon(con0), T_INT); |
3377 } | |
3378 if (con1 != 0) { | |
3379 ++new_int; | |
3380 offset += BytesPerInt; | |
3381 adr = make_raw_address(offset, phase); | |
3382 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3383 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3384 phase->intcon(con1), T_INT); |
3385 } | |
3386 } | |
3387 | |
3388 // Insert second store first, then the first before the second. | |
3389 // Insert each one just before any overlapping non-constant stores. | |
3390 while (nst > 0) { | |
3391 Node* st1 = st[--nst]; | |
3392 C->copy_node_notes_to(st1, old); | |
3393 st1 = phase->transform(st1); | |
3394 offset = off[nst]; | |
3395 assert(offset >= header_size, "do not smash header"); | |
3396 int ins_idx = captured_store_insertion_point(offset, /*size:*/0, phase); | |
3397 guarantee(ins_idx != 0, "must re-insert constant store"); | |
3398 if (ins_idx < 0) ins_idx = -ins_idx; // never overlap | |
3399 if (ins_idx > InitializeNode::RawStores && in(ins_idx-1) == zmem) | |
3400 set_req(--ins_idx, st1); | |
3401 else | |
3402 ins_req(ins_idx, st1); | |
3403 } | |
3404 } | |
3405 | |
3406 if (PrintCompilation && WizardMode) | |
3407 tty->print_cr("Changed %d/%d subword/long constants into %d/%d int/long", | |
3408 old_subword, old_long, new_int, new_long); | |
3409 if (C->log() != NULL) | |
3410 C->log()->elem("comment that='%d/%d subword/long to %d/%d int/long'", | |
3411 old_subword, old_long, new_int, new_long); | |
3412 | |
3413 // Clean up any remaining occurrences of zmem: | |
3414 remove_extra_zeroes(); | |
3415 } | |
3416 | |
3417 // Explore forward from in(start) to find the first fully initialized | |
3418 // word, and return its offset. Skip groups of subword stores which | |
3419 // together initialize full words. If in(start) is itself part of a | |
3420 // fully initialized word, return the offset of in(start). If there | |
3421 // are no following full-word stores, or if something is fishy, return | |
3422 // a negative value. | |
3423 intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) { | |
3424 int int_map = 0; | |
3425 intptr_t int_map_off = 0; | |
3426 const int FULL_MAP = right_n_bits(BytesPerInt); // the int_map we hope for | |
3427 | |
3428 for (uint i = start, limit = req(); i < limit; i++) { | |
3429 Node* st = in(i); | |
3430 | |
3431 intptr_t st_off = get_store_offset(st, phase); | |
3432 if (st_off < 0) break; // return conservative answer | |
3433 | |
3434 int st_size = st->as_Store()->memory_size(); | |
3435 if (st_size >= BytesPerInt && (st_off % BytesPerInt) == 0) { | |
3436 return st_off; // we found a complete word init | |
3437 } | |
3438 | |
3439 // update the map: | |
3440 | |
3441 intptr_t this_int_off = align_size_down(st_off, BytesPerInt); | |
3442 if (this_int_off != int_map_off) { | |
3443 // reset the map: | |
3444 int_map = 0; | |
3445 int_map_off = this_int_off; | |
3446 } | |
3447 | |
3448 int subword_off = st_off - this_int_off; | |
3449 int_map |= right_n_bits(st_size) << subword_off; | |
3450 if ((int_map & FULL_MAP) == FULL_MAP) { | |
3451 return this_int_off; // we found a complete word init | |
3452 } | |
3453 | |
3454 // Did this store hit or cross the word boundary? | |
3455 intptr_t next_int_off = align_size_down(st_off + st_size, BytesPerInt); | |
3456 if (next_int_off == this_int_off + BytesPerInt) { | |
3457 // We passed the current int, without fully initializing it. | |
3458 int_map_off = next_int_off; | |
3459 int_map >>= BytesPerInt; | |
3460 } else if (next_int_off > this_int_off + BytesPerInt) { | |
3461 // We passed the current and next int. | |
3462 return this_int_off + BytesPerInt; | |
3463 } | |
3464 } | |
3465 | |
3466 return -1; | |
3467 } | |
3468 | |
3469 | |
3470 // Called when the associated AllocateNode is expanded into CFG. | |
3471 // At this point, we may perform additional optimizations. | |
3472 // Linearize the stores by ascending offset, to make memory | |
3473 // activity as coherent as possible. | |
3474 Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, | |
3475 intptr_t header_size, | |
3476 Node* size_in_bytes, | |
3477 PhaseGVN* phase) { | |
3478 assert(!is_complete(), "not already complete"); | |
3479 assert(stores_are_sane(phase), ""); | |
3480 assert(allocation() != NULL, "must be present"); | |
3481 | |
3482 remove_extra_zeroes(); | |
3483 | |
3484 if (ReduceFieldZeroing || ReduceBulkZeroing) | |
3485 // reduce instruction count for common initialization patterns | |
3486 coalesce_subword_stores(header_size, size_in_bytes, phase); | |
3487 | |
3488 Node* zmem = zero_memory(); // initially zero memory state | |
3489 Node* inits = zmem; // accumulating a linearized chain of inits | |
3490 #ifdef ASSERT | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3491 intptr_t first_offset = allocation()->minimum_header_size(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3492 intptr_t last_init_off = first_offset; // previous init offset |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3493 intptr_t last_init_end = first_offset; // previous init offset+size |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3494 intptr_t last_tile_end = first_offset; // previous tile offset+size |
0 | 3495 #endif |
3496 intptr_t zeroes_done = header_size; | |
3497 | |
3498 bool do_zeroing = true; // we might give up if inits are very sparse | |
3499 int big_init_gaps = 0; // how many large gaps have we seen? | |
3500 | |
3501 if (ZeroTLAB) do_zeroing = false; | |
3502 if (!ReduceFieldZeroing && !ReduceBulkZeroing) do_zeroing = false; | |
3503 | |
3504 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { | |
3505 Node* st = in(i); | |
3506 intptr_t st_off = get_store_offset(st, phase); | |
3507 if (st_off < 0) | |
3508 break; // unknown junk in the inits | |
3509 if (st->in(MemNode::Memory) != zmem) | |
3510 break; // complicated store chains somehow in list | |
3511 | |
3512 int st_size = st->as_Store()->memory_size(); | |
3513 intptr_t next_init_off = st_off + st_size; | |
3514 | |
3515 if (do_zeroing && zeroes_done < next_init_off) { | |
3516 // See if this store needs a zero before it or under it. | |
3517 intptr_t zeroes_needed = st_off; | |
3518 | |
3519 if (st_size < BytesPerInt) { | |
3520 // Look for subword stores which only partially initialize words. | |
3521 // If we find some, we must lay down some word-level zeroes first, | |
3522 // underneath the subword stores. | |
3523 // | |
3524 // Examples: | |
3525 // byte[] a = { p,q,r,s } => a[0]=p,a[1]=q,a[2]=r,a[3]=s | |
3526 // byte[] a = { x,y,0,0 } => a[0..3] = 0, a[0]=x,a[1]=y | |
3527 // byte[] a = { 0,0,z,0 } => a[0..3] = 0, a[2]=z | |
3528 // | |
3529 // Note: coalesce_subword_stores may have already done this, | |
3530 // if it was prompted by constant non-zero subword initializers. | |
3531 // But this case can still arise with non-constant stores. | |
3532 | |
3533 intptr_t next_full_store = find_next_fullword_store(i, phase); | |
3534 | |
3535 // In the examples above: | |
3536 // in(i) p q r s x y z | |
3537 // st_off 12 13 14 15 12 13 14 | |
3538 // st_size 1 1 1 1 1 1 1 | |
3539 // next_full_s. 12 16 16 16 16 16 16 | |
3540 // z's_done 12 16 16 16 12 16 12 | |
3541 // z's_needed 12 16 16 16 16 16 16 | |
3542 // zsize 0 0 0 0 4 0 4 | |
3543 if (next_full_store < 0) { | |
3544 // Conservative tack: Zero to end of current word. | |
3545 zeroes_needed = align_size_up(zeroes_needed, BytesPerInt); | |
3546 } else { | |
3547 // Zero to beginning of next fully initialized word. | |
3548 // Or, don't zero at all, if we are already in that word. | |
3549 assert(next_full_store >= zeroes_needed, "must go forward"); | |
3550 assert((next_full_store & (BytesPerInt-1)) == 0, "even boundary"); | |
3551 zeroes_needed = next_full_store; | |
3552 } | |
3553 } | |
3554 | |
3555 if (zeroes_needed > zeroes_done) { | |
3556 intptr_t zsize = zeroes_needed - zeroes_done; | |
3557 // Do some incremental zeroing on rawmem, in parallel with inits. | |
3558 zeroes_done = align_size_down(zeroes_done, BytesPerInt); | |
3559 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, | |
3560 zeroes_done, zeroes_needed, | |
3561 phase); | |
3562 zeroes_done = zeroes_needed; | |
3563 if (zsize > Matcher::init_array_short_size && ++big_init_gaps > 2) | |
3564 do_zeroing = false; // leave the hole, next time | |
3565 } | |
3566 } | |
3567 | |
3568 // Collect the store and move on: | |
3569 st->set_req(MemNode::Memory, inits); | |
3570 inits = st; // put it on the linearized chain | |
3571 set_req(i, zmem); // unhook from previous position | |
3572 | |
3573 if (zeroes_done == st_off) | |
3574 zeroes_done = next_init_off; | |
3575 | |
3576 assert(!do_zeroing || zeroes_done >= next_init_off, "don't miss any"); | |
3577 | |
3578 #ifdef ASSERT | |
3579 // Various order invariants. Weaker than stores_are_sane because | |
3580 // a large constant tile can be filled in by smaller non-constant stores. | |
3581 assert(st_off >= last_init_off, "inits do not reverse"); | |
3582 last_init_off = st_off; | |
3583 const Type* val = NULL; | |
3584 if (st_size >= BytesPerInt && | |
3585 (val = phase->type(st->in(MemNode::ValueIn)))->singleton() && | |
3586 (int)val->basic_type() < (int)T_OBJECT) { | |
3587 assert(st_off >= last_tile_end, "tiles do not overlap"); | |
3588 assert(st_off >= last_init_end, "tiles do not overwrite inits"); | |
3589 last_tile_end = MAX2(last_tile_end, next_init_off); | |
3590 } else { | |
3591 intptr_t st_tile_end = align_size_up(next_init_off, BytesPerLong); | |
3592 assert(st_tile_end >= last_tile_end, "inits stay with tiles"); | |
3593 assert(st_off >= last_init_end, "inits do not overlap"); | |
3594 last_init_end = next_init_off; // it's a non-tile | |
3595 } | |
3596 #endif //ASSERT | |
3597 } | |
3598 | |
3599 remove_extra_zeroes(); // clear out all the zmems left over | |
3600 add_req(inits); | |
3601 | |
3602 if (!ZeroTLAB) { | |
3603 // If anything remains to be zeroed, zero it all now. | |
3604 zeroes_done = align_size_down(zeroes_done, BytesPerInt); | |
3605 // if it is the last unused 4 bytes of an instance, forget about it | |
3606 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint); | |
3607 if (zeroes_done + BytesPerLong >= size_limit) { | |
3608 assert(allocation() != NULL, ""); | |
2004
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3609 if (allocation()->Opcode() == Op_Allocate) { |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3610 Node* klass_node = allocation()->in(AllocateNode::KlassNode); |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3611 ciKlass* k = phase->type(klass_node)->is_klassptr()->klass(); |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3612 if (zeroes_done == k->layout_helper()) |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3613 zeroes_done = size_limit; |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3614 } |
0 | 3615 } |
3616 if (zeroes_done < size_limit) { | |
3617 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, | |
3618 zeroes_done, size_in_bytes, phase); | |
3619 } | |
3620 } | |
3621 | |
3622 set_complete(phase); | |
3623 return rawmem; | |
3624 } | |
3625 | |
3626 | |
3627 #ifdef ASSERT | |
3628 bool InitializeNode::stores_are_sane(PhaseTransform* phase) { | |
3629 if (is_complete()) | |
3630 return true; // stores could be anything at this point | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3631 assert(allocation() != NULL, "must be present"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3632 intptr_t last_off = allocation()->minimum_header_size(); |
0 | 3633 for (uint i = InitializeNode::RawStores; i < req(); i++) { |
3634 Node* st = in(i); | |
3635 intptr_t st_off = get_store_offset(st, phase); | |
3636 if (st_off < 0) continue; // ignore dead garbage | |
3637 if (last_off > st_off) { | |
3638 tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off); | |
3639 this->dump(2); | |
3640 assert(false, "ascending store offsets"); | |
3641 return false; | |
3642 } | |
3643 last_off = st_off + st->as_Store()->memory_size(); | |
3644 } | |
3645 return true; | |
3646 } | |
3647 #endif //ASSERT | |
3648 | |
3649 | |
3650 | |
3651 | |
3652 //============================MergeMemNode===================================== | |
3653 // | |
3654 // SEMANTICS OF MEMORY MERGES: A MergeMem is a memory state assembled from several | |
3655 // contributing store or call operations. Each contributor provides the memory | |
3656 // state for a particular "alias type" (see Compile::alias_type). For example, | |
3657 // if a MergeMem has an input X for alias category #6, then any memory reference | |
3658 // to alias category #6 may use X as its memory state input, as an exact equivalent | |
3659 // to using the MergeMem as a whole. | |
3660 // Load<6>( MergeMem(<6>: X, ...), p ) <==> Load<6>(X,p) | |
3661 // | |
3662 // (Here, the <N> notation gives the index of the relevant adr_type.) | |
3663 // | |
3664 // In one special case (and more cases in the future), alias categories overlap. | |
3665 // The special alias category "Bot" (Compile::AliasIdxBot) includes all memory | |
3666 // states. Therefore, if a MergeMem has only one contributing input W for Bot, | |
3667 // it is exactly equivalent to that state W: | |
3668 // MergeMem(<Bot>: W) <==> W | |
3669 // | |
3670 // Usually, the merge has more than one input. In that case, where inputs | |
3671 // overlap (i.e., one is Bot), the narrower alias type determines the memory | |
3672 // state for that type, and the wider alias type (Bot) fills in everywhere else: | |
3673 // Load<5>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<5>(W,p) | |
3674 // Load<6>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<6>(X,p) | |
3675 // | |
3676 // A merge can take a "wide" memory state as one of its narrow inputs. | |
3677 // This simply means that the merge observes out only the relevant parts of | |
3678 // the wide input. That is, wide memory states arriving at narrow merge inputs | |
3679 // are implicitly "filtered" or "sliced" as necessary. (This is rare.) | |
3680 // | |
3681 // These rules imply that MergeMem nodes may cascade (via their <Bot> links), | |
3682 // and that memory slices "leak through": | |
3683 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y)) <==> MergeMem(<Bot>: W, <7>: Y) | |
3684 // | |
3685 // But, in such a cascade, repeated memory slices can "block the leak": | |
3686 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y), <7>: Y') <==> MergeMem(<Bot>: W, <7>: Y') | |
3687 // | |
3688 // In the last example, Y is not part of the combined memory state of the | |
3689 // outermost MergeMem. The system must, of course, prevent unschedulable | |
3690 // memory states from arising, so you can be sure that the state Y is somehow | |
3691 // a precursor to state Y'. | |
3692 // | |
3693 // | |
3694 // REPRESENTATION OF MEMORY MERGES: The indexes used to address the Node::in array | |
3695 // of each MergeMemNode array are exactly the numerical alias indexes, including | |
3696 // but not limited to AliasIdxTop, AliasIdxBot, and AliasIdxRaw. The functions | |
3697 // Compile::alias_type (and kin) produce and manage these indexes. | |
3698 // | |
3699 // By convention, the value of in(AliasIdxTop) (i.e., in(1)) is always the top node. | |
3700 // (Note that this provides quick access to the top node inside MergeMem methods, | |
3701 // without the need to reach out via TLS to Compile::current.) | |
3702 // | |
3703 // As a consequence of what was just described, a MergeMem that represents a full | |
3704 // memory state has an edge in(AliasIdxBot) which is a "wide" memory state, | |
3705 // containing all alias categories. | |
3706 // | |
3707 // MergeMem nodes never (?) have control inputs, so in(0) is NULL. | |
3708 // | |
3709 // All other edges in(N) (including in(AliasIdxRaw), which is in(3)) are either | |
3710 // a memory state for the alias type <N>, or else the top node, meaning that | |
3711 // there is no particular input for that alias type. Note that the length of | |
3712 // a MergeMem is variable, and may be extended at any time to accommodate new | |
3713 // memory states at larger alias indexes. When merges grow, they are of course | |
3714 // filled with "top" in the unused in() positions. | |
3715 // | |
3716 // This use of top is named "empty_memory()", or "empty_mem" (no-memory) as a variable. | |
3717 // (Top was chosen because it works smoothly with passes like GCM.) | |
3718 // | |
3719 // For convenience, we hardwire the alias index for TypeRawPtr::BOTTOM. (It is | |
3720 // the type of random VM bits like TLS references.) Since it is always the | |
3721 // first non-Bot memory slice, some low-level loops use it to initialize an | |
3722 // index variable: for (i = AliasIdxRaw; i < req(); i++). | |
3723 // | |
3724 // | |
3725 // ACCESSORS: There is a special accessor MergeMemNode::base_memory which returns | |
3726 // the distinguished "wide" state. The accessor MergeMemNode::memory_at(N) returns | |
3727 // the memory state for alias type <N>, or (if there is no particular slice at <N>, | |
3728 // it returns the base memory. To prevent bugs, memory_at does not accept <Top> | |
3729 // or <Bot> indexes. The iterator MergeMemStream provides robust iteration over | |
3730 // MergeMem nodes or pairs of such nodes, ensuring that the non-top edges are visited. | |
3731 // | |
3732 // %%%% We may get rid of base_memory as a separate accessor at some point; it isn't | |
3733 // really that different from the other memory inputs. An abbreviation called | |
3734 // "bot_memory()" for "memory_at(AliasIdxBot)" would keep code tidy. | |
3735 // | |
3736 // | |
3737 // PARTIAL MEMORY STATES: During optimization, MergeMem nodes may arise that represent | |
3738 // partial memory states. When a Phi splits through a MergeMem, the copy of the Phi | |
3739 // that "emerges though" the base memory will be marked as excluding the alias types | |
3740 // of the other (narrow-memory) copies which "emerged through" the narrow edges: | |
3741 // | |
3742 // Phi<Bot>(U, MergeMem(<Bot>: W, <8>: Y)) | |
3743 // ==Ideal=> MergeMem(<Bot>: Phi<Bot-8>(U, W), Phi<8>(U, Y)) | |
3744 // | |
3745 // This strange "subtraction" effect is necessary to ensure IGVN convergence. | |
3746 // (It is currently unimplemented.) As you can see, the resulting merge is | |
3747 // actually a disjoint union of memory states, rather than an overlay. | |
3748 // | |
3749 | |
3750 //------------------------------MergeMemNode----------------------------------- | |
3751 Node* MergeMemNode::make_empty_memory() { | |
3752 Node* empty_memory = (Node*) Compile::current()->top(); | |
3753 assert(empty_memory->is_top(), "correct sentinel identity"); | |
3754 return empty_memory; | |
3755 } | |
3756 | |
3757 MergeMemNode::MergeMemNode(Node *new_base) : Node(1+Compile::AliasIdxRaw) { | |
3758 init_class_id(Class_MergeMem); | |
3759 // all inputs are nullified in Node::Node(int) | |
3760 // set_input(0, NULL); // no control input | |
3761 | |
3762 // Initialize the edges uniformly to top, for starters. | |
3763 Node* empty_mem = make_empty_memory(); | |
3764 for (uint i = Compile::AliasIdxTop; i < req(); i++) { | |
3765 init_req(i,empty_mem); | |
3766 } | |
3767 assert(empty_memory() == empty_mem, ""); | |
3768 | |
3769 if( new_base != NULL && new_base->is_MergeMem() ) { | |
3770 MergeMemNode* mdef = new_base->as_MergeMem(); | |
3771 assert(mdef->empty_memory() == empty_mem, "consistent sentinels"); | |
3772 for (MergeMemStream mms(this, mdef); mms.next_non_empty2(); ) { | |
3773 mms.set_memory(mms.memory2()); | |
3774 } | |
3775 assert(base_memory() == mdef->base_memory(), ""); | |
3776 } else { | |
3777 set_base_memory(new_base); | |
3778 } | |
3779 } | |
3780 | |
3781 // Make a new, untransformed MergeMem with the same base as 'mem'. | |
3782 // If mem is itself a MergeMem, populate the result with the same edges. | |
3783 MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { | |
3784 return new(C, 1+Compile::AliasIdxRaw) MergeMemNode(mem); | |
3785 } | |
3786 | |
3787 //------------------------------cmp-------------------------------------------- | |
3788 uint MergeMemNode::hash() const { return NO_HASH; } | |
3789 uint MergeMemNode::cmp( const Node &n ) const { | |
3790 return (&n == this); // Always fail except on self | |
3791 } | |
3792 | |
3793 //------------------------------Identity--------------------------------------- | |
3794 Node* MergeMemNode::Identity(PhaseTransform *phase) { | |
3795 // Identity if this merge point does not record any interesting memory | |
3796 // disambiguations. | |
3797 Node* base_mem = base_memory(); | |
3798 Node* empty_mem = empty_memory(); | |
3799 if (base_mem != empty_mem) { // Memory path is not dead? | |
3800 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3801 Node* mem = in(i); | |
3802 if (mem != empty_mem && mem != base_mem) { | |
3803 return this; // Many memory splits; no change | |
3804 } | |
3805 } | |
3806 } | |
3807 return base_mem; // No memory splits; ID on the one true input | |
3808 } | |
3809 | |
3810 //------------------------------Ideal------------------------------------------ | |
3811 // This method is invoked recursively on chains of MergeMem nodes | |
3812 Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
3813 // Remove chain'd MergeMems | |
3814 // | |
3815 // This is delicate, because the each "in(i)" (i >= Raw) is interpreted | |
3816 // relative to the "in(Bot)". Since we are patching both at the same time, | |
3817 // we have to be careful to read each "in(i)" relative to the old "in(Bot)", | |
3818 // but rewrite each "in(i)" relative to the new "in(Bot)". | |
3819 Node *progress = NULL; | |
3820 | |
3821 | |
3822 Node* old_base = base_memory(); | |
3823 Node* empty_mem = empty_memory(); | |
3824 if (old_base == empty_mem) | |
3825 return NULL; // Dead memory path. | |
3826 | |
3827 MergeMemNode* old_mbase; | |
3828 if (old_base != NULL && old_base->is_MergeMem()) | |
3829 old_mbase = old_base->as_MergeMem(); | |
3830 else | |
3831 old_mbase = NULL; | |
3832 Node* new_base = old_base; | |
3833 | |
3834 // simplify stacked MergeMems in base memory | |
3835 if (old_mbase) new_base = old_mbase->base_memory(); | |
3836 | |
3837 // the base memory might contribute new slices beyond my req() | |
3838 if (old_mbase) grow_to_match(old_mbase); | |
3839 | |
3840 // Look carefully at the base node if it is a phi. | |
3841 PhiNode* phi_base; | |
3842 if (new_base != NULL && new_base->is_Phi()) | |
3843 phi_base = new_base->as_Phi(); | |
3844 else | |
3845 phi_base = NULL; | |
3846 | |
3847 Node* phi_reg = NULL; | |
3848 uint phi_len = (uint)-1; | |
3849 if (phi_base != NULL && !phi_base->is_copy()) { | |
3850 // do not examine phi if degraded to a copy | |
3851 phi_reg = phi_base->region(); | |
3852 phi_len = phi_base->req(); | |
3853 // see if the phi is unfinished | |
3854 for (uint i = 1; i < phi_len; i++) { | |
3855 if (phi_base->in(i) == NULL) { | |
3856 // incomplete phi; do not look at it yet! | |
3857 phi_reg = NULL; | |
3858 phi_len = (uint)-1; | |
3859 break; | |
3860 } | |
3861 } | |
3862 } | |
3863 | |
3864 // Note: We do not call verify_sparse on entry, because inputs | |
3865 // can normalize to the base_memory via subsume_node or similar | |
3866 // mechanisms. This method repairs that damage. | |
3867 | |
3868 assert(!old_mbase || old_mbase->is_empty_memory(empty_mem), "consistent sentinels"); | |
3869 | |
3870 // Look at each slice. | |
3871 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3872 Node* old_in = in(i); | |
3873 // calculate the old memory value | |
3874 Node* old_mem = old_in; | |
3875 if (old_mem == empty_mem) old_mem = old_base; | |
3876 assert(old_mem == memory_at(i), ""); | |
3877 | |
3878 // maybe update (reslice) the old memory value | |
3879 | |
3880 // simplify stacked MergeMems | |
3881 Node* new_mem = old_mem; | |
3882 MergeMemNode* old_mmem; | |
3883 if (old_mem != NULL && old_mem->is_MergeMem()) | |
3884 old_mmem = old_mem->as_MergeMem(); | |
3885 else | |
3886 old_mmem = NULL; | |
3887 if (old_mmem == this) { | |
3888 // This can happen if loops break up and safepoints disappear. | |
3889 // A merge of BotPtr (default) with a RawPtr memory derived from a | |
3890 // safepoint can be rewritten to a merge of the same BotPtr with | |
3891 // the BotPtr phi coming into the loop. If that phi disappears | |
3892 // also, we can end up with a self-loop of the mergemem. | |
3893 // In general, if loops degenerate and memory effects disappear, | |
3894 // a mergemem can be left looking at itself. This simply means | |
3895 // that the mergemem's default should be used, since there is | |
3896 // no longer any apparent effect on this slice. | |
3897 // Note: If a memory slice is a MergeMem cycle, it is unreachable | |
3898 // from start. Update the input to TOP. | |
3899 new_mem = (new_base == this || new_base == empty_mem)? empty_mem : new_base; | |
3900 } | |
3901 else if (old_mmem != NULL) { | |
3902 new_mem = old_mmem->memory_at(i); | |
3903 } | |
605 | 3904 // else preceding memory was not a MergeMem |
0 | 3905 |
3906 // replace equivalent phis (unfortunately, they do not GVN together) | |
3907 if (new_mem != NULL && new_mem != new_base && | |
3908 new_mem->req() == phi_len && new_mem->in(0) == phi_reg) { | |
3909 if (new_mem->is_Phi()) { | |
3910 PhiNode* phi_mem = new_mem->as_Phi(); | |
3911 for (uint i = 1; i < phi_len; i++) { | |
3912 if (phi_base->in(i) != phi_mem->in(i)) { | |
3913 phi_mem = NULL; | |
3914 break; | |
3915 } | |
3916 } | |
3917 if (phi_mem != NULL) { | |
3918 // equivalent phi nodes; revert to the def | |
3919 new_mem = new_base; | |
3920 } | |
3921 } | |
3922 } | |
3923 | |
3924 // maybe store down a new value | |
3925 Node* new_in = new_mem; | |
3926 if (new_in == new_base) new_in = empty_mem; | |
3927 | |
3928 if (new_in != old_in) { | |
3929 // Warning: Do not combine this "if" with the previous "if" | |
3930 // A memory slice might have be be rewritten even if it is semantically | |
3931 // unchanged, if the base_memory value has changed. | |
3932 set_req(i, new_in); | |
3933 progress = this; // Report progress | |
3934 } | |
3935 } | |
3936 | |
3937 if (new_base != old_base) { | |
3938 set_req(Compile::AliasIdxBot, new_base); | |
3939 // Don't use set_base_memory(new_base), because we need to update du. | |
3940 assert(base_memory() == new_base, ""); | |
3941 progress = this; | |
3942 } | |
3943 | |
3944 if( base_memory() == this ) { | |
3945 // a self cycle indicates this memory path is dead | |
3946 set_req(Compile::AliasIdxBot, empty_mem); | |
3947 } | |
3948 | |
3949 // Resolve external cycles by calling Ideal on a MergeMem base_memory | |
3950 // Recursion must occur after the self cycle check above | |
3951 if( base_memory()->is_MergeMem() ) { | |
3952 MergeMemNode *new_mbase = base_memory()->as_MergeMem(); | |
3953 Node *m = phase->transform(new_mbase); // Rollup any cycles | |
3954 if( m != NULL && (m->is_top() || | |
3955 m->is_MergeMem() && m->as_MergeMem()->base_memory() == empty_mem) ) { | |
3956 // propagate rollup of dead cycle to self | |
3957 set_req(Compile::AliasIdxBot, empty_mem); | |
3958 } | |
3959 } | |
3960 | |
3961 if( base_memory() == empty_mem ) { | |
3962 progress = this; | |
3963 // Cut inputs during Parse phase only. | |
3964 // During Optimize phase a dead MergeMem node will be subsumed by Top. | |
3965 if( !can_reshape ) { | |
3966 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3967 if( in(i) != empty_mem ) { set_req(i, empty_mem); } | |
3968 } | |
3969 } | |
3970 } | |
3971 | |
3972 if( !progress && base_memory()->is_Phi() && can_reshape ) { | |
3973 // Check if PhiNode::Ideal's "Split phis through memory merges" | |
3974 // transform should be attempted. Look for this->phi->this cycle. | |
3975 uint merge_width = req(); | |
3976 if (merge_width > Compile::AliasIdxRaw) { | |
3977 PhiNode* phi = base_memory()->as_Phi(); | |
3978 for( uint i = 1; i < phi->req(); ++i ) {// For all paths in | |
3979 if (phi->in(i) == this) { | |
3980 phase->is_IterGVN()->_worklist.push(phi); | |
3981 break; | |
3982 } | |
3983 } | |
3984 } | |
3985 } | |
3986 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
3987 assert(progress || verify_sparse(), "please, no dups of base"); |
0 | 3988 return progress; |
3989 } | |
3990 | |
3991 //-------------------------set_base_memory------------------------------------- | |
3992 void MergeMemNode::set_base_memory(Node *new_base) { | |
3993 Node* empty_mem = empty_memory(); | |
3994 set_req(Compile::AliasIdxBot, new_base); | |
3995 assert(memory_at(req()) == new_base, "must set default memory"); | |
3996 // Clear out other occurrences of new_base: | |
3997 if (new_base != empty_mem) { | |
3998 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3999 if (in(i) == new_base) set_req(i, empty_mem); | |
4000 } | |
4001 } | |
4002 } | |
4003 | |
4004 //------------------------------out_RegMask------------------------------------ | |
4005 const RegMask &MergeMemNode::out_RegMask() const { | |
4006 return RegMask::Empty; | |
4007 } | |
4008 | |
4009 //------------------------------dump_spec-------------------------------------- | |
4010 #ifndef PRODUCT | |
4011 void MergeMemNode::dump_spec(outputStream *st) const { | |
4012 st->print(" {"); | |
4013 Node* base_mem = base_memory(); | |
4014 for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) { | |
4015 Node* mem = memory_at(i); | |
4016 if (mem == base_mem) { st->print(" -"); continue; } | |
4017 st->print( " N%d:", mem->_idx ); | |
4018 Compile::current()->get_adr_type(i)->dump_on(st); | |
4019 } | |
4020 st->print(" }"); | |
4021 } | |
4022 #endif // !PRODUCT | |
4023 | |
4024 | |
4025 #ifdef ASSERT | |
4026 static bool might_be_same(Node* a, Node* b) { | |
4027 if (a == b) return true; | |
4028 if (!(a->is_Phi() || b->is_Phi())) return false; | |
4029 // phis shift around during optimization | |
4030 return true; // pretty stupid... | |
4031 } | |
4032 | |
4033 // verify a narrow slice (either incoming or outgoing) | |
4034 static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) { | |
4035 if (!VerifyAliases) return; // don't bother to verify unless requested | |
4036 if (is_error_reported()) return; // muzzle asserts when debugging an error | |
4037 if (Node::in_dump()) return; // muzzle asserts when printing | |
4038 assert(alias_idx >= Compile::AliasIdxRaw, "must not disturb base_memory or sentinel"); | |
4039 assert(n != NULL, ""); | |
4040 // Elide intervening MergeMem's | |
4041 while (n->is_MergeMem()) { | |
4042 n = n->as_MergeMem()->memory_at(alias_idx); | |
4043 } | |
4044 Compile* C = Compile::current(); | |
4045 const TypePtr* n_adr_type = n->adr_type(); | |
4046 if (n == m->empty_memory()) { | |
4047 // Implicit copy of base_memory() | |
4048 } else if (n_adr_type != TypePtr::BOTTOM) { | |
4049 assert(n_adr_type != NULL, "new memory must have a well-defined adr_type"); | |
4050 assert(C->must_alias(n_adr_type, alias_idx), "new memory must match selected slice"); | |
4051 } else { | |
4052 // A few places like make_runtime_call "know" that VM calls are narrow, | |
4053 // and can be used to update only the VM bits stored as TypeRawPtr::BOTTOM. | |
4054 bool expected_wide_mem = false; | |
4055 if (n == m->base_memory()) { | |
4056 expected_wide_mem = true; | |
4057 } else if (alias_idx == Compile::AliasIdxRaw || | |
4058 n == m->memory_at(Compile::AliasIdxRaw)) { | |
4059 expected_wide_mem = true; | |
4060 } else if (!C->alias_type(alias_idx)->is_rewritable()) { | |
4061 // memory can "leak through" calls on channels that | |
4062 // are write-once. Allow this also. | |
4063 expected_wide_mem = true; | |
4064 } | |
4065 assert(expected_wide_mem, "expected narrow slice replacement"); | |
4066 } | |
4067 } | |
4068 #else // !ASSERT | |
4069 #define verify_memory_slice(m,i,n) (0) // PRODUCT version is no-op | |
4070 #endif | |
4071 | |
4072 | |
4073 //-----------------------------memory_at--------------------------------------- | |
4074 Node* MergeMemNode::memory_at(uint alias_idx) const { | |
4075 assert(alias_idx >= Compile::AliasIdxRaw || | |
4076 alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, | |
4077 "must avoid base_memory and AliasIdxTop"); | |
4078 | |
4079 // Otherwise, it is a narrow slice. | |
4080 Node* n = alias_idx < req() ? in(alias_idx) : empty_memory(); | |
4081 Compile *C = Compile::current(); | |
4082 if (is_empty_memory(n)) { | |
4083 // the array is sparse; empty slots are the "top" node | |
4084 n = base_memory(); | |
4085 assert(Node::in_dump() | |
4086 || n == NULL || n->bottom_type() == Type::TOP | |
2317
5a41a201d08c
6812217: Base memory of MergeMem node violates assert during killing expanded AllocateArray node
kvn
parents:
2004
diff
changeset
|
4087 || n->adr_type() == NULL // address is TOP |
0 | 4088 || n->adr_type() == TypePtr::BOTTOM |
4089 || n->adr_type() == TypeRawPtr::BOTTOM | |
4090 || Compile::current()->AliasLevel() == 0, | |
4091 "must be a wide memory"); | |
4092 // AliasLevel == 0 if we are organizing the memory states manually. | |
4093 // See verify_memory_slice for comments on TypeRawPtr::BOTTOM. | |
4094 } else { | |
4095 // make sure the stored slice is sane | |
4096 #ifdef ASSERT | |
4097 if (is_error_reported() || Node::in_dump()) { | |
4098 } else if (might_be_same(n, base_memory())) { | |
4099 // Give it a pass: It is a mostly harmless repetition of the base. | |
4100 // This can arise normally from node subsumption during optimization. | |
4101 } else { | |
4102 verify_memory_slice(this, alias_idx, n); | |
4103 } | |
4104 #endif | |
4105 } | |
4106 return n; | |
4107 } | |
4108 | |
4109 //---------------------------set_memory_at------------------------------------- | |
4110 void MergeMemNode::set_memory_at(uint alias_idx, Node *n) { | |
4111 verify_memory_slice(this, alias_idx, n); | |
4112 Node* empty_mem = empty_memory(); | |
4113 if (n == base_memory()) n = empty_mem; // collapse default | |
4114 uint need_req = alias_idx+1; | |
4115 if (req() < need_req) { | |
4116 if (n == empty_mem) return; // already the default, so do not grow me | |
4117 // grow the sparse array | |
4118 do { | |
4119 add_req(empty_mem); | |
4120 } while (req() < need_req); | |
4121 } | |
4122 set_req( alias_idx, n ); | |
4123 } | |
4124 | |
4125 | |
4126 | |
4127 //--------------------------iteration_setup------------------------------------ | |
4128 void MergeMemNode::iteration_setup(const MergeMemNode* other) { | |
4129 if (other != NULL) { | |
4130 grow_to_match(other); | |
4131 // invariant: the finite support of mm2 is within mm->req() | |
4132 #ifdef ASSERT | |
4133 for (uint i = req(); i < other->req(); i++) { | |
4134 assert(other->is_empty_memory(other->in(i)), "slice left uncovered"); | |
4135 } | |
4136 #endif | |
4137 } | |
4138 // Replace spurious copies of base_memory by top. | |
4139 Node* base_mem = base_memory(); | |
4140 if (base_mem != NULL && !base_mem->is_top()) { | |
4141 for (uint i = Compile::AliasIdxBot+1, imax = req(); i < imax; i++) { | |
4142 if (in(i) == base_mem) | |
4143 set_req(i, empty_memory()); | |
4144 } | |
4145 } | |
4146 } | |
4147 | |
4148 //---------------------------grow_to_match------------------------------------- | |
4149 void MergeMemNode::grow_to_match(const MergeMemNode* other) { | |
4150 Node* empty_mem = empty_memory(); | |
4151 assert(other->is_empty_memory(empty_mem), "consistent sentinels"); | |
4152 // look for the finite support of the other memory | |
4153 for (uint i = other->req(); --i >= req(); ) { | |
4154 if (other->in(i) != empty_mem) { | |
4155 uint new_len = i+1; | |
4156 while (req() < new_len) add_req(empty_mem); | |
4157 break; | |
4158 } | |
4159 } | |
4160 } | |
4161 | |
4162 //---------------------------verify_sparse------------------------------------- | |
4163 #ifndef PRODUCT | |
4164 bool MergeMemNode::verify_sparse() const { | |
4165 assert(is_empty_memory(make_empty_memory()), "sane sentinel"); | |
4166 Node* base_mem = base_memory(); | |
4167 // The following can happen in degenerate cases, since empty==top. | |
4168 if (is_empty_memory(base_mem)) return true; | |
4169 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
4170 assert(in(i) != NULL, "sane slice"); | |
4171 if (in(i) == base_mem) return false; // should have been the sentinel value! | |
4172 } | |
4173 return true; | |
4174 } | |
4175 | |
4176 bool MergeMemStream::match_memory(Node* mem, const MergeMemNode* mm, int idx) { | |
4177 Node* n; | |
4178 n = mm->in(idx); | |
4179 if (mem == n) return true; // might be empty_memory() | |
4180 n = (idx == Compile::AliasIdxBot)? mm->base_memory(): mm->memory_at(idx); | |
4181 if (mem == n) return true; | |
4182 while (n->is_Phi() && (n = n->as_Phi()->is_copy()) != NULL) { | |
4183 if (mem == n) return true; | |
4184 if (n == NULL) break; | |
4185 } | |
4186 return false; | |
4187 } | |
4188 #endif // !PRODUCT |