annotate src/share/vm/opto/callnode.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents a1980da045cc
children 424f9bfe6b96
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 163
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #include "incls/_callnode.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
33 uint StartNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
34 uint StartNode::cmp( const Node &n ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
35 { return _domain == ((StartNode&)n)._domain; }
a61af66fc99e Initial load
duke
parents:
diff changeset
36 const Type *StartNode::bottom_type() const { return _domain; }
a61af66fc99e Initial load
duke
parents:
diff changeset
37 const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; }
a61af66fc99e Initial load
duke
parents:
diff changeset
38 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
39 void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);}
a61af66fc99e Initial load
duke
parents:
diff changeset
40 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
43 Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return remove_dead_region(phase, can_reshape) ? this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
48 void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 Matcher::calling_convention( sig_bt, parm_regs, argcnt, false );
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 //------------------------------Registers--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
53 const RegMask &StartNode::in_RegMask(uint) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 }
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 //------------------------------match------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Construct projections for incoming parameters, and their RegMask info
a61af66fc99e Initial load
duke
parents:
diff changeset
59 Node *StartNode::match( const ProjNode *proj, const Matcher *match ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 switch (proj->_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 case TypeFunc::Control:
a61af66fc99e Initial load
duke
parents:
diff changeset
62 case TypeFunc::I_O:
a61af66fc99e Initial load
duke
parents:
diff changeset
63 case TypeFunc::Memory:
a61af66fc99e Initial load
duke
parents:
diff changeset
64 return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
65 case TypeFunc::FramePtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
66 return new (match->C, 1) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return new (match->C, 1) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 case TypeFunc::Parms:
a61af66fc99e Initial load
duke
parents:
diff changeset
70 default: {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 uint parm_num = proj->_con - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 const Type *t = _domain->field_at(proj->_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if (t->base() == Type::Half) // 2nd half of Longs and Doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
74 return new (match->C, 1) ConNode(Type::TOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
75 uint ideal_reg = Matcher::base2reg[t->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
76 RegMask &rm = match->_calling_convention_mask[parm_num];
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 //------------------------------StartOSRNode----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // The method start node for an on stack replacement adapter
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 //------------------------------osr_domain-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
87 const TypeTuple *StartOSRNode::osr_domain() {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 const Type **fields = TypeTuple::fields(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // address of osr buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 return TypeTuple::make(TypeFunc::Parms+1, fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
95 const char * const ParmNode::names[TypeFunc::Parms+1] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 "Control", "I_O", "Memory", "FramePtr", "ReturnAdr", "Parms"
a61af66fc99e Initial load
duke
parents:
diff changeset
97 };
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
100 void ParmNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if( _con < TypeFunc::Parms ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 st->print(names[_con]);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 st->print("Parm%d: ",_con-TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Verbose and WizardMode dump bottom_type for all nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
106 if( !Verbose && !WizardMode ) bottom_type()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 uint ParmNode::ideal_reg() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 switch( _con ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 case TypeFunc::Control : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
114 case TypeFunc::I_O : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
115 case TypeFunc::Memory : return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 case TypeFunc::FramePtr : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
117 case TypeFunc::ReturnAdr: return Op_RegP;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 default : assert( _con > TypeFunc::Parms, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
120 case TypeFunc::Parms : {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Type of argument being passed
a61af66fc99e Initial load
duke
parents:
diff changeset
122 const Type *t = in(0)->as_Start()->_domain->field_at(_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 return Matcher::base2reg[t->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
127 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
131 ReturnNode::ReturnNode(uint edges, Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(edges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 init_req(TypeFunc::Control,cntrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 init_req(TypeFunc::I_O,i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 init_req(TypeFunc::Memory,memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 init_req(TypeFunc::FramePtr,frameptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 init_req(TypeFunc::ReturnAdr,retadr);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Node *ReturnNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return remove_dead_region(phase, can_reshape) ? this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 const Type *ReturnNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 return ( phase->type(in(TypeFunc::Control)) == Type::TOP)
a61af66fc99e Initial load
duke
parents:
diff changeset
145 ? Type::TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
146 : Type::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Do we Match on this edge index or not? No edges on return nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
150 uint ReturnNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
156 void ReturnNode::dump_req() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Dump the required inputs, enclosed in '(' and ')'
a61af66fc99e Initial load
duke
parents:
diff changeset
158 uint i; // Exit value of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
159 for( i=0; i<req(); i++ ) { // For all required inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if( i == TypeFunc::Parms ) tty->print("returns");
a61af66fc99e Initial load
duke
parents:
diff changeset
161 if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 else tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
168 RethrowNode::RethrowNode(
a61af66fc99e Initial load
duke
parents:
diff changeset
169 Node* cntrl,
a61af66fc99e Initial load
duke
parents:
diff changeset
170 Node* i_o,
a61af66fc99e Initial load
duke
parents:
diff changeset
171 Node* memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
172 Node* frameptr,
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Node* ret_adr,
a61af66fc99e Initial load
duke
parents:
diff changeset
174 Node* exception
a61af66fc99e Initial load
duke
parents:
diff changeset
175 ) : Node(TypeFunc::Parms + 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 init_req(TypeFunc::Control , cntrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
177 init_req(TypeFunc::I_O , i_o );
a61af66fc99e Initial load
duke
parents:
diff changeset
178 init_req(TypeFunc::Memory , memory );
a61af66fc99e Initial load
duke
parents:
diff changeset
179 init_req(TypeFunc::FramePtr , frameptr );
a61af66fc99e Initial load
duke
parents:
diff changeset
180 init_req(TypeFunc::ReturnAdr, ret_adr);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 init_req(TypeFunc::Parms , exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 Node *RethrowNode::Ideal(PhaseGVN *phase, bool can_reshape){
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return remove_dead_region(phase, can_reshape) ? this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 const Type *RethrowNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return (phase->type(in(TypeFunc::Control)) == Type::TOP)
a61af66fc99e Initial load
duke
parents:
diff changeset
190 ? Type::TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
191 : Type::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 uint RethrowNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
199 void RethrowNode::dump_req() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Dump the required inputs, enclosed in '(' and ')'
a61af66fc99e Initial load
duke
parents:
diff changeset
201 uint i; // Exit value of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
202 for( i=0; i<req(); i++ ) { // For all required inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
203 if( i == TypeFunc::Parms ) tty->print("exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 else tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Do we Match on this edge index or not? Match only target address & method
a61af66fc99e Initial load
duke
parents:
diff changeset
212 uint TailCallNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Do we Match on this edge index or not? Match only target address & oop
a61af66fc99e Initial load
duke
parents:
diff changeset
218 uint TailJumpNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
223 JVMState::JVMState(ciMethod* method, JVMState* caller) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 assert(method != NULL, "must be valid call site");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 debug_only(_bci = -99); // random garbage value
a61af66fc99e Initial load
duke
parents:
diff changeset
227 debug_only(_map = (SafePointNode*)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _caller = caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 _depth = 1 + (caller == NULL ? 0 : caller->depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
230 _locoff = TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 _stkoff = _locoff + _method->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 _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
233 _scloff = _monoff;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
234 _endoff = _monoff;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 _sp = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237 JVMState::JVMState(int stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 _method = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _bci = InvocationEntryBci;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 debug_only(_map = (SafePointNode*)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 _caller = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 _depth = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 _locoff = TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 _stkoff = _locoff;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _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
246 _scloff = _monoff;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 _endoff = _monoff;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 _sp = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 //--------------------------------of_depth-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
252 JVMState* JVMState::of_depth(int d) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 const JVMState* jvmp = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 assert(0 < d && (uint)d <= depth(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
255 for (int skip = depth() - d; skip > 0; skip--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 jvmp = jvmp->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 assert(jvmp->depth() == (uint)d, "found the right one");
a61af66fc99e Initial load
duke
parents:
diff changeset
259 return (JVMState*)jvmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 //-----------------------------same_calls_as-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
263 bool JVMState::same_calls_as(const JVMState* that) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 if (this == that) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (this->depth() != that->depth()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 const JVMState* p = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 const JVMState* q = that;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if (p->_method != q->_method) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 if (p->_method == NULL) return true; // bci is irrelevant
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (p->_bci != q->_bci) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 p = p->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
273 q = q->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if (p == q) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 assert(p != NULL && q != NULL, "depth check ensures we don't run off end");
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 //------------------------------debug_start------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
280 uint JVMState::debug_start() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 debug_only(JVMState* jvmroot = of_depth(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
282 assert(jvmroot->locoff() <= this->locoff(), "youngest JVMState must be last");
a61af66fc99e Initial load
duke
parents:
diff changeset
283 return of_depth(1)->locoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 //-------------------------------debug_end-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
287 uint JVMState::debug_end() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 debug_only(JVMState* jvmroot = of_depth(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
289 assert(jvmroot->endoff() <= this->endoff(), "youngest JVMState must be last");
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return endoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 //------------------------------debug_depth------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
294 uint JVMState::debug_depth() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 uint total = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 for (const JVMState* jvmp = this; jvmp != NULL; jvmp = jvmp->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 total += jvmp->debug_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 return total;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301
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
302 #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
303
0
a61af66fc99e Initial load
duke
parents:
diff changeset
304 //------------------------------format_helper----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Given an allocation (a Chaitin object) and a Node decide if the Node carries
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // 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
307 static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i, GrowableArray<SafePointScalarObjectNode*> *scobjs ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
308 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
309 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
310 // 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
311 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
312 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
313 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
314 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
315 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
316 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
317 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined
a61af66fc99e Initial load
duke
parents:
diff changeset
319 char buf[50];
a61af66fc99e Initial load
duke
parents:
diff changeset
320 regalloc->dump_register(n,buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 st->print(" %s%d]=%s",msg,i,buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 } else { // No register, but might be constant
a61af66fc99e Initial load
duke
parents:
diff changeset
323 const Type *t = n->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
324 switch (t->base()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 case Type::Int:
a61af66fc99e Initial load
duke
parents:
diff changeset
326 st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
327 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 case Type::AnyPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
329 assert( t == TypePtr::NULL_PTR, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
330 st->print(" %s%d]=#NULL",msg,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 case Type::AryPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
333 case Type::KlassPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
334 case Type::InstPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
335 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
336 break;
331
cecd8eb4e0ca 6706829: Compressed Oops: add debug info for narrow oops
kvn
parents: 305
diff changeset
337 case Type::NarrowOop:
cecd8eb4e0ca 6706829: Compressed Oops: add debug info for narrow oops
kvn
parents: 305
diff changeset
338 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop());
cecd8eb4e0ca 6706829: Compressed Oops: add debug info for narrow oops
kvn
parents: 305
diff changeset
339 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
340 case Type::RawPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
341 st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
342 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 case Type::DoubleCon:
a61af66fc99e Initial load
duke
parents:
diff changeset
344 st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 case Type::FloatCon:
a61af66fc99e Initial load
duke
parents:
diff changeset
347 st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 case Type::Long:
a61af66fc99e Initial load
duke
parents:
diff changeset
350 st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
351 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 case Type::Half:
a61af66fc99e Initial load
duke
parents:
diff changeset
353 case Type::Top:
a61af66fc99e Initial load
duke
parents:
diff changeset
354 st->print(" %s%d]=_",msg,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 //------------------------------format-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
362 void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 st->print(" #");
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if( _method ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 st->print(" @ bci:%d ",_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 st->print_cr(" runtime stub ");
a61af66fc99e Initial load
duke
parents:
diff changeset
369 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371 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
372 GrowableArray<SafePointScalarObjectNode*> scobjs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
373 MachSafePointNode *mcall = n->as_MachSafePoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
374 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // Print locals
a61af66fc99e Initial load
duke
parents:
diff changeset
376 for( i = 0; i < (uint)loc_size(); i++ )
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
377 format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Print stack
a61af66fc99e Initial load
duke
parents:
diff changeset
379 for (i = 0; i < (uint)stk_size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if ((uint)(_stkoff + i) >= mcall->len())
a61af66fc99e Initial load
duke
parents:
diff changeset
381 st->print(" oob ");
a61af66fc99e Initial load
duke
parents:
diff changeset
382 else
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
383 format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385 for (i = 0; (int)i < nof_monitors(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 Node *box = mcall->monitor_box(this, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 Node *obj = mcall->monitor_obj(this, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 while( !box->is_BoxLock() ) box = box->in(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
390 format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
391 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 st->print(" MON-BOX%d=%s+%d",
a61af66fc99e Initial load
duke
parents:
diff changeset
394 i,
a61af66fc99e Initial load
duke
parents:
diff changeset
395 OptoReg::regname(OptoReg::c_frame_pointer),
a61af66fc99e Initial load
duke
parents:
diff changeset
396 regalloc->reg2offset(box_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
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
398 format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
399 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
400
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
401 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
402 // Scalar replaced objects.
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
403 st->print_cr("");
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
404 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
405 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
406 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
407 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
408 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
409 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
410 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
411 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
412 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
413 } 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
414 cik->as_array_klass()->base_element_type()->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
415 st->print("[%d]=", 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
416 } else if (cik->is_obj_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
417 ciType* cie = cik->as_array_klass()->base_element_type();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
418 int ndim = 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
419 while (cie->is_obj_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
420 ndim += 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
421 cie = cie->as_array_klass()->base_element_type();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
422 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
423 cie->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
424 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
425 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
426 }
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 st->print("[%d]=", 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
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 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
430 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
431 if (nf > 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
432 uint first_ind = spobj->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
433 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
434 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
435 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
436 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
437 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
438 cifield->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
439 format_helper( regalloc, st, fld_node, ":", 0, &scobjs );
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 } else {
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 format_helper( regalloc, st, fld_node, "[", 0, &scobjs );
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 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
443 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
444 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
445 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
446 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
447 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
448 cifield->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
449 format_helper( regalloc, st, fld_node, ":", j, &scobjs );
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
450 } else {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
451 format_helper( regalloc, st, fld_node, ", [", j, &scobjs );
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 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
453 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
454 }
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 st->print(" }");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 st->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (caller() != NULL) caller()->format(regalloc, n, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461
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
462
0
a61af66fc99e Initial load
duke
parents:
diff changeset
463 void JVMState::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (_method != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 bool printed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if (!Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // The JVMS dumps make really, really long lines.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // Take out the most boring parts, which are the package prefixes.
a61af66fc99e Initial load
duke
parents:
diff changeset
469 char buf[500];
a61af66fc99e Initial load
duke
parents:
diff changeset
470 stringStream namest(buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _method->print_short_name(&namest);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (namest.count() < sizeof(buf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 const char* name = namest.base();
a61af66fc99e Initial load
duke
parents:
diff changeset
474 if (name[0] == ' ') ++name;
a61af66fc99e Initial load
duke
parents:
diff changeset
475 const char* endcn = strchr(name, ':'); // end of class name
a61af66fc99e Initial load
duke
parents:
diff changeset
476 if (endcn == NULL) endcn = strchr(name, '(');
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (endcn == NULL) endcn = name + strlen(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/')
a61af66fc99e Initial load
duke
parents:
diff changeset
479 --endcn;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 st->print(" %s", endcn);
a61af66fc99e Initial load
duke
parents:
diff changeset
481 printed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (!printed)
a61af66fc99e Initial load
duke
parents:
diff changeset
485 _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 st->print(" @ bci:%d",_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 st->print(" runtime stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (caller() != NULL) caller()->dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492
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
493
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494 void JVMState::dump_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (_map && !((uintptr_t)_map & 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (_map->len() > _map->req()) { // _map->has_exceptions()
a61af66fc99e Initial load
duke
parents:
diff changeset
497 Node* ex = _map->in(_map->req()); // _map->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // skip the first one; it's already being printed
a61af66fc99e Initial load
duke
parents:
diff changeset
499 while (ex != NULL && ex->len() > ex->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 ex = ex->in(ex->req()); // ex->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
501 ex->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 _map->dump(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
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
506 st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d method=",
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
507 depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (_method == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 st->print_cr("(none)");
a61af66fc99e Initial load
duke
parents:
diff changeset
510 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 _method->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (bci() >= 0 && bci() < _method->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 st->print(" bc: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
515 _method->print_codes_on(bci(), bci()+1, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (caller() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 caller()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Extra way to dump a jvms from the debugger,
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // to avoid a bug with C++ member function calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 void dump_jvms(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 jvms->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 //--------------------------clone_shallow--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
531 JVMState* JVMState::clone_shallow(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 JVMState* n = has_method() ? new (C) JVMState(_method, _caller) : new (C) JVMState(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 n->set_bci(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 n->set_locoff(_locoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 n->set_stkoff(_stkoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 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
537 n->set_scloff(_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
538 n->set_endoff(_endoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
539 n->set_sp(_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 n->set_map(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
541 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 //---------------------------clone_deep----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
545 JVMState* JVMState::clone_deep(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 JVMState* n = clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 for (JVMState* p = n; p->_caller != NULL; p = p->_caller) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 p->_caller = p->_caller->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550 assert(n->depth() == depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
551 assert(n->debug_depth() == debug_depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
552 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
556 uint CallNode::cmp( const Node &n ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
557 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
a61af66fc99e Initial load
duke
parents:
diff changeset
558 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
559 void CallNode::dump_req() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Dump the required inputs, enclosed in '(' and ')'
a61af66fc99e Initial load
duke
parents:
diff changeset
561 uint i; // Exit value of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
562 for( i=0; i<req(); i++ ) { // For all required inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if( i == TypeFunc::Parms ) tty->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 else tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567 tty->print(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 void CallNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
572 tf()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (jvms() != NULL) jvms()->dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578 const Type *CallNode::bottom_type() const { return tf()->range(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 const Type *CallNode::Value(PhaseTransform *phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (phase->type(in(0)) == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 return tf()->range();
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
585 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // Use the standard compiler calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
587 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true );
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 //------------------------------match------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Construct projections for control, I/O, memory-fields, ..., and
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // return result(s) along with their RegMask info
a61af66fc99e Initial load
duke
parents:
diff changeset
594 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 switch (proj->_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 case TypeFunc::Control:
a61af66fc99e Initial load
duke
parents:
diff changeset
597 case TypeFunc::I_O:
a61af66fc99e Initial load
duke
parents:
diff changeset
598 case TypeFunc::Memory:
a61af66fc99e Initial load
duke
parents:
diff changeset
599 return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 case TypeFunc::Parms+1: // For LONG & DOUBLE returns
a61af66fc99e Initial load
duke
parents:
diff changeset
602 assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // 2nd half of doubles and longs
a61af66fc99e Initial load
duke
parents:
diff changeset
604 return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 case TypeFunc::Parms: { // Normal returns
a61af66fc99e Initial load
duke
parents:
diff changeset
607 uint ideal_reg = Matcher::base2reg[tf()->range()->field_at(TypeFunc::Parms)->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
608 OptoRegPair regs = is_CallRuntime()
a61af66fc99e Initial load
duke
parents:
diff changeset
609 ? match->c_return_value(ideal_reg,true) // Calls into C runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
610 : match-> return_value(ideal_reg,true); // Calls into compiled Java code
a61af66fc99e Initial load
duke
parents:
diff changeset
611 RegMask rm = RegMask(regs.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if( OptoReg::is_valid(regs.second()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
613 rm.Insert( regs.second() );
a61af66fc99e Initial load
duke
parents:
diff changeset
614 return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
618 case TypeFunc::FramePtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
619 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
620 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
626 uint CallNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
630 //
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 66
diff changeset
631 // 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
632 // instance at the specified offset.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
633 //
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
634 bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
635 const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
636
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
637 // If not an OopPtr or not an instance type, assume the worst.
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
638 // Note: currently this method is called only for instance types.
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
639 if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
640 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
641 }
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
642 // The instance_id is set only for scalar-replaceable allocations which
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
643 // are not passed as arguments according to Escape Analysis.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
644 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
645 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
646
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
647 // Does this call have a direct reference to n other than debug information?
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
648 bool CallNode::has_non_debug_use(Node *n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
649 const TypeTuple * d = tf()->domain();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
650 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
651 Node *arg = in(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
652 if (arg == n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
653 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
654 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
655 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
656 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
657 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
658
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
659 // Returns the unique CheckCastPP of a call
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
660 // or 'this' if there are several CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
661 // or returns NULL if there is no one.
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
662 Node *CallNode::result_cast() {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
663 Node *cast = NULL;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
664
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
665 Node *p = proj_out(TypeFunc::Parms);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
666 if (p == NULL)
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
667 return NULL;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
668
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
669 for (DUIterator_Fast imax, i = p->fast_outs(imax); i < imax; i++) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
670 Node *use = p->fast_out(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
671 if (use->is_CheckCastPP()) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
672 if (cast != NULL) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
673 return this; // more than 1 CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
674 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
675 cast = use;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
676 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
677 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
678 return cast;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
679 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
680
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
681
0
a61af66fc99e Initial load
duke
parents:
diff changeset
682 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
683 uint CallJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 uint CallJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 CallJavaNode &call = (CallJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
686 return CallNode::cmp(call) && _method == call._method;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
689 void CallJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 if( _method ) _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
696 uint CallStaticJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 uint CallStaticJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
698 CallStaticJavaNode &call = (CallStaticJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
699 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701
a61af66fc99e Initial load
duke
parents:
diff changeset
702 //----------------------------uncommon_trap_request----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // If this is an uncommon trap, return the request code, else zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
704 int CallStaticJavaNode::uncommon_trap_request() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 if (_name != NULL && !strcmp(_name, "uncommon_trap")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
706 return extract_uncommon_trap_request(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
708 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
710 int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if (!(call->req() > TypeFunc::Parms &&
a61af66fc99e Initial load
duke
parents:
diff changeset
713 call->in(TypeFunc::Parms) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
714 call->in(TypeFunc::Parms)->is_Con())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
715 assert(_in_dump_cnt != 0, "OK if dumping");
a61af66fc99e Initial load
duke
parents:
diff changeset
716 tty->print("[bad uncommon trap]");
a61af66fc99e Initial load
duke
parents:
diff changeset
717 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
719 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
720 return call->in(TypeFunc::Parms)->bottom_type()->is_int()->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722
a61af66fc99e Initial load
duke
parents:
diff changeset
723 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
724 void CallStaticJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 st->print("# Static ");
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 st->print("%s", _name);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 int trap_req = uncommon_trap_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if (trap_req != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
731 st->print("(%s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
732 Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
733 trap_req));
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
742 uint CallDynamicJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 uint CallDynamicJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 CallDynamicJavaNode &call = (CallDynamicJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
748 void CallDynamicJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 st->print("# Dynamic ");
a61af66fc99e Initial load
duke
parents:
diff changeset
750 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
753
a61af66fc99e Initial load
duke
parents:
diff changeset
754 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
755 uint CallRuntimeNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
756 uint CallRuntimeNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 CallRuntimeNode &call = (CallRuntimeNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 return CallNode::cmp(call) && !strcmp(_name,call._name);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
761 void CallRuntimeNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
763 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
769 void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 Matcher::c_calling_convention( sig_bt, parm_regs, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
774 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
778 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
779 void CallLeafNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
781 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
789 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
790 int loc = jvms->locoff() + idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 if (in(loc)->is_top() && idx > 0 && !c->is_top() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // If current local idx is top then local idx - 1 could
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // be a long/double that needs to be killed since top could
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // represent the 2nd half ofthe long/double.
a61af66fc99e Initial load
duke
parents:
diff changeset
795 uint ideal = in(loc -1)->ideal_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if (ideal == Op_RegD || ideal == Op_RegL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // set other (low index) half to top
a61af66fc99e Initial load
duke
parents:
diff changeset
798 set_req(loc - 1, in(loc));
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 set_req(loc, c);
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 uint SafePointNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
805 uint SafePointNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 //-------------------------set_next_exception----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
810 void SafePointNode::set_next_exception(SafePointNode* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 assert(n == NULL || n->Opcode() == Op_SafePoint, "correct value for next_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
812 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if (n != NULL) add_prec(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
815 set_prec(req(), n);
a61af66fc99e Initial load
duke
parents:
diff changeset
816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819
a61af66fc99e Initial load
duke
parents:
diff changeset
820 //----------------------------next_exception-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
821 SafePointNode* SafePointNode::next_exception() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 Node* n = in(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
826 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges");
a61af66fc99e Initial load
duke
parents:
diff changeset
827 return (SafePointNode*) n;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // Skip over any collapsed Regions
a61af66fc99e Initial load
duke
parents:
diff changeset
834 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) {
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 247
diff changeset
835 return remove_dead_region(phase, can_reshape) ? this : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // Remove obviously duplicate safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
840 Node *SafePointNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // If you have back to back safepoints, remove one
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if( in(TypeFunc::Control)->is_SafePoint() )
a61af66fc99e Initial load
duke
parents:
diff changeset
844 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 if( in(0)->is_Proj() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 Node *n0 = in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // Check if he is a call projection (except Leaf Call)
a61af66fc99e Initial load
duke
parents:
diff changeset
849 if( n0->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
850 n0 = n0->in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 assert( n0->is_Call(), "expect a call here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // Useless Safepoint, so remove it
a61af66fc99e Initial load
duke
parents:
diff changeset
855 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858
a61af66fc99e Initial load
duke
parents:
diff changeset
859 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
863 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
864 if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
865 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
a61af66fc99e Initial load
duke
parents:
diff changeset
866 return Type::CONTROL;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
870 void SafePointNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 st->print(" SafePoint ");
a61af66fc99e Initial load
duke
parents:
diff changeset
872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
873 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
874
a61af66fc99e Initial load
duke
parents:
diff changeset
875 const RegMask &SafePointNode::in_RegMask(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
876 if( idx < TypeFunc::Parms ) return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Values outside the domain represent debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
878 return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880 const RegMask &SafePointNode::out_RegMask() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
883
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
a61af66fc99e Initial load
duke
parents:
diff changeset
886 assert((int)grow_by > 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
887 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
888 int scloff = jvms->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
889 int endoff = jvms->endoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
890 assert(endoff == (int)req(), "no other states or debug info after me");
a61af66fc99e Initial load
duke
parents:
diff changeset
891 Node* top = Compile::current()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
892 for (uint i = 0; i < grow_by; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 ins_req(monoff, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895 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
896 jvms->set_scloff(scloff + grow_by);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
897 jvms->set_endoff(endoff + grow_by);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 void SafePointNode::push_monitor(const FastLockNode *lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // Add a LockNode, which points to both the original BoxLockNode (the
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // stack space for the monitor) and the Object being locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
903 const int MonitorEdges = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
a61af66fc99e Initial load
duke
parents:
diff changeset
905 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
906 int nextmon = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 add_req(lock->box_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
909 add_req(lock->obj_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
910 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 add_req(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 add_req(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
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
914 jvms()->set_scloff(nextmon+MonitorEdges);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 jvms()->set_endoff(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void SafePointNode::pop_monitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Delete last monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
920 debug_only(int num_before_pop = jvms()->nof_monitors());
a61af66fc99e Initial load
duke
parents:
diff changeset
921 const int MonitorEdges = (1<<JVMState::logMonitorEdges);
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
922 int scloff = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
923 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
924 int new_scloff = scloff - MonitorEdges;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
925 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
926 jvms()->set_scloff(new_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
927 jvms()->set_endoff(new_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
928 while (scloff > new_scloff) del_req(--scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
929 assert(jvms()->nof_monitors() == num_before_pop-1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 Node *SafePointNode::peek_monitor_box() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
934 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
935 return monitor_box(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937
a61af66fc99e Initial load
duke
parents:
diff changeset
938 Node *SafePointNode::peek_monitor_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
939 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
940 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
941 return monitor_obj(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
945 uint SafePointNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if( !needs_polling_address_input() )
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 return (TypeFunc::Parms == idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951
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
952 //============== 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
953
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
954 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
955 #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
956 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
957 #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
958 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
959 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
960 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
961 #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
962 _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
963 #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
964 _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
965 _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
966 {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
967 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
968 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
969
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 366
diff changeset
970 bool SafePointScalarObjectNode::pinned() const { return true; }
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
971
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
972 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
973 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
974 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
975
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
976 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
977 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
978 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
979
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
980 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
981 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
982 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
983
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
984 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
985 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
986 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
987
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
988 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
989 SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) 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
990 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
991 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
992 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
993 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
994 Compile* C = Compile::current();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
995 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
996 res->_first_index += jvms_adj;
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
997 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
998 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
999 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1000
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1001
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1002 #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
1003 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
1004 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
1005 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
1006 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1007
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1008 #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
1009
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 uint AllocateNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 Node *ctrl, Node *mem, Node *abio,
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 Node *size, Node *klass_node, Node *initial_test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 : CallNode(atype, NULL, TypeRawPtr::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 init_class_id(Class_Allocate);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 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
1020 _is_scalar_replaceable = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 Node *topnode = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 init_req( TypeFunc::Control , ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 init_req( TypeFunc::I_O , abio );
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 init_req( TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 init_req( TypeFunc::ReturnAdr, topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 init_req( TypeFunc::FramePtr , topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 init_req( AllocSize , size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 init_req( KlassNode , klass_node);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 init_req( InitialTest , initial_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 init_req( ALength , topnode);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 C->add_macro_node(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 uint AllocateArrayNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1038 // 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
1039 // 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
1040 // 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
1041 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
1042 Node *length = in(AllocateNode::ALength);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1043 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
1044
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1045 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
1046 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
1047
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1048 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
1049 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
1050 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
1051 // Assert one of:
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1052 // - the narrow_length is 0
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1053 // - 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
1054 assert(narrow_length_type == TypeInt::ZERO ||
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1055 (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
1056 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
1057 "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
1058
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1059 // 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
1060 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
1061 // 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
1062 // propagate the fact that the array length must be positive.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1063 length = new (phase->C, 2) CastIINode(length, narrow_length_type);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1064 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
1065 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1066 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1067
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1068 return length;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1069 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1070
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 uint LockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // Redundant lock elimination
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // There are various patterns of locking where we release and
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // immediately reacquire a lock in a piece of code where no operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // occur in between that would be observable. In those cases we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // skip releasing and reacquiring the lock without violating any
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // fairness requirements. Doing this around a loop could cause a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // to be held for a very long time so we concentrate on non-looping
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // control flow. We also require that the operations are fully
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // redundant meaning that we don't introduce new lock operations on
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // some paths so to be able to eliminate it on others ala PRE. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // would probably require some more extensive graph manipulation to
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // guarantee that the memory edges were all handled correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // Assuming p is a simple predicate which can't trap in any way and s
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // is a synchronized method consider this code:
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // 1. The unlocks of the first call to s can be eliminated if the
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 // locks inside the then and else branches are eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // 2. The unlocks of the then and else branches can be eliminated if
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // the lock of the final call to s is eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // Either of these cases subsumes the simple case of sequential control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // Addtionally we can eliminate versions without the else case:
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // 3. In this case we eliminate the unlock of the first s, the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 // and unlock in the then case and the lock in the final s.
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // Note also that in all these cases the then/else pieces don't have
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // to be trivial as long as they begin and end with synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 // f();
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // The code will work properly for this case, leaving in the unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // before the call to f and the relock after it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // A potentially interesting case which isn't handled here is when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // locking is partially redundant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // This could be eliminated putting unlocking on the else case and
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // eliminating the first unlock and the lock in the then side.
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Alternatively the unlock could be moved out of the then side so it
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // was after the merge and the first unlock and second lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // eliminated. This might require less manipulation of the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // state to get correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // Additionally we might allow work between a unlock and lock before
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // giving up eliminating the locks. The current code disallows any
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // conditional control flow between these operations. A formulation
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // similar to partial redundancy elimination computing the
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // availability of unlocking and the anticipatability of locking at a
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // program point would allow detection of fully redundant locking with
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // some amount of work in between. I'm not sure how often I really
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // think that would occur though. Most of the cases I've seen
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // indicate it's likely non-trivial work would occur in between.
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // There may be other more complicated constructs where we could
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // eliminate locking but I haven't seen any others appear as hot or
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // interesting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // Locking and unlocking have a canonical form in ideal that looks
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // roughly like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // <obj>
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // | \\------+
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // | BoxLock \
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // | | | \
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // | | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // | | FastLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // Lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // MembarAcquire
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // MembarRelease
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // This code proceeds by processing Lock nodes during PhaseIterGVN
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // and searching back through its control for the proper code
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // patterns. Once it finds a set of lock and unlock operations to
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // eliminate they are marked as eliminatable which causes the
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // expansion of the Lock and Unlock macro nodes to make the operation a NOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1195
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // Utility function to skip over uninteresting control nodes. Nodes skipped are:
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // - copy regions. (These may not have been optimized away yet.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // - eliminated locking nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 static Node *next_control(Node *ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 if (ctrl == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 RegionNode *r = ctrl->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 Node *n = r->is_copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (n == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 break; // hit a region, return it
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 ctrl = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 } else if (ctrl->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 Node *in0 = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if (in0->is_AbstractLock() && in0->as_AbstractLock()->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 ctrl = in0->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 break; // found an interesting control
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 return ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // Given a control, see if it's the control projection of an Unlock which
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // operating on the same object as lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 bool AbstractLockNode::find_matching_unlock(const Node* ctrl, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 Node *n = ctrl_proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (n != NULL && n->is_Unlock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 UnlockNode *unlock = n->as_Unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 if ((lock->obj_node() == unlock->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 lock_ops.append(unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // Find the lock matching an unlock. Returns null if a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // or complicated control is encountered first.
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 LockNode *AbstractLockNode::find_matching_lock(UnlockNode* unlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 LockNode *lock_result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // find the matching lock, or an intervening safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 Node *ctrl = next_control(unlock->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 assert(ctrl != NULL, "invalid control graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 assert(!ctrl->is_Start(), "missing lock for unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 if (ctrl->is_top()) break; // dead control path
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 if (ctrl->is_Proj()) ctrl = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if (ctrl->is_SafePoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 break; // found a safepoint (may be the lock we are searching for)
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 } else if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // Check for a simple diamond pattern. Punt on anything more complicated
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 if (ctrl->req() == 3 && ctrl->in(1) != NULL && ctrl->in(2) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 Node *in1 = next_control(ctrl->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 Node *in2 = next_control(ctrl->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 if (((in1->is_IfTrue() && in2->is_IfFalse()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 (in2->is_IfTrue() && in1->is_IfFalse())) && (in1->in(0) == in2->in(0))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 ctrl = next_control(in1->in(0)->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 ctrl = next_control(ctrl->in(0)); // keep searching
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 if (ctrl->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 LockNode *lock = ctrl->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 if ((lock->obj_node() == unlock->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 (lock->box_node() == unlock->box_node())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 lock_result = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 return lock_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // This code corresponds to case 3 above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1289
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 bool AbstractLockNode::find_lock_and_unlock_through_if(Node* node, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 Node* if_node = node->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 bool if_true = node->is_IfTrue();
a61af66fc99e Initial load
duke
parents:
diff changeset
1294
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 if (if_node->is_If() && if_node->outcnt() == 2 && (if_true || node->is_IfFalse())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 Node *lock_ctrl = next_control(if_node->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 if (find_matching_unlock(lock_ctrl, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 Node* lock1_node = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 ProjNode* proj = if_node->as_If()->proj_out(!if_true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 if (if_true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 if (proj->is_IfFalse() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if (proj->is_IfTrue() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if (lock1_node != NULL && lock1_node->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 LockNode *lock1 = lock1_node->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 if ((lock->obj_node() == lock1->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 lock_ops.append(lock1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1319
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // check each control merging at this point for a matching unlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // in(0) should be self edge so skip it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 for (int i = 1; i < (int)region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 Node *in_node = next_control(region->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 if (in_node != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 if (find_matching_unlock(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // found a match so keep on checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 } else if (find_lock_and_unlock_through_if(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // If we fall through to here then it was some kind of node we
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // don't understand or there wasn't a matching unlock, so give
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // up trying to merge locks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1348
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // Create a counter which counts the number of times this lock is acquired
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 void AbstractLockNode::create_lock_counter(JVMState* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 void AbstractLockNode::set_eliminated() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 _eliminate = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 if (_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 // Update the counter to indicate that this lock was eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // The counter update code will stay around even though the
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // optimizer will eliminate the lock operation itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 _counter->set_tag(NamedCounter::EliminatedLockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1372
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1373 // perform any generic optimizations first (returns 'this' or NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 Node *result = SafePointNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // Now see if we can optimize away this lock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // remove the locking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // prevents macro expansion from expanding the lock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // one computed above.
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1381 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1382 //
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1383 // 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
1384 //
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1385 ConnectionGraph *cgr = Compile::current()->congraph();
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1386 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1387 if (cgr != NULL)
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1388 es = cgr->escape_state(obj_node(), phase);
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1389 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1390 // Mark it eliminated to update any counters
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1391 this->set_eliminated();
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1392 return result;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1393 }
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1394
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // Try lock coarsening
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 PhaseIterGVN* iter = phase->is_IterGVN();
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 if (iter != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 GrowableArray<AbstractLockNode*> lock_ops;
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 Node *ctrl = next_control(in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // now search back for a matching Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (find_matching_unlock(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // found an unlock directly preceding this lock. This is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // case of single unlock directly control dependent on a
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // single lock which is the trivial version of case 1 or 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 } else if (ctrl->is_Region() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if (find_unlocks_for_region(ctrl->as_Region(), this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // found lock preceded by multiple unlocks along all paths
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // joining at this point which is case 3 in description above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // see if this lock comes from either half of an if and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // predecessors merges unlocks and the other half of the if
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // performs a lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 if (find_lock_and_unlock_through_if(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // found unlock splitting to an if with locks on both branches.
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 if (lock_ops.length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 // add ourselves to the list of locks to be eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 lock_ops.append(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 if (PrintEliminateLocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 int locks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 int unlocks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 AbstractLockNode* lock = lock_ops.at(i);
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1434 if (lock->Opcode() == Op_Lock)
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1435 locks++;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1436 else
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1437 unlocks++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 lock->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // for each of the identified locks, mark them
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // as eliminatable
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 AbstractLockNode* lock = lock_ops.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Mark it eliminated to update any counters
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 lock->set_eliminated();
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 } else if (result != NULL && ctrl->is_Region() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 iter->_worklist.member(ctrl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // We weren't able to find any opportunities but the region this
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // lock is control dependent on hasn't been processed yet so put
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // this lock back on the worklist so we can check again once any
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // region simplification has occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 iter->_worklist.push(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1467
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 uint UnlockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1474 // perform any generic optimizations first (returns 'this' or NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 Node * result = SafePointNode::Ideal(phase, can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // Now see if we can optimize away this unlock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // remove the unlocking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // prevents macro expansion from expanding the unlock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // one computed above.
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1482 // Escape state is defined after Parse phase.
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1483 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 //
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1485 // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 ConnectionGraph *cgr = Compile::current()->congraph();
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1488 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1489 if (cgr != NULL)
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1490 es = cgr->escape_state(obj_node(), phase);
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1491 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1492 // Mark it eliminated to update any counters
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1493 this->set_eliminated();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 }