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