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