annotate src/share/vm/opto/callnode.cpp @ 8804:91bf0bdae37b

8008217: CDS: Class data sharing limits the malloc heap on Solaris Summary: In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address. Reviewed-by: kvn, dcubed, zgu, hseigel
author coleenp
date Wed, 20 Mar 2013 08:04:54 -0400
parents a7114d3d712e
children 6f3fd5150b67
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
5948
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4790
diff changeset
2 * Copyright (c) 1997, 2012, 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) {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
461 uint first_ind = spobj->first_index();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
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 {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (_map && !((uintptr_t)_map & 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (_map->len() > _map->req()) { // _map->has_exceptions()
a61af66fc99e Initial load
duke
parents:
diff changeset
528 Node* ex = _map->in(_map->req()); // _map->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // skip the first one; it's already being printed
a61af66fc99e Initial load
duke
parents:
diff changeset
530 while (ex != NULL && ex->len() > ex->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 ex = ex->in(ex->req()); // ex->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
532 ex->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535 _map->dump(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
537 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
538 depth(), locoff(), stkoff(), argoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (_method == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 st->print_cr("(none)");
a61af66fc99e Initial load
duke
parents:
diff changeset
541 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 _method->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
544 if (bci() >= 0 && bci() < _method->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 st->print(" bc: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
546 _method->print_codes_on(bci(), bci()+1, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (caller() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 caller()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // Extra way to dump a jvms from the debugger,
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // to avoid a bug with C++ member function calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
556 void dump_jvms(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 jvms->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 //--------------------------clone_shallow--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
562 JVMState* JVMState::clone_shallow(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 JVMState* n = has_method() ? new (C) JVMState(_method, _caller) : new (C) JVMState(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 n->set_bci(_bci);
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
565 n->_reexecute = _reexecute;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
566 n->set_locoff(_locoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 n->set_stkoff(_stkoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 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
569 n->set_scloff(_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
570 n->set_endoff(_endoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
571 n->set_sp(_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 n->set_map(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
573 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 //---------------------------clone_deep----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
577 JVMState* JVMState::clone_deep(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 JVMState* n = clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
579 for (JVMState* p = n; p->_caller != NULL; p = p->_caller) {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 p->_caller = p->_caller->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 assert(n->depth() == depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
583 assert(n->debug_depth() == debug_depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
584 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
588 uint CallNode::cmp( const Node &n ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
589 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 #ifndef PRODUCT
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
591 void CallNode::dump_req(outputStream *st) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Dump the required inputs, enclosed in '(' and ')'
a61af66fc99e Initial load
duke
parents:
diff changeset
593 uint i; // Exit value of loop
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
594 for (i = 0; i < req(); i++) { // For all required inputs
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
595 if (i == TypeFunc::Parms) st->print("(");
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
596 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
597 else st->print("_ ");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
598 }
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
599 st->print(")");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602 void CallNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
603 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
604 tf()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
606 if (jvms() != NULL) jvms()->dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
608 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 const Type *CallNode::bottom_type() const { return tf()->range(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
611 const Type *CallNode::Value(PhaseTransform *phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if (phase->type(in(0)) == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 return tf()->range();
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
617 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Use the standard compiler calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
619 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true );
a61af66fc99e Initial load
duke
parents:
diff changeset
620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 //------------------------------match------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Construct projections for control, I/O, memory-fields, ..., and
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // return result(s) along with their RegMask info
a61af66fc99e Initial load
duke
parents:
diff changeset
626 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 switch (proj->_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 case TypeFunc::Control:
a61af66fc99e Initial load
duke
parents:
diff changeset
629 case TypeFunc::I_O:
a61af66fc99e Initial load
duke
parents:
diff changeset
630 case TypeFunc::Memory:
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
631 return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 case TypeFunc::Parms+1: // For LONG & DOUBLE returns
a61af66fc99e Initial load
duke
parents:
diff changeset
634 assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // 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
636 return new (match->C) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 case TypeFunc::Parms: { // Normal returns
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
639 uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
640 OptoRegPair regs = is_CallRuntime()
a61af66fc99e Initial load
duke
parents:
diff changeset
641 ? match->c_return_value(ideal_reg,true) // Calls into C runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
642 : match-> return_value(ideal_reg,true); // Calls into compiled Java code
a61af66fc99e Initial load
duke
parents:
diff changeset
643 RegMask rm = RegMask(regs.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
644 if( OptoReg::is_valid(regs.second()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
645 rm.Insert( regs.second() );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
646 return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
650 case TypeFunc::FramePtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
651 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
652 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
658 uint CallNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
662 //
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 66
diff changeset
663 // 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
664 // instance at the specified offset.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
665 //
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
666 bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
667 const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
668
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
669 // If not an OopPtr or not an instance type, assume the worst.
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
670 // Note: currently this method is called only for instance types.
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
671 if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
672 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
673 }
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
674 // The instance_id is set only for scalar-replaceable allocations which
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
675 // are not passed as arguments according to Escape Analysis.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
676 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
677 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
678
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
679 // 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
680 bool CallNode::has_non_debug_use(Node *n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
681 const TypeTuple * d = tf()->domain();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
682 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
683 Node *arg = in(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
684 if (arg == n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
685 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
686 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
687 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
688 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
689 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
690
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
691 // Returns the unique CheckCastPP of a call
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
692 // or 'this' if there are several CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
693 // or returns NULL if there is no one.
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
694 Node *CallNode::result_cast() {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
695 Node *cast = NULL;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
696
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
697 Node *p = proj_out(TypeFunc::Parms);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
698 if (p == NULL)
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
699 return NULL;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
700
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
701 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
702 Node *use = p->fast_out(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
703 if (use->is_CheckCastPP()) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
704 if (cast != NULL) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
705 return this; // more than 1 CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
706 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
707 cast = use;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
708 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
709 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
710 return cast;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
711 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
712
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
713
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
714 void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
715 projs->fallthrough_proj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
716 projs->fallthrough_catchproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
717 projs->fallthrough_ioproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
718 projs->catchall_ioproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
719 projs->catchall_catchproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
720 projs->fallthrough_memproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
721 projs->catchall_memproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
722 projs->resproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
723 projs->exobj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
724
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
725 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
726 ProjNode *pn = fast_out(i)->as_Proj();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
727 if (pn->outcnt() == 0) continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
728 switch (pn->_con) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
729 case TypeFunc::Control:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
730 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
731 // 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
732 projs->fallthrough_proj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
733 DUIterator_Fast jmax, j = pn->fast_outs(jmax);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
734 const Node *cn = pn->fast_out(j);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
735 if (cn->is_Catch()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
736 ProjNode *cpn = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
737 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
738 cpn = cn->fast_out(k)->as_Proj();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
739 assert(cpn->is_CatchProj(), "must be a CatchProjNode");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
740 if (cpn->_con == CatchProjNode::fall_through_index)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
741 projs->fallthrough_catchproj = cpn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
742 else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
743 assert(cpn->_con == CatchProjNode::catch_all_index, "must be correct index.");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
744 projs->catchall_catchproj = cpn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
745 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
746 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
747 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
748 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
749 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
750 case TypeFunc::I_O:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
751 if (pn->_is_io_use)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
752 projs->catchall_ioproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
753 else
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
754 projs->fallthrough_ioproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
755 for (DUIterator j = pn->outs(); pn->has_out(j); j++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
756 Node* e = pn->out(j);
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 6804
diff changeset
757 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
758 assert(projs->exobj == NULL, "only one");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
759 projs->exobj = e;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
760 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
761 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
762 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
763 case TypeFunc::Memory:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
764 if (pn->_is_io_use)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
765 projs->catchall_memproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
766 else
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
767 projs->fallthrough_memproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
768 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
769 case TypeFunc::Parms:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
770 projs->resproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
771 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
772 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
773 assert(false, "unexpected projection from allocation node.");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
774 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
775 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
776
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
777 // The resproj may not exist because the result couuld be ignored
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
778 // and the exception object may not exist if an exception handler
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
779 // 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
780 assert(projs->fallthrough_proj != NULL, "must be found");
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
781 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
782 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj != NULL, "must be found");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
783 assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj != NULL, "must be found");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
784 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
785 if (separate_io_proj) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
786 assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj != NULL, "must be found");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
787 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
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
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
791 Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
792 CallGenerator* cg = generator();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
793 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
794 // Check whether this MH handle call becomes a candidate for inlining
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
795 ciMethod* callee = cg->method();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
796 vmIntrinsics::ID iid = callee->intrinsic_id();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
797 if (iid == vmIntrinsics::_invokeBasic) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
798 if (in(TypeFunc::Parms)->Opcode() == Op_ConP) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
799 phase->C->prepend_late_inline(cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
800 set_generator(NULL);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
801 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
802 } else {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
803 assert(callee->has_member_arg(), "wrong type of call?");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
804 if (in(TypeFunc::Parms + callee->arg_size() - 1)->Opcode() == Op_ConP) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
805 phase->C->prepend_late_inline(cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
806 set_generator(NULL);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
807 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
808 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
809 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
810 return SafePointNode::Ideal(phase, can_reshape);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
811 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
812
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
813
0
a61af66fc99e Initial load
duke
parents:
diff changeset
814 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
815 uint CallJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 uint CallJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 CallJavaNode &call = (CallJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
818 return CallNode::cmp(call) && _method == call._method;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
821 void CallJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 if( _method ) _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
823 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
828 uint CallStaticJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
829 uint CallStaticJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 CallStaticJavaNode &call = (CallStaticJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 //----------------------------uncommon_trap_request----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // If this is an uncommon trap, return the request code, else zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
836 int CallStaticJavaNode::uncommon_trap_request() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 if (_name != NULL && !strcmp(_name, "uncommon_trap")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 return extract_uncommon_trap_request(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
844 if (!(call->req() > TypeFunc::Parms &&
a61af66fc99e Initial load
duke
parents:
diff changeset
845 call->in(TypeFunc::Parms) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
846 call->in(TypeFunc::Parms)->is_Con())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 assert(_in_dump_cnt != 0, "OK if dumping");
a61af66fc99e Initial load
duke
parents:
diff changeset
848 tty->print("[bad uncommon trap]");
a61af66fc99e Initial load
duke
parents:
diff changeset
849 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
852 return call->in(TypeFunc::Parms)->bottom_type()->is_int()->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
856 void CallStaticJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 st->print("# Static ");
a61af66fc99e Initial load
duke
parents:
diff changeset
858 if (_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 st->print("%s", _name);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 int trap_req = uncommon_trap_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (trap_req != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
863 st->print("(%s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
864 Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
865 trap_req));
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
874 uint CallDynamicJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
875 uint CallDynamicJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
876 CallDynamicJavaNode &call = (CallDynamicJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
879 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
880 void CallDynamicJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 st->print("# Dynamic ");
a61af66fc99e Initial load
duke
parents:
diff changeset
882 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
887 uint CallRuntimeNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
888 uint CallRuntimeNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 CallRuntimeNode &call = (CallRuntimeNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 return CallNode::cmp(call) && !strcmp(_name,call._name);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
892 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
893 void CallRuntimeNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
895 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
901 void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 Matcher::c_calling_convention( sig_bt, parm_regs, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
906 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
910 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
911 void CallLeafNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
913 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
922 int loc = jvms->locoff() + idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
923 if (in(loc)->is_top() && idx > 0 && !c->is_top() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // If current local idx is top then local idx - 1 could
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // be a long/double that needs to be killed since top could
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // represent the 2nd half ofthe long/double.
a61af66fc99e Initial load
duke
parents:
diff changeset
927 uint ideal = in(loc -1)->ideal_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
928 if (ideal == Op_RegD || ideal == Op_RegL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // set other (low index) half to top
a61af66fc99e Initial load
duke
parents:
diff changeset
930 set_req(loc - 1, in(loc));
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933 set_req(loc, c);
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 uint SafePointNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
937 uint SafePointNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 //-------------------------set_next_exception----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
942 void SafePointNode::set_next_exception(SafePointNode* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 assert(n == NULL || n->Opcode() == Op_SafePoint, "correct value for next_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
945 if (n != NULL) add_prec(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 set_prec(req(), n);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 //----------------------------next_exception-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
953 SafePointNode* SafePointNode::next_exception() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
956 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 Node* n = in(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
958 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges");
a61af66fc99e Initial load
duke
parents:
diff changeset
959 return (SafePointNode*) n;
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
a61af66fc99e Initial load
duke
parents:
diff changeset
964 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // Skip over any collapsed Regions
a61af66fc99e Initial load
duke
parents:
diff changeset
966 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) {
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 247
diff changeset
967 return remove_dead_region(phase, can_reshape) ? this : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // Remove obviously duplicate safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
972 Node *SafePointNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // If you have back to back safepoints, remove one
a61af66fc99e Initial load
duke
parents:
diff changeset
975 if( in(TypeFunc::Control)->is_SafePoint() )
a61af66fc99e Initial load
duke
parents:
diff changeset
976 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 if( in(0)->is_Proj() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 Node *n0 = in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // Check if he is a call projection (except Leaf Call)
a61af66fc99e Initial load
duke
parents:
diff changeset
981 if( n0->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 n0 = n0->in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 assert( n0->is_Call(), "expect a call here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // Useless Safepoint, so remove it
a61af66fc99e Initial load
duke
parents:
diff changeset
987 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990
a61af66fc99e Initial load
duke
parents:
diff changeset
991 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
995 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
a61af66fc99e Initial load
duke
parents:
diff changeset
998 return Type::CONTROL;
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 void SafePointNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 st->print(" SafePoint ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 const RegMask &SafePointNode::in_RegMask(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if( idx < TypeFunc::Parms ) return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // Values outside the domain represent debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 const RegMask &SafePointNode::out_RegMask() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 assert((int)grow_by > 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 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
1020 int scloff = jvms->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 int endoff = jvms->endoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 assert(endoff == (int)req(), "no other states or debug info after me");
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 Node* top = Compile::current()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 for (uint i = 0; i < grow_by; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 ins_req(monoff, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 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
1028 jvms->set_scloff(scloff + grow_by);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 jvms->set_endoff(endoff + grow_by);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 void SafePointNode::push_monitor(const FastLockNode *lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // Add a LockNode, which points to both the original BoxLockNode (the
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // stack space for the monitor) and the Object being locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 const int MonitorEdges = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 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
1038 int nextmon = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 if (GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 add_req(lock->box_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 add_req(lock->obj_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 } else {
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1043 Node* top = Compile::current()->top();
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1044 add_req(top);
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1045 add_req(top);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 }
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
1047 jvms()->set_scloff(nextmon+MonitorEdges);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 jvms()->set_endoff(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 void SafePointNode::pop_monitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // Delete last monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 debug_only(int num_before_pop = jvms()->nof_monitors());
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 const int MonitorEdges = (1<<JVMState::logMonitorEdges);
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1055 int scloff = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 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
1057 int new_scloff = scloff - MonitorEdges;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 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
1059 jvms()->set_scloff(new_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 jvms()->set_endoff(new_endoff);
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1061 while (scloff > new_scloff) del_req(--scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 assert(jvms()->nof_monitors() == num_before_pop-1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 Node *SafePointNode::peek_monitor_box() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 return monitor_box(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 Node *SafePointNode::peek_monitor_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 return monitor_obj(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 uint SafePointNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if( !needs_polling_address_input() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 return (TypeFunc::Parms == idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
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
1085 //============== 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
1086
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1087 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
1088 #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
1089 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
1090 #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
1091 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
1092 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
1093 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
1094 #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
1095 _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
1096 #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
1097 _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
1098 _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
1099 {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1100 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
1101 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1102
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1103 // Do not allow value-numbering for SafePointScalarObject node.
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1104 uint SafePointScalarObjectNode::hash() const { return NO_HASH; }
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1105 uint SafePointScalarObjectNode::cmp( const Node &n ) const {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1106 return (&n == this); // Always fail except on self
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1107 }
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
1108
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1109 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
1110 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
1111 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1112
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1113 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
1114 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
1115 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1116
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1117 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
1118 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
1119 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1120
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1121 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
1122 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
1123 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1124
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1125 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
1126 SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1127 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
1128 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
1129 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
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* 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
1132 res->_first_index += jvms_adj;
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1133 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
1134 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
1135 }
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
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
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 #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
1139 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
1140 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
1141 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
1142 }
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 #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
1145
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 uint AllocateNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 Node *ctrl, Node *mem, Node *abio,
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 Node *size, Node *klass_node, Node *initial_test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 : CallNode(atype, NULL, TypeRawPtr::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 init_class_id(Class_Allocate);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 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
1156 _is_scalar_replaceable = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 Node *topnode = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 init_req( TypeFunc::Control , ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 init_req( TypeFunc::I_O , abio );
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 init_req( TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 init_req( TypeFunc::ReturnAdr, topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 init_req( TypeFunc::FramePtr , topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 init_req( AllocSize , size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 init_req( KlassNode , klass_node);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 init_req( InitialTest , initial_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 init_req( ALength , topnode);
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 C->add_macro_node(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 uint AllocateArrayNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
704
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1174 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
1175 if (remove_dead_region(phase, can_reshape)) return this;
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1176 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1177 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
1178
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1179 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
1180 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
1181 if (can_reshape) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1182 PhaseIterGVN *igvn = phase->is_IterGVN();
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1183 // 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
1184 // 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
1185 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
1186 Node* catchproj = NULL;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1187 if (proj != NULL) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1188 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
1189 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
1190 if (cn->is_Catch()) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1191 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
1192 break;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1193 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1194 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1195 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1196 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
1197 (catchproj->outcnt() > 1 ||
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1198 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
1199 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
1200 Node* nproj = catchproj->clone();
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1201 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
1202
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1203 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
1204 frame = phase->transform(frame);
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1205 // Halt & Catch Fire
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1206 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
1207 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
1208 phase->transform(halt);
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1209
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1210 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
1211 return this;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1212 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1213 } else {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1214 // 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
1215 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
1216 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1217 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1218 return NULL;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1219 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1220
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1221 // 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
1222 // 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
1223 // 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
1224 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
1225 Node *length = in(AllocateNode::ALength);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1226 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
1227
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1228 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
1229 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
1230
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1231 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
1232 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
1233 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
1234 // Assert one of:
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1235 // - the narrow_length is 0
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1236 // - 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
1237 assert(narrow_length_type == TypeInt::ZERO ||
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1238 (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
1239 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
1240 "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
1241
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1242 // 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
1243 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
1244 // 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
1245 // 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
1246 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
1247 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
1248 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1249 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1250
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1251 return length;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1252 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1253
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 uint LockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // Redundant lock elimination
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // There are various patterns of locking where we release and
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // immediately reacquire a lock in a piece of code where no operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // occur in between that would be observable. In those cases we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // skip releasing and reacquiring the lock without violating any
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // fairness requirements. Doing this around a loop could cause a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // to be held for a very long time so we concentrate on non-looping
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // control flow. We also require that the operations are fully
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // redundant meaning that we don't introduce new lock operations on
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // some paths so to be able to eliminate it on others ala PRE. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 // would probably require some more extensive graph manipulation to
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // guarantee that the memory edges were all handled correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // Assuming p is a simple predicate which can't trap in any way and s
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // is a synchronized method consider this code:
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // 1. The unlocks of the first call to s can be eliminated if the
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // locks inside the then and else branches are eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // 2. The unlocks of the then and else branches can be eliminated if
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // the lock of the final call to s is eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // Either of these cases subsumes the simple case of sequential control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // Addtionally we can eliminate versions without the else case:
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // 3. In this case we eliminate the unlock of the first s, the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // and unlock in the then case and the lock in the final s.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // Note also that in all these cases the then/else pieces don't have
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // to be trivial as long as they begin and end with synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // f();
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // The code will work properly for this case, leaving in the unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // before the call to f and the relock after it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // A potentially interesting case which isn't handled here is when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // locking is partially redundant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // This could be eliminated putting unlocking on the else case and
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // eliminating the first unlock and the lock in the then side.
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // Alternatively the unlock could be moved out of the then side so it
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // was after the merge and the first unlock and second lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // eliminated. This might require less manipulation of the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // state to get correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // Additionally we might allow work between a unlock and lock before
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // giving up eliminating the locks. The current code disallows any
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 // conditional control flow between these operations. A formulation
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // similar to partial redundancy elimination computing the
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // availability of unlocking and the anticipatability of locking at a
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // program point would allow detection of fully redundant locking with
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // some amount of work in between. I'm not sure how often I really
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // think that would occur though. Most of the cases I've seen
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // indicate it's likely non-trivial work would occur in between.
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // There may be other more complicated constructs where we could
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 // eliminate locking but I haven't seen any others appear as hot or
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // interesting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // Locking and unlocking have a canonical form in ideal that looks
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // roughly like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // <obj>
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // | \\------+
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // | BoxLock \
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // | | | \
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // | | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // | | FastLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // Lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // MembarAcquire
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 // MembarRelease
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // This code proceeds by processing Lock nodes during PhaseIterGVN
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // and searching back through its control for the proper code
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // patterns. Once it finds a set of lock and unlock operations to
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // eliminate they are marked as eliminatable which causes the
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 // expansion of the Lock and Unlock macro nodes to make the operation a NOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1378
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // Utility function to skip over uninteresting control nodes. Nodes skipped are:
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // - copy regions. (These may not have been optimized away yet.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // - eliminated locking nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 static Node *next_control(Node *ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 if (ctrl == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 RegionNode *r = ctrl->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 Node *n = r->is_copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 if (n == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 break; // hit a region, return it
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 ctrl = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 } else if (ctrl->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 Node *in0 = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 if (in0->is_AbstractLock() && in0->as_AbstractLock()->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 ctrl = in0->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 break; // found an interesting control
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 return ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // Given a control, see if it's the control projection of an Unlock which
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 // operating on the same object as lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 bool AbstractLockNode::find_matching_unlock(const Node* ctrl, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 Node *n = ctrl_proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 if (n != NULL && n->is_Unlock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 UnlockNode *unlock = n->as_Unlock();
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4777
diff changeset
1419 if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1420 BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1421 !unlock->is_eliminated()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 lock_ops.append(unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1429
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // Find the lock matching an unlock. Returns null if a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // or complicated control is encountered first.
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 LockNode *AbstractLockNode::find_matching_lock(UnlockNode* unlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 LockNode *lock_result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // find the matching lock, or an intervening safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 Node *ctrl = next_control(unlock->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 assert(ctrl != NULL, "invalid control graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 assert(!ctrl->is_Start(), "missing lock for unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 if (ctrl->is_top()) break; // dead control path
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 if (ctrl->is_Proj()) ctrl = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 if (ctrl->is_SafePoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 break; // found a safepoint (may be the lock we are searching for)
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 } else if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // Check for a simple diamond pattern. Punt on anything more complicated
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 if (ctrl->req() == 3 && ctrl->in(1) != NULL && ctrl->in(2) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 Node *in1 = next_control(ctrl->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 Node *in2 = next_control(ctrl->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (((in1->is_IfTrue() && in2->is_IfFalse()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 (in2->is_IfTrue() && in1->is_IfFalse())) && (in1->in(0) == in2->in(0))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 ctrl = next_control(in1->in(0)->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 ctrl = next_control(ctrl->in(0)); // keep searching
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 if (ctrl->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 LockNode *lock = ctrl->as_Lock();
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4777
diff changeset
1464 if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1465 BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 lock_result = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 return lock_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1471
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // This code corresponds to case 3 above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 bool AbstractLockNode::find_lock_and_unlock_through_if(Node* node, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 Node* if_node = node->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 bool if_true = node->is_IfTrue();
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 if (if_node->is_If() && if_node->outcnt() == 2 && (if_true || node->is_IfFalse())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 Node *lock_ctrl = next_control(if_node->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 if (find_matching_unlock(lock_ctrl, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 Node* lock1_node = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 ProjNode* proj = if_node->as_If()->proj_out(!if_true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 if (if_true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 if (proj->is_IfFalse() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 if (proj->is_IfTrue() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 if (lock1_node != NULL && lock1_node->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 LockNode *lock1 = lock1_node->as_Lock();
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4777
diff changeset
1495 if (lock->obj_node()->eqv_uncast(lock1->obj_node()) &&
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1496 BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1497 !lock1->is_eliminated()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 lock_ops.append(lock1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1508
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // check each control merging at this point for a matching unlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // in(0) should be self edge so skip it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 for (int i = 1; i < (int)region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 Node *in_node = next_control(region->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 if (in_node != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 if (find_matching_unlock(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // found a match so keep on checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 } else if (find_lock_and_unlock_through_if(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // If we fall through to here then it was some kind of node we
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // don't understand or there wasn't a matching unlock, so give
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // up trying to merge locks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1533
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // Create a counter which counts the number of times this lock is acquired
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 void AbstractLockNode::create_lock_counter(JVMState* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1542 void AbstractLockNode::set_eliminated_lock_counter() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 if (_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // Update the counter to indicate that this lock was eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // The counter update code will stay around even though the
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // optimizer will eliminate the lock operation itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 _counter->set_tag(NamedCounter::EliminatedLockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 }
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1549 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1551
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1554
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1555 // perform any generic optimizations first (returns 'this' or NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 Node *result = SafePointNode::Ideal(phase, can_reshape);
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1557 if (result != NULL) return result;
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1558 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1559 if (in(0) && in(0)->is_top()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // Now see if we can optimize away this lock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // remove the locking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // prevents macro expansion from expanding the lock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // one computed above.
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1566 if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1567 //
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1568 // 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
1569 //
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1570 ConnectionGraph *cgr = phase->C->congraph();
5948
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4790
diff changeset
1571 if (cgr != NULL && cgr->not_global_escape(obj_node())) {
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1572 assert(!is_eliminated() || is_coarsened(), "sanity");
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1573 // The lock could be marked eliminated by lock coarsening
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1574 // code during first IGVN before EA. Replace coarsened flag
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1575 // to eliminate all associated locks/unlocks.
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1576 this->set_non_esc_obj();
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1577 return result;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1578 }
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1579
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // Try lock coarsening
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 PhaseIterGVN* iter = phase->is_IterGVN();
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1584 if (iter != NULL && !is_eliminated()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1585
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 GrowableArray<AbstractLockNode*> lock_ops;
a61af66fc99e Initial load
duke
parents:
diff changeset
1587
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 Node *ctrl = next_control(in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1589
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // now search back for a matching Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 if (find_matching_unlock(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 // found an unlock directly preceding this lock. This is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // case of single unlock directly control dependent on a
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // single lock which is the trivial version of case 1 or 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 } else if (ctrl->is_Region() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 if (find_unlocks_for_region(ctrl->as_Region(), this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // found lock preceded by multiple unlocks along all paths
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // joining at this point which is case 3 in description above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 // see if this lock comes from either half of an if and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // predecessors merges unlocks and the other half of the if
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // performs a lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 if (find_lock_and_unlock_through_if(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // found unlock splitting to an if with locks on both branches.
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 if (lock_ops.length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // add ourselves to the list of locks to be eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 lock_ops.append(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1612
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 if (PrintEliminateLocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 int locks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 int unlocks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 AbstractLockNode* lock = lock_ops.at(i);
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1619 if (lock->Opcode() == Op_Lock)
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1620 locks++;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1621 else
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1622 unlocks++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 lock->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // for each of the identified locks, mark them
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // as eliminatable
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 AbstractLockNode* lock = lock_ops.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1636 // 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
1637 lock->set_coarsened();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 }
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1639 } else if (ctrl->is_Region() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 iter->_worklist.member(ctrl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // We weren't able to find any opportunities but the region this
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // lock is control dependent on hasn't been processed yet so put
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // this lock back on the worklist so we can check again once any
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // region simplification has occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 iter->_worklist.push(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1649
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1652
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 //=============================================================================
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1654 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
1655 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
1656 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
1657 if (stk_slot <= 0)
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1658 return false; // External lock or it is not Box (Phi node).
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1659
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1660 // Ignore complex cases: merged locks or multiple locks.
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1661 Node* obj = obj_node();
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1662 LockNode* unique_lock = NULL;
4790
b0ff910edfc9 7128355: assert(!nocreate) failed: Cannot build a phi for a block already parsed
kvn
parents: 4778
diff changeset
1663 if (!box->is_simple_lock_region(&unique_lock, obj) ||
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1664 (unique_lock != this)) {
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1665 return false;
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1666 }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1667
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1668 // Look for external lock for the same object.
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1669 SafePointNode* sfn = this->as_SafePoint();
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1670 JVMState* youngest_jvms = sfn->jvms();
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1671 int max_depth = youngest_jvms->depth();
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1672 for (int depth = 1; depth <= max_depth; depth++) {
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1673 JVMState* jvms = youngest_jvms->of_depth(depth);
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1674 int num_mon = jvms->nof_monitors();
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1675 // Loop over monitors
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1676 for (int idx = 0; idx < num_mon; idx++) {
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1677 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
1678 BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock();
4778
35acf8f0a2e4 7128352: assert(obj_node == obj) failed
kvn
parents: 4777
diff changeset
1679 if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) {
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1680 return true;
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1681 }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1682 }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1683 }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1684 return false;
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1685 }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1686
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1687 //=============================================================================
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 uint UnlockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1689
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1693 // perform any generic optimizations first (returns 'this' or NULL)
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1694 Node *result = SafePointNode::Ideal(phase, can_reshape);
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1695 if (result != NULL) return result;
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1696 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1697 if (in(0) && in(0)->is_top()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // Now see if we can optimize away this unlock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // remove the unlocking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // prevents macro expansion from expanding the unlock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // one computed above.
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1704 // Escape state is defined after Parse phase.
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1705 if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 //
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1707 // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 //
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1709 ConnectionGraph *cgr = phase->C->congraph();
5948
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4790
diff changeset
1710 if (cgr != NULL && cgr->not_global_escape(obj_node())) {
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1711 assert(!is_eliminated() || is_coarsened(), "sanity");
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1712 // The lock could be marked eliminated by lock coarsening
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1713 // code during first IGVN before EA. Replace coarsened flag
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1714 // to eliminate all associated locks/unlocks.
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4115
diff changeset
1715 this->set_non_esc_obj();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 }