annotate src/share/vm/opto/callnode.cpp @ 17716:cdb71841f4bc

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