annotate src/share/vm/opto/callnode.cpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents 1bd45abaa507
children e9a5e0a812c8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1634
diff changeset
2 * Copyright (c) 1997, 2010, 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:
a61af66fc99e Initial load
duke
parents:
diff changeset
75 return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 case TypeFunc::FramePtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return new (match->C, 1) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return new (match->C, 1) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP);
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
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return new (match->C, 1) ConNode(Type::TOP);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 uint ideal_reg = Matcher::base2reg[t->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
87 RegMask &rm = match->_calling_convention_mask[parm_num];
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
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);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 return Matcher::base2reg[t->base()];
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 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
234 JVMState::JVMState(ciMethod* method, JVMState* caller) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 assert(method != NULL, "must be valid call site");
a61af66fc99e Initial load
duke
parents:
diff changeset
236 _method = method;
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 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 JVMState::JVMState(int stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _method = NULL;
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::KlassPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
348 case Type::InstPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
349 st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
350 break;
331
cecd8eb4e0ca 6706829: Compressed Oops: add debug info for narrow oops
kvn
parents: 305
diff changeset
351 case Type::NarrowOop:
cecd8eb4e0ca 6706829: Compressed Oops: add debug info for narrow oops
kvn
parents: 305
diff changeset
352 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
353 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
354 case Type::RawPtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
355 st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
356 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 case Type::DoubleCon:
a61af66fc99e Initial load
duke
parents:
diff changeset
358 st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 case Type::FloatCon:
a61af66fc99e Initial load
duke
parents:
diff changeset
361 st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 case Type::Long:
a61af66fc99e Initial load
duke
parents:
diff changeset
364 st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con());
a61af66fc99e Initial load
duke
parents:
diff changeset
365 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 case Type::Half:
a61af66fc99e Initial load
duke
parents:
diff changeset
367 case Type::Top:
a61af66fc99e Initial load
duke
parents:
diff changeset
368 st->print(" %s%d]=_",msg,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 //------------------------------format-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
376 void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 st->print(" #");
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if( _method ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
380 st->print(" @ bci:%d ",_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
381 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 st->print_cr(" runtime stub ");
a61af66fc99e Initial load
duke
parents:
diff changeset
383 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385 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
386 GrowableArray<SafePointScalarObjectNode*> scobjs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387 MachSafePointNode *mcall = n->as_MachSafePoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
388 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // Print locals
a61af66fc99e Initial load
duke
parents:
diff changeset
390 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
391 format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // Print stack
a61af66fc99e Initial load
duke
parents:
diff changeset
393 for (i = 0; i < (uint)stk_size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 if ((uint)(_stkoff + i) >= mcall->len())
a61af66fc99e Initial load
duke
parents:
diff changeset
395 st->print(" oob ");
a61af66fc99e Initial load
duke
parents:
diff changeset
396 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
397 format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399 for (i = 0; (int)i < nof_monitors(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 Node *box = mcall->monitor_box(this, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 Node *obj = mcall->monitor_obj(this, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 while( !box->is_BoxLock() ) box = box->in(1);
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
404 format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 st->print(" MON-BOX%d=%s+%d",
a61af66fc99e Initial load
duke
parents:
diff changeset
408 i,
a61af66fc99e Initial load
duke
parents:
diff changeset
409 OptoReg::regname(OptoReg::c_frame_pointer),
a61af66fc99e Initial load
duke
parents:
diff changeset
410 regalloc->reg2offset(box_reg));
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
412 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
413 if (EliminateLocks) {
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
414 while( !box->is_BoxLock() ) box = box->in(1);
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
415 if (box->as_BoxLock()->is_eliminated())
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
416 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
417 }
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
418 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
419 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
420
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
421 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
422 // 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
423 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
424 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
425 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
426 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
427 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
428 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
429 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
430 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
431 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
432 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
433 } 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
434 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
435 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
436 } 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
437 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
438 if (cie->is_instance_klass()) {
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
439 cie->print_name_on(st);
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
440 } else if (cie->is_type_array_klass()) {
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
441 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
442 } else {
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
443 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
444 }
1040
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
445 st->print("[%d]", spobj->n_fields());
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
446 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
447 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
448 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
449 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
450 }
1040
873ec3787992 6892186: SA does not dump debug info for scalar replaced objects
kvn
parents: 931
diff changeset
451 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
452 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
453 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
454 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
455 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
456 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
457 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
458 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
459 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
460 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
461 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
462 } 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
463 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
464 }
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 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
466 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
467 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
468 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
469 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
470 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
471 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
472 } 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
473 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
474 }
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 }
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 }
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 st->print(" }");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 st->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
481 if (caller() != NULL) caller()->format(regalloc, n, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
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
484
0
a61af66fc99e Initial load
duke
parents:
diff changeset
485 void JVMState::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if (_method != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 bool printed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 if (!Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // The JVMS dumps make really, really long lines.
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Take out the most boring parts, which are the package prefixes.
a61af66fc99e Initial load
duke
parents:
diff changeset
491 char buf[500];
a61af66fc99e Initial load
duke
parents:
diff changeset
492 stringStream namest(buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
493 _method->print_short_name(&namest);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (namest.count() < sizeof(buf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 const char* name = namest.base();
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (name[0] == ' ') ++name;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 const char* endcn = strchr(name, ':'); // end of class name
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (endcn == NULL) endcn = strchr(name, '(');
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (endcn == NULL) endcn = name + strlen(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/')
a61af66fc99e Initial load
duke
parents:
diff changeset
501 --endcn;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 st->print(" %s", endcn);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 printed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (!printed)
a61af66fc99e Initial load
duke
parents:
diff changeset
507 _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
508 st->print(" @ bci:%d",_bci);
931
72088be4b386 6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents: 903
diff changeset
509 if(_reexecute == Reexecute_True)
72088be4b386 6873116: Modify reexecute implementation to use pcDesc to record the reexecute bit
cfang
parents: 903
diff changeset
510 st->print(" reexecute");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
511 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
512 st->print(" runtime stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (caller() != NULL) caller()->dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516
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
517
0
a61af66fc99e Initial load
duke
parents:
diff changeset
518 void JVMState::dump_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 if (_map && !((uintptr_t)_map & 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 if (_map->len() > _map->req()) { // _map->has_exceptions()
a61af66fc99e Initial load
duke
parents:
diff changeset
521 Node* ex = _map->in(_map->req()); // _map->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // skip the first one; it's already being printed
a61af66fc99e Initial load
duke
parents:
diff changeset
523 while (ex != NULL && ex->len() > ex->req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 ex = ex->in(ex->req()); // ex->next_exception()
a61af66fc99e Initial load
duke
parents:
diff changeset
525 ex->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528 _map->dump(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
530 st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=",
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
531 depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (_method == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 st->print_cr("(none)");
a61af66fc99e Initial load
duke
parents:
diff changeset
534 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 _method->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (bci() >= 0 && bci() < _method->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 st->print(" bc: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
539 _method->print_codes_on(bci(), bci()+1, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (caller() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 caller()->dump_on(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
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Extra way to dump a jvms from the debugger,
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // to avoid a bug with C++ member function calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
549 void dump_jvms(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 jvms->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 //--------------------------clone_shallow--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
555 JVMState* JVMState::clone_shallow(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 JVMState* n = has_method() ? new (C) JVMState(_method, _caller) : new (C) JVMState(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
557 n->set_bci(_bci);
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
558 n->_reexecute = _reexecute;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
559 n->set_locoff(_locoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 n->set_stkoff(_stkoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 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
562 n->set_scloff(_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
563 n->set_endoff(_endoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 n->set_sp(_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 n->set_map(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 //---------------------------clone_deep----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
570 JVMState* JVMState::clone_deep(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 JVMState* n = clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 for (JVMState* p = n; p->_caller != NULL; p = p->_caller) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 p->_caller = p->_caller->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575 assert(n->depth() == depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
576 assert(n->debug_depth() == debug_depth(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
577 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
581 uint CallNode::cmp( const Node &n ) const
a61af66fc99e Initial load
duke
parents:
diff changeset
582 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
584 void CallNode::dump_req() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Dump the required inputs, enclosed in '(' and ')'
a61af66fc99e Initial load
duke
parents:
diff changeset
586 uint i; // Exit value of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
587 for( i=0; i<req(); i++ ) { // For all required inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if( i == TypeFunc::Parms ) tty->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
589 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
590 else tty->print("_ ");
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592 tty->print(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595 void CallNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
597 tf()->dump_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
598 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (jvms() != NULL) jvms()->dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 const Type *CallNode::bottom_type() const { return tf()->range(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
604 const Type *CallNode::Value(PhaseTransform *phase) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (phase->type(in(0)) == Type::TOP) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 return tf()->range();
a61af66fc99e Initial load
duke
parents:
diff changeset
607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
610 void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // Use the standard compiler calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
612 Matcher::calling_convention( sig_bt, parm_regs, argcnt, true );
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 //------------------------------match------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // Construct projections for control, I/O, memory-fields, ..., and
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // return result(s) along with their RegMask info
a61af66fc99e Initial load
duke
parents:
diff changeset
619 Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 switch (proj->_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 case TypeFunc::Control:
a61af66fc99e Initial load
duke
parents:
diff changeset
622 case TypeFunc::I_O:
a61af66fc99e Initial load
duke
parents:
diff changeset
623 case TypeFunc::Memory:
a61af66fc99e Initial load
duke
parents:
diff changeset
624 return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 case TypeFunc::Parms+1: // For LONG & DOUBLE returns
a61af66fc99e Initial load
duke
parents:
diff changeset
627 assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // 2nd half of doubles and longs
a61af66fc99e Initial load
duke
parents:
diff changeset
629 return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 case TypeFunc::Parms: { // Normal returns
a61af66fc99e Initial load
duke
parents:
diff changeset
632 uint ideal_reg = Matcher::base2reg[tf()->range()->field_at(TypeFunc::Parms)->base()];
a61af66fc99e Initial load
duke
parents:
diff changeset
633 OptoRegPair regs = is_CallRuntime()
a61af66fc99e Initial load
duke
parents:
diff changeset
634 ? match->c_return_value(ideal_reg,true) // Calls into C runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
635 : match-> return_value(ideal_reg,true); // Calls into compiled Java code
a61af66fc99e Initial load
duke
parents:
diff changeset
636 RegMask rm = RegMask(regs.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
637 if( OptoReg::is_valid(regs.second()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
638 rm.Insert( regs.second() );
a61af66fc99e Initial load
duke
parents:
diff changeset
639 return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
643 case TypeFunc::FramePtr:
a61af66fc99e Initial load
duke
parents:
diff changeset
644 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
645 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
651 uint CallNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
655 //
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 66
diff changeset
656 // 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
657 // instance at the specified offset.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
658 //
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
659 bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
660 const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
661
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
662 // 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
663 // Note: currently this method is called only for instance types.
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
664 if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
665 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
666 }
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
667 // The instance_id is set only for scalar-replaceable allocations which
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 235
diff changeset
668 // are not passed as arguments according to Escape Analysis.
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
669 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
670 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
671
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
672 // 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
673 bool CallNode::has_non_debug_use(Node *n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
674 const TypeTuple * d = tf()->domain();
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
675 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
676 Node *arg = in(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
677 if (arg == n) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
678 return true;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
679 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
680 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
681 return false;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
682 }
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 // Returns the unique CheckCastPP of a call
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
685 // or 'this' if there are several CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
686 // or returns NULL if there is no one.
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
687 Node *CallNode::result_cast() {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
688 Node *cast = NULL;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
689
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
690 Node *p = proj_out(TypeFunc::Parms);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
691 if (p == NULL)
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
692 return 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 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
695 Node *use = p->fast_out(i);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
696 if (use->is_CheckCastPP()) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
697 if (cast != NULL) {
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
698 return this; // more than 1 CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
699 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
700 cast = use;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
701 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
702 }
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
703 return cast;
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
704 }
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
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
707 void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
708 projs->fallthrough_proj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
709 projs->fallthrough_catchproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
710 projs->fallthrough_ioproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
711 projs->catchall_ioproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
712 projs->catchall_catchproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
713 projs->fallthrough_memproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
714 projs->catchall_memproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
715 projs->resproj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
716 projs->exobj = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
717
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
718 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
719 ProjNode *pn = fast_out(i)->as_Proj();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
720 if (pn->outcnt() == 0) continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
721 switch (pn->_con) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
722 case TypeFunc::Control:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
723 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
724 // 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
725 projs->fallthrough_proj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
726 DUIterator_Fast jmax, j = pn->fast_outs(jmax);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
727 const Node *cn = pn->fast_out(j);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
728 if (cn->is_Catch()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
729 ProjNode *cpn = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
730 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
731 cpn = cn->fast_out(k)->as_Proj();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
732 assert(cpn->is_CatchProj(), "must be a CatchProjNode");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
733 if (cpn->_con == CatchProjNode::fall_through_index)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
734 projs->fallthrough_catchproj = cpn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
735 else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
736 assert(cpn->_con == CatchProjNode::catch_all_index, "must be correct index.");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
737 projs->catchall_catchproj = cpn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
738 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
739 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
740 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
741 break;
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 case TypeFunc::I_O:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
744 if (pn->_is_io_use)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
745 projs->catchall_ioproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
746 else
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
747 projs->fallthrough_ioproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
748 for (DUIterator j = pn->outs(); pn->has_out(j); j++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
749 Node* e = pn->out(j);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
750 if (e->Opcode() == Op_CreateEx && e->in(0)->is_CatchProj()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
751 assert(projs->exobj == NULL, "only one");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
752 projs->exobj = e;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
753 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
754 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
755 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
756 case TypeFunc::Memory:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
757 if (pn->_is_io_use)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
758 projs->catchall_memproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
759 else
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
760 projs->fallthrough_memproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
761 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
762 case TypeFunc::Parms:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
763 projs->resproj = pn;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
764 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
765 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
766 assert(false, "unexpected projection from allocation node.");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
767 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
768 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
769
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
770 // The resproj may not exist because the result couuld be ignored
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
771 // and the exception object may not exist if an exception handler
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
772 // 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
773 assert(projs->fallthrough_proj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
774 assert(projs->fallthrough_catchproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
775 assert(projs->fallthrough_memproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
776 assert(projs->fallthrough_ioproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
777 assert(projs->catchall_catchproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
778 if (separate_io_proj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
779 assert(projs->catchall_memproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
780 assert(projs->catchall_ioproj != NULL, "must be found");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
781 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
782 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
783
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1040
diff changeset
784
0
a61af66fc99e Initial load
duke
parents:
diff changeset
785 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
786 uint CallJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
787 uint CallJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 CallJavaNode &call = (CallJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 return CallNode::cmp(call) && _method == call._method;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
792 void CallJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if( _method ) _method->print_short_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
799 uint CallStaticJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 uint CallStaticJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
801 CallStaticJavaNode &call = (CallStaticJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 //----------------------------uncommon_trap_request----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // If this is an uncommon trap, return the request code, else zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
807 int CallStaticJavaNode::uncommon_trap_request() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (_name != NULL && !strcmp(_name, "uncommon_trap")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 return extract_uncommon_trap_request(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
813 int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
814 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
815 if (!(call->req() > TypeFunc::Parms &&
a61af66fc99e Initial load
duke
parents:
diff changeset
816 call->in(TypeFunc::Parms) != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
817 call->in(TypeFunc::Parms)->is_Con())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 assert(_in_dump_cnt != 0, "OK if dumping");
a61af66fc99e Initial load
duke
parents:
diff changeset
819 tty->print("[bad uncommon trap]");
a61af66fc99e Initial load
duke
parents:
diff changeset
820 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
823 return call->in(TypeFunc::Parms)->bottom_type()->is_int()->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
827 void CallStaticJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
828 st->print("# Static ");
a61af66fc99e Initial load
duke
parents:
diff changeset
829 if (_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 st->print("%s", _name);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 int trap_req = uncommon_trap_request();
a61af66fc99e Initial load
duke
parents:
diff changeset
832 if (trap_req != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
833 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
834 st->print("(%s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
835 Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
836 trap_req));
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
845 uint CallDynamicJavaNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
846 uint CallDynamicJavaNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 CallDynamicJavaNode &call = (CallDynamicJavaNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 return CallJavaNode::cmp(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
850 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
851 void CallDynamicJavaNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 st->print("# Dynamic ");
a61af66fc99e Initial load
duke
parents:
diff changeset
853 CallJavaNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
858 uint CallRuntimeNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
859 uint CallRuntimeNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 CallRuntimeNode &call = (CallRuntimeNode&)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 return CallNode::cmp(call) && !strcmp(_name,call._name);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
864 void CallRuntimeNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
866 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
867 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871 //------------------------------calling_convention-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
872 void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Matcher::c_calling_convention( sig_bt, parm_regs, argcnt );
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
877 //------------------------------calling_convention-----------------------------
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 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
882 void CallLeafNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 st->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
884 st->print(_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 CallNode::dump_spec(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
893 int loc = jvms->locoff() + idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (in(loc)->is_top() && idx > 0 && !c->is_top() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // If current local idx is top then local idx - 1 could
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // be a long/double that needs to be killed since top could
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // represent the 2nd half ofthe long/double.
a61af66fc99e Initial load
duke
parents:
diff changeset
898 uint ideal = in(loc -1)->ideal_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 if (ideal == Op_RegD || ideal == Op_RegL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // set other (low index) half to top
a61af66fc99e Initial load
duke
parents:
diff changeset
901 set_req(loc - 1, in(loc));
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904 set_req(loc, c);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 uint SafePointNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
908 uint SafePointNode::cmp( const Node &n ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 return (&n == this); // Always fail except on self
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 //-------------------------set_next_exception----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
913 void SafePointNode::set_next_exception(SafePointNode* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 assert(n == NULL || n->Opcode() == Op_SafePoint, "correct value for next_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
915 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 if (n != NULL) add_prec(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 set_prec(req(), n);
a61af66fc99e Initial load
duke
parents:
diff changeset
919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922
a61af66fc99e Initial load
duke
parents:
diff changeset
923 //----------------------------next_exception-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
924 SafePointNode* SafePointNode::next_exception() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (len() == req()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 Node* n = in(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
929 assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges");
a61af66fc99e Initial load
duke
parents:
diff changeset
930 return (SafePointNode*) n;
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 //------------------------------Ideal------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // Skip over any collapsed Regions
a61af66fc99e Initial load
duke
parents:
diff changeset
937 Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) {
305
ab075d07f1ba 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 247
diff changeset
938 return remove_dead_region(phase, can_reshape) ? this : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 //------------------------------Identity---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // Remove obviously duplicate safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
943 Node *SafePointNode::Identity( PhaseTransform *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // If you have back to back safepoints, remove one
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if( in(TypeFunc::Control)->is_SafePoint() )
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if( in(0)->is_Proj() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 Node *n0 = in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Check if he is a call projection (except Leaf Call)
a61af66fc99e Initial load
duke
parents:
diff changeset
952 if( n0->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 n0 = n0->in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 assert( n0->is_Call(), "expect a call here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Useless Safepoint, so remove it
a61af66fc99e Initial load
duke
parents:
diff changeset
958 return in(TypeFunc::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return this;
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 //------------------------------Value------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
966 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
a61af66fc99e Initial load
duke
parents:
diff changeset
969 return Type::CONTROL;
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
973 void SafePointNode::dump_spec(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 st->print(" SafePoint ");
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 const RegMask &SafePointNode::in_RegMask(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
979 if( idx < TypeFunc::Parms ) return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // Values outside the domain represent debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
981 return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 const RegMask &SafePointNode::out_RegMask() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 return RegMask::Empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 assert((int)grow_by > 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
990 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
991 int scloff = jvms->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
992 int endoff = jvms->endoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
993 assert(endoff == (int)req(), "no other states or debug info after me");
a61af66fc99e Initial load
duke
parents:
diff changeset
994 Node* top = Compile::current()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
995 for (uint i = 0; i < grow_by; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 ins_req(monoff, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998 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
999 jvms->set_scloff(scloff + grow_by);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 jvms->set_endoff(endoff + grow_by);
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 void SafePointNode::push_monitor(const FastLockNode *lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // Add a LockNode, which points to both the original BoxLockNode (the
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // stack space for the monitor) and the Object being locked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 const int MonitorEdges = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 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
1009 int nextmon = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 if (GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 add_req(lock->box_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 add_req(lock->obj_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 } else {
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1014 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
1015 add_req(top);
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1016 add_req(top);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
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
1018 jvms()->set_scloff(nextmon+MonitorEdges);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 jvms()->set_endoff(req());
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 void SafePointNode::pop_monitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // Delete last monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 debug_only(int num_before_pop = jvms()->nof_monitors());
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 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
1026 int scloff = jvms()->scloff();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 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
1028 int new_scloff = scloff - MonitorEdges;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 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
1030 jvms()->set_scloff(new_scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 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
1032 while (scloff > new_scloff) del_req(--scloff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 assert(jvms()->nof_monitors() == num_before_pop-1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 Node *SafePointNode::peek_monitor_box() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return monitor_box(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 Node *SafePointNode::peek_monitor_obj() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 int mon = jvms()->nof_monitors() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 assert(mon >= 0, "most have a monitor");
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 return monitor_obj(jvms(), mon);
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1047
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // Do we Match on this edge index or not? Match no edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 uint SafePointNode::match_edge(uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 if( !needs_polling_address_input() )
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 return (TypeFunc::Parms == idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
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
1056 //============== 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
1057
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1058 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
1059 #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
1060 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
1061 #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
1062 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
1063 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
1064 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
1065 #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
1066 _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
1067 #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
1068 _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
1069 _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
1070 {
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 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
1072 }
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
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1074 // Do not allow value-numbering for SafePointScalarObject node.
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1075 uint SafePointScalarObjectNode::hash() const { return NO_HASH; }
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1076 uint SafePointScalarObjectNode::cmp( const Node &n ) const {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1077 return (&n == this); // Always fail except on self
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1078 }
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
1079
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1080 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
1081 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
1082 }
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 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
1085 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
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::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
1089 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
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 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
1093 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
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 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
1097 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
1098 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
1099 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
1100 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
1101 }
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1102 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
1103 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
1104 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
1105 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
1106 }
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
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1108
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
1109 #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
1110 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
1111 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
1112 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
1113 }
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
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 #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
1116
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 uint AllocateNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 Node *ctrl, Node *mem, Node *abio,
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 Node *size, Node *klass_node, Node *initial_test)
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 : CallNode(atype, NULL, TypeRawPtr::BOTTOM)
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 init_class_id(Class_Allocate);
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 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
1127 _is_scalar_replaceable = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 Node *topnode = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 init_req( TypeFunc::Control , ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 init_req( TypeFunc::I_O , abio );
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 init_req( TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 init_req( TypeFunc::ReturnAdr, topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 init_req( TypeFunc::FramePtr , topnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 init_req( AllocSize , size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 init_req( KlassNode , klass_node);
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 init_req( InitialTest , initial_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 init_req( ALength , topnode);
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 C->add_macro_node(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 uint AllocateArrayNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
704
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1145 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
1146 if (remove_dead_region(phase, can_reshape)) return this;
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1147 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1148 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
1149
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1150 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
1151 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
1152 if (can_reshape) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1153 PhaseIterGVN *igvn = phase->is_IterGVN();
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1154 // 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
1155 // 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
1156 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
1157 Node* catchproj = NULL;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1158 if (proj != NULL) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1159 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
1160 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
1161 if (cn->is_Catch()) {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1162 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
1163 break;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1164 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1165 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1166 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1167 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
1168 (catchproj->outcnt() > 1 ||
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1169 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
1170 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
1171 Node* nproj = catchproj->clone();
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1172 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
1173
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1174 Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr );
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1175 frame = phase->transform(frame);
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1176 // Halt & Catch Fire
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1177 Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame );
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1178 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
1179 phase->transform(halt);
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1180
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1181 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
1182 return this;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1183 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1184 } else {
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1185 // 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
1186 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
1187 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1188 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1189 return NULL;
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1190 }
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
1191
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1192 // 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
1193 // 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
1194 // 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
1195 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
1196 Node *length = in(AllocateNode::ALength);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1197 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
1198
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1199 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
1200 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
1201
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1202 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
1203 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
1204 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
1205 // Assert one of:
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1206 // - the narrow_length is 0
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1207 // - 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
1208 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
1209 (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
1210 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
1211 "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
1212
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1213 // 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
1214 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
1215 // 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
1216 // propagate the fact that the array length must be positive.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1217 length = new (phase->C, 2) CastIINode(length, narrow_length_type);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1218 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
1219 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1220 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1221
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 331
diff changeset
1222 return length;
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
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 uint LockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // Redundant lock elimination
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // There are various patterns of locking where we release and
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // immediately reacquire a lock in a piece of code where no operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // occur in between that would be observable. In those cases we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // skip releasing and reacquiring the lock without violating any
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // fairness requirements. Doing this around a loop could cause a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // to be held for a very long time so we concentrate on non-looping
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // control flow. We also require that the operations are fully
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // redundant meaning that we don't introduce new lock operations on
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // some paths so to be able to eliminate it on others ala PRE. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // would probably require some more extensive graph manipulation to
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // guarantee that the memory edges were all handled correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // Assuming p is a simple predicate which can't trap in any way and s
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // is a synchronized method consider this code:
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 // 1. The unlocks of the first call to s can be eliminated if the
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 // locks inside the then and else branches are eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // 2. The unlocks of the then and else branches can be eliminated if
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // the lock of the final call to s is eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // Either of these cases subsumes the simple case of sequential control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Addtionally we can eliminate versions without the else case:
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // 3. In this case we eliminate the unlock of the first s, the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 // and unlock in the then case and the lock in the final s.
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // Note also that in all these cases the then/else pieces don't have
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // to be trivial as long as they begin and end with synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // f();
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // The code will work properly for this case, leaving in the unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // before the call to f and the relock after it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // A potentially interesting case which isn't handled here is when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // locking is partially redundant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // if (p)
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // s();
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // This could be eliminated putting unlocking on the else case and
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // eliminating the first unlock and the lock in the then side.
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // Alternatively the unlock could be moved out of the then side so it
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // was after the merge and the first unlock and second lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // eliminated. This might require less manipulation of the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // state to get correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // Additionally we might allow work between a unlock and lock before
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // giving up eliminating the locks. The current code disallows any
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // conditional control flow between these operations. A formulation
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // similar to partial redundancy elimination computing the
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // availability of unlocking and the anticipatability of locking at a
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // program point would allow detection of fully redundant locking with
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // some amount of work in between. I'm not sure how often I really
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // think that would occur though. Most of the cases I've seen
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // indicate it's likely non-trivial work would occur in between.
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // There may be other more complicated constructs where we could
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // eliminate locking but I haven't seen any others appear as hot or
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // interesting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // Locking and unlocking have a canonical form in ideal that looks
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // roughly like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // <obj>
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // | \\------+
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // | BoxLock \
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // | | | \
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // | | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // | | FastLock
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // | | /
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 // Lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // Proj #0
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // |
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 // MembarAcquire
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 // MembarRelease
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 // Unlock
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 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // This code proceeds by processing Lock nodes during PhaseIterGVN
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // and searching back through its control for the proper code
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // patterns. Once it finds a set of lock and unlock operations to
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // eliminate they are marked as eliminatable which causes the
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // expansion of the Lock and Unlock macro nodes to make the operation a NOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // Utility function to skip over uninteresting control nodes. Nodes skipped are:
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // - copy regions. (These may not have been optimized away yet.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // - eliminated locking nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 static Node *next_control(Node *ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 if (ctrl == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 RegionNode *r = ctrl->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 Node *n = r->is_copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 if (n == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 break; // hit a region, return it
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 ctrl = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 } else if (ctrl->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 Node *in0 = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 if (in0->is_AbstractLock() && in0->as_AbstractLock()->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 ctrl = in0->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 break; // found an interesting control
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 return ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // Given a control, see if it's the control projection of an Unlock which
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // operating on the same object as lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 bool AbstractLockNode::find_matching_unlock(const Node* ctrl, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 Node *n = ctrl_proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 if (n != NULL && n->is_Unlock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 UnlockNode *unlock = n->as_Unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 if ((lock->obj_node() == unlock->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 lock_ops.append(unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1399
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // Find the lock matching an unlock. Returns null if a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // or complicated control is encountered first.
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 LockNode *AbstractLockNode::find_matching_lock(UnlockNode* unlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 LockNode *lock_result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // find the matching lock, or an intervening safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 Node *ctrl = next_control(unlock->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 assert(ctrl != NULL, "invalid control graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 assert(!ctrl->is_Start(), "missing lock for unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 if (ctrl->is_top()) break; // dead control path
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if (ctrl->is_Proj()) ctrl = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 if (ctrl->is_SafePoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 break; // found a safepoint (may be the lock we are searching for)
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 } else if (ctrl->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // Check for a simple diamond pattern. Punt on anything more complicated
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 if (ctrl->req() == 3 && ctrl->in(1) != NULL && ctrl->in(2) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 Node *in1 = next_control(ctrl->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 Node *in2 = next_control(ctrl->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 if (((in1->is_IfTrue() && in2->is_IfFalse()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 (in2->is_IfTrue() && in1->is_IfFalse())) && (in1->in(0) == in2->in(0))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 ctrl = next_control(in1->in(0)->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 ctrl = next_control(ctrl->in(0)); // keep searching
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (ctrl->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 LockNode *lock = ctrl->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 if ((lock->obj_node() == unlock->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 (lock->box_node() == unlock->box_node())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 lock_result = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 return lock_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1441
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 // This code corresponds to case 3 above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 bool AbstractLockNode::find_lock_and_unlock_through_if(Node* node, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 Node* if_node = node->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 bool if_true = node->is_IfTrue();
a61af66fc99e Initial load
duke
parents:
diff changeset
1448
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (if_node->is_If() && if_node->outcnt() == 2 && (if_true || node->is_IfFalse())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 Node *lock_ctrl = next_control(if_node->in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 if (find_matching_unlock(lock_ctrl, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 Node* lock1_node = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 ProjNode* proj = if_node->as_If()->proj_out(!if_true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (if_true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 if (proj->is_IfFalse() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 if (proj->is_IfTrue() && proj->outcnt() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 lock1_node = proj->unique_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 if (lock1_node != NULL && lock1_node->is_Lock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 LockNode *lock1 = lock1_node->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 if ((lock->obj_node() == lock1->obj_node()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 lock_ops.append(lock1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1477
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 GrowableArray<AbstractLockNode*> &lock_ops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // check each control merging at this point for a matching unlock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // in(0) should be self edge so skip it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 for (int i = 1; i < (int)region->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 Node *in_node = next_control(region->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 if (in_node != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 if (find_matching_unlock(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 // found a match so keep on checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 } else if (find_lock_and_unlock_through_if(in_node, lock, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1491
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // If we fall through to here then it was some kind of node we
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // don't understand or there wasn't a matching unlock, so give
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // up trying to merge locks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 lock_ops.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // Create a counter which counts the number of times this lock is acquired
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 void AbstractLockNode::create_lock_counter(JVMState* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1511
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 void AbstractLockNode::set_eliminated() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 _eliminate = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 if (_counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // Update the counter to indicate that this lock was eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // The counter update code will stay around even though the
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // optimizer will eliminate the lock operation itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 _counter->set_tag(NamedCounter::EliminatedLockCounter);
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1527 // perform any generic optimizations first (returns 'this' or NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 Node *result = SafePointNode::Ideal(phase, can_reshape);
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1529 if (result != NULL) return result;
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1530 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1531 if (in(0) && in(0)->is_top()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // Now see if we can optimize away this lock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // remove the locking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // prevents macro expansion from expanding the lock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // one computed above.
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1538 if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1539 //
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1540 // 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
1541 //
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1542 ConnectionGraph *cgr = phase->C->congraph();
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1543 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1544 if (cgr != NULL)
1634
60a14ad85270 6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents: 1552
diff changeset
1545 es = cgr->escape_state(obj_node());
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1546 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1547 if (!is_eliminated()) {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1548 // Mark it eliminated to update any counters
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1549 this->set_eliminated();
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1550 } else {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1551 assert(is_coarsened(), "sanity");
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1552 // The lock could be marked eliminated by lock coarsening
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1553 // code during first IGVN before EA. Clear coarsened flag
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1554 // to eliminate all associated locks/unlocks.
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1555 this->clear_coarsened();
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1556 }
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1557 return result;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1558 }
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // Try lock coarsening
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 PhaseIterGVN* iter = phase->is_IterGVN();
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1564 if (iter != NULL && !is_eliminated()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 GrowableArray<AbstractLockNode*> lock_ops;
a61af66fc99e Initial load
duke
parents:
diff changeset
1567
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 Node *ctrl = next_control(in(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // now search back for a matching Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 if (find_matching_unlock(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // found an unlock directly preceding this lock. This is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // case of single unlock directly control dependent on a
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // single lock which is the trivial version of case 1 or 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 } else if (ctrl->is_Region() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 if (find_unlocks_for_region(ctrl->as_Region(), this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // found lock preceded by multiple unlocks along all paths
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // joining at this point which is case 3 in description above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // see if this lock comes from either half of an if and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // predecessors merges unlocks and the other half of the if
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // performs a lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 if (find_lock_and_unlock_through_if(ctrl, this, lock_ops)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // found unlock splitting to an if with locks on both branches.
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 if (lock_ops.length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // add ourselves to the list of locks to be eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 lock_ops.append(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1592
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 if (PrintEliminateLocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 int locks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 int unlocks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 AbstractLockNode* lock = lock_ops.at(i);
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1599 if (lock->Opcode() == Op_Lock)
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1600 locks++;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1601 else
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1602 unlocks++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 lock->dump(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // for each of the identified locks, mark them
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // as eliminatable
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 for (int i = 0; i < lock_ops.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 AbstractLockNode* lock = lock_ops.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // Mark it eliminated to update any counters
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 lock->set_eliminated();
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1618 lock->set_coarsened();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 }
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1620 } else if (ctrl->is_Region() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 iter->_worklist.member(ctrl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // We weren't able to find any opportunities but the region this
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // lock is control dependent on hasn't been processed yet so put
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // this lock back on the worklist so we can check again once any
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // region simplification has occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 iter->_worklist.push(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 uint UnlockNode::size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1636
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1639
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1640 // perform any generic optimizations first (returns 'this' or NULL)
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1641 Node *result = SafePointNode::Ideal(phase, can_reshape);
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1642 if (result != NULL) return result;
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1643 // Don't bother trying to transform a dead node
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1644 if (in(0) && in(0)->is_top()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // Now see if we can optimize away this unlock. We don't actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // remove the unlocking here, we simply set the _eliminate flag which
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // prevents macro expansion from expanding the unlock. Since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // modify the graph, the value returned from this function is the
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // one computed above.
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1651 // Escape state is defined after Parse phase.
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1652 if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 //
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1654 // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 //
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
1656 ConnectionGraph *cgr = phase->C->congraph();
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1657 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1658 if (cgr != NULL)
1634
60a14ad85270 6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents: 1552
diff changeset
1659 es = cgr->escape_state(obj_node());
66
6dbf1a175d6b 6672848: (Escape Analysis) improve lock elimination with EA
kvn
parents: 65
diff changeset
1660 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1661 if (!is_eliminated()) {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1662 // Mark it eliminated to update any counters
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1663 this->set_eliminated();
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1664 } else {
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1665 assert(is_coarsened(), "sanity");
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1666 // The lock could be marked eliminated by lock coarsening
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1667 // code during first IGVN before EA. Clear coarsened flag
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1668 // to eliminate all associated locks/unlocks.
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1669 this->clear_coarsened();
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 1972
diff changeset
1670 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 }