annotate src/share/vm/opto/callnode.cpp @ 6972:bd7a7ce2e264

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