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