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