Mercurial > hg > graal-jvmci-8
annotate src/share/vm/opto/callnode.cpp @ 23054:55d07ec5bde4
8036851: volatile double accesses are not explicitly atomic in C2
Summary: The C2 structure is adapted to distinguish between volatile and non-volatile double accesses.
Reviewed-by: twisti, kvn
Contributed-by: Tobias Hartmann <tobias.hartmann@oracle.com>
author | anoll |
---|---|
date | Tue, 06 May 2014 09:17:57 +0200 |
parents | 6e8e0bf87bbe |
children | dd9cc155639c |
rev | line source |
---|---|
0 | 1 /* |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
2 * Copyright (c) 1997, 2015, 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:
1080
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1080
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:
1080
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
26 #include "compiler/compileLog.hpp" |
1972 | 27 #include "ci/bcEscapeAnalyzer.hpp" |
28 #include "compiler/oopMap.hpp" | |
7473 | 29 #include "opto/callGenerator.hpp" |
1972 | 30 #include "opto/callnode.hpp" |
31 #include "opto/escape.hpp" | |
32 #include "opto/locknode.hpp" | |
33 #include "opto/machnode.hpp" | |
34 #include "opto/matcher.hpp" | |
35 #include "opto/parse.hpp" | |
36 #include "opto/regalloc.hpp" | |
37 #include "opto/regmask.hpp" | |
38 #include "opto/rootnode.hpp" | |
39 #include "opto/runtime.hpp" | |
40 | |
0 | 41 // Portions of code courtesy of Clifford Click |
42 | |
43 // Optimization - Graph Style | |
44 | |
45 //============================================================================= | |
46 uint StartNode::size_of() const { return sizeof(*this); } | |
47 uint StartNode::cmp( const Node &n ) const | |
48 { return _domain == ((StartNode&)n)._domain; } | |
49 const Type *StartNode::bottom_type() const { return _domain; } | |
50 const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; } | |
51 #ifndef PRODUCT | |
52 void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);} | |
53 #endif | |
54 | |
55 //------------------------------Ideal------------------------------------------ | |
56 Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
57 return remove_dead_region(phase, can_reshape) ? this : NULL; | |
58 } | |
59 | |
60 //------------------------------calling_convention----------------------------- | |
61 void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { | |
62 Matcher::calling_convention( sig_bt, parm_regs, argcnt, false ); | |
63 } | |
64 | |
65 //------------------------------Registers-------------------------------------- | |
66 const RegMask &StartNode::in_RegMask(uint) const { | |
67 return RegMask::Empty; | |
68 } | |
69 | |
70 //------------------------------match------------------------------------------ | |
71 // Construct projections for incoming parameters, and their RegMask info | |
72 Node *StartNode::match( const ProjNode *proj, const Matcher *match ) { | |
73 switch (proj->_con) { | |
74 case TypeFunc::Control: | |
75 case TypeFunc::I_O: | |
76 case TypeFunc::Memory: | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
77 return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); |
0 | 78 case TypeFunc::FramePtr: |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
79 return new (match->C) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); |
0 | 80 case TypeFunc::ReturnAdr: |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
81 return new (match->C) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); |
0 | 82 case TypeFunc::Parms: |
83 default: { | |
84 uint parm_num = proj->_con - TypeFunc::Parms; | |
85 const Type *t = _domain->field_at(proj->_con); | |
86 if (t->base() == Type::Half) // 2nd half of Longs and Doubles | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
87 return new (match->C) ConNode(Type::TOP); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
88 uint ideal_reg = t->ideal_reg(); |
0 | 89 RegMask &rm = match->_calling_convention_mask[parm_num]; |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
90 return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); |
0 | 91 } |
92 } | |
93 return NULL; | |
94 } | |
95 | |
96 //------------------------------StartOSRNode---------------------------------- | |
97 // The method start node for an on stack replacement adapter | |
98 | |
99 //------------------------------osr_domain----------------------------- | |
100 const TypeTuple *StartOSRNode::osr_domain() { | |
101 const Type **fields = TypeTuple::fields(2); | |
102 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // address of osr buffer | |
103 | |
104 return TypeTuple::make(TypeFunc::Parms+1, fields); | |
105 } | |
106 | |
107 //============================================================================= | |
108 const char * const ParmNode::names[TypeFunc::Parms+1] = { | |
109 "Control", "I_O", "Memory", "FramePtr", "ReturnAdr", "Parms" | |
110 }; | |
111 | |
112 #ifndef PRODUCT | |
113 void ParmNode::dump_spec(outputStream *st) const { | |
114 if( _con < TypeFunc::Parms ) { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
115 st->print("%s", names[_con]); |
0 | 116 } else { |
117 st->print("Parm%d: ",_con-TypeFunc::Parms); | |
118 // Verbose and WizardMode dump bottom_type for all nodes | |
119 if( !Verbose && !WizardMode ) bottom_type()->dump_on(st); | |
120 } | |
121 } | |
122 #endif | |
123 | |
124 uint ParmNode::ideal_reg() const { | |
125 switch( _con ) { | |
126 case TypeFunc::Control : // fall through | |
127 case TypeFunc::I_O : // fall through | |
128 case TypeFunc::Memory : return 0; | |
129 case TypeFunc::FramePtr : // fall through | |
130 case TypeFunc::ReturnAdr: return Op_RegP; | |
131 default : assert( _con > TypeFunc::Parms, "" ); | |
132 // fall through | |
133 case TypeFunc::Parms : { | |
134 // Type of argument being passed | |
135 const Type *t = in(0)->as_Start()->_domain->field_at(_con); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
136 return t->ideal_reg(); |
0 | 137 } |
138 } | |
139 ShouldNotReachHere(); | |
140 return 0; | |
141 } | |
142 | |
143 //============================================================================= | |
144 ReturnNode::ReturnNode(uint edges, Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(edges) { | |
145 init_req(TypeFunc::Control,cntrl); | |
146 init_req(TypeFunc::I_O,i_o); | |
147 init_req(TypeFunc::Memory,memory); | |
148 init_req(TypeFunc::FramePtr,frameptr); | |
149 init_req(TypeFunc::ReturnAdr,retadr); | |
150 } | |
151 | |
152 Node *ReturnNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
153 return remove_dead_region(phase, can_reshape) ? this : NULL; | |
154 } | |
155 | |
156 const Type *ReturnNode::Value( PhaseTransform *phase ) const { | |
157 return ( phase->type(in(TypeFunc::Control)) == Type::TOP) | |
158 ? Type::TOP | |
159 : Type::BOTTOM; | |
160 } | |
161 | |
162 // Do we Match on this edge index or not? No edges on return nodes | |
163 uint ReturnNode::match_edge(uint idx) const { | |
164 return 0; | |
165 } | |
166 | |
167 | |
168 #ifndef PRODUCT | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
169 void ReturnNode::dump_req(outputStream *st) const { |
0 | 170 // Dump the required inputs, enclosed in '(' and ')' |
171 uint i; // Exit value of loop | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
172 for (i = 0; i < req(); i++) { // For all required inputs |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
173 if (i == TypeFunc::Parms) st->print("returns"); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
174 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
175 else st->print("_ "); |
0 | 176 } |
177 } | |
178 #endif | |
179 | |
180 //============================================================================= | |
181 RethrowNode::RethrowNode( | |
182 Node* cntrl, | |
183 Node* i_o, | |
184 Node* memory, | |
185 Node* frameptr, | |
186 Node* ret_adr, | |
187 Node* exception | |
188 ) : Node(TypeFunc::Parms + 1) { | |
189 init_req(TypeFunc::Control , cntrl ); | |
190 init_req(TypeFunc::I_O , i_o ); | |
191 init_req(TypeFunc::Memory , memory ); | |
192 init_req(TypeFunc::FramePtr , frameptr ); | |
193 init_req(TypeFunc::ReturnAdr, ret_adr); | |
194 init_req(TypeFunc::Parms , exception); | |
195 } | |
196 | |
197 Node *RethrowNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
198 return remove_dead_region(phase, can_reshape) ? this : NULL; | |
199 } | |
200 | |
201 const Type *RethrowNode::Value( PhaseTransform *phase ) const { | |
202 return (phase->type(in(TypeFunc::Control)) == Type::TOP) | |
203 ? Type::TOP | |
204 : Type::BOTTOM; | |
205 } | |
206 | |
207 uint RethrowNode::match_edge(uint idx) const { | |
208 return 0; | |
209 } | |
210 | |
211 #ifndef PRODUCT | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
212 void RethrowNode::dump_req(outputStream *st) const { |
0 | 213 // Dump the required inputs, enclosed in '(' and ')' |
214 uint i; // Exit value of loop | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
215 for (i = 0; i < req(); i++) { // For all required inputs |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
216 if (i == TypeFunc::Parms) st->print("exception"); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
217 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
218 else st->print("_ "); |
0 | 219 } |
220 } | |
221 #endif | |
222 | |
223 //============================================================================= | |
224 // Do we Match on this edge index or not? Match only target address & method | |
225 uint TailCallNode::match_edge(uint idx) const { | |
226 return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1; | |
227 } | |
228 | |
229 //============================================================================= | |
230 // Do we Match on this edge index or not? Match only target address & oop | |
231 uint TailJumpNode::match_edge(uint idx) const { | |
232 return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1; | |
233 } | |
234 | |
235 //============================================================================= | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
236 JVMState::JVMState(ciMethod* method, JVMState* caller) : |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
237 _method(method) { |
0 | 238 assert(method != NULL, "must be valid call site"); |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
704
diff
changeset
|
239 _reexecute = Reexecute_Undefined; |
0 | 240 debug_only(_bci = -99); // random garbage value |
241 debug_only(_map = (SafePointNode*)-1); | |
242 _caller = caller; | |
243 _depth = 1 + (caller == NULL ? 0 : caller->depth()); | |
244 _locoff = TypeFunc::Parms; | |
245 _stkoff = _locoff + _method->max_locals(); | |
246 _monoff = _stkoff + _method->max_stack(); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
247 _scloff = _monoff; |
0 | 248 _endoff = _monoff; |
249 _sp = 0; | |
250 } | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
251 JVMState::JVMState(int stack_size) : |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
252 _method(NULL) { |
0 | 253 _bci = InvocationEntryBci; |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
704
diff
changeset
|
254 _reexecute = Reexecute_Undefined; |
0 | 255 debug_only(_map = (SafePointNode*)-1); |
256 _caller = NULL; | |
257 _depth = 1; | |
258 _locoff = TypeFunc::Parms; | |
259 _stkoff = _locoff; | |
260 _monoff = _stkoff + stack_size; | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
261 _scloff = _monoff; |
0 | 262 _endoff = _monoff; |
263 _sp = 0; | |
264 } | |
265 | |
266 //--------------------------------of_depth------------------------------------- | |
267 JVMState* JVMState::of_depth(int d) const { | |
268 const JVMState* jvmp = this; | |
269 assert(0 < d && (uint)d <= depth(), "oob"); | |
270 for (int skip = depth() - d; skip > 0; skip--) { | |
271 jvmp = jvmp->caller(); | |
272 } | |
273 assert(jvmp->depth() == (uint)d, "found the right one"); | |
274 return (JVMState*)jvmp; | |
275 } | |
276 | |
277 //-----------------------------same_calls_as----------------------------------- | |
278 bool JVMState::same_calls_as(const JVMState* that) const { | |
279 if (this == that) return true; | |
280 if (this->depth() != that->depth()) return false; | |
281 const JVMState* p = this; | |
282 const JVMState* q = that; | |
283 for (;;) { | |
284 if (p->_method != q->_method) return false; | |
285 if (p->_method == NULL) return true; // bci is irrelevant | |
286 if (p->_bci != q->_bci) return false; | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
704
diff
changeset
|
287 if (p->_reexecute != q->_reexecute) return false; |
0 | 288 p = p->caller(); |
289 q = q->caller(); | |
290 if (p == q) return true; | |
291 assert(p != NULL && q != NULL, "depth check ensures we don't run off end"); | |
292 } | |
293 } | |
294 | |
295 //------------------------------debug_start------------------------------------ | |
296 uint JVMState::debug_start() const { | |
297 debug_only(JVMState* jvmroot = of_depth(1)); | |
298 assert(jvmroot->locoff() <= this->locoff(), "youngest JVMState must be last"); | |
299 return of_depth(1)->locoff(); | |
300 } | |
301 | |
302 //-------------------------------debug_end------------------------------------- | |
303 uint JVMState::debug_end() const { | |
304 debug_only(JVMState* jvmroot = of_depth(1)); | |
305 assert(jvmroot->endoff() <= this->endoff(), "youngest JVMState must be last"); | |
306 return endoff(); | |
307 } | |
308 | |
309 //------------------------------debug_depth------------------------------------ | |
310 uint JVMState::debug_depth() const { | |
311 uint total = 0; | |
312 for (const JVMState* jvmp = this; jvmp != NULL; jvmp = jvmp->caller()) { | |
313 total += jvmp->debug_size(); | |
314 } | |
315 return total; | |
316 } | |
317 | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
318 #ifndef PRODUCT |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
319 |
0 | 320 //------------------------------format_helper---------------------------------- |
321 // Given an allocation (a Chaitin object) and a Node decide if the Node carries | |
322 // any defined value or not. If it does, print out the register or constant. | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
323 static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i, GrowableArray<SafePointScalarObjectNode*> *scobjs ) { |
0 | 324 if (n == NULL) { st->print(" NULL"); return; } |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
325 if (n->is_SafePointScalarObject()) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
326 // Scalar replacement. |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
327 SafePointScalarObjectNode* spobj = n->as_SafePointScalarObject(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
328 scobjs->append_if_missing(spobj); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
329 int sco_n = scobjs->find(spobj); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
330 assert(sco_n >= 0, ""); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
331 st->print(" %s%d]=#ScObj" INT32_FORMAT, msg, i, sco_n); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
332 return; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
333 } |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
334 if (regalloc->node_regs_max_index() > 0 && |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
335 OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined |
0 | 336 char buf[50]; |
337 regalloc->dump_register(n,buf); | |
338 st->print(" %s%d]=%s",msg,i,buf); | |
339 } else { // No register, but might be constant | |
340 const Type *t = n->bottom_type(); | |
341 switch (t->base()) { | |
342 case Type::Int: | |
343 st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con()); | |
344 break; | |
345 case Type::AnyPtr: | |
14438
4cdf4f71177d
8029025: PPC64 (part 203): opto: Move static _in_dump_cnt to Compile object.
goetz
parents:
12158
diff
changeset
|
346 assert( t == TypePtr::NULL_PTR || n->in_dump(), "" ); |
0 | 347 st->print(" %s%d]=#NULL",msg,i); |
348 break; | |
349 case Type::AryPtr: | |
350 case Type::InstPtr: | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
351 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->isa_oopptr()->const_oop())); |
0 | 352 break; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
353 case Type::KlassPtr: |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
354 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_klassptr()->klass())); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
355 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
356 case Type::MetadataPtr: |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
357 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_metadataptr()->metadata())); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
358 break; |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
305
diff
changeset
|
359 case Type::NarrowOop: |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
360 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,p2i(t->make_ptr()->isa_oopptr()->const_oop())); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
305
diff
changeset
|
361 break; |
0 | 362 case Type::RawPtr: |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
363 st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,p2i(t->is_rawptr())); |
0 | 364 break; |
365 case Type::DoubleCon: | |
366 st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); | |
367 break; | |
368 case Type::FloatCon: | |
369 st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); | |
370 break; | |
371 case Type::Long: | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
372 st->print(" %s%d]=#"INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con())); |
0 | 373 break; |
374 case Type::Half: | |
375 case Type::Top: | |
376 st->print(" %s%d]=_",msg,i); | |
377 break; | |
378 default: ShouldNotReachHere(); | |
379 } | |
380 } | |
381 } | |
382 | |
383 //------------------------------format----------------------------------------- | |
384 void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const { | |
385 st->print(" #"); | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
386 if (_method) { |
0 | 387 _method->print_short_name(st); |
388 st->print(" @ bci:%d ",_bci); | |
389 } else { | |
390 st->print_cr(" runtime stub "); | |
391 return; | |
392 } | |
393 if (n->is_MachSafePoint()) { | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
394 GrowableArray<SafePointScalarObjectNode*> scobjs; |
0 | 395 MachSafePointNode *mcall = n->as_MachSafePoint(); |
396 uint i; | |
397 // Print locals | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
398 for (i = 0; i < (uint)loc_size(); i++) |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
399 format_helper(regalloc, st, mcall->local(this, i), "L[", i, &scobjs); |
0 | 400 // Print stack |
401 for (i = 0; i < (uint)stk_size(); i++) { | |
402 if ((uint)(_stkoff + i) >= mcall->len()) | |
403 st->print(" oob "); | |
404 else | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
405 format_helper(regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs); |
0 | 406 } |
407 for (i = 0; (int)i < nof_monitors(); i++) { | |
408 Node *box = mcall->monitor_box(this, i); | |
409 Node *obj = mcall->monitor_obj(this, i); | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
410 if (regalloc->node_regs_max_index() > 0 && |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
411 OptoReg::is_valid(regalloc->get_reg_first(box))) { |
4777 | 412 box = BoxLockNode::box_node(box); |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
413 format_helper(regalloc, st, box, "MON-BOX[", i, &scobjs); |
0 | 414 } else { |
4777 | 415 OptoReg::Name box_reg = BoxLockNode::reg(box); |
0 | 416 st->print(" MON-BOX%d=%s+%d", |
417 i, | |
418 OptoReg::regname(OptoReg::c_frame_pointer), | |
419 regalloc->reg2offset(box_reg)); | |
420 } | |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
421 const char* obj_msg = "MON-OBJ["; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
422 if (EliminateLocks) { |
4777 | 423 if (BoxLockNode::box_node(box)->is_eliminated()) |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
424 obj_msg = "MON-OBJ(LOCK ELIMINATED)["; |
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
425 } |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
426 format_helper(regalloc, st, obj, obj_msg, i, &scobjs); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
427 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
428 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
429 for (i = 0; i < (uint)scobjs.length(); i++) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
430 // Scalar replaced objects. |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
431 st->cr(); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
432 st->print(" # ScObj" INT32_FORMAT " ", i); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
433 SafePointScalarObjectNode* spobj = scobjs.at(i); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
434 ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
435 assert(cik->is_instance_klass() || |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
436 cik->is_array_klass(), "Not supported allocation."); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
437 ciInstanceKlass *iklass = NULL; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
438 if (cik->is_instance_klass()) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
439 cik->print_name_on(st); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
440 iklass = cik->as_instance_klass(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
441 } else if (cik->is_type_array_klass()) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
442 cik->as_array_klass()->base_element_type()->print_name_on(st); |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
443 st->print("[%d]", spobj->n_fields()); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
444 } else if (cik->is_obj_array_klass()) { |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
445 ciKlass* cie = cik->as_obj_array_klass()->base_element_klass(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
446 if (cie->is_instance_klass()) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
447 cie->print_name_on(st); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
448 } else if (cie->is_type_array_klass()) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
449 cie->as_array_klass()->base_element_type()->print_name_on(st); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
450 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
451 ShouldNotReachHere(); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
452 } |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
453 st->print("[%d]", spobj->n_fields()); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
454 int ndim = cik->as_array_klass()->dimension() - 1; |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
455 while (ndim-- > 0) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
456 st->print("[]"); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
457 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
458 } |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
931
diff
changeset
|
459 st->print("={"); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
460 uint nf = spobj->n_fields(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
461 if (nf > 0) { |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
462 uint first_ind = spobj->first_index(mcall->jvms()); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
463 Node* fld_node = mcall->in(first_ind); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
464 ciField* cifield; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
465 if (iklass != NULL) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
466 st->print(" ["); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
467 cifield = iklass->nonstatic_field_at(0); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
468 cifield->print_name_on(st); |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
469 format_helper(regalloc, st, fld_node, ":", 0, &scobjs); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
470 } else { |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
471 format_helper(regalloc, st, fld_node, "[", 0, &scobjs); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
472 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
473 for (uint j = 1; j < nf; j++) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
474 fld_node = mcall->in(first_ind+j); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
475 if (iklass != NULL) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
476 st->print(", ["); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
477 cifield = iklass->nonstatic_field_at(j); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
478 cifield->print_name_on(st); |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
479 format_helper(regalloc, st, fld_node, ":", j, &scobjs); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
480 } else { |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
481 format_helper(regalloc, st, fld_node, ", [", j, &scobjs); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
482 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
483 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
484 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
485 st->print(" }"); |
0 | 486 } |
487 } | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
488 st->cr(); |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
489 if (caller() != NULL) caller()->format(regalloc, n, st); |
0 | 490 } |
491 | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
492 |
0 | 493 void JVMState::dump_spec(outputStream *st) const { |
494 if (_method != NULL) { | |
495 bool printed = false; | |
496 if (!Verbose) { | |
497 // The JVMS dumps make really, really long lines. | |
498 // Take out the most boring parts, which are the package prefixes. | |
499 char buf[500]; | |
500 stringStream namest(buf, sizeof(buf)); | |
501 _method->print_short_name(&namest); | |
502 if (namest.count() < sizeof(buf)) { | |
503 const char* name = namest.base(); | |
504 if (name[0] == ' ') ++name; | |
505 const char* endcn = strchr(name, ':'); // end of class name | |
506 if (endcn == NULL) endcn = strchr(name, '('); | |
507 if (endcn == NULL) endcn = name + strlen(name); | |
508 while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/') | |
509 --endcn; | |
510 st->print(" %s", endcn); | |
511 printed = true; | |
512 } | |
513 } | |
514 if (!printed) | |
515 _method->print_short_name(st); | |
516 st->print(" @ bci:%d",_bci); | |
931
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
903
diff
changeset
|
517 if(_reexecute == Reexecute_True) |
72088be4b386
6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents:
903
diff
changeset
|
518 st->print(" reexecute"); |
0 | 519 } else { |
520 st->print(" runtime stub"); | |
521 } | |
522 if (caller() != NULL) caller()->dump_spec(st); | |
523 } | |
524 | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
525 |
0 | 526 void JVMState::dump_on(outputStream* st) const { |
10278 | 527 bool print_map = _map && !((uintptr_t)_map & 1) && |
528 ((caller() == NULL) || (caller()->map() != _map)); | |
529 if (print_map) { | |
0 | 530 if (_map->len() > _map->req()) { // _map->has_exceptions() |
531 Node* ex = _map->in(_map->req()); // _map->next_exception() | |
532 // skip the first one; it's already being printed | |
533 while (ex != NULL && ex->len() > ex->req()) { | |
534 ex = ex->in(ex->req()); // ex->next_exception() | |
535 ex->dump(1); | |
536 } | |
537 } | |
10278 | 538 _map->dump(Verbose ? 2 : 1); |
539 } | |
540 if (caller() != NULL) { | |
541 caller()->dump_on(st); | |
0 | 542 } |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
543 st->print("JVMS depth=%d loc=%d stk=%d arg=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=", |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
5948
diff
changeset
|
544 depth(), locoff(), stkoff(), argoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false"); |
0 | 545 if (_method == NULL) { |
546 st->print_cr("(none)"); | |
547 } else { | |
548 _method->print_name(st); | |
549 st->cr(); | |
550 if (bci() >= 0 && bci() < _method->code_size()) { | |
551 st->print(" bc: "); | |
552 _method->print_codes_on(bci(), bci()+1, st); | |
553 } | |
554 } | |
555 } | |
556 | |
557 // Extra way to dump a jvms from the debugger, | |
558 // to avoid a bug with C++ member function calls. | |
559 void dump_jvms(JVMState* jvms) { | |
560 jvms->dump(); | |
561 } | |
562 #endif | |
563 | |
564 //--------------------------clone_shallow-------------------------------------- | |
565 JVMState* JVMState::clone_shallow(Compile* C) const { | |
566 JVMState* n = has_method() ? new (C) JVMState(_method, _caller) : new (C) JVMState(0); | |
567 n->set_bci(_bci); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
704
diff
changeset
|
568 n->_reexecute = _reexecute; |
0 | 569 n->set_locoff(_locoff); |
570 n->set_stkoff(_stkoff); | |
571 n->set_monoff(_monoff); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
572 n->set_scloff(_scloff); |
0 | 573 n->set_endoff(_endoff); |
574 n->set_sp(_sp); | |
575 n->set_map(_map); | |
576 return n; | |
577 } | |
578 | |
579 //---------------------------clone_deep---------------------------------------- | |
580 JVMState* JVMState::clone_deep(Compile* C) const { | |
581 JVMState* n = clone_shallow(C); | |
582 for (JVMState* p = n; p->_caller != NULL; p = p->_caller) { | |
583 p->_caller = p->_caller->clone_shallow(C); | |
584 } | |
585 assert(n->depth() == depth(), "sanity"); | |
586 assert(n->debug_depth() == debug_depth(), "sanity"); | |
587 return n; | |
588 } | |
589 | |
10278 | 590 /** |
591 * Reset map for all callers | |
592 */ | |
593 void JVMState::set_map_deep(SafePointNode* map) { | |
594 for (JVMState* p = this; p->_caller != NULL; p = p->_caller) { | |
595 p->set_map(map); | |
596 } | |
597 } | |
598 | |
17791
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
599 // Adapt offsets in in-array after adding or removing an edge. |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
600 // Prerequisite is that the JVMState is used by only one node. |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
601 void JVMState::adapt_position(int delta) { |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
602 for (JVMState* jvms = this; jvms != NULL; jvms = jvms->caller()) { |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
603 jvms->set_locoff(jvms->locoff() + delta); |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
604 jvms->set_stkoff(jvms->stkoff() + delta); |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
605 jvms->set_monoff(jvms->monoff() + delta); |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
606 jvms->set_scloff(jvms->scloff() + delta); |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
607 jvms->set_endoff(jvms->endoff() + delta); |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
608 } |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
609 } |
ad3b94907eed
8030863: PPC64: (part 220): ConstantTableBase for calls between args and jvms
goetz
parents:
14438
diff
changeset
|
610 |
17980
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
611 // Mirror the stack size calculation in the deopt code |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
612 // How much stack space would we need at this point in the program in |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
613 // case of deoptimization? |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
614 int JVMState::interpreter_frame_size() const { |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
615 const JVMState* jvms = this; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
616 int size = 0; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
617 int callee_parameters = 0; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
618 int callee_locals = 0; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
619 int extra_args = method()->max_stack() - stk_size(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
620 |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
621 while (jvms != NULL) { |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
622 int locks = jvms->nof_monitors(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
623 int temps = jvms->stk_size(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
624 bool is_top_frame = (jvms == this); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
625 ciMethod* method = jvms->method(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
626 |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
627 int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(), |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
628 temps + callee_parameters, |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
629 extra_args, |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
630 locks, |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
631 callee_parameters, |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
632 callee_locals, |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
633 is_top_frame); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
634 size += frame_size; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
635 |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
636 callee_parameters = method->size_of_parameters(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
637 callee_locals = method->max_locals(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
638 extra_args = 0; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
639 jvms = jvms->caller(); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
640 } |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
641 return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
642 } |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17937
diff
changeset
|
643 |
0 | 644 //============================================================================= |
645 uint CallNode::cmp( const Node &n ) const | |
646 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; } | |
647 #ifndef PRODUCT | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
648 void CallNode::dump_req(outputStream *st) const { |
0 | 649 // Dump the required inputs, enclosed in '(' and ')' |
650 uint i; // Exit value of loop | |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
651 for (i = 0; i < req(); i++) { // For all required inputs |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
652 if (i == TypeFunc::Parms) st->print("("); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
653 if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); |
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
654 else st->print("_ "); |
0 | 655 } |
7636
a7114d3d712e
8005055: pass outputStream to more opto debug routines
kvn
parents:
7473
diff
changeset
|
656 st->print(")"); |
0 | 657 } |
658 | |
659 void CallNode::dump_spec(outputStream *st) const { | |
660 st->print(" "); | |
661 tf()->dump_on(st); | |
662 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); | |
663 if (jvms() != NULL) jvms()->dump_spec(st); | |
664 } | |
665 #endif | |
666 | |
667 const Type *CallNode::bottom_type() const { return tf()->range(); } | |
668 const Type *CallNode::Value(PhaseTransform *phase) const { | |
669 if (phase->type(in(0)) == Type::TOP) return Type::TOP; | |
670 return tf()->range(); | |
671 } | |
672 | |
673 //------------------------------calling_convention----------------------------- | |
674 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { | |
675 // Use the standard compiler calling convention | |
676 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true ); | |
677 } | |
678 | |
679 | |
680 //------------------------------match------------------------------------------ | |
681 // Construct projections for control, I/O, memory-fields, ..., and | |
682 // return result(s) along with their RegMask info | |
683 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) { | |
684 switch (proj->_con) { | |
685 case TypeFunc::Control: | |
686 case TypeFunc::I_O: | |
687 case TypeFunc::Memory: | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
688 return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); |
0 | 689 |
690 case TypeFunc::Parms+1: // For LONG & DOUBLE returns | |
691 assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, ""); | |
692 // 2nd half of doubles and longs | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
693 return new (match->C) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); |
0 | 694 |
695 case TypeFunc::Parms: { // Normal returns | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
696 uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg(); |
0 | 697 OptoRegPair regs = is_CallRuntime() |
698 ? match->c_return_value(ideal_reg,true) // Calls into C runtime | |
699 : match-> return_value(ideal_reg,true); // Calls into compiled Java code | |
700 RegMask rm = RegMask(regs.first()); | |
701 if( OptoReg::is_valid(regs.second()) ) | |
702 rm.Insert( regs.second() ); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
703 return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); |
0 | 704 } |
705 | |
706 case TypeFunc::ReturnAdr: | |
707 case TypeFunc::FramePtr: | |
708 default: | |
709 ShouldNotReachHere(); | |
710 } | |
711 return NULL; | |
712 } | |
713 | |
714 // Do we Match on this edge index or not? Match no edges | |
715 uint CallNode::match_edge(uint idx) const { | |
716 return 0; | |
717 } | |
718 | |
65 | 719 // |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
66
diff
changeset
|
720 // Determine whether the call could modify the field of the specified |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
66
diff
changeset
|
721 // instance at the specified offset. |
65 | 722 // |
10278 | 723 bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) { |
724 assert((t_oop != NULL), "sanity"); | |
725 if (t_oop->is_known_instance()) { | |
726 // The instance_id is set only for scalar-replaceable allocations which | |
727 // are not passed as arguments according to Escape Analysis. | |
728 return false; | |
65 | 729 } |
10278 | 730 if (t_oop->is_ptr_to_boxed_value()) { |
731 ciKlass* boxing_klass = t_oop->klass(); | |
732 if (is_CallStaticJava() && as_CallStaticJava()->is_boxing_method()) { | |
733 // Skip unrelated boxing methods. | |
734 Node* proj = proj_out(TypeFunc::Parms); | |
735 if ((proj == NULL) || (phase->type(proj)->is_instptr()->klass() != boxing_klass)) { | |
736 return false; | |
737 } | |
738 } | |
739 if (is_CallJava() && as_CallJava()->method() != NULL) { | |
740 ciMethod* meth = as_CallJava()->method(); | |
741 if (meth->is_accessor()) { | |
742 return false; | |
743 } | |
744 // May modify (by reflection) if an boxing object is passed | |
745 // as argument or returned. | |
746 if (returns_pointer() && (proj_out(TypeFunc::Parms) != NULL)) { | |
747 Node* proj = proj_out(TypeFunc::Parms); | |
748 const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr(); | |
749 if ((inst_t != NULL) && (!inst_t->klass_is_exact() || | |
750 (inst_t->klass() == boxing_klass))) { | |
751 return true; | |
752 } | |
753 } | |
754 const TypeTuple* d = tf()->domain(); | |
755 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { | |
756 const TypeInstPtr* inst_t = d->field_at(i)->isa_instptr(); | |
757 if ((inst_t != NULL) && (!inst_t->klass_is_exact() || | |
758 (inst_t->klass() == boxing_klass))) { | |
759 return true; | |
760 } | |
761 } | |
762 return false; | |
763 } | |
764 } | |
765 return true; | |
65 | 766 } |
767 | |
768 // Does this call have a direct reference to n other than debug information? | |
769 bool CallNode::has_non_debug_use(Node *n) { | |
770 const TypeTuple * d = tf()->domain(); | |
771 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { | |
772 Node *arg = in(i); | |
773 if (arg == n) { | |
774 return true; | |
775 } | |
776 } | |
777 return false; | |
778 } | |
779 | |
780 // Returns the unique CheckCastPP of a call | |
20452
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
781 // or 'this' if there are several CheckCastPP or unexpected uses |
65 | 782 // or returns NULL if there is no one. |
783 Node *CallNode::result_cast() { | |
784 Node *cast = NULL; | |
785 | |
786 Node *p = proj_out(TypeFunc::Parms); | |
787 if (p == NULL) | |
788 return NULL; | |
789 | |
790 for (DUIterator_Fast imax, i = p->fast_outs(imax); i < imax; i++) { | |
791 Node *use = p->fast_out(i); | |
792 if (use->is_CheckCastPP()) { | |
793 if (cast != NULL) { | |
794 return this; // more than 1 CheckCastPP | |
795 } | |
796 cast = use; | |
20452
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
797 } else if (!use->is_Initialize() && |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
798 !use->is_AddP()) { |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
799 // Expected uses are restricted to a CheckCastPP, an Initialize |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
800 // node, and AddP nodes. If we encounter any other use (a Phi |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
801 // node can be seen in rare cases) return this to prevent |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
802 // incorrect optimizations. |
f8afcfbdbf1c
8046698: assert(false) failed: only Initialize or AddP expected macro.cpp:943
roland
parents:
20327
diff
changeset
|
803 return this; |
65 | 804 } |
805 } | |
806 return cast; | |
807 } | |
808 | |
809 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
810 void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
811 projs->fallthrough_proj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
812 projs->fallthrough_catchproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
813 projs->fallthrough_ioproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
814 projs->catchall_ioproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
815 projs->catchall_catchproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
816 projs->fallthrough_memproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
817 projs->catchall_memproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
818 projs->resproj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
819 projs->exobj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
820 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
821 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
822 ProjNode *pn = fast_out(i)->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
823 if (pn->outcnt() == 0) continue; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
824 switch (pn->_con) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
825 case TypeFunc::Control: |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
826 { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
827 // For Control (fallthrough) and I_O (catch_all_index) we have CatchProj -> Catch -> Proj |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
828 projs->fallthrough_proj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
829 DUIterator_Fast jmax, j = pn->fast_outs(jmax); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
830 const Node *cn = pn->fast_out(j); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
831 if (cn->is_Catch()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
832 ProjNode *cpn = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
833 for (DUIterator_Fast kmax, k = cn->fast_outs(kmax); k < kmax; k++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
834 cpn = cn->fast_out(k)->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
835 assert(cpn->is_CatchProj(), "must be a CatchProjNode"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
836 if (cpn->_con == CatchProjNode::fall_through_index) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
837 projs->fallthrough_catchproj = cpn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
838 else { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
839 assert(cpn->_con == CatchProjNode::catch_all_index, "must be correct index."); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
840 projs->catchall_catchproj = cpn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
841 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
842 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
843 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
844 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
845 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
846 case TypeFunc::I_O: |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
847 if (pn->_is_io_use) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
848 projs->catchall_ioproj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
849 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
850 projs->fallthrough_ioproj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
851 for (DUIterator j = pn->outs(); pn->has_out(j); j++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
852 Node* e = pn->out(j); |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
6804
diff
changeset
|
853 if (e->Opcode() == Op_CreateEx && e->in(0)->is_CatchProj() && e->outcnt() > 0) { |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
854 assert(projs->exobj == NULL, "only one"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
855 projs->exobj = e; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
856 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
857 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
858 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
859 case TypeFunc::Memory: |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
860 if (pn->_is_io_use) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
861 projs->catchall_memproj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
862 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
863 projs->fallthrough_memproj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
864 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
865 case TypeFunc::Parms: |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
866 projs->resproj = pn; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
867 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
868 default: |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
869 assert(false, "unexpected projection from allocation node."); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
870 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
871 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
872 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
873 // The resproj may not exist because the result couuld be ignored |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
874 // and the exception object may not exist if an exception handler |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
875 // swallows the exception but all the other must exist and be found. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
876 assert(projs->fallthrough_proj != NULL, "must be found"); |
7473 | 877 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found"); |
878 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj != NULL, "must be found"); | |
879 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj != NULL, "must be found"); | |
880 assert(Compile::current()->inlining_incrementally() || projs->catchall_catchproj != NULL, "must be found"); | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
881 if (separate_io_proj) { |
7473 | 882 assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj != NULL, "must be found"); |
883 assert(Compile::current()->inlining_incrementally() || projs->catchall_ioproj != NULL, "must be found"); | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
884 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
885 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
886 |
7473 | 887 Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
888 CallGenerator* cg = generator(); | |
889 if (can_reshape && cg != NULL && cg->is_mh_late_inline() && !cg->already_attempted()) { | |
890 // Check whether this MH handle call becomes a candidate for inlining | |
891 ciMethod* callee = cg->method(); | |
892 vmIntrinsics::ID iid = callee->intrinsic_id(); | |
893 if (iid == vmIntrinsics::_invokeBasic) { | |
894 if (in(TypeFunc::Parms)->Opcode() == Op_ConP) { | |
895 phase->C->prepend_late_inline(cg); | |
896 set_generator(NULL); | |
897 } | |
898 } else { | |
899 assert(callee->has_member_arg(), "wrong type of call?"); | |
900 if (in(TypeFunc::Parms + callee->arg_size() - 1)->Opcode() == Op_ConP) { | |
901 phase->C->prepend_late_inline(cg); | |
902 set_generator(NULL); | |
903 } | |
904 } | |
905 } | |
906 return SafePointNode::Ideal(phase, can_reshape); | |
907 } | |
908 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1040
diff
changeset
|
909 |
0 | 910 //============================================================================= |
911 uint CallJavaNode::size_of() const { return sizeof(*this); } | |
912 uint CallJavaNode::cmp( const Node &n ) const { | |
913 CallJavaNode &call = (CallJavaNode&)n; | |
914 return CallNode::cmp(call) && _method == call._method; | |
915 } | |
916 #ifndef PRODUCT | |
917 void CallJavaNode::dump_spec(outputStream *st) const { | |
918 if( _method ) _method->print_short_name(st); | |
919 CallNode::dump_spec(st); | |
920 } | |
921 #endif | |
922 | |
923 //============================================================================= | |
924 uint CallStaticJavaNode::size_of() const { return sizeof(*this); } | |
925 uint CallStaticJavaNode::cmp( const Node &n ) const { | |
926 CallStaticJavaNode &call = (CallStaticJavaNode&)n; | |
927 return CallJavaNode::cmp(call); | |
928 } | |
929 | |
930 //----------------------------uncommon_trap_request---------------------------- | |
931 // If this is an uncommon trap, return the request code, else zero. | |
932 int CallStaticJavaNode::uncommon_trap_request() const { | |
933 if (_name != NULL && !strcmp(_name, "uncommon_trap")) { | |
934 return extract_uncommon_trap_request(this); | |
935 } | |
936 return 0; | |
937 } | |
938 int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) { | |
939 #ifndef PRODUCT | |
940 if (!(call->req() > TypeFunc::Parms && | |
941 call->in(TypeFunc::Parms) != NULL && | |
942 call->in(TypeFunc::Parms)->is_Con())) { | |
14438
4cdf4f71177d
8029025: PPC64 (part 203): opto: Move static _in_dump_cnt to Compile object.
goetz
parents:
12158
diff
changeset
|
943 assert(in_dump() != 0, "OK if dumping"); |
0 | 944 tty->print("[bad uncommon trap]"); |
945 return 0; | |
946 } | |
947 #endif | |
948 return call->in(TypeFunc::Parms)->bottom_type()->is_int()->get_con(); | |
949 } | |
950 | |
951 #ifndef PRODUCT | |
952 void CallStaticJavaNode::dump_spec(outputStream *st) const { | |
953 st->print("# Static "); | |
954 if (_name != NULL) { | |
955 st->print("%s", _name); | |
956 int trap_req = uncommon_trap_request(); | |
957 if (trap_req != 0) { | |
958 char buf[100]; | |
959 st->print("(%s)", | |
960 Deoptimization::format_trap_request(buf, sizeof(buf), | |
961 trap_req)); | |
962 } | |
963 st->print(" "); | |
964 } | |
965 CallJavaNode::dump_spec(st); | |
966 } | |
967 #endif | |
968 | |
969 //============================================================================= | |
970 uint CallDynamicJavaNode::size_of() const { return sizeof(*this); } | |
971 uint CallDynamicJavaNode::cmp( const Node &n ) const { | |
972 CallDynamicJavaNode &call = (CallDynamicJavaNode&)n; | |
973 return CallJavaNode::cmp(call); | |
974 } | |
975 #ifndef PRODUCT | |
976 void CallDynamicJavaNode::dump_spec(outputStream *st) const { | |
977 st->print("# Dynamic "); | |
978 CallJavaNode::dump_spec(st); | |
979 } | |
980 #endif | |
981 | |
982 //============================================================================= | |
983 uint CallRuntimeNode::size_of() const { return sizeof(*this); } | |
984 uint CallRuntimeNode::cmp( const Node &n ) const { | |
985 CallRuntimeNode &call = (CallRuntimeNode&)n; | |
986 return CallNode::cmp(call) && !strcmp(_name,call._name); | |
987 } | |
988 #ifndef PRODUCT | |
989 void CallRuntimeNode::dump_spec(outputStream *st) const { | |
990 st->print("# "); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
991 st->print("%s", _name); |
0 | 992 CallNode::dump_spec(st); |
993 } | |
994 #endif | |
995 | |
996 //------------------------------calling_convention----------------------------- | |
997 void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { | |
998 Matcher::c_calling_convention( sig_bt, parm_regs, argcnt ); | |
999 } | |
1000 | |
1001 //============================================================================= | |
1002 //------------------------------calling_convention----------------------------- | |
1003 | |
1004 | |
1005 //============================================================================= | |
1006 #ifndef PRODUCT | |
1007 void CallLeafNode::dump_spec(outputStream *st) const { | |
1008 st->print("# "); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17795
diff
changeset
|
1009 st->print("%s", _name); |
0 | 1010 CallNode::dump_spec(st); |
1011 } | |
1012 #endif | |
1013 | |
1014 //============================================================================= | |
1015 | |
1016 void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) { | |
1017 assert(verify_jvms(jvms), "jvms must match"); | |
1018 int loc = jvms->locoff() + idx; | |
1019 if (in(loc)->is_top() && idx > 0 && !c->is_top() ) { | |
1020 // If current local idx is top then local idx - 1 could | |
1021 // be a long/double that needs to be killed since top could | |
1022 // represent the 2nd half ofthe long/double. | |
1023 uint ideal = in(loc -1)->ideal_reg(); | |
1024 if (ideal == Op_RegD || ideal == Op_RegL) { | |
1025 // set other (low index) half to top | |
1026 set_req(loc - 1, in(loc)); | |
1027 } | |
1028 } | |
1029 set_req(loc, c); | |
1030 } | |
1031 | |
1032 uint SafePointNode::size_of() const { return sizeof(*this); } | |
1033 uint SafePointNode::cmp( const Node &n ) const { | |
1034 return (&n == this); // Always fail except on self | |
1035 } | |
1036 | |
1037 //-------------------------set_next_exception---------------------------------- | |
1038 void SafePointNode::set_next_exception(SafePointNode* n) { | |
1039 assert(n == NULL || n->Opcode() == Op_SafePoint, "correct value for next_exception"); | |
1040 if (len() == req()) { | |
1041 if (n != NULL) add_prec(n); | |
1042 } else { | |
1043 set_prec(req(), n); | |
1044 } | |
1045 } | |
1046 | |
1047 | |
1048 //----------------------------next_exception----------------------------------- | |
1049 SafePointNode* SafePointNode::next_exception() const { | |
1050 if (len() == req()) { | |
1051 return NULL; | |
1052 } else { | |
1053 Node* n = in(req()); | |
1054 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges"); | |
1055 return (SafePointNode*) n; | |
1056 } | |
1057 } | |
1058 | |
1059 | |
1060 //------------------------------Ideal------------------------------------------ | |
1061 // Skip over any collapsed Regions | |
1062 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
305 | 1063 return remove_dead_region(phase, can_reshape) ? this : NULL; |
0 | 1064 } |
1065 | |
1066 //------------------------------Identity--------------------------------------- | |
1067 // Remove obviously duplicate safepoints | |
1068 Node *SafePointNode::Identity( PhaseTransform *phase ) { | |
1069 | |
1070 // If you have back to back safepoints, remove one | |
1071 if( in(TypeFunc::Control)->is_SafePoint() ) | |
1072 return in(TypeFunc::Control); | |
1073 | |
1074 if( in(0)->is_Proj() ) { | |
1075 Node *n0 = in(0)->in(0); | |
1076 // Check if he is a call projection (except Leaf Call) | |
1077 if( n0->is_Catch() ) { | |
1078 n0 = n0->in(0)->in(0); | |
1079 assert( n0->is_Call(), "expect a call here" ); | |
1080 } | |
1081 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) { | |
1082 // Useless Safepoint, so remove it | |
1083 return in(TypeFunc::Control); | |
1084 } | |
1085 } | |
1086 | |
1087 return this; | |
1088 } | |
1089 | |
1090 //------------------------------Value------------------------------------------ | |
1091 const Type *SafePointNode::Value( PhaseTransform *phase ) const { | |
1092 if( phase->type(in(0)) == Type::TOP ) return Type::TOP; | |
1093 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop | |
1094 return Type::CONTROL; | |
1095 } | |
1096 | |
1097 #ifndef PRODUCT | |
1098 void SafePointNode::dump_spec(outputStream *st) const { | |
1099 st->print(" SafePoint "); | |
20327
411e30e5fbb8
8026796: Make replace_in_map() on parent maps generic
roland
parents:
17980
diff
changeset
|
1100 _replaced_nodes.dump(st); |
0 | 1101 } |
1102 #endif | |
1103 | |
1104 const RegMask &SafePointNode::in_RegMask(uint idx) const { | |
1105 if( idx < TypeFunc::Parms ) return RegMask::Empty; | |
1106 // Values outside the domain represent debug info | |
1107 return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]); | |
1108 } | |
1109 const RegMask &SafePointNode::out_RegMask() const { | |
1110 return RegMask::Empty; | |
1111 } | |
1112 | |
1113 | |
1114 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { | |
1115 assert((int)grow_by > 0, "sanity"); | |
1116 int monoff = jvms->monoff(); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1117 int scloff = jvms->scloff(); |
0 | 1118 int endoff = jvms->endoff(); |
1119 assert(endoff == (int)req(), "no other states or debug info after me"); | |
1120 Node* top = Compile::current()->top(); | |
1121 for (uint i = 0; i < grow_by; i++) { | |
1122 ins_req(monoff, top); | |
1123 } | |
1124 jvms->set_monoff(monoff + grow_by); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1125 jvms->set_scloff(scloff + grow_by); |
0 | 1126 jvms->set_endoff(endoff + grow_by); |
1127 } | |
1128 | |
1129 void SafePointNode::push_monitor(const FastLockNode *lock) { | |
1130 // Add a LockNode, which points to both the original BoxLockNode (the | |
1131 // stack space for the monitor) and the Object being locked. | |
1132 const int MonitorEdges = 2; | |
1133 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); | |
1134 assert(req() == jvms()->endoff(), "correct sizing"); | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1135 int nextmon = jvms()->scloff(); |
0 | 1136 if (GenerateSynchronizationCode) { |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1137 ins_req(nextmon, lock->box_node()); |
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1138 ins_req(nextmon+1, lock->obj_node()); |
0 | 1139 } else { |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
1140 Node* top = Compile::current()->top(); |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1141 ins_req(nextmon, top); |
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1142 ins_req(nextmon, top); |
0 | 1143 } |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1144 jvms()->set_scloff(nextmon + MonitorEdges); |
0 | 1145 jvms()->set_endoff(req()); |
1146 } | |
1147 | |
1148 void SafePointNode::pop_monitor() { | |
1149 // Delete last monitor from debug info | |
1150 debug_only(int num_before_pop = jvms()->nof_monitors()); | |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1151 const int MonitorEdges = 2; |
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1152 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1153 int scloff = jvms()->scloff(); |
0 | 1154 int endoff = jvms()->endoff(); |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1155 int new_scloff = scloff - MonitorEdges; |
0 | 1156 int new_endoff = endoff - MonitorEdges; |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1157 jvms()->set_scloff(new_scloff); |
0 | 1158 jvms()->set_endoff(new_endoff); |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1159 while (scloff > new_scloff) del_req_ordered(--scloff); |
0 | 1160 assert(jvms()->nof_monitors() == num_before_pop-1, ""); |
1161 } | |
1162 | |
1163 Node *SafePointNode::peek_monitor_box() const { | |
1164 int mon = jvms()->nof_monitors() - 1; | |
1165 assert(mon >= 0, "most have a monitor"); | |
1166 return monitor_box(jvms(), mon); | |
1167 } | |
1168 | |
1169 Node *SafePointNode::peek_monitor_obj() const { | |
1170 int mon = jvms()->nof_monitors() - 1; | |
1171 assert(mon >= 0, "most have a monitor"); | |
1172 return monitor_obj(jvms(), mon); | |
1173 } | |
1174 | |
1175 // Do we Match on this edge index or not? Match no edges | |
1176 uint SafePointNode::match_edge(uint idx) const { | |
1177 if( !needs_polling_address_input() ) | |
1178 return 0; | |
1179 | |
1180 return (TypeFunc::Parms == idx); | |
1181 } | |
1182 | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1183 //============== SafePointScalarObjectNode ============== |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1184 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1185 SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1186 #ifdef ASSERT |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1187 AllocateNode* alloc, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1188 #endif |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1189 uint first_index, |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1190 uint n_fields) : |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1191 TypeNode(tp, 1), // 1 control input -- seems required. Get from root. |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1192 #ifdef ASSERT |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1193 _alloc(alloc), |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1194 #endif |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1195 _first_index(first_index), |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1196 _n_fields(n_fields) |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1197 { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1198 init_class_id(Class_SafePointScalarObject); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1199 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1200 |
4115 | 1201 // Do not allow value-numbering for SafePointScalarObject node. |
1202 uint SafePointScalarObjectNode::hash() const { return NO_HASH; } | |
1203 uint SafePointScalarObjectNode::cmp( const Node &n ) const { | |
1204 return (&n == this); // Always fail except on self | |
1205 } | |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1206 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1207 uint SafePointScalarObjectNode::ideal_reg() const { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1208 return 0; // No matching to machine instruction |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1209 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1210 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1211 const RegMask &SafePointScalarObjectNode::in_RegMask(uint idx) const { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1212 return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1213 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1214 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1215 const RegMask &SafePointScalarObjectNode::out_RegMask() const { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1216 return RegMask::Empty; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1217 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1218 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1219 uint SafePointScalarObjectNode::match_edge(uint idx) const { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1220 return 0; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1221 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1222 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1223 SafePointScalarObjectNode* |
12158
766fac3395d6
8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents:
10278
diff
changeset
|
1224 SafePointScalarObjectNode::clone(Dict* sosn_map) const { |
63
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1225 void* cached = (*sosn_map)[(void*)this]; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1226 if (cached != NULL) { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1227 return (SafePointScalarObjectNode*)cached; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1228 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1229 SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1230 sosn_map->Insert((void*)this, (void*)res); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1231 return res; |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1232 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1233 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1234 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1235 #ifndef PRODUCT |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1236 void SafePointScalarObjectNode::dump_spec(outputStream *st) const { |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1237 st->print(" # fields@[%d..%d]", first_index(), |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1238 first_index() + n_fields() - 1); |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1239 } |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1240 |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1241 #endif |
eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents:
39
diff
changeset
|
1242 |
0 | 1243 //============================================================================= |
1244 uint AllocateNode::size_of() const { return sizeof(*this); } | |
1245 | |
1246 AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, | |
1247 Node *ctrl, Node *mem, Node *abio, | |
1248 Node *size, Node *klass_node, Node *initial_test) | |
1249 : CallNode(atype, NULL, TypeRawPtr::BOTTOM) | |
1250 { | |
1251 init_class_id(Class_Allocate); | |
1252 init_flags(Flag_is_macro); | |
39
76256d272075
6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents:
0
diff
changeset
|
1253 _is_scalar_replaceable = false; |
10278 | 1254 _is_non_escaping = false; |
0 | 1255 Node *topnode = C->top(); |
1256 | |
1257 init_req( TypeFunc::Control , ctrl ); | |
1258 init_req( TypeFunc::I_O , abio ); | |
1259 init_req( TypeFunc::Memory , mem ); | |
1260 init_req( TypeFunc::ReturnAdr, topnode ); | |
1261 init_req( TypeFunc::FramePtr , topnode ); | |
1262 init_req( AllocSize , size); | |
1263 init_req( KlassNode , klass_node); | |
1264 init_req( InitialTest , initial_test); | |
1265 init_req( ALength , topnode); | |
1266 C->add_macro_node(this); | |
1267 } | |
1268 | |
1269 //============================================================================= | |
704
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1270 Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1271 if (remove_dead_region(phase, can_reshape)) return this; |
4115 | 1272 // Don't bother trying to transform a dead node |
1273 if (in(0) && in(0)->is_top()) return NULL; | |
704
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1274 |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1275 const Type* type = phase->type(Ideal_length()); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1276 if (type->isa_int() && type->is_int()->_hi < 0) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1277 if (can_reshape) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1278 PhaseIterGVN *igvn = phase->is_IterGVN(); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1279 // Unreachable fall through path (negative array length), |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1280 // the allocation can only throw so disconnect it. |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1281 Node* proj = proj_out(TypeFunc::Control); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1282 Node* catchproj = NULL; |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1283 if (proj != NULL) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1284 for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1285 Node *cn = proj->fast_out(i); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1286 if (cn->is_Catch()) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1287 catchproj = cn->as_Multi()->proj_out(CatchProjNode::fall_through_index); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1288 break; |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1289 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1290 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1291 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1292 if (catchproj != NULL && catchproj->outcnt() > 0 && |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1293 (catchproj->outcnt() > 1 || |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1294 catchproj->unique_out()->Opcode() != Op_Halt)) { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1295 assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1296 Node* nproj = catchproj->clone(); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1297 igvn->register_new_node_with_optimizer(nproj); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1298 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1299 Node *frame = new (phase->C) ParmNode( phase->C->start(), TypeFunc::FramePtr ); |
704
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1300 frame = phase->transform(frame); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1301 // Halt & Catch Fire |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1302 Node *halt = new (phase->C) HaltNode( nproj, frame ); |
704
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1303 phase->C->root()->add_req(halt); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1304 phase->transform(halt); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1305 |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1306 igvn->replace_node(catchproj, phase->C->top()); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1307 return this; |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1308 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1309 } else { |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1310 // Can't correct it during regular GVN so register for IGVN |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1311 phase->C->record_for_igvn(this); |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1312 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1313 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1314 return NULL; |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1315 } |
ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents:
601
diff
changeset
|
1316 |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1317 // Retrieve the length from the AllocateArrayNode. Narrow the type with a |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1318 // CastII, if appropriate. If we are not allowed to create new nodes, and |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1319 // a CastII is appropriate, return NULL. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1320 Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTransform *phase, bool allow_new_nodes) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1321 Node *length = in(AllocateNode::ALength); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1322 assert(length != NULL, "length is not null"); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1323 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1324 const TypeInt* length_type = phase->find_int_type(length); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1325 const TypeAryPtr* ary_type = oop_type->isa_aryptr(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1326 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1327 if (ary_type != NULL && length_type != NULL) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1328 const TypeInt* narrow_length_type = ary_type->narrow_size_type(length_type); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1329 if (narrow_length_type != length_type) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1330 // Assert one of: |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1331 // - the narrow_length is 0 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1332 // - the narrow_length is not wider than length |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1333 assert(narrow_length_type == TypeInt::ZERO || |
10278 | 1334 length_type->is_con() && narrow_length_type->is_con() && |
1335 (narrow_length_type->_hi <= length_type->_lo) || | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1336 (narrow_length_type->_hi <= length_type->_hi && |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1337 narrow_length_type->_lo >= length_type->_lo), |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1338 "narrow type must be narrower than length type"); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1339 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1340 // Return NULL if new nodes are not allowed |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1341 if (!allow_new_nodes) return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1342 // Create a cast which is control dependent on the initialization to |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1343 // propagate the fact that the array length must be positive. |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
1344 length = new (phase->C) CastIINode(length, narrow_length_type); |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1345 length->set_req(0, initialization()->proj_out(0)); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1346 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1347 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1348 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1349 return length; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1350 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
331
diff
changeset
|
1351 |
0 | 1352 //============================================================================= |
1353 uint LockNode::size_of() const { return sizeof(*this); } | |
1354 | |
1355 // Redundant lock elimination | |
1356 // | |
1357 // There are various patterns of locking where we release and | |
1358 // immediately reacquire a lock in a piece of code where no operations | |
1359 // occur in between that would be observable. In those cases we can | |
1360 // skip releasing and reacquiring the lock without violating any | |
1361 // fairness requirements. Doing this around a loop could cause a lock | |
1362 // to be held for a very long time so we concentrate on non-looping | |
1363 // control flow. We also require that the operations are fully | |
1364 // redundant meaning that we don't introduce new lock operations on | |
1365 // some paths so to be able to eliminate it on others ala PRE. This | |
1366 // would probably require some more extensive graph manipulation to | |
1367 // guarantee that the memory edges were all handled correctly. | |
1368 // | |
1369 // Assuming p is a simple predicate which can't trap in any way and s | |
1370 // is a synchronized method consider this code: | |
1371 // | |
1372 // s(); | |
1373 // if (p) | |
1374 // s(); | |
1375 // else | |
1376 // s(); | |
1377 // s(); | |
1378 // | |
1379 // 1. The unlocks of the first call to s can be eliminated if the | |
1380 // locks inside the then and else branches are eliminated. | |
1381 // | |
1382 // 2. The unlocks of the then and else branches can be eliminated if | |
1383 // the lock of the final call to s is eliminated. | |
1384 // | |
1385 // Either of these cases subsumes the simple case of sequential control flow | |
1386 // | |
1387 // Addtionally we can eliminate versions without the else case: | |
1388 // | |
1389 // s(); | |
1390 // if (p) | |
1391 // s(); | |
1392 // s(); | |
1393 // | |
1394 // 3. In this case we eliminate the unlock of the first s, the lock | |
1395 // and unlock in the then case and the lock in the final s. | |
1396 // | |
1397 // Note also that in all these cases the then/else pieces don't have | |
1398 // to be trivial as long as they begin and end with synchronization | |
1399 // operations. | |
1400 // | |
1401 // s(); | |
1402 // if (p) | |
1403 // s(); | |
1404 // f(); | |
1405 // s(); | |
1406 // s(); | |
1407 // | |
1408 // The code will work properly for this case, leaving in the unlock | |
1409 // before the call to f and the relock after it. | |
1410 // | |
1411 // A potentially interesting case which isn't handled here is when the | |
1412 // locking is partially redundant. | |
1413 // | |
1414 // s(); | |
1415 // if (p) | |
1416 // s(); | |
1417 // | |
1418 // This could be eliminated putting unlocking on the else case and | |
1419 // eliminating the first unlock and the lock in the then side. | |
1420 // Alternatively the unlock could be moved out of the then side so it | |
1421 // was after the merge and the first unlock and second lock | |
1422 // eliminated. This might require less manipulation of the memory | |
1423 // state to get correct. | |
1424 // | |
1425 // Additionally we might allow work between a unlock and lock before | |
1426 // giving up eliminating the locks. The current code disallows any | |
1427 // conditional control flow between these operations. A formulation | |
1428 // similar to partial redundancy elimination computing the | |
1429 // availability of unlocking and the anticipatability of locking at a | |
1430 // program point would allow detection of fully redundant locking with | |
1431 // some amount of work in between. I'm not sure how often I really | |
1432 // think that would occur though. Most of the cases I've seen | |
1433 // indicate it's likely non-trivial work would occur in between. | |
1434 // There may be other more complicated constructs where we could | |
1435 // eliminate locking but I haven't seen any others appear as hot or | |
1436 // interesting. | |
1437 // | |
1438 // Locking and unlocking have a canonical form in ideal that looks | |
1439 // roughly like this: | |
1440 // | |
1441 // <obj> | |
1442 // | \\------+ | |
1443 // | \ \ | |
1444 // | BoxLock \ | |
1445 // | | | \ | |
1446 // | | \ \ | |
1447 // | | FastLock | |
1448 // | | / | |
1449 // | | / | |
1450 // | | | | |
1451 // | |
1452 // Lock | |
1453 // | | |
1454 // Proj #0 | |
1455 // | | |
1456 // MembarAcquire | |
1457 // | | |
1458 // Proj #0 | |
1459 // | |
1460 // MembarRelease | |
1461 // | | |
1462 // Proj #0 | |
1463 // | | |
1464 // Unlock | |
1465 // | | |
1466 // Proj #0 | |
1467 // | |
1468 // | |
1469 // This code proceeds by processing Lock nodes during PhaseIterGVN | |
1470 // and searching back through its control for the proper code | |
1471 // patterns. Once it finds a set of lock and unlock operations to | |
1472 // eliminate they are marked as eliminatable which causes the | |
1473 // expansion of the Lock and Unlock macro nodes to make the operation a NOP | |
1474 // | |
1475 //============================================================================= | |
1476 | |
1477 // | |
1478 // Utility function to skip over uninteresting control nodes. Nodes skipped are: | |
1479 // - copy regions. (These may not have been optimized away yet.) | |
1480 // - eliminated locking nodes | |
1481 // | |
1482 static Node *next_control(Node *ctrl) { | |
1483 if (ctrl == NULL) | |
1484 return NULL; | |
1485 while (1) { | |
1486 if (ctrl->is_Region()) { | |
1487 RegionNode *r = ctrl->as_Region(); | |
1488 Node *n = r->is_copy(); | |
1489 if (n == NULL) | |
1490 break; // hit a region, return it | |
1491 else | |
1492 ctrl = n; | |
1493 } else if (ctrl->is_Proj()) { | |
1494 Node *in0 = ctrl->in(0); | |
1495 if (in0->is_AbstractLock() && in0->as_AbstractLock()->is_eliminated()) { | |
1496 ctrl = in0->in(0); | |
1497 } else { | |
1498 break; | |
1499 } | |
1500 } else { | |
1501 break; // found an interesting control | |
1502 } | |
1503 } | |
1504 return ctrl; | |
1505 } | |
1506 // | |
1507 // Given a control, see if it's the control projection of an Unlock which | |
1508 // operating on the same object as lock. | |
1509 // | |
1510 bool AbstractLockNode::find_matching_unlock(const Node* ctrl, LockNode* lock, | |
1511 GrowableArray<AbstractLockNode*> &lock_ops) { | |
1512 ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL; | |
1513 if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) { | |
1514 Node *n = ctrl_proj->in(0); | |
1515 if (n != NULL && n->is_Unlock()) { | |
1516 UnlockNode *unlock = n->as_Unlock(); | |
4778 | 1517 if (lock->obj_node()->eqv_uncast(unlock->obj_node()) && |
4777 | 1518 BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) && |
1519 !unlock->is_eliminated()) { | |
0 | 1520 lock_ops.append(unlock); |
1521 return true; | |
1522 } | |
1523 } | |
1524 } | |
1525 return false; | |
1526 } | |
1527 | |
1528 // | |
1529 // Find the lock matching an unlock. Returns null if a safepoint | |
1530 // or complicated control is encountered first. | |
1531 LockNode *AbstractLockNode::find_matching_lock(UnlockNode* unlock) { | |
1532 LockNode *lock_result = NULL; | |
1533 // find the matching lock, or an intervening safepoint | |
1534 Node *ctrl = next_control(unlock->in(0)); | |
1535 while (1) { | |
1536 assert(ctrl != NULL, "invalid control graph"); | |
1537 assert(!ctrl->is_Start(), "missing lock for unlock"); | |
1538 if (ctrl->is_top()) break; // dead control path | |
1539 if (ctrl->is_Proj()) ctrl = ctrl->in(0); | |
1540 if (ctrl->is_SafePoint()) { | |
1541 break; // found a safepoint (may be the lock we are searching for) | |
1542 } else if (ctrl->is_Region()) { | |
1543 // Check for a simple diamond pattern. Punt on anything more complicated | |
1544 if (ctrl->req() == 3 && ctrl->in(1) != NULL && ctrl->in(2) != NULL) { | |
1545 Node *in1 = next_control(ctrl->in(1)); | |
1546 Node *in2 = next_control(ctrl->in(2)); | |
1547 if (((in1->is_IfTrue() && in2->is_IfFalse()) || | |
1548 (in2->is_IfTrue() && in1->is_IfFalse())) && (in1->in(0) == in2->in(0))) { | |
1549 ctrl = next_control(in1->in(0)->in(0)); | |
1550 } else { | |
1551 break; | |
1552 } | |
1553 } else { | |
1554 break; | |
1555 } | |
1556 } else { | |
1557 ctrl = next_control(ctrl->in(0)); // keep searching | |
1558 } | |
1559 } | |
1560 if (ctrl->is_Lock()) { | |
1561 LockNode *lock = ctrl->as_Lock(); | |
4778 | 1562 if (lock->obj_node()->eqv_uncast(unlock->obj_node()) && |
4777 | 1563 BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) { |
0 | 1564 lock_result = lock; |
1565 } | |
1566 } | |
1567 return lock_result; | |
1568 } | |
1569 | |
1570 // This code corresponds to case 3 above. | |
1571 | |
1572 bool AbstractLockNode::find_lock_and_unlock_through_if(Node* node, LockNode* lock, | |
1573 GrowableArray<AbstractLockNode*> &lock_ops) { | |
1574 Node* if_node = node->in(0); | |
1575 bool if_true = node->is_IfTrue(); | |
1576 | |
1577 if (if_node->is_If() && if_node->outcnt() == 2 && (if_true || node->is_IfFalse())) { | |
1578 Node *lock_ctrl = next_control(if_node->in(0)); | |
1579 if (find_matching_unlock(lock_ctrl, lock, lock_ops)) { | |
1580 Node* lock1_node = NULL; | |
1581 ProjNode* proj = if_node->as_If()->proj_out(!if_true); | |
1582 if (if_true) { | |
1583 if (proj->is_IfFalse() && proj->outcnt() == 1) { | |
1584 lock1_node = proj->unique_out(); | |
1585 } | |
1586 } else { | |
1587 if (proj->is_IfTrue() && proj->outcnt() == 1) { | |
1588 lock1_node = proj->unique_out(); | |
1589 } | |
1590 } | |
1591 if (lock1_node != NULL && lock1_node->is_Lock()) { | |
1592 LockNode *lock1 = lock1_node->as_Lock(); | |
4778 | 1593 if (lock->obj_node()->eqv_uncast(lock1->obj_node()) && |
4777 | 1594 BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) && |
1595 !lock1->is_eliminated()) { | |
0 | 1596 lock_ops.append(lock1); |
1597 return true; | |
1598 } | |
1599 } | |
1600 } | |
1601 } | |
1602 | |
1603 lock_ops.trunc_to(0); | |
1604 return false; | |
1605 } | |
1606 | |
1607 bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNode* lock, | |
1608 GrowableArray<AbstractLockNode*> &lock_ops) { | |
1609 // check each control merging at this point for a matching unlock. | |
1610 // in(0) should be self edge so skip it. | |
1611 for (int i = 1; i < (int)region->req(); i++) { | |
1612 Node *in_node = next_control(region->in(i)); | |
1613 if (in_node != NULL) { | |
1614 if (find_matching_unlock(in_node, lock, lock_ops)) { | |
1615 // found a match so keep on checking. | |
1616 continue; | |
1617 } else if (find_lock_and_unlock_through_if(in_node, lock, lock_ops)) { | |
1618 continue; | |
1619 } | |
1620 | |
1621 // If we fall through to here then it was some kind of node we | |
1622 // don't understand or there wasn't a matching unlock, so give | |
1623 // up trying to merge locks. | |
1624 lock_ops.trunc_to(0); | |
1625 return false; | |
1626 } | |
1627 } | |
1628 return true; | |
1629 | |
1630 } | |
1631 | |
1632 #ifndef PRODUCT | |
1633 // | |
1634 // Create a counter which counts the number of times this lock is acquired | |
1635 // | |
1636 void AbstractLockNode::create_lock_counter(JVMState* state) { | |
1637 _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter); | |
1638 } | |
1639 | |
4777 | 1640 void AbstractLockNode::set_eliminated_lock_counter() { |
0 | 1641 if (_counter) { |
1642 // Update the counter to indicate that this lock was eliminated. | |
1643 // The counter update code will stay around even though the | |
1644 // optimizer will eliminate the lock operation itself. | |
1645 _counter->set_tag(NamedCounter::EliminatedLockCounter); | |
1646 } | |
4777 | 1647 } |
0 | 1648 #endif |
1649 | |
1650 //============================================================================= | |
1651 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1652 | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1653 // perform any generic optimizations first (returns 'this' or NULL) |
0 | 1654 Node *result = SafePointNode::Ideal(phase, can_reshape); |
4115 | 1655 if (result != NULL) return result; |
1656 // Don't bother trying to transform a dead node | |
1657 if (in(0) && in(0)->is_top()) return NULL; | |
0 | 1658 |
1659 // Now see if we can optimize away this lock. We don't actually | |
1660 // remove the locking here, we simply set the _eliminate flag which | |
1661 // prevents macro expansion from expanding the lock. Since we don't | |
1662 // modify the graph, the value returned from this function is the | |
1663 // one computed above. | |
4777 | 1664 if (can_reshape && EliminateLocks && !is_non_esc_obj()) { |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1665 // |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1666 // If we are locking an unescaped object, the lock/unlock is unnecessary |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1667 // |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
1668 ConnectionGraph *cgr = phase->C->congraph(); |
5948
ee138854b3a6
7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents:
4790
diff
changeset
|
1669 if (cgr != NULL && cgr->not_global_escape(obj_node())) { |
4777 | 1670 assert(!is_eliminated() || is_coarsened(), "sanity"); |
1671 // The lock could be marked eliminated by lock coarsening | |
1672 // code during first IGVN before EA. Replace coarsened flag | |
1673 // to eliminate all associated locks/unlocks. | |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1674 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1675 this->log_lock_optimization(phase->C,"eliminate_lock_set_non_esc1"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1676 #endif |
4777 | 1677 this->set_non_esc_obj(); |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1678 return result; |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1679 } |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1680 |
0 | 1681 // |
1682 // Try lock coarsening | |
1683 // | |
1684 PhaseIterGVN* iter = phase->is_IterGVN(); | |
4115 | 1685 if (iter != NULL && !is_eliminated()) { |
0 | 1686 |
1687 GrowableArray<AbstractLockNode*> lock_ops; | |
1688 | |
1689 Node *ctrl = next_control(in(0)); | |
1690 | |
1691 // now search back for a matching Unlock | |
1692 if (find_matching_unlock(ctrl, this, lock_ops)) { | |
1693 // found an unlock directly preceding this lock. This is the | |
1694 // case of single unlock directly control dependent on a | |
1695 // single lock which is the trivial version of case 1 or 2. | |
1696 } else if (ctrl->is_Region() ) { | |
1697 if (find_unlocks_for_region(ctrl->as_Region(), this, lock_ops)) { | |
1698 // found lock preceded by multiple unlocks along all paths | |
1699 // joining at this point which is case 3 in description above. | |
1700 } | |
1701 } else { | |
1702 // see if this lock comes from either half of an if and the | |
1703 // predecessors merges unlocks and the other half of the if | |
1704 // performs a lock. | |
1705 if (find_lock_and_unlock_through_if(ctrl, this, lock_ops)) { | |
1706 // found unlock splitting to an if with locks on both branches. | |
1707 } | |
1708 } | |
1709 | |
1710 if (lock_ops.length() > 0) { | |
1711 // add ourselves to the list of locks to be eliminated. | |
1712 lock_ops.append(this); | |
1713 | |
1714 #ifndef PRODUCT | |
1715 if (PrintEliminateLocks) { | |
1716 int locks = 0; | |
1717 int unlocks = 0; | |
1718 for (int i = 0; i < lock_ops.length(); i++) { | |
1719 AbstractLockNode* lock = lock_ops.at(i); | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1720 if (lock->Opcode() == Op_Lock) |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1721 locks++; |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1722 else |
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1723 unlocks++; |
0 | 1724 if (Verbose) { |
1725 lock->dump(1); | |
1726 } | |
1727 } | |
1728 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks); | |
1729 } | |
1730 #endif | |
1731 | |
1732 // for each of the identified locks, mark them | |
1733 // as eliminatable | |
1734 for (int i = 0; i < lock_ops.length(); i++) { | |
1735 AbstractLockNode* lock = lock_ops.at(i); | |
1736 | |
4777 | 1737 // Mark it eliminated by coarsening and update any counters |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1738 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1739 lock->log_lock_optimization(phase->C, "eliminate_lock_set_coarsened"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1740 #endif |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
1741 lock->set_coarsened(); |
0 | 1742 } |
4115 | 1743 } else if (ctrl->is_Region() && |
0 | 1744 iter->_worklist.member(ctrl)) { |
1745 // We weren't able to find any opportunities but the region this | |
1746 // lock is control dependent on hasn't been processed yet so put | |
1747 // this lock back on the worklist so we can check again once any | |
1748 // region simplification has occurred. | |
1749 iter->_worklist.push(this); | |
1750 } | |
1751 } | |
1752 } | |
1753 | |
1754 return result; | |
1755 } | |
1756 | |
1757 //============================================================================= | |
4777 | 1758 bool LockNode::is_nested_lock_region() { |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1759 return is_nested_lock_region(NULL); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1760 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1761 |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1762 // p is used for access to compilation log; no logging if NULL |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1763 bool LockNode::is_nested_lock_region(Compile * c) { |
4790
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
1764 BoxLockNode* box = box_node()->as_BoxLock(); |
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
1765 int stk_slot = box->stack_slot(); |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1766 if (stk_slot <= 0) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1767 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1768 this->log_lock_optimization(c, "eliminate_lock_INLR_1"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1769 #endif |
4777 | 1770 return false; // External lock or it is not Box (Phi node). |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1771 } |
4777 | 1772 |
1773 // Ignore complex cases: merged locks or multiple locks. | |
1774 Node* obj = obj_node(); | |
1775 LockNode* unique_lock = NULL; | |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1776 if (!box->is_simple_lock_region(&unique_lock, obj)) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1777 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1778 this->log_lock_optimization(c, "eliminate_lock_INLR_2a"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1779 #endif |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1780 return false; |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1781 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1782 if (unique_lock != this) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1783 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1784 this->log_lock_optimization(c, "eliminate_lock_INLR_2b"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1785 #endif |
4777 | 1786 return false; |
1787 } | |
1788 | |
1789 // Look for external lock for the same object. | |
1790 SafePointNode* sfn = this->as_SafePoint(); | |
1791 JVMState* youngest_jvms = sfn->jvms(); | |
1792 int max_depth = youngest_jvms->depth(); | |
1793 for (int depth = 1; depth <= max_depth; depth++) { | |
1794 JVMState* jvms = youngest_jvms->of_depth(depth); | |
1795 int num_mon = jvms->nof_monitors(); | |
1796 // Loop over monitors | |
1797 for (int idx = 0; idx < num_mon; idx++) { | |
1798 Node* obj_node = sfn->monitor_obj(jvms, idx); | |
4790
b0ff910edfc9
7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents:
4778
diff
changeset
|
1799 BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock(); |
4778 | 1800 if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) { |
4777 | 1801 return true; |
1802 } | |
1803 } | |
1804 } | |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1805 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1806 this->log_lock_optimization(c, "eliminate_lock_INLR_3"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1807 #endif |
4777 | 1808 return false; |
1809 } | |
1810 | |
1811 //============================================================================= | |
0 | 1812 uint UnlockNode::size_of() const { return sizeof(*this); } |
1813 | |
1814 //============================================================================= | |
1815 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1816 | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1817 // perform any generic optimizations first (returns 'this' or NULL) |
4115 | 1818 Node *result = SafePointNode::Ideal(phase, can_reshape); |
1819 if (result != NULL) return result; | |
1820 // Don't bother trying to transform a dead node | |
1821 if (in(0) && in(0)->is_top()) return NULL; | |
0 | 1822 |
1823 // Now see if we can optimize away this unlock. We don't actually | |
1824 // remove the unlocking here, we simply set the _eliminate flag which | |
1825 // prevents macro expansion from expanding the unlock. Since we don't | |
1826 // modify the graph, the value returned from this function is the | |
1827 // one computed above. | |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1828 // Escape state is defined after Parse phase. |
4777 | 1829 if (can_reshape && EliminateLocks && !is_non_esc_obj()) { |
0 | 1830 // |
66
6dbf1a175d6b
6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents:
65
diff
changeset
|
1831 // If we are unlocking an unescaped object, the lock/unlock is unnecessary. |
0 | 1832 // |
460
424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents:
420
diff
changeset
|
1833 ConnectionGraph *cgr = phase->C->congraph(); |
5948
ee138854b3a6
7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents:
4790
diff
changeset
|
1834 if (cgr != NULL && cgr->not_global_escape(obj_node())) { |
4777 | 1835 assert(!is_eliminated() || is_coarsened(), "sanity"); |
1836 // The lock could be marked eliminated by lock coarsening | |
1837 // code during first IGVN before EA. Replace coarsened flag | |
1838 // to eliminate all associated locks/unlocks. | |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1839 #ifdef ASSERT |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1840 this->log_lock_optimization(phase->C, "eliminate_lock_set_non_esc2"); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1841 #endif |
4777 | 1842 this->set_non_esc_obj(); |
0 | 1843 } |
1844 } | |
1845 return result; | |
1846 } | |
22833
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1847 |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1848 const char * AbstractLockNode::kind_as_string() const { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1849 return is_coarsened() ? "coarsened" : |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1850 is_nested() ? "nested" : |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1851 is_non_esc_obj() ? "non_escaping" : |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1852 "?"; |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1853 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1854 |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1855 void AbstractLockNode::log_lock_optimization(Compile *C, const char * tag) const { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1856 if (C == NULL) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1857 return; |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1858 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1859 CompileLog* log = C->log(); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1860 if (log != NULL) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1861 log->begin_head("%s lock='%d' compile_id='%d' class_id='%s' kind='%s'", |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1862 tag, is_Lock(), C->compile_id(), |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1863 is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?", |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1864 kind_as_string()); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1865 log->stamp(); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1866 log->end_head(); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1867 JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms(); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1868 while (p != NULL) { |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1869 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1870 p = p->caller(); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1871 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1872 log->tail(tag); |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1873 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1874 } |
6e8e0bf87bbe
8069412: Locks need better debug-printing support
drchase
parents:
20452
diff
changeset
|
1875 |