Mercurial > hg > graal-compiler
annotate src/share/vm/opto/macro.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | 8651f608fea4 |
children | 6f3fd5150b67 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 2005, 2012, 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:
1367
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1367
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:
1367
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileLog.hpp" | |
27 #include "libadt/vectset.hpp" | |
28 #include "opto/addnode.hpp" | |
29 #include "opto/callnode.hpp" | |
30 #include "opto/cfgnode.hpp" | |
31 #include "opto/compile.hpp" | |
32 #include "opto/connode.hpp" | |
33 #include "opto/locknode.hpp" | |
34 #include "opto/loopnode.hpp" | |
35 #include "opto/macro.hpp" | |
36 #include "opto/memnode.hpp" | |
37 #include "opto/node.hpp" | |
38 #include "opto/phaseX.hpp" | |
39 #include "opto/rootnode.hpp" | |
40 #include "opto/runtime.hpp" | |
41 #include "opto/subnode.hpp" | |
42 #include "opto/type.hpp" | |
43 #include "runtime/sharedRuntime.hpp" | |
0 | 44 |
45 | |
46 // | |
47 // Replace any references to "oldref" in inputs to "use" with "newref". | |
48 // Returns the number of replacements made. | |
49 // | |
50 int PhaseMacroExpand::replace_input(Node *use, Node *oldref, Node *newref) { | |
51 int nreplacements = 0; | |
52 uint req = use->req(); | |
53 for (uint j = 0; j < use->len(); j++) { | |
54 Node *uin = use->in(j); | |
55 if (uin == oldref) { | |
56 if (j < req) | |
57 use->set_req(j, newref); | |
58 else | |
59 use->set_prec(j, newref); | |
60 nreplacements++; | |
61 } else if (j >= req && uin == NULL) { | |
62 break; | |
63 } | |
64 } | |
65 return nreplacements; | |
66 } | |
67 | |
68 void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcall) { | |
69 // Copy debug information and adjust JVMState information | |
70 uint old_dbg_start = oldcall->tf()->domain()->cnt(); | |
71 uint new_dbg_start = newcall->tf()->domain()->cnt(); | |
72 int jvms_adj = new_dbg_start - old_dbg_start; | |
73 assert (new_dbg_start == newcall->req(), "argument count mismatch"); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
74 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
75 Dict* sosn_map = new Dict(cmpkey,hashkey); |
0 | 76 for (uint i = old_dbg_start; i < oldcall->req(); i++) { |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
77 Node* old_in = oldcall->in(i); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
78 // Clone old SafePointScalarObjectNodes, adjusting their field contents. |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
79 if (old_in != NULL && old_in->is_SafePointScalarObject()) { |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
80 SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
81 uint old_unique = C->unique(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
82 Node* new_in = old_sosn->clone(jvms_adj, sosn_map); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
83 if (old_unique != C->unique()) { |
4115 | 84 new_in->set_req(0, C->root()); // reset control edge |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
85 new_in = transform_later(new_in); // Register new node. |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
86 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
87 old_in = new_in; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
88 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
89 newcall->add_req(old_in); |
0 | 90 } |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
91 |
0 | 92 newcall->set_jvms(oldcall->jvms()); |
93 for (JVMState *jvms = newcall->jvms(); jvms != NULL; jvms = jvms->caller()) { | |
94 jvms->set_map(newcall); | |
95 jvms->set_locoff(jvms->locoff()+jvms_adj); | |
96 jvms->set_stkoff(jvms->stkoff()+jvms_adj); | |
97 jvms->set_monoff(jvms->monoff()+jvms_adj); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
0
diff
changeset
|
98 jvms->set_scloff(jvms->scloff()+jvms_adj); |
0 | 99 jvms->set_endoff(jvms->endoff()+jvms_adj); |
100 } | |
101 } | |
102 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
103 Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
104 Node* cmp; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
105 if (mask != 0) { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
106 Node* and_node = transform_later(new (C) AndXNode(word, MakeConX(mask))); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
107 cmp = transform_later(new (C) CmpXNode(and_node, MakeConX(bits))); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
108 } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
109 cmp = word; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
110 } |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
111 Node* bol = transform_later(new (C) BoolNode(cmp, BoolTest::ne)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
112 IfNode* iff = new (C) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
113 transform_later(iff); |
0 | 114 |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
115 // Fast path taken. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
116 Node *fast_taken = transform_later( new (C) IfFalseNode(iff) ); |
0 | 117 |
118 // Fast path not-taken, i.e. slow path | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
119 Node *slow_taken = transform_later( new (C) IfTrueNode(iff) ); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
120 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
121 if (return_fast_path) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
122 region->init_req(edge, slow_taken); // Capture slow-control |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
123 return fast_taken; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
124 } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
125 region->init_req(edge, fast_taken); // Capture fast-control |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
126 return slow_taken; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
127 } |
0 | 128 } |
129 | |
130 //--------------------copy_predefined_input_for_runtime_call-------------------- | |
131 void PhaseMacroExpand::copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call) { | |
132 // Set fixed predefined input arguments | |
133 call->init_req( TypeFunc::Control, ctrl ); | |
134 call->init_req( TypeFunc::I_O , oldcall->in( TypeFunc::I_O) ); | |
135 call->init_req( TypeFunc::Memory , oldcall->in( TypeFunc::Memory ) ); // ????? | |
136 call->init_req( TypeFunc::ReturnAdr, oldcall->in( TypeFunc::ReturnAdr ) ); | |
137 call->init_req( TypeFunc::FramePtr, oldcall->in( TypeFunc::FramePtr ) ); | |
138 } | |
139 | |
140 //------------------------------make_slow_call--------------------------------- | |
141 CallNode* PhaseMacroExpand::make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call, const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1) { | |
142 | |
143 // Slow-path call | |
144 CallNode *call = leaf_name | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
145 ? (CallNode*)new (C) CallLeafNode ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM ) |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
146 : (CallNode*)new (C) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM ); |
0 | 147 |
148 // Slow path call has no side-effects, uses few values | |
149 copy_predefined_input_for_runtime_call(slow_path, oldcall, call ); | |
150 if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); | |
151 if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); | |
152 copy_call_debug_info(oldcall, call); | |
153 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1609
diff
changeset
|
154 _igvn.replace_node(oldcall, call); |
0 | 155 transform_later(call); |
156 | |
157 return call; | |
158 } | |
159 | |
160 void PhaseMacroExpand::extract_call_projections(CallNode *call) { | |
161 _fallthroughproj = NULL; | |
162 _fallthroughcatchproj = NULL; | |
163 _ioproj_fallthrough = NULL; | |
164 _ioproj_catchall = NULL; | |
165 _catchallcatchproj = NULL; | |
166 _memproj_fallthrough = NULL; | |
167 _memproj_catchall = NULL; | |
168 _resproj = NULL; | |
169 for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) { | |
170 ProjNode *pn = call->fast_out(i)->as_Proj(); | |
171 switch (pn->_con) { | |
172 case TypeFunc::Control: | |
173 { | |
174 // For Control (fallthrough) and I_O (catch_all_index) we have CatchProj -> Catch -> Proj | |
175 _fallthroughproj = pn; | |
176 DUIterator_Fast jmax, j = pn->fast_outs(jmax); | |
177 const Node *cn = pn->fast_out(j); | |
178 if (cn->is_Catch()) { | |
179 ProjNode *cpn = NULL; | |
180 for (DUIterator_Fast kmax, k = cn->fast_outs(kmax); k < kmax; k++) { | |
181 cpn = cn->fast_out(k)->as_Proj(); | |
182 assert(cpn->is_CatchProj(), "must be a CatchProjNode"); | |
183 if (cpn->_con == CatchProjNode::fall_through_index) | |
184 _fallthroughcatchproj = cpn; | |
185 else { | |
186 assert(cpn->_con == CatchProjNode::catch_all_index, "must be correct index."); | |
187 _catchallcatchproj = cpn; | |
188 } | |
189 } | |
190 } | |
191 break; | |
192 } | |
193 case TypeFunc::I_O: | |
194 if (pn->_is_io_use) | |
195 _ioproj_catchall = pn; | |
196 else | |
197 _ioproj_fallthrough = pn; | |
198 break; | |
199 case TypeFunc::Memory: | |
200 if (pn->_is_io_use) | |
201 _memproj_catchall = pn; | |
202 else | |
203 _memproj_fallthrough = pn; | |
204 break; | |
205 case TypeFunc::Parms: | |
206 _resproj = pn; | |
207 break; | |
208 default: | |
209 assert(false, "unexpected projection from allocation node."); | |
210 } | |
211 } | |
212 | |
213 } | |
214 | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
215 // Eliminate a card mark sequence. p2x is a ConvP2XNode |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
216 void PhaseMacroExpand::eliminate_card_mark(Node* p2x) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
217 assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required"); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
218 if (!UseG1GC) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
219 // vanilla/CMS post barrier |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
220 Node *shift = p2x->unique_out(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
221 Node *addp = shift->unique_out(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
222 for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) { |
3282 | 223 Node *mem = addp->last_out(j); |
224 if (UseCondCardMark && mem->is_Load()) { | |
225 assert(mem->Opcode() == Op_LoadB, "unexpected code shape"); | |
226 // The load is checking if the card has been written so | |
227 // replace it with zero to fold the test. | |
228 _igvn.replace_node(mem, intcon(0)); | |
229 continue; | |
230 } | |
231 assert(mem->is_Store(), "store required"); | |
232 _igvn.replace_node(mem, mem->in(MemNode::Memory)); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
233 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
234 } else { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
235 // G1 pre/post barriers |
4894
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
236 assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes"); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
237 // It could be only one user, URShift node, in Object.clone() instrinsic |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
238 // but the new allocation is passed to arraycopy stub and it could not |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
239 // be scalar replaced. So we don't check the case. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
240 |
4894
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
241 // An other case of only one user (Xor) is when the value check for NULL |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
242 // in G1 post barrier is folded after CCP so the code which used URShift |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
243 // is removed. |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
244 |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
245 // Take Region node before eliminating post barrier since it also |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
246 // eliminates CastP2X node when it has only one user. |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
247 Node* this_region = p2x->in(0); |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
248 assert(this_region != NULL, ""); |
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
249 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
250 // Remove G1 post barrier. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
251 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
252 // Search for CastP2X->Xor->URShift->Cmp path which |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
253 // checks if the store done to a different from the value's region. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
254 // And replace Cmp with #0 (false) to collapse G1 post barrier. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
255 Node* xorx = NULL; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
256 for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
257 Node* u = p2x->fast_out(i); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
258 if (u->Opcode() == Op_XorX) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
259 xorx = u; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
260 break; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
261 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
262 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
263 assert(xorx != NULL, "missing G1 post barrier"); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
264 Node* shift = xorx->unique_out(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
265 Node* cmpx = shift->unique_out(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
266 assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() && |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
267 cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
268 "missing region check in G1 post barrier"); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
269 _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
270 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
271 // Remove G1 pre barrier. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
272 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
273 // Search "if (marking != 0)" check and set it to "false". |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
274 // There is no G1 pre barrier if previous stored value is NULL |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
275 // (for example, after initialization). |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
276 if (this_region->is_Region() && this_region->req() == 3) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
277 int ind = 1; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
278 if (!this_region->in(ind)->is_IfFalse()) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
279 ind = 2; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
280 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
281 if (this_region->in(ind)->is_IfFalse()) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
282 Node* bol = this_region->in(ind)->in(0)->in(1); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
283 assert(bol->is_Bool(), ""); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
284 cmpx = bol->in(1); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
285 if (bol->as_Bool()->_test._test == BoolTest::ne && |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
286 cmpx->is_Cmp() && cmpx->in(2) == intcon(0) && |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
287 cmpx->in(1)->is_Load()) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
288 Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
289 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
290 PtrQueue::byte_offset_of_active()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
291 if (adr->is_AddP() && adr->in(AddPNode::Base) == top() && |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
292 adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
293 adr->in(AddPNode::Offset) == MakeConX(marking_offset)) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
294 _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
295 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
296 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
297 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
298 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
299 // Now CastP2X can be removed since it is used only on dead path |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
300 // which currently still alive until igvn optimize it. |
4894
b9bc6cae88f2
7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents:
4792
diff
changeset
|
301 assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, ""); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
780
diff
changeset
|
302 _igvn.replace_node(p2x, top()); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
303 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
304 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
305 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
306 // Search for a memory operation for the specified memory slice. |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
307 static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
308 Node *orig_mem = mem; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
309 Node *alloc_mem = alloc->in(TypeFunc::Memory); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
310 const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr(); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
311 while (true) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
312 if (mem == alloc_mem || mem == start_mem ) { |
605 | 313 return mem; // hit one of our sentinels |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
314 } else if (mem->is_MergeMem()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
315 mem = mem->as_MergeMem()->memory_at(alias_idx); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
316 } else if (mem->is_Proj() && mem->as_Proj()->_con == TypeFunc::Memory) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
317 Node *in = mem->in(0); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
318 // we can safely skip over safepoints, calls, locks and membars because we |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
319 // already know that the object is safe to eliminate. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
320 if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
321 return in; |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
322 } else if (in->is_Call()) { |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
323 CallNode *call = in->as_Call(); |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
324 if (!call->may_modify(tinst, phase)) { |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
325 mem = call->in(TypeFunc::Memory); |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
326 } |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
327 mem = in->in(TypeFunc::Memory); |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
328 } else if (in->is_MemBar()) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
329 mem = in->in(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
330 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
331 assert(false, "unexpected projection"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
332 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
333 } else if (mem->is_Store()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
334 const TypePtr* atype = mem->as_Store()->adr_type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
335 int adr_idx = Compile::current()->get_alias_index(atype); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
336 if (adr_idx == alias_idx) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
337 assert(atype->isa_oopptr(), "address type must be oopptr"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
338 int adr_offset = atype->offset(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
339 uint adr_iid = atype->is_oopptr()->instance_id(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
340 // Array elements references have the same alias_idx |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
341 // but different offset and different instance_id. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
342 if (adr_offset == offset && adr_iid == alloc->_idx) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
343 return mem; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
344 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
345 assert(adr_idx == Compile::AliasIdxRaw, "address must match or be raw"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
346 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
347 mem = mem->in(MemNode::Memory); |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
348 } else if (mem->is_ClearArray()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
349 if (!ClearArrayNode::step_through(&mem, alloc->_idx, phase)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
350 // Can not bypass initialization of the instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
351 // we are looking. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
352 debug_only(intptr_t offset;) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
353 assert(alloc == AllocateNode::Ideal_allocation(mem->in(3), phase, offset), "sanity"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
354 InitializeNode* init = alloc->as_Allocate()->initialization(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
355 // We are looking for stored value, return Initialize node |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
356 // or memory edge from Allocate node. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
357 if (init != NULL) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
358 return init; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
359 else |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
360 return alloc->in(TypeFunc::Memory); // It will produce zero value (see callers). |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
361 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
362 // Otherwise skip it (the call updated 'mem' value). |
584 | 363 } else if (mem->Opcode() == Op_SCMemProj) { |
7637
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
364 mem = mem->in(0); |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
365 Node* adr = NULL; |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
366 if (mem->is_LoadStore()) { |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
367 adr = mem->in(MemNode::Address); |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
368 } else { |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
369 assert(mem->Opcode() == Op_EncodeISOArray, "sanity"); |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
370 adr = mem->in(3); // Destination array |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
371 } |
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
372 const TypePtr* atype = adr->bottom_type()->is_ptr(); |
584 | 373 int adr_idx = Compile::current()->get_alias_index(atype); |
374 if (adr_idx == alias_idx) { | |
375 assert(false, "Object is not scalar replaceable if a LoadStore node access its field"); | |
376 return NULL; | |
377 } | |
7637
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
378 mem = mem->in(MemNode::Memory); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
379 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
380 return mem; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
381 } |
247 | 382 assert(mem != orig_mem, "dead memory loop"); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
383 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
384 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
385 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
386 // |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
387 // Given a Memory Phi, compute a value Phi containing the values from stores |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
388 // on the input paths. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
389 // Note: this function is recursive, its depth is limied by the "level" argument |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
390 // Returns the computed Phi, or NULL if it cannot compute it. |
247 | 391 Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) { |
392 assert(mem->is_Phi(), "sanity"); | |
393 int alias_idx = C->get_alias_index(adr_t); | |
394 int offset = adr_t->offset(); | |
395 int instance_id = adr_t->instance_id(); | |
396 | |
397 // Check if an appropriate value phi already exists. | |
398 Node* region = mem->in(0); | |
399 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { | |
400 Node* phi = region->fast_out(k); | |
401 if (phi->is_Phi() && phi != mem && | |
402 phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { | |
403 return phi; | |
404 } | |
405 } | |
406 // Check if an appropriate new value phi already exists. | |
3788
e3cbc9ddd434
7044738: Loop unroll optimization causes incorrect result
kvn
parents:
3754
diff
changeset
|
407 Node* new_phi = value_phis->find(mem->_idx); |
e3cbc9ddd434
7044738: Loop unroll optimization causes incorrect result
kvn
parents:
3754
diff
changeset
|
408 if (new_phi != NULL) |
e3cbc9ddd434
7044738: Loop unroll optimization causes incorrect result
kvn
parents:
3754
diff
changeset
|
409 return new_phi; |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
410 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
411 if (level <= 0) { |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
412 return NULL; // Give up: phi tree too deep |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
413 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
414 Node *start_mem = C->start()->proj_out(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
415 Node *alloc_mem = alloc->in(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
416 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
417 uint length = mem->req(); |
6197 | 418 GrowableArray <Node *> values(length, length, NULL, false); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
419 |
247 | 420 // create a new Phi for the value |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
421 PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); |
247 | 422 transform_later(phi); |
423 value_phis->push(phi, mem->_idx); | |
424 | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
425 for (uint j = 1; j < length; j++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
426 Node *in = mem->in(j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
427 if (in == NULL || in->is_top()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
428 values.at_put(j, in); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
429 } else { |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
430 Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
431 if (val == start_mem || val == alloc_mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
432 // hit a sentinel, return appropriate 0 value |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
433 values.at_put(j, _igvn.zerocon(ft)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
434 continue; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
435 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
436 if (val->is_Initialize()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
437 val = val->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
438 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
439 if (val == NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
440 return NULL; // can't find a value on this path |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
441 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
442 if (val == mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
443 values.at_put(j, mem); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
444 } else if (val->is_Store()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
445 values.at_put(j, val->in(MemNode::ValueIn)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
446 } else if(val->is_Proj() && val->in(0) == alloc) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
447 values.at_put(j, _igvn.zerocon(ft)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
448 } else if (val->is_Phi()) { |
247 | 449 val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1); |
450 if (val == NULL) { | |
451 return NULL; | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
452 } |
247 | 453 values.at_put(j, val); |
584 | 454 } else if (val->Opcode() == Op_SCMemProj) { |
7637
b30b3c2a0cf2
6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86
kvn
parents:
7196
diff
changeset
|
455 assert(val->in(0)->is_LoadStore() || val->in(0)->Opcode() == Op_EncodeISOArray, "sanity"); |
584 | 456 assert(false, "Object is not scalar replaceable if a LoadStore node access its field"); |
457 return NULL; | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
458 } else { |
584 | 459 #ifdef ASSERT |
460 val->dump(); | |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
461 assert(false, "unknown node on this path"); |
584 | 462 #endif |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
463 return NULL; // unknown node on this path |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
464 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
465 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
466 } |
247 | 467 // Set Phi's inputs |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
468 for (uint j = 1; j < length; j++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
469 if (values.at(j) == mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
470 phi->init_req(j, phi); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
471 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
472 phi->init_req(j, values.at(j)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
473 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
474 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
475 return phi; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
476 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
477 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
478 // Search the last value stored into the object's field. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
479 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) { |
223 | 480 assert(adr_t->is_known_instance_field(), "instance required"); |
481 int instance_id = adr_t->instance_id(); | |
482 assert((uint)instance_id == alloc->_idx, "wrong allocation"); | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
483 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
484 int alias_idx = C->get_alias_index(adr_t); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
485 int offset = adr_t->offset(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
486 Node *start_mem = C->start()->proj_out(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
487 Node *alloc_ctrl = alloc->in(TypeFunc::Control); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
488 Node *alloc_mem = alloc->in(TypeFunc::Memory); |
247 | 489 Arena *a = Thread::current()->resource_area(); |
490 VectorSet visited(a); | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
491 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
492 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
493 bool done = sfpt_mem == alloc_mem; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
494 Node *mem = sfpt_mem; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
495 while (!done) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
496 if (visited.test_set(mem->_idx)) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
497 return NULL; // found a loop, give up |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
498 } |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
499 mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
500 if (mem == start_mem || mem == alloc_mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
501 done = true; // hit a sentinel, return appropriate 0 value |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
502 } else if (mem->is_Initialize()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
503 mem = mem->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
504 if (mem == NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
505 done = true; // Something go wrong. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
506 } else if (mem->is_Store()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
507 const TypePtr* atype = mem->as_Store()->adr_type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
508 assert(C->get_alias_index(atype) == Compile::AliasIdxRaw, "store is correct memory slice"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
509 done = true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
510 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
511 } else if (mem->is_Store()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
512 const TypeOopPtr* atype = mem->as_Store()->adr_type()->isa_oopptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
513 assert(atype != NULL, "address type must be oopptr"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
514 assert(C->get_alias_index(atype) == alias_idx && |
223 | 515 atype->is_known_instance_field() && atype->offset() == offset && |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
516 atype->instance_id() == instance_id, "store is correct memory slice"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
517 done = true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
518 } else if (mem->is_Phi()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
519 // try to find a phi's unique input |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
520 Node *unique_input = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
521 Node *top = C->top(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
522 for (uint i = 1; i < mem->req(); i++) { |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
523 Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
524 if (n == NULL || n == top || n == mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
525 continue; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
526 } else if (unique_input == NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
527 unique_input = n; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
528 } else if (unique_input != n) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
529 unique_input = top; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
530 break; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
531 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
532 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
533 if (unique_input != NULL && unique_input != top) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
534 mem = unique_input; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
535 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
536 done = true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
537 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
538 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
539 assert(false, "unexpected node"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
540 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
541 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
542 if (mem != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
543 if (mem == start_mem || mem == alloc_mem) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
544 // hit a sentinel, return appropriate 0 value |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
545 return _igvn.zerocon(ft); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
546 } else if (mem->is_Store()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
547 return mem->in(MemNode::ValueIn); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
548 } else if (mem->is_Phi()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
549 // attempt to produce a Phi reflecting the values on the input paths of the Phi |
247 | 550 Node_Stack value_phis(a, 8); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
551 Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
552 if (phi != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
553 return phi; |
247 | 554 } else { |
555 // Kill all new Phis | |
556 while(value_phis.is_nonempty()) { | |
557 Node* n = value_phis.node(); | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1609
diff
changeset
|
558 _igvn.replace_node(n, C->top()); |
247 | 559 value_phis.pop(); |
560 } | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
561 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
562 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
563 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
564 // Something go wrong. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
565 return NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
566 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
567 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
568 // Check the possibility of scalar replacement. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
569 bool PhaseMacroExpand::can_eliminate_allocation(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
570 // Scan the uses of the allocation to check for anything that would |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
571 // prevent us from eliminating it. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
572 NOT_PRODUCT( const char* fail_eliminate = NULL; ) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
573 DEBUG_ONLY( Node* disq_node = NULL; ) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
574 bool can_eliminate = true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
575 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
576 Node* res = alloc->result_cast(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
577 const TypeOopPtr* res_type = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
578 if (res == NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
579 // All users were eliminated. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
580 } else if (!res->is_CheckCastPP()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
581 NOT_PRODUCT(fail_eliminate = "Allocation does not have unique CheckCastPP";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
582 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
583 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
584 res_type = _igvn.type(res)->isa_oopptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
585 if (res_type == NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
586 NOT_PRODUCT(fail_eliminate = "Neither instance or array allocation";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
587 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
588 } else if (res_type->isa_aryptr()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
589 int length = alloc->in(AllocateNode::ALength)->find_int_con(-1); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
590 if (length < 0) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
591 NOT_PRODUCT(fail_eliminate = "Array's size is not constant";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
592 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
593 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
594 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
595 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
596 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
597 if (can_eliminate && res != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
598 for (DUIterator_Fast jmax, j = res->fast_outs(jmax); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
599 j < jmax && can_eliminate; j++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
600 Node* use = res->fast_out(j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
601 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
602 if (use->is_AddP()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
603 const TypePtr* addp_type = _igvn.type(use)->is_ptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
604 int offset = addp_type->offset(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
605 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
606 if (offset == Type::OffsetTop || offset == Type::OffsetBot) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
607 NOT_PRODUCT(fail_eliminate = "Undefined field referrence";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
608 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
609 break; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
610 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
611 for (DUIterator_Fast kmax, k = use->fast_outs(kmax); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
612 k < kmax && can_eliminate; k++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
613 Node* n = use->fast_out(k); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
614 if (!n->is_Store() && n->Opcode() != Op_CastP2X) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
615 DEBUG_ONLY(disq_node = n;) |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
616 if (n->is_Load() || n->is_LoadStore()) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
617 NOT_PRODUCT(fail_eliminate = "Field load";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
618 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
619 NOT_PRODUCT(fail_eliminate = "Not store field referrence";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
620 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
621 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
622 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
623 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
624 } else if (use->is_SafePoint()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
625 SafePointNode* sfpt = use->as_SafePoint(); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
163
diff
changeset
|
626 if (sfpt->is_Call() && sfpt->as_Call()->has_non_debug_use(res)) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
627 // Object is passed as argument. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
628 DEBUG_ONLY(disq_node = use;) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
629 NOT_PRODUCT(fail_eliminate = "Object is passed as argument";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
630 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
631 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
632 Node* sfptMem = sfpt->memory(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
633 if (sfptMem == NULL || sfptMem->is_top()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
634 DEBUG_ONLY(disq_node = use;) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
635 NOT_PRODUCT(fail_eliminate = "NULL or TOP memory";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
636 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
637 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
638 safepoints.append_if_missing(sfpt); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
639 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
640 } else if (use->Opcode() != Op_CastP2X) { // CastP2X is used by card mark |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
641 if (use->is_Phi()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
642 if (use->outcnt() == 1 && use->unique_out()->Opcode() == Op_Return) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
643 NOT_PRODUCT(fail_eliminate = "Object is return value";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
644 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
645 NOT_PRODUCT(fail_eliminate = "Object is referenced by Phi";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
646 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
647 DEBUG_ONLY(disq_node = use;) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
648 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
649 if (use->Opcode() == Op_Return) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
650 NOT_PRODUCT(fail_eliminate = "Object is return value";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
651 }else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
652 NOT_PRODUCT(fail_eliminate = "Object is referenced by node";) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
653 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
654 DEBUG_ONLY(disq_node = use;) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
655 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
656 can_eliminate = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
657 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
658 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
659 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
660 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
661 #ifndef PRODUCT |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
662 if (PrintEliminateAllocations) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
663 if (can_eliminate) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
664 tty->print("Scalar "); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
665 if (res == NULL) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
666 alloc->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
667 else |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
668 res->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
669 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
670 tty->print("NotScalar (%s)", fail_eliminate); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
671 if (res == NULL) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
672 alloc->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
673 else |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
674 res->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
675 #ifdef ASSERT |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
676 if (disq_node != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
677 tty->print(" >>>> "); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
678 disq_node->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
679 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
680 #endif /*ASSERT*/ |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
681 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
682 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
683 #endif |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
684 return can_eliminate; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
685 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
686 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
687 // Do scalar replacement. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
688 bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
689 GrowableArray <SafePointNode *> safepoints_done; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
690 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
691 ciKlass* klass = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
692 ciInstanceKlass* iklass = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
693 int nfields = 0; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
694 int array_base; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
695 int element_size; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
696 BasicType basic_elem_type; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
697 ciType* elem_type; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
698 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
699 Node* res = alloc->result_cast(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
700 const TypeOopPtr* res_type = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
701 if (res != NULL) { // Could be NULL when there are no users |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
702 res_type = _igvn.type(res)->isa_oopptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
703 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
704 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
705 if (res != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
706 klass = res_type->klass(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
707 if (res_type->isa_instptr()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
708 // find the fields of the class which will be needed for safepoint debug information |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
709 assert(klass->is_instance_klass(), "must be an instance klass."); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
710 iklass = klass->as_instance_klass(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
711 nfields = iklass->nof_nonstatic_fields(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
712 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
713 // find the array's elements which will be needed for safepoint debug information |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
714 nfields = alloc->in(AllocateNode::ALength)->find_int_con(-1); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
715 assert(klass->is_array_klass() && nfields >= 0, "must be an array klass."); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
716 elem_type = klass->as_array_klass()->element_type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
717 basic_elem_type = elem_type->basic_type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
718 array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
719 element_size = type2aelembytes(basic_elem_type); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
720 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
721 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
722 // |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
723 // Process the safepoint uses |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
724 // |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
725 while (safepoints.length() > 0) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
726 SafePointNode* sfpt = safepoints.pop(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
727 Node* mem = sfpt->memory(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
728 uint first_ind = sfpt->req(); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
729 SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type, |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
730 #ifdef ASSERT |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
731 alloc, |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
732 #endif |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
733 first_ind, nfields); |
4115 | 734 sobj->init_req(0, C->root()); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
735 transform_later(sobj); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
736 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
737 // Scan object's fields adding an input to the safepoint for each field. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
738 for (int j = 0; j < nfields; j++) { |
306
af945ba2e739
6741738: TypePtr::add_offset() set incorrect offset when the add overflows
kvn
parents:
253
diff
changeset
|
739 intptr_t offset; |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
740 ciField* field = NULL; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
741 if (iklass != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
742 field = iklass->nonstatic_field_at(j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
743 offset = field->offset(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
744 elem_type = field->type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
745 basic_elem_type = field->layout_type(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
746 } else { |
306
af945ba2e739
6741738: TypePtr::add_offset() set incorrect offset when the add overflows
kvn
parents:
253
diff
changeset
|
747 offset = array_base + j * (intptr_t)element_size; |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
748 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
749 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
750 const Type *field_type; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
751 // The next code is taken from Parse::do_get_xxx(). |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
752 if (basic_elem_type == T_OBJECT || basic_elem_type == T_ARRAY) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
753 if (!elem_type->is_loaded()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
754 field_type = TypeInstPtr::BOTTOM; |
1682
e5dfb3ccb88b
6969569: assert(is_static() && is_constant()) failed: illegal call to constant_value()
kvn
parents:
1621
diff
changeset
|
755 } else if (field != NULL && field->is_constant() && field->is_static()) { |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
756 // This can happen if the constant oop is non-perm. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
757 ciObject* con = field->constant_value().as_object(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
758 // Do not "join" in the previous type; it doesn't add value, |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
759 // and may yield a vacuous result if the field is of interface type. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
760 field_type = TypeOopPtr::make_from_constant(con)->isa_oopptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
761 assert(field_type != NULL, "field singleton type must be consistent"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
762 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
763 field_type = TypeOopPtr::make_from_klass(elem_type->as_klass()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
764 } |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
765 if (UseCompressedOops) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
766 field_type = field_type->make_narrowoop(); |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
767 basic_elem_type = T_NARROWOOP; |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
768 } |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
769 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
770 field_type = Type::get_const_basic_type(basic_elem_type); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
771 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
772 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
773 const TypeOopPtr *field_addr_type = res_type->add_offset(offset)->isa_oopptr(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
774 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
775 Node *field_val = value_from_mem(mem, basic_elem_type, field_type, field_addr_type, alloc); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
776 if (field_val == NULL) { |
4115 | 777 // We weren't able to find a value for this field, |
778 // give up on eliminating this allocation. | |
779 | |
780 // Remove any extra entries we added to the safepoint. | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
781 uint last = sfpt->req() - 1; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
782 for (int k = 0; k < j; k++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
783 sfpt->del_req(last--); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
784 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
785 // rollback processed safepoints |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
786 while (safepoints_done.length() > 0) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
787 SafePointNode* sfpt_done = safepoints_done.pop(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
788 // remove any extra entries we added to the safepoint |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
789 last = sfpt_done->req() - 1; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
790 for (int k = 0; k < nfields; k++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
791 sfpt_done->del_req(last--); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
792 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
793 JVMState *jvms = sfpt_done->jvms(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
794 jvms->set_endoff(sfpt_done->req()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
795 // Now make a pass over the debug information replacing any references |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
796 // to SafePointScalarObjectNode with the allocated object. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
797 int start = jvms->debug_start(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
798 int end = jvms->debug_end(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
799 for (int i = start; i < end; i++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
800 if (sfpt_done->in(i)->is_SafePointScalarObject()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
801 SafePointScalarObjectNode* scobj = sfpt_done->in(i)->as_SafePointScalarObject(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
802 if (scobj->first_index() == sfpt_done->req() && |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
803 scobj->n_fields() == (uint)nfields) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
804 assert(scobj->alloc() == alloc, "sanity"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
805 sfpt_done->set_req(i, res); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
806 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
807 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
808 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
809 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
810 #ifndef PRODUCT |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
811 if (PrintEliminateAllocations) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
812 if (field != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
813 tty->print("=== At SafePoint node %d can't find value of Field: ", |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
814 sfpt->_idx); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
815 field->print(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
816 int field_idx = C->get_alias_index(field_addr_type); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
817 tty->print(" (alias_idx=%d)", field_idx); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
818 } else { // Array's element |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
819 tty->print("=== At SafePoint node %d can't find value of array element [%d]", |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
820 sfpt->_idx, j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
821 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
822 tty->print(", which prevents elimination of: "); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
823 if (res == NULL) |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
824 alloc->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
825 else |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
826 res->dump(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
827 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
828 #endif |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
829 return false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
830 } |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
831 if (UseCompressedOops && field_type->isa_narrowoop()) { |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
832 // Enable "DecodeN(EncodeP(Allocate)) --> Allocate" transformation |
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
833 // to be able scalar replace the allocation. |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
834 if (field_val->is_EncodeP()) { |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
835 field_val = field_val->in(1); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
836 } else { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
837 field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr())); |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
838 } |
124
b130b98db9cf
6689060: Escape Analysis does not work with Compressed Oops
kvn
parents:
113
diff
changeset
|
839 } |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
840 sfpt->add_req(field_val); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
841 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
842 JVMState *jvms = sfpt->jvms(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
843 jvms->set_endoff(sfpt->req()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
844 // Now make a pass over the debug information replacing any references |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
845 // to the allocated object with "sobj" |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
846 int start = jvms->debug_start(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
847 int end = jvms->debug_end(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
848 for (int i = start; i < end; i++) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
849 if (sfpt->in(i) == res) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
850 sfpt->set_req(i, sobj); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
851 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
852 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
853 safepoints_done.append_if_missing(sfpt); // keep it for rollback |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
854 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
855 return true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
856 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
857 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
858 // Process users of eliminated allocation. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
859 void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
860 Node* res = alloc->result_cast(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
861 if (res != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
862 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
863 Node *use = res->last_out(j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
864 uint oc1 = res->outcnt(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
865 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
866 if (use->is_AddP()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
867 for (DUIterator_Last kmin, k = use->last_outs(kmin); k >= kmin; ) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
868 Node *n = use->last_out(k); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
869 uint oc2 = use->outcnt(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
870 if (n->is_Store()) { |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
871 #ifdef ASSERT |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
872 // Verify that there is no dependent MemBarVolatile nodes, |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
873 // they should be removed during IGVN, see MemBarNode::Ideal(). |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
874 for (DUIterator_Fast pmax, p = n->fast_outs(pmax); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
875 p < pmax; p++) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
876 Node* mb = n->fast_out(p); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
877 assert(mb->is_Initialize() || !mb->is_MemBar() || |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
878 mb->req() <= MemBarNode::Precedent || |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
879 mb->in(MemBarNode::Precedent) != n, |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
880 "MemBarVolatile should be eliminated for non-escaping object"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
881 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
882 #endif |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
883 _igvn.replace_node(n, n->in(MemNode::Memory)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
884 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
885 eliminate_card_mark(n); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
886 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
887 k -= (oc2 - use->outcnt()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
888 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
889 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
890 eliminate_card_mark(use); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
891 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
892 j -= (oc1 - res->outcnt()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
893 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
894 assert(res->outcnt() == 0, "all uses of allocated objects must be deleted"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
895 _igvn.remove_dead_node(res); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
896 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
897 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
898 // |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
899 // Process other users of allocation's projections |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
900 // |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
901 if (_resproj != NULL && _resproj->outcnt() != 0) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
902 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
903 Node *use = _resproj->last_out(j); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
904 uint oc1 = _resproj->outcnt(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
905 if (use->is_Initialize()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
906 // Eliminate Initialize node. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
907 InitializeNode *init = use->as_Initialize(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
908 assert(init->outcnt() <= 2, "only a control and memory projection expected"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
909 Node *ctrl_proj = init->proj_out(TypeFunc::Control); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
910 if (ctrl_proj != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
911 assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
912 _igvn.replace_node(ctrl_proj, _fallthroughcatchproj); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
913 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
914 Node *mem_proj = init->proj_out(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
915 if (mem_proj != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
916 Node *mem = init->in(TypeFunc::Memory); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
917 #ifdef ASSERT |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
918 if (mem->is_MergeMem()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
919 assert(mem->in(TypeFunc::Memory) == _memproj_fallthrough, "allocation memory projection"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
920 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
921 assert(mem == _memproj_fallthrough, "allocation memory projection"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
922 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
923 #endif |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
924 _igvn.replace_node(mem_proj, mem); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
925 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
926 } else if (use->is_AddP()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
927 // raw memory addresses used only by the initialization |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
928 _igvn.replace_node(use, C->top()); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
929 } else { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
930 assert(false, "only Initialize or AddP expected"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
931 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
932 j -= (oc1 - _resproj->outcnt()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
933 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
934 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
935 if (_fallthroughcatchproj != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
936 _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
937 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
938 if (_memproj_fallthrough != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
939 _igvn.replace_node(_memproj_fallthrough, alloc->in(TypeFunc::Memory)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
940 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
941 if (_memproj_catchall != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
942 _igvn.replace_node(_memproj_catchall, C->top()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
943 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
944 if (_ioproj_fallthrough != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
945 _igvn.replace_node(_ioproj_fallthrough, alloc->in(TypeFunc::I_O)); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
946 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
947 if (_ioproj_catchall != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
948 _igvn.replace_node(_ioproj_catchall, C->top()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
949 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
950 if (_catchallcatchproj != NULL) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
951 _igvn.replace_node(_catchallcatchproj, C->top()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
952 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
953 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
954 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
955 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
956 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
957 if (!EliminateAllocations || !alloc->_is_scalar_replaceable) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
958 return false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
959 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
960 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
961 extract_call_projections(alloc); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
962 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
963 GrowableArray <SafePointNode *> safepoints; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
964 if (!can_eliminate_allocation(alloc, safepoints)) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
965 return false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
966 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
967 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
968 if (!scalar_replacement(alloc, safepoints)) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
969 return false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
970 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
971 |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
972 CompileLog* log = C->log(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
973 if (log != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
974 Node* klass = alloc->in(AllocateNode::KlassNode); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
975 const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
976 log->head("eliminate_allocation type='%d'", |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
977 log->identify(tklass->klass())); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
978 JVMState* p = alloc->jvms(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
979 while (p != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
980 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
981 p = p->caller(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
982 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
983 log->tail("eliminate_allocation"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
984 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
985 |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
986 process_users_of_allocation(alloc); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
987 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
988 #ifndef PRODUCT |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
989 if (PrintEliminateAllocations) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
990 if (alloc->is_AllocateArray()) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
991 tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
992 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
993 tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
994 } |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
995 #endif |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
996 |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
997 return true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
998 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
999 |
0 | 1000 |
1001 //---------------------------set_eden_pointers------------------------- | |
1002 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { | |
1003 if (UseTLAB) { // Private allocation: load from TLS | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1004 Node* thread = transform_later(new (C) ThreadLocalNode()); |
0 | 1005 int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset()); |
1006 int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset()); | |
1007 eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset); | |
1008 eden_end_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_end_offset); | |
1009 } else { // Shared allocation: load from globals | |
1010 CollectedHeap* ch = Universe::heap(); | |
1011 address top_adr = (address)ch->top_addr(); | |
1012 address end_adr = (address)ch->end_addr(); | |
1013 eden_top_adr = makecon(TypeRawPtr::make(top_adr)); | |
1014 eden_end_adr = basic_plus_adr(eden_top_adr, end_adr - top_adr); | |
1015 } | |
1016 } | |
1017 | |
1018 | |
1019 Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) { | |
1020 Node* adr = basic_plus_adr(base, offset); | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
1021 const TypePtr* adr_type = adr->bottom_type()->is_ptr(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
1022 Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt); |
0 | 1023 transform_later(value); |
1024 return value; | |
1025 } | |
1026 | |
1027 | |
1028 Node* PhaseMacroExpand::make_store(Node* ctl, Node* mem, Node* base, int offset, Node* value, BasicType bt) { | |
1029 Node* adr = basic_plus_adr(base, offset); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
1030 mem = StoreNode::make(_igvn, ctl, mem, adr, NULL, value, bt); |
0 | 1031 transform_later(mem); |
1032 return mem; | |
1033 } | |
1034 | |
1035 //============================================================================= | |
1036 // | |
1037 // A L L O C A T I O N | |
1038 // | |
1039 // Allocation attempts to be fast in the case of frequent small objects. | |
1040 // It breaks down like this: | |
1041 // | |
1042 // 1) Size in doublewords is computed. This is a constant for objects and | |
1043 // variable for most arrays. Doubleword units are used to avoid size | |
1044 // overflow of huge doubleword arrays. We need doublewords in the end for | |
1045 // rounding. | |
1046 // | |
1047 // 2) Size is checked for being 'too large'. Too-large allocations will go | |
1048 // the slow path into the VM. The slow path can throw any required | |
1049 // exceptions, and does all the special checks for very large arrays. The | |
1050 // size test can constant-fold away for objects. For objects with | |
1051 // finalizers it constant-folds the otherway: you always go slow with | |
1052 // finalizers. | |
1053 // | |
1054 // 3) If NOT using TLABs, this is the contended loop-back point. | |
1055 // Load-Locked the heap top. If using TLABs normal-load the heap top. | |
1056 // | |
1057 // 4) Check that heap top + size*8 < max. If we fail go the slow ` route. | |
1058 // NOTE: "top+size*8" cannot wrap the 4Gig line! Here's why: for largish | |
1059 // "size*8" we always enter the VM, where "largish" is a constant picked small | |
1060 // enough that there's always space between the eden max and 4Gig (old space is | |
1061 // there so it's quite large) and large enough that the cost of entering the VM | |
1062 // is dwarfed by the cost to initialize the space. | |
1063 // | |
1064 // 5) If NOT using TLABs, Store-Conditional the adjusted heap top back | |
1065 // down. If contended, repeat at step 3. If using TLABs normal-store | |
1066 // adjusted heap top back down; there is no contention. | |
1067 // | |
1068 // 6) If !ZeroTLAB then Bulk-clear the object/array. Fill in klass & mark | |
1069 // fields. | |
1070 // | |
1071 // 7) Merge with the slow-path; cast the raw memory pointer to the correct | |
1072 // oop flavor. | |
1073 // | |
1074 //============================================================================= | |
1075 // FastAllocateSizeLimit value is in DOUBLEWORDS. | |
1076 // Allocations bigger than this always go the slow route. | |
1077 // This value must be small enough that allocation attempts that need to | |
1078 // trigger exceptions go the slow route. Also, it must be small enough so | |
1079 // that heap_top + size_in_bytes does not wrap around the 4Gig limit. | |
1080 //=============================================================================j// | |
1081 // %%% Here is an old comment from parseHelper.cpp; is it outdated? | |
1082 // The allocator will coalesce int->oop copies away. See comment in | |
1083 // coalesce.cpp about how this works. It depends critically on the exact | |
1084 // code shape produced here, so if you are changing this code shape | |
1085 // make sure the GC info for the heap-top is correct in and around the | |
1086 // slow-path call. | |
1087 // | |
1088 | |
1089 void PhaseMacroExpand::expand_allocate_common( | |
1090 AllocateNode* alloc, // allocation node to be expanded | |
1091 Node* length, // array length for an array allocation | |
1092 const TypeFunc* slow_call_type, // Type of slow call | |
1093 address slow_call_address // Address of slow call | |
1094 ) | |
1095 { | |
1096 | |
1097 Node* ctrl = alloc->in(TypeFunc::Control); | |
1098 Node* mem = alloc->in(TypeFunc::Memory); | |
1099 Node* i_o = alloc->in(TypeFunc::I_O); | |
1100 Node* size_in_bytes = alloc->in(AllocateNode::AllocSize); | |
1101 Node* klass_node = alloc->in(AllocateNode::KlassNode); | |
1102 Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); | |
1103 | |
1104 assert(ctrl != NULL, "must have control"); | |
1105 // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. | |
1106 // they will not be used if "always_slow" is set | |
1107 enum { slow_result_path = 1, fast_result_path = 2 }; | |
1108 Node *result_region; | |
1109 Node *result_phi_rawmem; | |
1110 Node *result_phi_rawoop; | |
1111 Node *result_phi_i_o; | |
1112 | |
1113 // The initial slow comparison is a size check, the comparison | |
1114 // we want to do is a BoolTest::gt | |
1115 bool always_slow = false; | |
1116 int tv = _igvn.find_int_con(initial_slow_test, -1); | |
1117 if (tv >= 0) { | |
1118 always_slow = (tv == 1); | |
1119 initial_slow_test = NULL; | |
1120 } else { | |
1121 initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn); | |
1122 } | |
1123 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
708
diff
changeset
|
1124 if (C->env()->dtrace_alloc_probes() || |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1125 !UseTLAB && (!Universe::heap()->supports_inline_contig_alloc() || |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1126 (UseConcMarkSweepGC && CMSIncrementalMode))) { |
0 | 1127 // Force slow-path allocation |
1128 always_slow = true; | |
1129 initial_slow_test = NULL; | |
1130 } | |
1131 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1132 |
0 | 1133 enum { too_big_or_final_path = 1, need_gc_path = 2 }; |
1134 Node *slow_region = NULL; | |
1135 Node *toobig_false = ctrl; | |
1136 | |
1137 assert (initial_slow_test == NULL || !always_slow, "arguments must be consistent"); | |
1138 // generate the initial test if necessary | |
1139 if (initial_slow_test != NULL ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1140 slow_region = new (C) RegionNode(3); |
0 | 1141 |
1142 // Now make the initial failure test. Usually a too-big test but | |
1143 // might be a TRUE for finalizers or a fancy class check for | |
1144 // newInstance0. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1145 IfNode *toobig_iff = new (C) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); |
0 | 1146 transform_later(toobig_iff); |
1147 // Plug the failing-too-big test into the slow-path region | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1148 Node *toobig_true = new (C) IfTrueNode( toobig_iff ); |
0 | 1149 transform_later(toobig_true); |
1150 slow_region ->init_req( too_big_or_final_path, toobig_true ); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1151 toobig_false = new (C) IfFalseNode( toobig_iff ); |
0 | 1152 transform_later(toobig_false); |
1153 } else { // No initial test, just fall into next case | |
1154 toobig_false = ctrl; | |
1155 debug_only(slow_region = NodeSentinel); | |
1156 } | |
1157 | |
1158 Node *slow_mem = mem; // save the current memory state for slow path | |
1159 // generate the fast allocation code unless we know that the initial test will always go slow | |
1160 if (!always_slow) { | |
565
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
490
diff
changeset
|
1161 // Fast path modifies only raw memory. |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
490
diff
changeset
|
1162 if (mem->is_MergeMem()) { |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
490
diff
changeset
|
1163 mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
490
diff
changeset
|
1164 } |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
490
diff
changeset
|
1165 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1166 Node* eden_top_adr; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1167 Node* eden_end_adr; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1168 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1169 set_eden_pointers(eden_top_adr, eden_end_adr); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1170 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1171 // Load Eden::end. Loop invariant and hoisted. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1172 // |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1173 // Note: We set the control input on "eden_end" and "old_eden_top" when using |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1174 // a TLAB to work around a bug where these values were being moved across |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1175 // a safepoint. These are not oops, so they cannot be include in the oop |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1176 // map, but they can be changed by a GC. The proper way to fix this would |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1177 // be to set the raw memory state when generating a SafepointNode. However |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1178 // this will require extensive changes to the loop optimization in order to |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1179 // prevent a degradation of the optimization. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1180 // See comment in memnode.hpp, around line 227 in class LoadPNode. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1181 Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
124
diff
changeset
|
1182 |
0 | 1183 // allocate the Region and Phi nodes for the result |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1184 result_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1185 result_phi_rawmem = new (C) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1186 result_phi_rawoop = new (C) PhiNode(result_region, TypeRawPtr::BOTTOM); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1187 result_phi_i_o = new (C) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch |
0 | 1188 |
1189 // We need a Region for the loop-back contended case. | |
1190 enum { fall_in_path = 1, contended_loopback_path = 2 }; | |
1191 Node *contended_region; | |
1192 Node *contended_phi_rawmem; | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1193 if (UseTLAB) { |
0 | 1194 contended_region = toobig_false; |
1195 contended_phi_rawmem = mem; | |
1196 } else { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1197 contended_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1198 contended_phi_rawmem = new (C) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM); |
0 | 1199 // Now handle the passing-too-big test. We fall into the contended |
1200 // loop-back merge point. | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1201 contended_region ->init_req(fall_in_path, toobig_false); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1202 contended_phi_rawmem->init_req(fall_in_path, mem); |
0 | 1203 transform_later(contended_region); |
1204 transform_later(contended_phi_rawmem); | |
1205 } | |
1206 | |
1207 // Load(-locked) the heap top. | |
1208 // See note above concerning the control input when using a TLAB | |
1209 Node *old_eden_top = UseTLAB | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1210 ? new (C) LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1211 : new (C) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr); |
0 | 1212 |
1213 transform_later(old_eden_top); | |
1214 // Add to heap top to get a new heap top | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1215 Node *new_eden_top = new (C) AddPNode(top(), old_eden_top, size_in_bytes); |
0 | 1216 transform_later(new_eden_top); |
1217 // Check for needing a GC; compare against heap end | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1218 Node *needgc_cmp = new (C) CmpPNode(new_eden_top, eden_end); |
0 | 1219 transform_later(needgc_cmp); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1220 Node *needgc_bol = new (C) BoolNode(needgc_cmp, BoolTest::ge); |
0 | 1221 transform_later(needgc_bol); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1222 IfNode *needgc_iff = new (C) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); |
0 | 1223 transform_later(needgc_iff); |
1224 | |
1225 // Plug the failing-heap-space-need-gc test into the slow-path region | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1226 Node *needgc_true = new (C) IfTrueNode(needgc_iff); |
0 | 1227 transform_later(needgc_true); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1228 if (initial_slow_test) { |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1229 slow_region->init_req(need_gc_path, needgc_true); |
0 | 1230 // This completes all paths into the slow merge point |
1231 transform_later(slow_region); | |
1232 } else { // No initial slow path needed! | |
1233 // Just fall from the need-GC path straight into the VM call. | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1234 slow_region = needgc_true; |
0 | 1235 } |
1236 // No need for a GC. Setup for the Store-Conditional | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1237 Node *needgc_false = new (C) IfFalseNode(needgc_iff); |
0 | 1238 transform_later(needgc_false); |
1239 | |
1240 // Grab regular I/O before optional prefetch may change it. | |
1241 // Slow-path does no I/O so just set it to the original I/O. | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1242 result_phi_i_o->init_req(slow_result_path, i_o); |
0 | 1243 |
1244 i_o = prefetch_allocation(i_o, needgc_false, contended_phi_rawmem, | |
1245 old_eden_top, new_eden_top, length); | |
1246 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1247 // Name successful fast-path variables |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1248 Node* fast_oop = old_eden_top; |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1249 Node* fast_oop_ctrl; |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1250 Node* fast_oop_rawmem; |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1251 |
0 | 1252 // Store (-conditional) the modified eden top back down. |
1253 // StorePConditional produces flags for a test PLUS a modified raw | |
1254 // memory state. | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1255 if (UseTLAB) { |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1256 Node* store_eden_top = |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1257 new (C) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr, |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1258 TypeRawPtr::BOTTOM, new_eden_top); |
0 | 1259 transform_later(store_eden_top); |
1260 fast_oop_ctrl = needgc_false; // No contention, so this is the fast path | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1261 fast_oop_rawmem = store_eden_top; |
0 | 1262 } else { |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1263 Node* store_eden_top = |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1264 new (C) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr, |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1265 new_eden_top, fast_oop/*old_eden_top*/); |
0 | 1266 transform_later(store_eden_top); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1267 Node *contention_check = new (C) BoolNode(store_eden_top, BoolTest::ne); |
0 | 1268 transform_later(contention_check); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1269 store_eden_top = new (C) SCMemProjNode(store_eden_top); |
0 | 1270 transform_later(store_eden_top); |
1271 | |
1272 // If not using TLABs, check to see if there was contention. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1273 IfNode *contention_iff = new (C) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN); |
0 | 1274 transform_later(contention_iff); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1275 Node *contention_true = new (C) IfTrueNode(contention_iff); |
0 | 1276 transform_later(contention_true); |
1277 // If contention, loopback and try again. | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1278 contended_region->init_req(contended_loopback_path, contention_true); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1279 contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top); |
0 | 1280 |
1281 // Fast-path succeeded with no contention! | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1282 Node *contention_false = new (C) IfFalseNode(contention_iff); |
0 | 1283 transform_later(contention_false); |
1284 fast_oop_ctrl = contention_false; | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1285 |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1286 // Bump total allocated bytes for this thread |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1287 Node* thread = new (C) ThreadLocalNode(); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1288 transform_later(thread); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1289 Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread, |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1290 in_bytes(JavaThread::allocated_bytes_offset())); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1291 Node* alloc_bytes = make_load(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1292 0, TypeLong::LONG, T_LONG); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1293 #ifdef _LP64 |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1294 Node* alloc_size = size_in_bytes; |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1295 #else |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1296 Node* alloc_size = new (C) ConvI2LNode(size_in_bytes); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1297 transform_later(alloc_size); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1298 #endif |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1299 Node* new_alloc_bytes = new (C) AddLNode(alloc_bytes, alloc_size); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1300 transform_later(new_alloc_bytes); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1301 fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1302 0, new_alloc_bytes, T_LONG); |
0 | 1303 } |
1304 | |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1305 InitializeNode* init = alloc->initialization(); |
0 | 1306 fast_oop_rawmem = initialize_object(alloc, |
1307 fast_oop_ctrl, fast_oop_rawmem, fast_oop, | |
1308 klass_node, length, size_in_bytes); | |
1309 | |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1310 // If initialization is performed by an array copy, any required |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1311 // MemBarStoreStore was already added. If the object does not |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1312 // escape no need for a MemBarStoreStore. Otherwise we need a |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1313 // MemBarStoreStore so that stores that initialize this object |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1314 // can't be reordered with a subsequent store that makes this |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1315 // object accessible by other threads. |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1316 if (init == NULL || (!init->is_complete_with_arraycopy() && !init->does_not_escape())) { |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1317 if (init == NULL || init->req() < InitializeNode::RawStores) { |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1318 // No InitializeNode or no stores captured by zeroing |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1319 // elimination. Simply add the MemBarStoreStore after object |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1320 // initialization. |
8694
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
7637
diff
changeset
|
1321 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1322 transform_later(mb); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1323 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1324 mb->init_req(TypeFunc::Memory, fast_oop_rawmem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1325 mb->init_req(TypeFunc::Control, fast_oop_ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1326 fast_oop_ctrl = new (C) ProjNode(mb,TypeFunc::Control); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1327 transform_later(fast_oop_ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1328 fast_oop_rawmem = new (C) ProjNode(mb,TypeFunc::Memory); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1329 transform_later(fast_oop_rawmem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1330 } else { |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1331 // Add the MemBarStoreStore after the InitializeNode so that |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1332 // all stores performing the initialization that were moved |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1333 // before the InitializeNode happen before the storestore |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1334 // barrier. |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1335 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1336 Node* init_ctrl = init->proj_out(TypeFunc::Control); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1337 Node* init_mem = init->proj_out(TypeFunc::Memory); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1338 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1339 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1340 transform_later(mb); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1341 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1342 Node* ctrl = new (C) ProjNode(init,TypeFunc::Control); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1343 transform_later(ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1344 Node* mem = new (C) ProjNode(init,TypeFunc::Memory); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1345 transform_later(mem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1346 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1347 // The MemBarStoreStore depends on control and memory coming |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1348 // from the InitializeNode |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1349 mb->init_req(TypeFunc::Memory, mem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1350 mb->init_req(TypeFunc::Control, ctrl); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1351 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1352 ctrl = new (C) ProjNode(mb,TypeFunc::Control); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1353 transform_later(ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1354 mem = new (C) ProjNode(mb,TypeFunc::Memory); |
4763
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1355 transform_later(mem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1356 |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1357 // All nodes that depended on the InitializeNode for control |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1358 // and memory must now depend on the MemBarNode that itself |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1359 // depends on the InitializeNode |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1360 _igvn.replace_node(init_ctrl, ctrl); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1361 _igvn.replace_node(init_mem, mem); |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1362 } |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1363 } |
1dc233a8c7fe
7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents:
4762
diff
changeset
|
1364 |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
708
diff
changeset
|
1365 if (C->env()->dtrace_extended_probes()) { |
0 | 1366 // Slow-path call |
1367 int size = TypeFunc::Parms + 2; | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1368 CallLeafNode *call = new (C) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1369 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base), |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1370 "dtrace_object_alloc", |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1371 TypeRawPtr::BOTTOM); |
0 | 1372 |
1373 // Get base of thread-local storage area | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1374 Node* thread = new (C) ThreadLocalNode(); |
0 | 1375 transform_later(thread); |
1376 | |
1377 call->init_req(TypeFunc::Parms+0, thread); | |
1378 call->init_req(TypeFunc::Parms+1, fast_oop); | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1379 call->init_req(TypeFunc::Control, fast_oop_ctrl); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1380 call->init_req(TypeFunc::I_O , top()); // does no i/o |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1381 call->init_req(TypeFunc::Memory , fast_oop_rawmem); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1382 call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr)); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1383 call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr)); |
0 | 1384 transform_later(call); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1385 fast_oop_ctrl = new (C) ProjNode(call,TypeFunc::Control); |
0 | 1386 transform_later(fast_oop_ctrl); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1387 fast_oop_rawmem = new (C) ProjNode(call,TypeFunc::Memory); |
0 | 1388 transform_later(fast_oop_rawmem); |
1389 } | |
1390 | |
1391 // Plug in the successful fast-path into the result merge point | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1392 result_region ->init_req(fast_result_path, fast_oop_ctrl); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1393 result_phi_rawoop->init_req(fast_result_path, fast_oop); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1394 result_phi_i_o ->init_req(fast_result_path, i_o); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
1972
diff
changeset
|
1395 result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem); |
0 | 1396 } else { |
1397 slow_region = ctrl; | |
4767 | 1398 result_phi_i_o = i_o; // Rename it to use in the following code. |
0 | 1399 } |
1400 | |
1401 // Generate slow-path call | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1402 CallNode *call = new (C) CallStaticJavaNode(slow_call_type, slow_call_address, |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1403 OptoRuntime::stub_name(slow_call_address), |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1404 alloc->jvms()->bci(), |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1405 TypePtr::BOTTOM); |
0 | 1406 call->init_req( TypeFunc::Control, slow_region ); |
1407 call->init_req( TypeFunc::I_O , top() ) ; // does no i/o | |
1408 call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs | |
1409 call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) ); | |
1410 call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) ); | |
1411 | |
1412 call->init_req(TypeFunc::Parms+0, klass_node); | |
1413 if (length != NULL) { | |
1414 call->init_req(TypeFunc::Parms+1, length); | |
1415 } | |
1416 | |
1417 // Copy debug information and adjust JVMState information, then replace | |
1418 // allocate node with the call | |
1419 copy_call_debug_info((CallNode *) alloc, call); | |
1420 if (!always_slow) { | |
1421 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. | |
4767 | 1422 } else { |
1423 // Hook i_o projection to avoid its elimination during allocation | |
1424 // replacement (when only a slow call is generated). | |
1425 call->set_req(TypeFunc::I_O, result_phi_i_o); | |
0 | 1426 } |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1609
diff
changeset
|
1427 _igvn.replace_node(alloc, call); |
0 | 1428 transform_later(call); |
1429 | |
1430 // Identify the output projections from the allocate node and | |
1431 // adjust any references to them. | |
1432 // The control and io projections look like: | |
1433 // | |
1434 // v---Proj(ctrl) <-----+ v---CatchProj(ctrl) | |
1435 // Allocate Catch | |
1436 // ^---Proj(io) <-------+ ^---CatchProj(io) | |
1437 // | |
1438 // We are interested in the CatchProj nodes. | |
1439 // | |
1440 extract_call_projections(call); | |
1441 | |
4767 | 1442 // An allocate node has separate memory projections for the uses on |
1443 // the control and i_o paths. Replace the control memory projection with | |
1444 // result_phi_rawmem (unless we are only generating a slow call when | |
1445 // both memory projections are combined) | |
0 | 1446 if (!always_slow && _memproj_fallthrough != NULL) { |
1447 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { | |
1448 Node *use = _memproj_fallthrough->fast_out(i); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1449 _igvn.rehash_node_delayed(use); |
0 | 1450 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); |
1451 // back up iterator | |
1452 --i; | |
1453 } | |
1454 } | |
4767 | 1455 // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete |
1456 // _memproj_catchall so we end up with a call that has only 1 memory projection. | |
0 | 1457 if (_memproj_catchall != NULL ) { |
1458 if (_memproj_fallthrough == NULL) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1459 _memproj_fallthrough = new (C) ProjNode(call, TypeFunc::Memory); |
0 | 1460 transform_later(_memproj_fallthrough); |
1461 } | |
1462 for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) { | |
1463 Node *use = _memproj_catchall->fast_out(i); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1464 _igvn.rehash_node_delayed(use); |
0 | 1465 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); |
1466 // back up iterator | |
1467 --i; | |
1468 } | |
4767 | 1469 assert(_memproj_catchall->outcnt() == 0, "all uses must be deleted"); |
1470 _igvn.remove_dead_node(_memproj_catchall); | |
0 | 1471 } |
1472 | |
4767 | 1473 // An allocate node has separate i_o projections for the uses on the control |
1474 // and i_o paths. Always replace the control i_o projection with result i_o | |
1475 // otherwise incoming i_o become dead when only a slow call is generated | |
1476 // (it is different from memory projections where both projections are | |
1477 // combined in such case). | |
1478 if (_ioproj_fallthrough != NULL) { | |
0 | 1479 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1480 Node *use = _ioproj_fallthrough->fast_out(i); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1481 _igvn.rehash_node_delayed(use); |
0 | 1482 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); |
1483 // back up iterator | |
1484 --i; | |
1485 } | |
1486 } | |
4767 | 1487 // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete |
1488 // _ioproj_catchall so we end up with a call that has only 1 i_o projection. | |
0 | 1489 if (_ioproj_catchall != NULL ) { |
4767 | 1490 if (_ioproj_fallthrough == NULL) { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1491 _ioproj_fallthrough = new (C) ProjNode(call, TypeFunc::I_O); |
4767 | 1492 transform_later(_ioproj_fallthrough); |
1493 } | |
0 | 1494 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { |
1495 Node *use = _ioproj_catchall->fast_out(i); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1496 _igvn.rehash_node_delayed(use); |
0 | 1497 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); |
1498 // back up iterator | |
1499 --i; | |
1500 } | |
4767 | 1501 assert(_ioproj_catchall->outcnt() == 0, "all uses must be deleted"); |
1502 _igvn.remove_dead_node(_ioproj_catchall); | |
0 | 1503 } |
1504 | |
1505 // if we generated only a slow call, we are done | |
4767 | 1506 if (always_slow) { |
1507 // Now we can unhook i_o. | |
4769 | 1508 if (result_phi_i_o->outcnt() > 1) { |
1509 call->set_req(TypeFunc::I_O, top()); | |
1510 } else { | |
1511 assert(result_phi_i_o->unique_ctrl_out() == call, ""); | |
1512 // Case of new array with negative size known during compilation. | |
1513 // AllocateArrayNode::Ideal() optimization disconnect unreachable | |
1514 // following code since call to runtime will throw exception. | |
1515 // As result there will be no users of i_o after the call. | |
1516 // Leave i_o attached to this call to avoid problems in preceding graph. | |
1517 } | |
0 | 1518 return; |
4767 | 1519 } |
0 | 1520 |
1521 | |
1522 if (_fallthroughcatchproj != NULL) { | |
1523 ctrl = _fallthroughcatchproj->clone(); | |
1524 transform_later(ctrl); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
1525 _igvn.replace_node(_fallthroughcatchproj, result_region); |
0 | 1526 } else { |
1527 ctrl = top(); | |
1528 } | |
1529 Node *slow_result; | |
1530 if (_resproj == NULL) { | |
1531 // no uses of the allocation result | |
1532 slow_result = top(); | |
1533 } else { | |
1534 slow_result = _resproj->clone(); | |
1535 transform_later(slow_result); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
1536 _igvn.replace_node(_resproj, result_phi_rawoop); |
0 | 1537 } |
1538 | |
1539 // Plug slow-path into result merge point | |
1540 result_region ->init_req( slow_result_path, ctrl ); | |
1541 result_phi_rawoop->init_req( slow_result_path, slow_result); | |
1542 result_phi_rawmem->init_req( slow_result_path, _memproj_fallthrough ); | |
1543 transform_later(result_region); | |
1544 transform_later(result_phi_rawoop); | |
1545 transform_later(result_phi_rawmem); | |
1546 transform_later(result_phi_i_o); | |
1547 // This completes all paths into the result merge point | |
1548 } | |
1549 | |
1550 | |
1551 // Helper for PhaseMacroExpand::expand_allocate_common. | |
1552 // Initializes the newly-allocated storage. | |
1553 Node* | |
1554 PhaseMacroExpand::initialize_object(AllocateNode* alloc, | |
1555 Node* control, Node* rawmem, Node* object, | |
1556 Node* klass_node, Node* length, | |
1557 Node* size_in_bytes) { | |
1558 InitializeNode* init = alloc->initialization(); | |
1559 // Store the klass & mark bits | |
1560 Node* mark_node = NULL; | |
1561 // For now only enable fast locking for non-array types | |
1562 if (UseBiasedLocking && (length == NULL)) { | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4115
diff
changeset
|
1563 mark_node = make_load(control, rawmem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeRawPtr::BOTTOM, T_ADDRESS); |
0 | 1564 } else { |
1565 mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype())); | |
1566 } | |
1567 rawmem = make_store(control, rawmem, object, oopDesc::mark_offset_in_bytes(), mark_node, T_ADDRESS); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
1568 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1569 rawmem = make_store(control, rawmem, object, oopDesc::klass_offset_in_bytes(), klass_node, T_METADATA); |
0 | 1570 int header_size = alloc->minimum_header_size(); // conservatively small |
1571 | |
1572 // Array length | |
1573 if (length != NULL) { // Arrays need length field | |
1574 rawmem = make_store(control, rawmem, object, arrayOopDesc::length_offset_in_bytes(), length, T_INT); | |
1575 // conservatively small header size: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
1576 header_size = arrayOopDesc::base_offset_in_bytes(T_BYTE); |
0 | 1577 ciKlass* k = _igvn.type(klass_node)->is_klassptr()->klass(); |
1578 if (k->is_array_klass()) // we know the exact header size in most cases: | |
1579 header_size = Klass::layout_helper_header_size(k->layout_helper()); | |
1580 } | |
1581 | |
1582 // Clear the object body, if necessary. | |
1583 if (init == NULL) { | |
1584 // The init has somehow disappeared; be cautious and clear everything. | |
1585 // | |
1586 // This can happen if a node is allocated but an uncommon trap occurs | |
1587 // immediately. In this case, the Initialize gets associated with the | |
1588 // trap, and may be placed in a different (outer) loop, if the Allocate | |
1589 // is in a loop. If (this is rare) the inner loop gets unrolled, then | |
1590 // there can be two Allocates to one Initialize. The answer in all these | |
1591 // edge cases is safety first. It is always safe to clear immediately | |
1592 // within an Allocate, and then (maybe or maybe not) clear some more later. | |
1593 if (!ZeroTLAB) | |
1594 rawmem = ClearArrayNode::clear_memory(control, rawmem, object, | |
1595 header_size, size_in_bytes, | |
1596 &_igvn); | |
1597 } else { | |
1598 if (!init->is_complete()) { | |
1599 // Try to win by zeroing only what the init does not store. | |
1600 // We can also try to do some peephole optimizations, | |
1601 // such as combining some adjacent subword stores. | |
1602 rawmem = init->complete_stores(control, rawmem, object, | |
1603 header_size, size_in_bytes, &_igvn); | |
1604 } | |
1605 // We have no more use for this link, since the AllocateNode goes away: | |
1606 init->set_req(InitializeNode::RawAddress, top()); | |
1607 // (If we keep the link, it just confuses the register allocator, | |
1608 // who thinks he sees a real use of the address by the membar.) | |
1609 } | |
1610 | |
1611 return rawmem; | |
1612 } | |
1613 | |
1614 // Generate prefetch instructions for next allocations. | |
1615 Node* PhaseMacroExpand::prefetch_allocation(Node* i_o, Node*& needgc_false, | |
1616 Node*& contended_phi_rawmem, | |
1617 Node* old_eden_top, Node* new_eden_top, | |
1618 Node* length) { | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1619 enum { fall_in_path = 1, pf_path = 2 }; |
0 | 1620 if( UseTLAB && AllocatePrefetchStyle == 2 ) { |
1621 // Generate prefetch allocation with watermark check. | |
1622 // As an allocation hits the watermark, we will prefetch starting | |
1623 // at a "distance" away from watermark. | |
1624 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1625 Node *pf_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1626 Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, |
0 | 1627 TypeRawPtr::BOTTOM ); |
1628 // I/O is used for Prefetch | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1629 Node *pf_phi_abio = new (C) PhiNode( pf_region, Type::ABIO ); |
0 | 1630 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1631 Node *thread = new (C) ThreadLocalNode(); |
0 | 1632 transform_later(thread); |
1633 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1634 Node *eden_pf_adr = new (C) AddPNode( top()/*not oop*/, thread, |
0 | 1635 _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) ); |
1636 transform_later(eden_pf_adr); | |
1637 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1638 Node *old_pf_wm = new (C) LoadPNode( needgc_false, |
0 | 1639 contended_phi_rawmem, eden_pf_adr, |
1640 TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); | |
1641 transform_later(old_pf_wm); | |
1642 | |
1643 // check against new_eden_top | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1644 Node *need_pf_cmp = new (C) CmpPNode( new_eden_top, old_pf_wm ); |
0 | 1645 transform_later(need_pf_cmp); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1646 Node *need_pf_bol = new (C) BoolNode( need_pf_cmp, BoolTest::ge ); |
0 | 1647 transform_later(need_pf_bol); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1648 IfNode *need_pf_iff = new (C) IfNode( needgc_false, need_pf_bol, |
0 | 1649 PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN ); |
1650 transform_later(need_pf_iff); | |
1651 | |
1652 // true node, add prefetchdistance | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1653 Node *need_pf_true = new (C) IfTrueNode( need_pf_iff ); |
0 | 1654 transform_later(need_pf_true); |
1655 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1656 Node *need_pf_false = new (C) IfFalseNode( need_pf_iff ); |
0 | 1657 transform_later(need_pf_false); |
1658 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1659 Node *new_pf_wmt = new (C) AddPNode( top(), old_pf_wm, |
0 | 1660 _igvn.MakeConX(AllocatePrefetchDistance) ); |
1661 transform_later(new_pf_wmt ); | |
1662 new_pf_wmt->set_req(0, need_pf_true); | |
1663 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1664 Node *store_new_wmt = new (C) StorePNode( need_pf_true, |
0 | 1665 contended_phi_rawmem, eden_pf_adr, |
1666 TypeRawPtr::BOTTOM, new_pf_wmt ); | |
1667 transform_later(store_new_wmt); | |
1668 | |
1669 // adding prefetches | |
1670 pf_phi_abio->init_req( fall_in_path, i_o ); | |
1671 | |
1672 Node *prefetch_adr; | |
1673 Node *prefetch; | |
1674 uint lines = AllocatePrefetchDistance / AllocatePrefetchStepSize; | |
1675 uint step_size = AllocatePrefetchStepSize; | |
1676 uint distance = 0; | |
1677 | |
1678 for ( uint i = 0; i < lines; i++ ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1679 prefetch_adr = new (C) AddPNode( old_pf_wm, new_pf_wmt, |
0 | 1680 _igvn.MakeConX(distance) ); |
1681 transform_later(prefetch_adr); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1682 prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); |
0 | 1683 transform_later(prefetch); |
1684 distance += step_size; | |
1685 i_o = prefetch; | |
1686 } | |
1687 pf_phi_abio->set_req( pf_path, i_o ); | |
1688 | |
1689 pf_region->init_req( fall_in_path, need_pf_false ); | |
1690 pf_region->init_req( pf_path, need_pf_true ); | |
1691 | |
1692 pf_phi_rawmem->init_req( fall_in_path, contended_phi_rawmem ); | |
1693 pf_phi_rawmem->init_req( pf_path, store_new_wmt ); | |
1694 | |
1695 transform_later(pf_region); | |
1696 transform_later(pf_phi_rawmem); | |
1697 transform_later(pf_phi_abio); | |
1698 | |
1699 needgc_false = pf_region; | |
1700 contended_phi_rawmem = pf_phi_rawmem; | |
1701 i_o = pf_phi_abio; | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1702 } else if( UseTLAB && AllocatePrefetchStyle == 3 ) { |
3854 | 1703 // Insert a prefetch for each allocation. |
1704 // This code is used for Sparc with BIS. | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1705 Node *pf_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1706 Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1707 TypeRawPtr::BOTTOM ); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1708 |
3854 | 1709 // Generate several prefetch instructions. |
1710 uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines; | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1711 uint step_size = AllocatePrefetchStepSize; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1712 uint distance = AllocatePrefetchDistance; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1713 |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1714 // Next cache address. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1715 Node *cache_adr = new (C) AddPNode(old_eden_top, old_eden_top, |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1716 _igvn.MakeConX(distance)); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1717 transform_later(cache_adr); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1718 cache_adr = new (C) CastP2XNode(needgc_false, cache_adr); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1719 transform_later(cache_adr); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1720 Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1)); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1721 cache_adr = new (C) AndXNode(cache_adr, mask); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1722 transform_later(cache_adr); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1723 cache_adr = new (C) CastX2PNode(cache_adr); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1724 transform_later(cache_adr); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1725 |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1726 // Prefetch |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1727 Node *prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, cache_adr ); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1728 prefetch->set_req(0, needgc_false); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1729 transform_later(prefetch); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1730 contended_phi_rawmem = prefetch; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1731 Node *prefetch_adr; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1732 distance = step_size; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1733 for ( uint i = 1; i < lines; i++ ) { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1734 prefetch_adr = new (C) AddPNode( cache_adr, cache_adr, |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1735 _igvn.MakeConX(distance) ); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1736 transform_later(prefetch_adr); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1737 prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr ); |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1738 transform_later(prefetch); |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1739 distance += step_size; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1740 contended_phi_rawmem = prefetch; |
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1100
diff
changeset
|
1741 } |
0 | 1742 } else if( AllocatePrefetchStyle > 0 ) { |
1743 // Insert a prefetch for each allocation only on the fast-path | |
1744 Node *prefetch_adr; | |
1745 Node *prefetch; | |
3854 | 1746 // Generate several prefetch instructions. |
1747 uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines; | |
0 | 1748 uint step_size = AllocatePrefetchStepSize; |
1749 uint distance = AllocatePrefetchDistance; | |
1750 for ( uint i = 0; i < lines; i++ ) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1751 prefetch_adr = new (C) AddPNode( old_eden_top, new_eden_top, |
0 | 1752 _igvn.MakeConX(distance) ); |
1753 transform_later(prefetch_adr); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1754 prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); |
0 | 1755 // Do not let it float too high, since if eden_top == eden_end, |
1756 // both might be null. | |
1757 if( i == 0 ) { // Set control for first prefetch, next follows it | |
1758 prefetch->init_req(0, needgc_false); | |
1759 } | |
1760 transform_later(prefetch); | |
1761 distance += step_size; | |
1762 i_o = prefetch; | |
1763 } | |
1764 } | |
1765 return i_o; | |
1766 } | |
1767 | |
1768 | |
1769 void PhaseMacroExpand::expand_allocate(AllocateNode *alloc) { | |
1770 expand_allocate_common(alloc, NULL, | |
1771 OptoRuntime::new_instance_Type(), | |
1772 OptoRuntime::new_instance_Java()); | |
1773 } | |
1774 | |
1775 void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) { | |
1776 Node* length = alloc->in(AllocateNode::ALength); | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1777 InitializeNode* init = alloc->initialization(); |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1778 Node* klass_node = alloc->in(AllocateNode::KlassNode); |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1779 ciKlass* k = _igvn.type(klass_node)->is_klassptr()->klass(); |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1780 address slow_call_address; // Address of slow call |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1781 if (init != NULL && init->is_complete_with_arraycopy() && |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1782 k->is_type_array_klass()) { |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1783 // Don't zero type array during slow allocation in VM since |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1784 // it will be initialized later by arraycopy in compiled code. |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1785 slow_call_address = OptoRuntime::new_array_nozero_Java(); |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1786 } else { |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1787 slow_call_address = OptoRuntime::new_array_Java(); |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1788 } |
0 | 1789 expand_allocate_common(alloc, length, |
1790 OptoRuntime::new_array_Type(), | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
1791 slow_call_address); |
0 | 1792 } |
1793 | |
4777 | 1794 //-------------------mark_eliminated_box---------------------------------- |
1795 // | |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1796 // During EA obj may point to several objects but after few ideal graph |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1797 // transformations (CCP) it may point to only one non escaping object |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1798 // (but still using phi), corresponding locks and unlocks will be marked |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1799 // for elimination. Later obj could be replaced with a new node (new phi) |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1800 // and which does not have escape information. And later after some graph |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1801 // reshape other locks and unlocks (which were not marked for elimination |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1802 // before) are connected to this new obj (phi) but they still will not be |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1803 // marked for elimination since new obj has no escape information. |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1804 // Mark all associated (same box and obj) lock and unlock nodes for |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1805 // elimination if some of them marked already. |
4777 | 1806 void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) { |
4792 | 1807 if (oldbox->as_BoxLock()->is_eliminated()) |
1808 return; // This BoxLock node was processed already. | |
4777 | 1809 |
4792 | 1810 // New implementation (EliminateNestedLocks) has separate BoxLock |
1811 // node for each locked region so mark all associated locks/unlocks as | |
1812 // eliminated even if different objects are referenced in one locked region | |
1813 // (for example, OSR compilation of nested loop inside locked scope). | |
1814 if (EliminateNestedLocks || | |
4777 | 1815 oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj)) { |
1816 // Box is used only in one lock region. Mark this box as eliminated. | |
1817 _igvn.hash_delete(oldbox); | |
1818 oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value | |
1819 _igvn.hash_insert(oldbox); | |
1820 | |
1821 for (uint i = 0; i < oldbox->outcnt(); i++) { | |
1822 Node* u = oldbox->raw_out(i); | |
1823 if (u->is_AbstractLock() && !u->as_AbstractLock()->is_non_esc_obj()) { | |
1824 AbstractLockNode* alock = u->as_AbstractLock(); | |
1825 // Check lock's box since box could be referenced by Lock's debug info. | |
1826 if (alock->box_node() == oldbox) { | |
1827 // Mark eliminated all related locks and unlocks. | |
1828 alock->set_non_esc_obj(); | |
1829 } | |
1830 } | |
1831 } | |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1832 return; |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1833 } |
4777 | 1834 |
1835 // Create new "eliminated" BoxLock node and use it in monitor debug info | |
1836 // instead of oldbox for the same object. | |
4790
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
1837 BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); |
4777 | 1838 |
1839 // Note: BoxLock node is marked eliminated only here and it is used | |
1840 // to indicate that all associated lock and unlock nodes are marked | |
1841 // for elimination. | |
1842 newbox->set_eliminated(); | |
1843 transform_later(newbox); | |
1844 | |
1845 // Replace old box node with new box for all users of the same object. | |
1846 for (uint i = 0; i < oldbox->outcnt();) { | |
1847 bool next_edge = true; | |
1848 | |
1849 Node* u = oldbox->raw_out(i); | |
1850 if (u->is_AbstractLock()) { | |
1851 AbstractLockNode* alock = u->as_AbstractLock(); | |
4778 | 1852 if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) { |
4777 | 1853 // Replace Box and mark eliminated all related locks and unlocks. |
1854 alock->set_non_esc_obj(); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1855 _igvn.rehash_node_delayed(alock); |
4777 | 1856 alock->set_box_node(newbox); |
1857 next_edge = false; | |
1858 } | |
1859 } | |
4778 | 1860 if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) { |
4777 | 1861 FastLockNode* flock = u->as_FastLock(); |
1862 assert(flock->box_node() == oldbox, "sanity"); | |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1863 _igvn.rehash_node_delayed(flock); |
4777 | 1864 flock->set_box_node(newbox); |
1865 next_edge = false; | |
1866 } | |
1867 | |
1868 // Replace old box in monitor debug info. | |
1869 if (u->is_SafePoint() && u->as_SafePoint()->jvms()) { | |
1870 SafePointNode* sfn = u->as_SafePoint(); | |
1871 JVMState* youngest_jvms = sfn->jvms(); | |
1872 int max_depth = youngest_jvms->depth(); | |
1873 for (int depth = 1; depth <= max_depth; depth++) { | |
1874 JVMState* jvms = youngest_jvms->of_depth(depth); | |
1875 int num_mon = jvms->nof_monitors(); | |
1876 // Loop over monitors | |
1877 for (int idx = 0; idx < num_mon; idx++) { | |
1878 Node* obj_node = sfn->monitor_obj(jvms, idx); | |
1879 Node* box_node = sfn->monitor_box(jvms, idx); | |
4778 | 1880 if (box_node == oldbox && obj_node->eqv_uncast(obj)) { |
4777 | 1881 int j = jvms->monitor_box_offset(idx); |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4894
diff
changeset
|
1882 _igvn.replace_input_of(u, j, newbox); |
4777 | 1883 next_edge = false; |
1884 } | |
1885 } | |
1886 } | |
1887 } | |
1888 if (next_edge) i++; | |
1889 } | |
1890 } | |
1891 | |
1892 //-----------------------mark_eliminated_locking_nodes----------------------- | |
1893 void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) { | |
1894 if (EliminateNestedLocks) { | |
1895 if (alock->is_nested()) { | |
1896 assert(alock->box_node()->as_BoxLock()->is_eliminated(), "sanity"); | |
1897 return; | |
1898 } else if (!alock->is_non_esc_obj()) { // Not eliminated or coarsened | |
1899 // Only Lock node has JVMState needed here. | |
1900 if (alock->jvms() != NULL && alock->as_Lock()->is_nested_lock_region()) { | |
1901 // Mark eliminated related nested locks and unlocks. | |
1902 Node* obj = alock->obj_node(); | |
1903 BoxLockNode* box_node = alock->box_node()->as_BoxLock(); | |
1904 assert(!box_node->is_eliminated(), "should not be marked yet"); | |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1905 // Note: BoxLock node is marked eliminated only here |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1906 // and it is used to indicate that all associated lock |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1907 // and unlock nodes are marked for elimination. |
4777 | 1908 box_node->set_eliminated(); // Box's hash is always NO_HASH here |
1909 for (uint i = 0; i < box_node->outcnt(); i++) { | |
1910 Node* u = box_node->raw_out(i); | |
1911 if (u->is_AbstractLock()) { | |
1912 alock = u->as_AbstractLock(); | |
1913 if (alock->box_node() == box_node) { | |
1914 // Verify that this Box is referenced only by related locks. | |
4778 | 1915 assert(alock->obj_node()->eqv_uncast(obj), ""); |
4777 | 1916 // Mark all related locks and unlocks. |
1917 alock->set_nested(); | |
1918 } | |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
1919 } |
4777 | 1920 } |
1921 } | |
1922 return; | |
1923 } | |
1924 // Process locks for non escaping object | |
1925 assert(alock->is_non_esc_obj(), ""); | |
1926 } // EliminateNestedLocks | |
1927 | |
1928 if (alock->is_non_esc_obj()) { // Lock is used for non escaping object | |
1929 // Look for all locks of this object and mark them and | |
1930 // corresponding BoxLock nodes as eliminated. | |
1931 Node* obj = alock->obj_node(); | |
1932 for (uint j = 0; j < obj->outcnt(); j++) { | |
1933 Node* o = obj->raw_out(j); | |
4778 | 1934 if (o->is_AbstractLock() && |
1935 o->as_AbstractLock()->obj_node()->eqv_uncast(obj)) { | |
4777 | 1936 alock = o->as_AbstractLock(); |
1937 Node* box = alock->box_node(); | |
1938 // Replace old box node with new eliminated box for all users | |
1939 // of the same object and mark related locks as eliminated. | |
1940 mark_eliminated_box(box, obj); | |
1941 } | |
1942 } | |
1943 } | |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1944 } |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1945 |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1946 // we have determined that this lock/unlock can be eliminated, we simply |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1947 // eliminate the node without expanding it. |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1948 // |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1949 // Note: The membar's associated with the lock/unlock are currently not |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1950 // eliminated. This should be investigated as a future enhancement. |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1951 // |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1952 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1953 |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1954 if (!alock->is_eliminated()) { |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1955 return false; |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1956 } |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1957 #ifdef ASSERT |
4777 | 1958 if (!alock->is_coarsened()) { |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1959 // Check that new "eliminated" BoxLock node is created. |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1960 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1961 assert(oldbox->is_eliminated(), "should be done already"); |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1962 } |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
1963 #endif |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1964 CompileLog* log = C->log(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1965 if (log != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1966 log->head("eliminate_lock lock='%d'", |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1967 alock->is_Lock()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1968 JVMState* p = alock->jvms(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1969 while (p != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1970 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1971 p = p->caller(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1972 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1973 log->tail("eliminate_lock"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1974 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
851
diff
changeset
|
1975 |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1976 #ifndef PRODUCT |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1977 if (PrintEliminateLocks) { |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1978 if (alock->is_Lock()) { |
4115 | 1979 tty->print_cr("++++ Eliminated: %d Lock", alock->_idx); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1980 } else { |
4115 | 1981 tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1982 } |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1983 } |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1984 #endif |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1985 |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1986 Node* mem = alock->in(TypeFunc::Memory); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1987 Node* ctrl = alock->in(TypeFunc::Control); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1988 |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1989 extract_call_projections(alock); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1990 // There are 2 projections from the lock. The lock node will |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1991 // be deleted when its last use is subsumed below. |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1992 assert(alock->outcnt() == 2 && |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1993 _fallthroughproj != NULL && |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1994 _memproj_fallthrough != NULL, |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1995 "Unexpected projections from Lock/Unlock"); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1996 |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1997 Node* fallthroughproj = _fallthroughproj; |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
1998 Node* memproj_fallthrough = _memproj_fallthrough; |
0 | 1999 |
2000 // The memory projection from a lock/unlock is RawMem | |
2001 // The input to a Lock is merged memory, so extract its RawMem input | |
2002 // (unless the MergeMem has been optimized away.) | |
2003 if (alock->is_Lock()) { | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3788
diff
changeset
|
2004 // Seach for MemBarAcquireLock node and delete it also. |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2005 MemBarNode* membar = fallthroughproj->unique_ctrl_out()->as_MemBar(); |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3788
diff
changeset
|
2006 assert(membar != NULL && membar->Opcode() == Op_MemBarAcquireLock, ""); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2007 Node* ctrlproj = membar->proj_out(TypeFunc::Control); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2008 Node* memproj = membar->proj_out(TypeFunc::Memory); |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2009 _igvn.replace_node(ctrlproj, fallthroughproj); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2010 _igvn.replace_node(memproj, memproj_fallthrough); |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2011 |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2012 // Delete FastLock node also if this Lock node is unique user |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2013 // (a loop peeling may clone a Lock node). |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2014 Node* flock = alock->as_Lock()->fastlock_node(); |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2015 if (flock->outcnt() == 1) { |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2016 assert(flock->unique_out() == alock, "sanity"); |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2017 _igvn.replace_node(flock, top()); |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2018 } |
0 | 2019 } |
2020 | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3788
diff
changeset
|
2021 // Seach for MemBarReleaseLock node and delete it also. |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2022 if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() && |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2023 ctrl->in(0)->is_MemBar()) { |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2024 MemBarNode* membar = ctrl->in(0)->as_MemBar(); |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3788
diff
changeset
|
2025 assert(membar->Opcode() == Op_MemBarReleaseLock && |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2026 mem->is_Proj() && membar == mem->in(0), ""); |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2027 _igvn.replace_node(fallthroughproj, ctrl); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2028 _igvn.replace_node(memproj_fallthrough, mem); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2029 fallthroughproj = ctrl; |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2030 memproj_fallthrough = mem; |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2031 ctrl = membar->in(TypeFunc::Control); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2032 mem = membar->in(TypeFunc::Memory); |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2033 } |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2034 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2035 _igvn.replace_node(fallthroughproj, ctrl); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2036 _igvn.replace_node(memproj_fallthrough, mem); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2037 return true; |
0 | 2038 } |
2039 | |
2040 | |
2041 //------------------------------expand_lock_node---------------------- | |
2042 void PhaseMacroExpand::expand_lock_node(LockNode *lock) { | |
2043 | |
2044 Node* ctrl = lock->in(TypeFunc::Control); | |
2045 Node* mem = lock->in(TypeFunc::Memory); | |
2046 Node* obj = lock->obj_node(); | |
2047 Node* box = lock->box_node(); | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2048 Node* flock = lock->fastlock_node(); |
0 | 2049 |
4790
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
2050 assert(!box->as_BoxLock()->is_eliminated(), "sanity"); |
4777 | 2051 |
0 | 2052 // Make the merge point |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2053 Node *region; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2054 Node *mem_phi; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2055 Node *slow_path; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2056 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2057 if (UseOptoBiasInlining) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2058 /* |
605 | 2059 * See the full description in MacroAssembler::biased_locking_enter(). |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2060 * |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2061 * if( (mark_word & biased_lock_mask) == biased_lock_pattern ) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2062 * // The object is biased. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2063 * proto_node = klass->prototype_header; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2064 * o_node = thread | proto_node; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2065 * x_node = o_node ^ mark_word; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2066 * if( (x_node & ~age_mask) == 0 ) { // Biased to the current thread ? |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2067 * // Done. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2068 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2069 * if( (x_node & biased_lock_mask) != 0 ) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2070 * // The klass's prototype header is no longer biased. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2071 * cas(&mark_word, mark_word, proto_node) |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2072 * goto cas_lock; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2073 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2074 * // The klass's prototype header is still biased. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2075 * if( (x_node & epoch_mask) != 0 ) { // Expired epoch? |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2076 * old = mark_word; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2077 * new = o_node; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2078 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2079 * // Different thread or anonymous biased. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2080 * old = mark_word & (epoch_mask | age_mask | biased_lock_mask); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2081 * new = thread | old; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2082 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2083 * // Try to rebias. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2084 * if( cas(&mark_word, old, new) == 0 ) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2085 * // Done. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2086 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2087 * goto slow_path; // Failed. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2088 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2089 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2090 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2091 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2092 * // The object is not biased. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2093 * cas_lock: |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2094 * if( FastLock(obj) == 0 ) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2095 * // Done. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2096 * } else { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2097 * slow_path: |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2098 * OptoRuntime::complete_monitor_locking_Java(obj); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2099 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2100 * } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2101 */ |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2102 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2103 region = new (C) RegionNode(5); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2104 // create a Phi for the memory state |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2105 mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2106 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2107 Node* fast_lock_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2108 Node* fast_lock_mem_phi = new (C) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2109 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2110 // First, check mark word for the biased lock pattern. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2111 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2112 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2113 // Get fast path - mark word has the biased lock pattern. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2114 ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2115 markOopDesc::biased_lock_mask_in_place, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2116 markOopDesc::biased_lock_pattern, true); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2117 // fast_lock_region->in(1) is set to slow path. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2118 fast_lock_mem_phi->init_req(1, mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2119 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2120 // Now check that the lock is biased to the current thread and has |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2121 // the same epoch and bias as Klass::_prototype_header. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2122 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2123 // Special-case a fresh allocation to avoid building nodes: |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2124 Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2125 if (klass_node == NULL) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2126 Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2127 klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); |
490
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2128 #ifdef _LP64 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6804
diff
changeset
|
2129 if (UseCompressedKlassPointers && klass_node->is_DecodeNKlass()) { |
490
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2130 assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity"); |
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2131 klass_node->in(1)->init_req(0, ctrl); |
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2132 } else |
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2133 #endif |
dd70dd4c91de
6782820: Server VM fails with "unhandled implicit exception in compiled code"
kvn
parents:
460
diff
changeset
|
2134 klass_node->init_req(0, ctrl); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2135 } |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4115
diff
changeset
|
2136 Node *proto_node = make_load(ctrl, mem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeX_X, TypeX_X->basic_type()); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2137 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2138 Node* thread = transform_later(new (C) ThreadLocalNode()); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2139 Node* cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2140 Node* o_node = transform_later(new (C) OrXNode(cast_thread, proto_node)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2141 Node* x_node = transform_later(new (C) XorXNode(o_node, mark_node)); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2142 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2143 // Get slow path - mark word does NOT match the value. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2144 Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2145 (~markOopDesc::age_mask_in_place), 0); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2146 // region->in(3) is set to fast path - the object is biased to the current thread. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2147 mem_phi->init_req(3, mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2148 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2149 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2150 // Mark word does NOT match the value (thread | Klass::_prototype_header). |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2151 |
0 | 2152 |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2153 // First, check biased pattern. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2154 // Get fast path - _prototype_header has the same biased lock pattern. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2155 ctrl = opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2156 markOopDesc::biased_lock_mask_in_place, 0, true); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2157 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2158 not_biased_ctrl = fast_lock_region->in(2); // Slow path |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2159 // fast_lock_region->in(2) - the prototype header is no longer biased |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2160 // and we have to revoke the bias on this object. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2161 // We are going to try to reset the mark of this object to the prototype |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2162 // value and fall through to the CAS-based locking scheme. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2163 Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2164 Node* cas = new (C) StoreXConditionalNode(not_biased_ctrl, mem, adr, |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2165 proto_node, mark_node); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2166 transform_later(cas); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2167 Node* proj = transform_later( new (C) SCMemProjNode(cas)); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2168 fast_lock_mem_phi->init_req(2, proj); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2169 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2170 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2171 // Second, check epoch bits. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2172 Node* rebiased_region = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2173 Node* old_phi = new (C) PhiNode( rebiased_region, TypeX_X); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2174 Node* new_phi = new (C) PhiNode( rebiased_region, TypeX_X); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2175 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2176 // Get slow path - mark word does NOT match epoch bits. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2177 Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2178 markOopDesc::epoch_mask_in_place, 0); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2179 // The epoch of the current bias is not valid, attempt to rebias the object |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2180 // toward the current thread. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2181 rebiased_region->init_req(2, epoch_ctrl); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2182 old_phi->init_req(2, mark_node); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2183 new_phi->init_req(2, o_node); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2184 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2185 // rebiased_region->in(1) is set to fast path. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2186 // The epoch of the current bias is still valid but we know |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2187 // nothing about the owner; it might be set or it might be clear. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2188 Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place | |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2189 markOopDesc::age_mask_in_place | |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2190 markOopDesc::epoch_mask_in_place); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2191 Node* old = transform_later(new (C) AndXNode(mark_node, cmask)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2192 cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2193 Node* new_mark = transform_later(new (C) OrXNode(cast_thread, old)); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2194 old_phi->init_req(1, old); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2195 new_phi->init_req(1, new_mark); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2196 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2197 transform_later(rebiased_region); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2198 transform_later(old_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2199 transform_later(new_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2200 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2201 // Try to acquire the bias of the object using an atomic operation. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2202 // If this fails we will go in to the runtime to revoke the object's bias. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2203 cas = new (C) StoreXConditionalNode(rebiased_region, mem, adr, |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2204 new_phi, old_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2205 transform_later(cas); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2206 proj = transform_later( new (C) SCMemProjNode(cas)); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2207 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2208 // Get slow path - Failed to CAS. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2209 not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2210 mem_phi->init_req(4, proj); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2211 // region->in(4) is set to fast path - the object is rebiased to the current thread. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2212 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2213 // Failed to CAS. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2214 slow_path = new (C) RegionNode(3); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2215 Node *slow_mem = new (C) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2216 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2217 slow_path->init_req(1, not_biased_ctrl); // Capture slow-control |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2218 slow_mem->init_req(1, proj); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2219 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2220 // Call CAS-based locking scheme (FastLock node). |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2221 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2222 transform_later(fast_lock_region); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2223 transform_later(fast_lock_mem_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2224 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2225 // Get slow path - FastLock failed to lock the object. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2226 ctrl = opt_bits_test(fast_lock_region, region, 2, flock, 0, 0); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2227 mem_phi->init_req(2, fast_lock_mem_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2228 // region->in(2) is set to fast path - the object is locked to the current thread. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2229 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2230 slow_path->init_req(2, ctrl); // Capture slow-control |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2231 slow_mem->init_req(2, fast_lock_mem_phi); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2232 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2233 transform_later(slow_path); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2234 transform_later(slow_mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2235 // Reset lock's memory edge. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2236 lock->set_req(TypeFunc::Memory, slow_mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2237 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2238 } else { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2239 region = new (C) RegionNode(3); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2240 // create a Phi for the memory state |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2241 mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2242 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2243 // Optimize test; set region slot 2 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2244 slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2245 mem_phi->init_req(2, mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2246 } |
0 | 2247 |
2248 // Make slow path call | |
2249 CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box ); | |
2250 | |
2251 extract_call_projections(call); | |
2252 | |
2253 // Slow path can only throw asynchronous exceptions, which are always | |
2254 // de-opted. So the compiler thinks the slow-call can never throw an | |
2255 // exception. If it DOES throw an exception we would need the debug | |
2256 // info removed first (since if it throws there is no monitor). | |
2257 assert ( _ioproj_fallthrough == NULL && _ioproj_catchall == NULL && | |
2258 _memproj_catchall == NULL && _catchallcatchproj == NULL, "Unexpected projection from Lock"); | |
2259 | |
2260 // Capture slow path | |
2261 // disconnect fall-through projection from call and create a new one | |
2262 // hook up users of fall-through projection to region | |
2263 Node *slow_ctrl = _fallthroughproj->clone(); | |
2264 transform_later(slow_ctrl); | |
2265 _igvn.hash_delete(_fallthroughproj); | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6848
diff
changeset
|
2266 _fallthroughproj->disconnect_inputs(NULL, C); |
0 | 2267 region->init_req(1, slow_ctrl); |
2268 // region inputs are now complete | |
2269 transform_later(region); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2270 _igvn.replace_node(_fallthroughproj, region); |
0 | 2271 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2272 Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); |
0 | 2273 mem_phi->init_req(1, memproj ); |
2274 transform_later(mem_phi); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2275 _igvn.replace_node(_memproj_fallthrough, mem_phi); |
0 | 2276 } |
2277 | |
2278 //------------------------------expand_unlock_node---------------------- | |
2279 void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) { | |
2280 | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
63
diff
changeset
|
2281 Node* ctrl = unlock->in(TypeFunc::Control); |
0 | 2282 Node* mem = unlock->in(TypeFunc::Memory); |
2283 Node* obj = unlock->obj_node(); | |
2284 Node* box = unlock->box_node(); | |
2285 | |
4790
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
2286 assert(!box->as_BoxLock()->is_eliminated(), "sanity"); |
4777 | 2287 |
0 | 2288 // No need for a null check on unlock |
2289 | |
2290 // Make the merge point | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2291 Node *region; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2292 Node *mem_phi; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2293 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2294 if (UseOptoBiasInlining) { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2295 // Check for biased locking unlock case, which is a no-op. |
605 | 2296 // See the full description in MacroAssembler::biased_locking_exit(). |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2297 region = new (C) RegionNode(4); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2298 // create a Phi for the memory state |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2299 mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2300 mem_phi->init_req(3, mem); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2301 |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2302 Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2303 ctrl = opt_bits_test(ctrl, region, 3, mark_node, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2304 markOopDesc::biased_lock_mask_in_place, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2305 markOopDesc::biased_lock_pattern); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2306 } else { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2307 region = new (C) RegionNode(3); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2308 // create a Phi for the memory state |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2309 mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2310 } |
0 | 2311 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2312 FastUnlockNode *funlock = new (C) FastUnlockNode( ctrl, obj, box ); |
0 | 2313 funlock = transform_later( funlock )->as_FastUnlock(); |
2314 // Optimize test; set region slot 2 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
362
diff
changeset
|
2315 Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0); |
0 | 2316 |
2317 CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box ); | |
2318 | |
2319 extract_call_projections(call); | |
2320 | |
2321 assert ( _ioproj_fallthrough == NULL && _ioproj_catchall == NULL && | |
2322 _memproj_catchall == NULL && _catchallcatchproj == NULL, "Unexpected projection from Lock"); | |
2323 | |
2324 // No exceptions for unlocking | |
2325 // Capture slow path | |
2326 // disconnect fall-through projection from call and create a new one | |
2327 // hook up users of fall-through projection to region | |
2328 Node *slow_ctrl = _fallthroughproj->clone(); | |
2329 transform_later(slow_ctrl); | |
2330 _igvn.hash_delete(_fallthroughproj); | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6848
diff
changeset
|
2331 _fallthroughproj->disconnect_inputs(NULL, C); |
0 | 2332 region->init_req(1, slow_ctrl); |
2333 // region inputs are now complete | |
2334 transform_later(region); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2335 _igvn.replace_node(_fallthroughproj, region); |
0 | 2336 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
2337 Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); |
0 | 2338 mem_phi->init_req(1, memproj ); |
2339 mem_phi->init_req(2, mem); | |
2340 transform_later(mem_phi); | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
628
diff
changeset
|
2341 _igvn.replace_node(_memproj_fallthrough, mem_phi); |
0 | 2342 } |
2343 | |
4115 | 2344 //---------------------------eliminate_macro_nodes---------------------- |
2345 // Eliminate scalar replaced allocations and associated locks. | |
2346 void PhaseMacroExpand::eliminate_macro_nodes() { | |
0 | 2347 if (C->macro_count() == 0) |
4115 | 2348 return; |
2349 | |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2350 // First, attempt to eliminate locks |
3754
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2351 int cnt = C->macro_count(); |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2352 for (int i=0; i < cnt; i++) { |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2353 Node *n = C->macro_node(i); |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2354 if (n->is_AbstractLock()) { // Lock and Unlock nodes |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2355 // Before elimination mark all associated (same box and obj) |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2356 // lock and unlock nodes. |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2357 mark_eliminated_locking_nodes(n->as_AbstractLock()); |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2358 } |
642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
kvn
parents:
3345
diff
changeset
|
2359 } |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2360 bool progress = true; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2361 while (progress) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2362 progress = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2363 for (int i = C->macro_count(); i > 0; i--) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2364 Node * n = C->macro_node(i-1); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2365 bool success = false; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2366 debug_only(int old_macro_count = C->macro_count();); |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2367 if (n->is_AbstractLock()) { |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2368 success = eliminate_locking_node(n->as_AbstractLock()); |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2369 } |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2370 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2371 progress = progress || success; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2372 } |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2373 } |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2374 // Next, attempt to eliminate allocations |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2375 progress = true; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2376 while (progress) { |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2377 progress = false; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2378 for (int i = C->macro_count(); i > 0; i--) { |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2379 Node * n = C->macro_node(i-1); |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2380 bool success = false; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2381 debug_only(int old_macro_count = C->macro_count();); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2382 switch (n->class_id()) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2383 case Node::Class_Allocate: |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2384 case Node::Class_AllocateArray: |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2385 success = eliminate_allocate_node(n->as_Allocate()); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2386 break; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2387 case Node::Class_Lock: |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2388 case Node::Class_Unlock: |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
436
diff
changeset
|
2389 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2390 break; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2391 default: |
4115 | 2392 assert(n->Opcode() == Op_LoopLimit || |
2393 n->Opcode() == Op_Opaque1 || | |
2394 n->Opcode() == Op_Opaque2, "unknown node type in macro list"); | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2395 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2396 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2397 progress = progress || success; |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2398 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2399 } |
4115 | 2400 } |
2401 | |
2402 //------------------------------expand_macro_nodes---------------------- | |
2403 // Returns true if a failure occurred. | |
2404 bool PhaseMacroExpand::expand_macro_nodes() { | |
2405 // Last attempt to eliminate macro nodes. | |
2406 eliminate_macro_nodes(); | |
2407 | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2408 // Make sure expansion will not cause node limit to be exceeded. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2409 // Worst case is a macro node gets expanded into about 50 nodes. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2410 // Allow 50% more for optimization. |
0 | 2411 if (C->check_node_count(C->macro_count() * 75, "out of nodes before macro expansion" ) ) |
2412 return true; | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2413 |
4115 | 2414 // Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations. |
2415 bool progress = true; | |
2416 while (progress) { | |
2417 progress = false; | |
2418 for (int i = C->macro_count(); i > 0; i--) { | |
2419 Node * n = C->macro_node(i-1); | |
2420 bool success = false; | |
2421 debug_only(int old_macro_count = C->macro_count();); | |
2422 if (n->Opcode() == Op_LoopLimit) { | |
2423 // Remove it from macro list and put on IGVN worklist to optimize. | |
2424 C->remove_macro_node(n); | |
2425 _igvn._worklist.push(n); | |
2426 success = true; | |
2427 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | |
2428 _igvn.replace_node(n, n->in(1)); | |
2429 success = true; | |
2430 } | |
2431 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | |
2432 progress = progress || success; | |
2433 } | |
2434 } | |
2435 | |
0 | 2436 // expand "macro" nodes |
2437 // nodes are removed from the macro list as they are processed | |
2438 while (C->macro_count() > 0) { | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2439 int macro_count = C->macro_count(); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2440 Node * n = C->macro_node(macro_count-1); |
0 | 2441 assert(n->is_macro(), "only macro nodes expected here"); |
2442 if (_igvn.type(n) == Type::TOP || n->in(0)->is_top() ) { | |
2443 // node is unreachable, so don't try to expand it | |
2444 C->remove_macro_node(n); | |
2445 continue; | |
2446 } | |
2447 switch (n->class_id()) { | |
2448 case Node::Class_Allocate: | |
2449 expand_allocate(n->as_Allocate()); | |
2450 break; | |
2451 case Node::Class_AllocateArray: | |
2452 expand_allocate_array(n->as_AllocateArray()); | |
2453 break; | |
2454 case Node::Class_Lock: | |
2455 expand_lock_node(n->as_Lock()); | |
2456 break; | |
2457 case Node::Class_Unlock: | |
2458 expand_unlock_node(n->as_Unlock()); | |
2459 break; | |
2460 default: | |
2461 assert(false, "unknown node type in macro list"); | |
2462 } | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
66
diff
changeset
|
2463 assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); |
0 | 2464 if (C->failing()) return true; |
2465 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
2466 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
2467 _igvn.set_delay_transform(false); |
0 | 2468 _igvn.optimize(); |
4115 | 2469 if (C->failing()) return true; |
0 | 2470 return false; |
2471 } |