annotate src/share/vm/opto/callnode.hpp @ 9126:bc26f978b0ce

HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly don't use the (wrong) cached value, but ask the runtime on each request. Fixes regression on xml.* benchmarks @ specjvm2008. The problem was: After the constructor of Object was deoptimized due to an assumption violation, it was recompiled again after some time. However, on recompilation, the value of hasFinalizeSubclass for the class was not updated and it was compiled again with a, now wrong, assumption, which then triggers deoptimization again. This was repeated until it hit the recompilation limit (defined by PerMethodRecompilationCutoff), and therefore only executed by the interpreter from now on, causing the performance regression.
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 15 Apr 2013 19:54:58 +0200
parents a7114d3d712e
children 6f3fd5150b67
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
5948
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1137
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1137
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: 1137
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: 1552
diff changeset
25 #ifndef SHARE_VM_OPTO_CALLNODE_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_OPTO_CALLNODE_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/multnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "opto/opcodes.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "opto/phaseX.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "opto/type.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34
0
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 class Chaitin;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 class NamedCounter;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class MultiNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 class SafePointNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class CallNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 class CallJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 class CallStaticJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 class CallDynamicJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 class CallRuntimeNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 class CallLeafNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 class CallLeafNoFPNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 class AllocateNode;
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
51 class AllocateArrayNode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class LockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 class UnlockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 class JVMState;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 class OopMap;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 class State;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 class StartNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 class MachCallNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 class FastLockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 //------------------------------StartNode--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // The method start node
a61af66fc99e Initial load
duke
parents:
diff changeset
63 class StartNode : public MultiNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
66 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
67 const TypeTuple *_domain;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 StartNode( Node *root, const TypeTuple *domain ) : MultiNode(2), _domain(domain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 init_class_id(Class_Start);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 init_req(0,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 init_req(1,root);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 virtual bool pinned() const { return true; };
a61af66fc99e Initial load
duke
parents:
diff changeset
75 virtual const Type *bottom_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 virtual void calling_convention( BasicType* sig_bt, VMRegPair *parm_reg, uint length ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 virtual const RegMask &in_RegMask(uint) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 virtual Node *match( const ProjNode *proj, const Matcher *m );
a61af66fc99e Initial load
duke
parents:
diff changeset
82 virtual uint ideal_reg() const { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
84 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
86 };
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 //------------------------------StartOSRNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // The method start node for on stack replacement code
a61af66fc99e Initial load
duke
parents:
diff changeset
90 class StartOSRNode : public StartNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
92 StartOSRNode( Node *root, const TypeTuple *domain ) : StartNode(root, domain) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
93 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static const TypeTuple *osr_domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 };
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 //------------------------------ParmNode---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Incoming parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
100 class ParmNode : public ProjNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 static const char * const names[TypeFunc::Parms+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
102 public:
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
103 ParmNode( StartNode *src, uint con ) : ProjNode(src,con) {
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
104 init_class_id(Class_Parm);
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
105 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 virtual bool is_CFG() const { return (_con == TypeFunc::Control); }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 virtual uint ideal_reg() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
110 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
112 };
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 //------------------------------ReturnNode-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Return from subroutine node
a61af66fc99e Initial load
duke
parents:
diff changeset
117 class ReturnNode : public Node {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
119 ReturnNode( uint edges, Node *cntrl, Node *i_o, Node *memory, Node *retadr, Node *frameptr );
a61af66fc99e Initial load
duke
parents:
diff changeset
120 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 virtual bool is_CFG() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
a61af66fc99e Initial load
duke
parents:
diff changeset
123 virtual bool depends_only_on_test() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 virtual uint ideal_reg() const { return NotAMachineReg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 #ifndef PRODUCT
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
129 virtual void dump_req(outputStream *st = tty) const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
130 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
131 };
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 //------------------------------RethrowNode------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Rethrow of exception at call site. Ends a procedure before rethrowing;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // ends the current basic block like a ReturnNode. Restores registers and
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // unwinds stack. Rethrow happens in the caller's method.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 class RethrowNode : public Node {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
140 RethrowNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *ret_adr, Node *exception );
a61af66fc99e Initial load
duke
parents:
diff changeset
141 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 virtual bool is_CFG() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
143 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash
a61af66fc99e Initial load
duke
parents:
diff changeset
144 virtual bool depends_only_on_test() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 virtual uint ideal_reg() const { return NotAMachineReg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 #ifndef PRODUCT
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
150 virtual void dump_req(outputStream *st = tty) const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
151 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
152 };
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 //------------------------------TailCallNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Pop stack frame and jump indirect
a61af66fc99e Initial load
duke
parents:
diff changeset
157 class TailCallNode : public ReturnNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
159 TailCallNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr, Node *target, Node *moop )
a61af66fc99e Initial load
duke
parents:
diff changeset
160 : ReturnNode( TypeFunc::Parms+2, cntrl, i_o, memory, frameptr, retadr ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 init_req(TypeFunc::Parms, target);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 init_req(TypeFunc::Parms+1, moop);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 };
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 //------------------------------TailJumpNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Pop stack frame and jump indirect
a61af66fc99e Initial load
duke
parents:
diff changeset
171 class TailJumpNode : public ReturnNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
173 TailJumpNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *target, Node *ex_oop)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 : ReturnNode(TypeFunc::Parms+2, cntrl, i_o, memory, frameptr, Compile::current()->top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 init_req(TypeFunc::Parms, target);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 init_req(TypeFunc::Parms+1, ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 };
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 //-------------------------------JVMState-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // A linked list of JVMState nodes captures the whole interpreter state,
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // plus GC roots, for all active calls at some call site in this compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // unit. (If there is no inlining, then the list has exactly one link.)
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // This provides a way to map the optimized program back into the interpreter,
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // or to let the GC mark the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 class JVMState : public ResourceObj {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3842
diff changeset
190 friend class VMStructs;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
191 public:
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
192 typedef enum {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
193 Reexecute_Undefined = -1, // not defined -- will be translated into false later
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
194 Reexecute_False = 0, // false -- do not reexecute
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
195 Reexecute_True = 1 // true -- reexecute the bytecode
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
196 } ReexecuteState; //Reexecute State
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
197
0
a61af66fc99e Initial load
duke
parents:
diff changeset
198 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
199 JVMState* _caller; // List pointer for forming scope chains
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
200 uint _depth; // One more than caller depth, or one.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 uint _locoff; // Offset to locals in input edge mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
202 uint _stkoff; // Offset to stack in input edge mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
203 uint _monoff; // Offset to monitors in input edge mapping
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
204 uint _scloff; // Offset to fields of scalar objs in input edge mapping
0
a61af66fc99e Initial load
duke
parents:
diff changeset
205 uint _endoff; // Offset to end of input edge mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
206 uint _sp; // Jave Expression Stack Pointer for this state
a61af66fc99e Initial load
duke
parents:
diff changeset
207 int _bci; // Byte Code Index of this JVM point
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
208 ReexecuteState _reexecute; // Whether this bytecode need to be re-executed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
209 ciMethod* _method; // Method Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
210 SafePointNode* _map; // Map node associated with this scope
a61af66fc99e Initial load
duke
parents:
diff changeset
211 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
212 friend class Compile;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
213 friend class PreserveReexecuteState;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Because JVMState objects live over the entire lifetime of the
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // Compile object, they are allocated into the comp_arena, which
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // does not get resource marked or reset during the compile process
a61af66fc99e Initial load
duke
parents:
diff changeset
218 void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 void operator delete( void * ) { } // fast deallocation
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Create a new JVMState, ready for abstract interpretation.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 JVMState(ciMethod* method, JVMState* caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 JVMState(int stack_size); // root state; has a null method
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Access functions for the JVM
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
226 // ... --|--- loc ---|--- stk ---|--- arg ---|--- mon ---|--- scl ---|
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
227 // \ locoff \ stkoff \ argoff \ monoff \ scloff \ endoff
0
a61af66fc99e Initial load
duke
parents:
diff changeset
228 uint locoff() const { return _locoff; }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 uint stkoff() const { return _stkoff; }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 uint argoff() const { return _stkoff + _sp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 uint monoff() const { return _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
232 uint scloff() const { return _scloff; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
233 uint endoff() const { return _endoff; }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 uint oopoff() const { return debug_end(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
236 int loc_size() const { return stkoff() - locoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
237 int stk_size() const { return monoff() - stkoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
238 int arg_size() const { return monoff() - argoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
239 int mon_size() const { return scloff() - monoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
240 int scl_size() const { return endoff() - scloff(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
241
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
242 bool is_loc(uint i) const { return locoff() <= i && i < stkoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
243 bool is_stk(uint i) const { return stkoff() <= i && i < monoff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
244 bool is_mon(uint i) const { return monoff() <= i && i < scloff(); }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5948
diff changeset
245 bool is_scl(uint i) const { return scloff() <= i && i < endoff(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
246
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
247 uint sp() const { return _sp; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
248 int bci() const { return _bci; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
249 bool should_reexecute() const { return _reexecute==Reexecute_True; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
250 bool is_reexecute_undefined() const { return _reexecute==Reexecute_Undefined; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
251 bool has_method() const { return _method != NULL; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
252 ciMethod* method() const { assert(has_method(), ""); return _method; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
253 JVMState* caller() const { return _caller; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
254 SafePointNode* map() const { return _map; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
255 uint depth() const { return _depth; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
256 uint debug_start() const; // returns locoff of root caller
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
257 uint debug_end() const; // returns endoff of self
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
258 uint debug_size() const {
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
259 return loc_size() + sp() + mon_size() + scl_size();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
260 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
261 uint debug_depth() const; // returns sum of debug_size values at all depths
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // Returns the JVM state at the desired depth (1 == root).
a61af66fc99e Initial load
duke
parents:
diff changeset
264 JVMState* of_depth(int d) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Tells if two JVM states have the same call chain (depth, methods, & bcis).
a61af66fc99e Initial load
duke
parents:
diff changeset
267 bool same_calls_as(const JVMState* that) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Monitors (monitors are stored as (boxNode, objNode) pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
270 enum { logMonitorEdges = 1 };
a61af66fc99e Initial load
duke
parents:
diff changeset
271 int nof_monitors() const { return mon_size() >> logMonitorEdges; }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int monitor_depth() const { return nof_monitors() + (caller() ? caller()->monitor_depth() : 0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 int monitor_box_offset(int idx) const { return monoff() + (idx << logMonitorEdges) + 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 int monitor_obj_offset(int idx) const { return monoff() + (idx << logMonitorEdges) + 1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 bool is_monitor_box(uint off) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 assert(is_mon(off), "should be called only for monitor edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
277 return (0 == bitfield(off - monoff(), 0, logMonitorEdges));
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 bool is_monitor_use(uint off) const { return (is_mon(off)
a61af66fc99e Initial load
duke
parents:
diff changeset
280 && is_monitor_box(off))
a61af66fc99e Initial load
duke
parents:
diff changeset
281 || (caller() && caller()->is_monitor_use(off)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Initialization functions for the JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
284 void set_locoff(uint off) { _locoff = off; }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 void set_stkoff(uint off) { _stkoff = off; }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 void set_monoff(uint off) { _monoff = off; }
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
287 void set_scloff(uint off) { _scloff = off; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
288 void set_endoff(uint off) { _endoff = off; }
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
289 void set_offsets(uint off) {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
290 _locoff = _stkoff = _monoff = _scloff = _endoff = off;
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
291 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
292 void set_map(SafePointNode *map) { _map = map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 void set_sp(uint sp) { _sp = sp; }
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
294 // _reexecute is initialized to "undefined" for a new bci
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
295 void set_bci(int bci) {if(_bci != bci)_reexecute=Reexecute_Undefined; _bci = bci; }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 704
diff changeset
296 void set_should_reexecute(bool reexec) {_reexecute = reexec ? Reexecute_True : Reexecute_False;}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Miscellaneous utility functions
a61af66fc99e Initial load
duke
parents:
diff changeset
299 JVMState* clone_deep(Compile* C) const; // recursively clones caller chain
a61af66fc99e Initial load
duke
parents:
diff changeset
300 JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
303 void format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 void dump_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 void dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 dump_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
310 };
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 //------------------------------SafePointNode----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // A SafePointNode is a subclass of a MultiNode for convenience (and
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // potential code sharing) only - conceptually it is independent of
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // the Node semantics.
a61af66fc99e Initial load
duke
parents:
diff changeset
316 class SafePointNode : public MultiNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
321 SafePointNode(uint edges, JVMState* jvms,
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // A plain safepoint advertises no memory effects (NULL):
a61af66fc99e Initial load
duke
parents:
diff changeset
323 const TypePtr* adr_type = NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
324 : MultiNode( edges ),
a61af66fc99e Initial load
duke
parents:
diff changeset
325 _jvms(jvms),
a61af66fc99e Initial load
duke
parents:
diff changeset
326 _oop_map(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
327 _adr_type(adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
328 {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 init_class_id(Class_SafePoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC
a61af66fc99e Initial load
duke
parents:
diff changeset
333 JVMState* const _jvms; // Pointer to list of JVM State objects
a61af66fc99e Initial load
duke
parents:
diff changeset
334 const TypePtr* _adr_type; // What type of memory does this node produce?
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Many calls take *all* of memory as input,
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // but some produce a limited subset of that memory as output.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // The adr_type reports the call's behavior as a store, not a load.
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 virtual JVMState* jvms() const { return _jvms; }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 void set_jvms(JVMState* s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 *(JVMState**)&_jvms = s; // override const attribute in the accessor
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 OopMap *oop_map() const { return _oop_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
345 void set_oop_map(OopMap *om) { _oop_map = om; }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
347 private:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
348 void verify_input(JVMState* jvms, uint idx) const {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
349 assert(verify_jvms(jvms), "jvms must match");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
350 Node* n = in(idx);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
351 assert((!n->bottom_type()->isa_long() && !n->bottom_type()->isa_double()) ||
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
352 in(idx + 1)->is_top(), "2nd half of long/double");
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
353 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
354
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
355 public:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // Functionality from old debug nodes which has changed
a61af66fc99e Initial load
duke
parents:
diff changeset
357 Node *local(JVMState* jvms, uint idx) const {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
358 verify_input(jvms, jvms->locoff() + idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
359 return in(jvms->locoff() + idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 Node *stack(JVMState* jvms, uint idx) const {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
362 verify_input(jvms, jvms->stkoff() + idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return in(jvms->stkoff() + idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 Node *argument(JVMState* jvms, uint idx) const {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6266
diff changeset
366 verify_input(jvms, jvms->argoff() + idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
367 return in(jvms->argoff() + idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 Node *monitor_box(JVMState* jvms, uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
371 return in(jvms->monitor_box_offset(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 Node *monitor_obj(JVMState* jvms, uint idx) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
375 return in(jvms->monitor_obj_offset(idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 void set_local(JVMState* jvms, uint idx, Node *c);
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 void set_stack(JVMState* jvms, uint idx, Node *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
382 set_req(jvms->stkoff() + idx, c);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 void set_argument(JVMState* jvms, uint idx, Node *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
386 set_req(jvms->argoff() + idx, c);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 void ensure_stack(JVMState* jvms, uint stk_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 assert(verify_jvms(jvms), "jvms must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
390 int grow_by = (int)stk_size - (int)jvms->stk_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
391 if (grow_by > 0) grow_stack(jvms, grow_by);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void grow_stack(JVMState* jvms, uint grow_by);
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Handle monitor stack
a61af66fc99e Initial load
duke
parents:
diff changeset
395 void push_monitor( const FastLockNode *lock );
a61af66fc99e Initial load
duke
parents:
diff changeset
396 void pop_monitor ();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 Node *peek_monitor_box() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 Node *peek_monitor_obj() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // Access functions for the JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
401 Node *control () const { return in(TypeFunc::Control ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 Node *i_o () const { return in(TypeFunc::I_O ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 Node *memory () const { return in(TypeFunc::Memory ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
404 Node *returnadr() const { return in(TypeFunc::ReturnAdr); }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 Node *frameptr () const { return in(TypeFunc::FramePtr ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 void set_control ( Node *c ) { set_req(TypeFunc::Control,c); }
a61af66fc99e Initial load
duke
parents:
diff changeset
408 void set_i_o ( Node *c ) { set_req(TypeFunc::I_O ,c); }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 void set_memory ( Node *c ) { set_req(TypeFunc::Memory ,c); }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 MergeMemNode* merged_memory() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 return in(TypeFunc::Memory)->as_MergeMem();
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // The parser marks useless maps as dead when it's done with them:
a61af66fc99e Initial load
duke
parents:
diff changeset
416 bool is_killed() { return in(TypeFunc::Control) == NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Exception states bubbling out of subgraphs such as inlined calls
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // are recorded here. (There might be more than one, hence the "next".)
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // This feature is used only for safepoints which serve as "maps"
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // for JVM states during parsing, intrinsic expansion, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 SafePointNode* next_exception() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 void set_next_exception(SafePointNode* n);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 bool has_exceptions() const { return next_exception() != NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Standard Node stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
427 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 virtual bool pinned() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 virtual const Type *bottom_type() const { return Type::CONTROL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 virtual const TypePtr *adr_type() const { return _adr_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
432 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 virtual Node *Identity( PhaseTransform *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
434 virtual uint ideal_reg() const { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
435 virtual const RegMask &in_RegMask(uint) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
436 virtual const RegMask &out_RegMask() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
437 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 static bool needs_polling_address_input();
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
442 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
444 };
a61af66fc99e Initial load
duke
parents:
diff changeset
445
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
446 //------------------------------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
447 // A SafePointScalarObjectNode represents the state of a scalarized object
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 // at a safepoint.
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 class SafePointScalarObjectNode: public TypeNode {
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
451 uint _first_index; // First input edge index of a SafePoint node where
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 // states of the scalarized object fields are collected.
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 uint _n_fields; // Number of non-static fields of the scalarized object.
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 65
diff changeset
454 DEBUG_ONLY(AllocateNode* _alloc;)
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
455
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
456 virtual uint hash() const ; // { return NO_HASH; }
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
457 virtual uint cmp( const Node &n ) const;
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
458
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
459 public:
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 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
461 #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
462 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
463 #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
464 uint first_index, 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
465 virtual int Opcode() 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
466 virtual uint 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
467 virtual const RegMask &in_RegMask(uint) 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
468 virtual const RegMask &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
469 virtual uint 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
470
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 uint first_index() const { return _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
472 uint n_fields() const { return _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
473
4115
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
474 #ifdef ASSERT
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
475 AllocateNode* alloc() const { return _alloc; }
1bd45abaa507 6890673: Eliminate allocations immediately after EA
kvn
parents: 3939
diff changeset
476 #endif
601
523ded093c31 6809798: SafePointScalarObject node placed into incorrect block during GCM
kvn
parents: 460
diff changeset
477
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
478 virtual uint size_of() const { return sizeof(*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
479
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
480 // Assumes that "this" is an argument to a safepoint node "s", and that
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
481 // "new_call" is being created to correspond to "s". But the difference
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
482 // between the start index of the jvmstates of "new_call" and "s" is
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
483 // "jvms_adj". Produce and return a SafePointScalarObjectNode that
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 // corresponds appropriately to "this" in "new_call". Assumes that
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
485 // "sosn_map" is a map, specific to the translation of "s" to "new_call",
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
486 // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
487 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
488
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
489 #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
490 virtual void 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
491 #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
492 };
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 39
diff changeset
493
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
494
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
495 // Simple container for the outgoing projections of a call. Useful
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
496 // for serious surgery on calls.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
497 class CallProjections : public StackObj {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
498 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
499 Node* fallthrough_proj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
500 Node* fallthrough_catchproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
501 Node* fallthrough_memproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
502 Node* fallthrough_ioproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
503 Node* catchall_catchproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
504 Node* catchall_memproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
505 Node* catchall_ioproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
506 Node* resproj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
507 Node* exobj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
508 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
509
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
510 class CallGenerator;
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
511
0
a61af66fc99e Initial load
duke
parents:
diff changeset
512 //------------------------------CallNode---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Call nodes now subsume the function of debug nodes at callsites, so they
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // contain the functionality of a full scope chain of debug nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 class CallNode : public SafePointNode {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3842
diff changeset
516 friend class VMStructs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
518 const TypeFunc *_tf; // Function type
a61af66fc99e Initial load
duke
parents:
diff changeset
519 address _entry_point; // Address of method being called
a61af66fc99e Initial load
duke
parents:
diff changeset
520 float _cnt; // Estimate of number of times called
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
521 CallGenerator* _generator; // corresponding CallGenerator for some late inline calls
0
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
524 : SafePointNode(tf->domain()->cnt(), NULL, adr_type),
a61af66fc99e Initial load
duke
parents:
diff changeset
525 _tf(tf),
a61af66fc99e Initial load
duke
parents:
diff changeset
526 _entry_point(addr),
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
527 _cnt(COUNT_UNKNOWN),
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
528 _generator(NULL)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 init_class_id(Class_Call);
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
533 const TypeFunc* tf() const { return _tf; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
534 const address entry_point() const { return _entry_point; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
535 const float cnt() const { return _cnt; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
536 CallGenerator* generator() const { return _generator; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
537
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
538 void set_tf(const TypeFunc* tf) { _tf = tf; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
539 void set_entry_point(address p) { _entry_point = p; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
540 void set_cnt(float c) { _cnt = c; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
541 void set_generator(CallGenerator* cg) { _generator = cg; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 virtual const Type *bottom_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 virtual const Type *Value( PhaseTransform *phase ) const;
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7194
diff changeset
545 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
546 virtual Node *Identity( PhaseTransform *phase ) { return this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
547 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 virtual uint size_of() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 virtual void calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 virtual Node *match( const ProjNode *proj, const Matcher *m );
a61af66fc99e Initial load
duke
parents:
diff changeset
551 virtual uint ideal_reg() const { return NotAMachineReg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // Are we guaranteed that this node is a safepoint? Not true for leaf calls and
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // for some macro nodes whose expansion does not have a safepoint on the fast path.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 virtual bool guaranteed_safepoint() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // For macro nodes, the JVMState gets modified during expansion, so when cloning
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // the node the JVMState must be cloned.
a61af66fc99e Initial load
duke
parents:
diff changeset
557 virtual void clone_jvms() { } // default is not to clone
a61af66fc99e Initial load
duke
parents:
diff changeset
558
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
559 // Returns true if the call may modify n
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
560 virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase);
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
561 // Does this node have a use of n other than in debug information?
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 113
diff changeset
562 bool has_non_debug_use(Node *n);
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
563 // Returns the unique CheckCastPP of a call
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
564 // or result projection is there are several CheckCastPP
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
565 // or returns NULL if there is no one.
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
566 Node *result_cast();
5948
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
567 // Does this node returns pointer?
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
568 bool returns_pointer() const {
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
569 const TypeTuple *r = tf()->range();
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
570 return (r->cnt() > TypeFunc::Parms &&
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
571 r->field_at(TypeFunc::Parms)->isa_ptr());
ee138854b3a6 7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents: 4777
diff changeset
572 }
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
573
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
574 // Collect all the interesting edges from a call for use in
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
575 // replacing the call by something else. Used by macro expansion
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
576 // and the late inlining support.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
577 void extract_projections(CallProjections* projs, bool separate_io_proj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
578
0
a61af66fc99e Initial load
duke
parents:
diff changeset
579 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 #ifndef PRODUCT
7636
a7114d3d712e 8005055: pass outputStream to more opto debug routines
kvn
parents: 7473
diff changeset
582 virtual void dump_req(outputStream *st = tty) const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
583 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
585 };
a61af66fc99e Initial load
duke
parents:
diff changeset
586
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 903
diff changeset
587
0
a61af66fc99e Initial load
duke
parents:
diff changeset
588 //------------------------------CallJavaNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // Make a static or dynamic subroutine call node using Java calling
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // convention. (The "Java" calling convention is the compiler's calling
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // convention, as opposed to the interpreter's or that of native C.)
a61af66fc99e Initial load
duke
parents:
diff changeset
592 class CallJavaNode : public CallNode {
3939
f6f3bb0ee072 7088955: add C2 IR support to the SA
never
parents: 3842
diff changeset
593 friend class VMStructs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
594 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
595 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 bool _optimized_virtual;
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
599 bool _method_handle_invoke;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
600 ciMethod* _method; // Method being direct called
a61af66fc99e Initial load
duke
parents:
diff changeset
601 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
602 const int _bci; // Byte Code Index of call byte code
a61af66fc99e Initial load
duke
parents:
diff changeset
603 CallJavaNode(const TypeFunc* tf , address addr, ciMethod* method, int bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
604 : CallNode(tf, addr, TypePtr::BOTTOM),
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
605 _method(method), _bci(bci),
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
606 _optimized_virtual(false),
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
607 _method_handle_invoke(false)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
608 {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 init_class_id(Class_CallJava);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 ciMethod* method() const { return _method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
614 void set_method(ciMethod *m) { _method = m; }
a61af66fc99e Initial load
duke
parents:
diff changeset
615 void set_optimized_virtual(bool f) { _optimized_virtual = f; }
a61af66fc99e Initial load
duke
parents:
diff changeset
616 bool is_optimized_virtual() const { return _optimized_virtual; }
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
617 void set_method_handle_invoke(bool f) { _method_handle_invoke = f; }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
618 bool is_method_handle_invoke() const { return _method_handle_invoke; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
621 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
623 };
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 //------------------------------CallStaticJavaNode-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // Make a direct subroutine call using Java calling convention (for static
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // calls and optimized virtual calls, plus calls to wrappers for run-time
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // routines); generates static stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
629 class CallStaticJavaNode : public CallJavaNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
632 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
633 CallStaticJavaNode(const TypeFunc* tf, address addr, ciMethod* method, int bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
634 : CallJavaNode(tf, addr, method, bci), _name(NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 init_class_id(Class_CallStaticJava);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637 CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
638 const TypePtr* adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
639 : CallJavaNode(tf, addr, NULL, bci), _name(name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 init_class_id(Class_CallStaticJava);
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // This node calls a runtime stub, which often has narrow memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 _adr_type = adr_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 const char *_name; // Runtime wrapper name
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // If this is an uncommon trap, return the request code, else zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
647 int uncommon_trap_request() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 static int extract_uncommon_trap_request(const Node* call);
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
651 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
652 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
654 };
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 //------------------------------CallDynamicJavaNode----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // Make a dispatched call using Java calling convention.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 class CallDynamicJavaNode : public CallJavaNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
661 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
662 CallDynamicJavaNode( const TypeFunc *tf , address addr, ciMethod* method, int vtable_index, int bci ) : CallJavaNode(tf,addr,method,bci), _vtable_index(vtable_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 init_class_id(Class_CallDynamicJava);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 int _vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
667 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
669 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
671 };
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 //------------------------------CallRuntimeNode--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // Make a direct subroutine call node into compiled C++ code.
a61af66fc99e Initial load
duke
parents:
diff changeset
675 class CallRuntimeNode : public CallNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
678 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
679 CallRuntimeNode(const TypeFunc* tf, address addr, const char* name,
a61af66fc99e Initial load
duke
parents:
diff changeset
680 const TypePtr* adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
681 : CallNode(tf, addr, adr_type),
a61af66fc99e Initial load
duke
parents:
diff changeset
682 _name(name)
a61af66fc99e Initial load
duke
parents:
diff changeset
683 {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 init_class_id(Class_CallRuntime);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 const char *_name; // Printable name, if _method is NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
688 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 virtual void calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
692 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
694 };
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 //------------------------------CallLeafNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // Make a direct subroutine call node into compiled C++ code, without
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
699 class CallLeafNode : public CallRuntimeNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
701 CallLeafNode(const TypeFunc* tf, address addr, const char* name,
a61af66fc99e Initial load
duke
parents:
diff changeset
702 const TypePtr* adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
703 : CallRuntimeNode(tf, addr, name, adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
704 {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 init_class_id(Class_CallLeaf);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 virtual bool guaranteed_safepoint() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
709 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
710 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
711 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
712 };
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 //------------------------------CallLeafNoFPNode-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // CallLeafNode, not using floating point or using it in the same manner as
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // the generated code
a61af66fc99e Initial load
duke
parents:
diff changeset
717 class CallLeafNoFPNode : public CallLeafNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
718 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
719 CallLeafNoFPNode(const TypeFunc* tf, address addr, const char* name,
a61af66fc99e Initial load
duke
parents:
diff changeset
720 const TypePtr* adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
721 : CallLeafNode(tf, addr, name, adr_type)
a61af66fc99e Initial load
duke
parents:
diff changeset
722 {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 };
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 //------------------------------Allocate---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // High-level memory allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
730 //
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // AllocateNode and AllocateArrayNode are subclasses of CallNode because they will
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // get expanded into a code sequence containing a call. Unlike other CallNodes,
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // they have 2 memory projections and 2 i_o projections (which are distinguished by
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // the _is_io_use flag in the projection.) This is needed when expanding the node in
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // order to differentiate the uses of the projection on the normal control path from
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // those on the exception return path.
a61af66fc99e Initial load
duke
parents:
diff changeset
737 //
a61af66fc99e Initial load
duke
parents:
diff changeset
738 class AllocateNode : public CallNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
740 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
742 RawAddress = TypeFunc::Parms, // the newly-allocated raw address
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
744 AllocSize = TypeFunc::Parms, // size (in bytes) of the new object
a61af66fc99e Initial load
duke
parents:
diff changeset
745 KlassNode, // type (maybe dynamic) of the obj.
a61af66fc99e Initial load
duke
parents:
diff changeset
746 InitialTest, // slow-path test (may be constant)
a61af66fc99e Initial load
duke
parents:
diff changeset
747 ALength, // array length (or TOP if none)
a61af66fc99e Initial load
duke
parents:
diff changeset
748 ParmLimit
a61af66fc99e Initial load
duke
parents:
diff changeset
749 };
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 static const TypeFunc* alloc_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
753 fields[AllocSize] = TypeInt::POS;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 fields[KlassNode] = TypeInstPtr::NOTNULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 fields[InitialTest] = TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 fields[ALength] = TypeInt::INT; // length (can be a bad length)
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 const TypeTuple *domain = TypeTuple::make(ParmLimit, fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
759
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // create result type (range)
a61af66fc99e Initial load
duke
parents:
diff changeset
761 fields = TypeTuple::fields(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 return TypeFunc::make(domain, range);
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768
39
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 33
diff changeset
769 bool _is_scalar_replaceable; // Result of Escape Analysis
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 33
diff changeset
770
0
a61af66fc99e Initial load
duke
parents:
diff changeset
771 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
772 AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
a61af66fc99e Initial load
duke
parents:
diff changeset
773 Node *size, Node *klass_node, Node *initial_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // Expansion modifies the JVMState, so we need to clone it
a61af66fc99e Initial load
duke
parents:
diff changeset
775 virtual void clone_jvms() {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 set_jvms(jvms()->clone_deep(Compile::current()));
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
779 virtual uint ideal_reg() const { return Op_RegP; }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 virtual bool guaranteed_safepoint() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
781
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
782 // allocations do not modify their arguments
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
783 virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase) { return false;}
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
784
0
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // Pattern-match a possible usage of AllocateNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Return null if no allocation is recognized.
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // The operand is the pointer produced by the (possible) allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // It must be a projection of the Allocate or its subsequent CastPP.
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // (Note: This function is defined in file graphKit.cpp, near
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // GraphKit::new_instance/new_array, whose output it recognizes.)
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // The 'ptr' may not have an offset unless the 'offset' argument is given.
a61af66fc99e Initial load
duke
parents:
diff changeset
792 static AllocateNode* Ideal_allocation(Node* ptr, PhaseTransform* phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // Fancy version which uses AddPNode::Ideal_base_and_offset to strip
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // an offset, which is reported back to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // (Note: AllocateNode::Ideal_allocation is defined in graphKit.cpp.)
a61af66fc99e Initial load
duke
parents:
diff changeset
797 static AllocateNode* Ideal_allocation(Node* ptr, PhaseTransform* phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
798 intptr_t& offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // Dig the klass operand out of a (possible) allocation site.
a61af66fc99e Initial load
duke
parents:
diff changeset
801 static Node* Ideal_klass(Node* ptr, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 AllocateNode* allo = Ideal_allocation(ptr, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 return (allo == NULL) ? NULL : allo->in(KlassNode);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // Conservatively small estimate of offset of first non-header byte.
a61af66fc99e Initial load
duke
parents:
diff changeset
807 int minimum_header_size() {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 74
diff changeset
808 return is_AllocateArray() ? arrayOopDesc::base_offset_in_bytes(T_BYTE) :
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 74
diff changeset
809 instanceOopDesc::base_offset_in_bytes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // Return the corresponding initialization barrier (or null if none).
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // Walks out edges to find it...
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // (Note: Both InitializeNode::allocation and AllocateNode::initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // are defined in graphKit.cpp, which sets up the bidirectional relation.)
a61af66fc99e Initial load
duke
parents:
diff changeset
816 InitializeNode* initialization();
a61af66fc99e Initial load
duke
parents:
diff changeset
817
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4115
diff changeset
818 // Return the corresponding storestore barrier (or null if none).
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4115
diff changeset
819 // Walks out edges to find it...
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4115
diff changeset
820 MemBarStoreStoreNode* storestore();
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4115
diff changeset
821
0
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // Convenience for initialization->maybe_set_complete(phase)
a61af66fc99e Initial load
duke
parents:
diff changeset
823 bool maybe_set_complete(PhaseGVN* phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
824 };
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 //------------------------------AllocateArray---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
827 //
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // High-level array allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
829 //
a61af66fc99e Initial load
duke
parents:
diff changeset
830 class AllocateArrayNode : public AllocateNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
832 AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
a61af66fc99e Initial load
duke
parents:
diff changeset
833 Node* size, Node* klass_node, Node* initial_test,
a61af66fc99e Initial load
duke
parents:
diff changeset
834 Node* count_val
a61af66fc99e Initial load
duke
parents:
diff changeset
835 )
a61af66fc99e Initial load
duke
parents:
diff changeset
836 : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node,
a61af66fc99e Initial load
duke
parents:
diff changeset
837 initial_test)
a61af66fc99e Initial load
duke
parents:
diff changeset
838 {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 init_class_id(Class_AllocateArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
840 set_req(AllocateNode::ALength, count_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
843 virtual uint size_of() const; // Size is bigger
704
ad8c635e757e 6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
kvn
parents: 601
diff changeset
844 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
845
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
846 // Dig the length operand out of a array allocation site.
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
847 Node* Ideal_length() {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
848 return in(AllocateNode::ALength);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
849 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
850
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
851 // Dig the length operand out of a array allocation site and narrow the
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
852 // type with a CastII, if necesssary
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
853 Node* make_ideal_length(const TypeOopPtr* ary_type, PhaseTransform *phase, bool can_create = true);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 196
diff changeset
854
0
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // Pattern-match a possible usage of AllocateArrayNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Return null if no allocation is recognized.
a61af66fc99e Initial load
duke
parents:
diff changeset
857 static AllocateArrayNode* Ideal_array_allocation(Node* ptr, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 AllocateNode* allo = Ideal_allocation(ptr, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 return (allo == NULL || !allo->is_AllocateArray())
a61af66fc99e Initial load
duke
parents:
diff changeset
860 ? NULL : allo->as_AllocateArray();
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 };
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 //------------------------------AbstractLockNode-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
865 class AbstractLockNode: public CallNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 private:
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
867 enum {
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
868 Regular = 0, // Normal lock
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
869 NonEscObj, // Lock is used for non escaping object
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
870 Coarsened, // Lock was coarsened
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
871 Nested // Nested lock
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
872 } _kind;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
873 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
874 NamedCounter* _counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // helper functions for lock elimination
a61af66fc99e Initial load
duke
parents:
diff changeset
879 //
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 bool find_matching_unlock(const Node* ctrl, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
882 GrowableArray<AbstractLockNode*> &lock_ops);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 bool find_lock_and_unlock_through_if(Node* node, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
884 GrowableArray<AbstractLockNode*> &lock_ops);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 bool find_unlocks_for_region(const RegionNode* region, LockNode* lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
886 GrowableArray<AbstractLockNode*> &lock_ops);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 LockNode *find_matching_lock(UnlockNode* unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
888
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
889 // Update the counter to indicate that this lock was eliminated.
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
890 void set_eliminated_lock_counter() PRODUCT_RETURN;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
893 AbstractLockNode(const TypeFunc *tf)
a61af66fc99e Initial load
duke
parents:
diff changeset
894 : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
895 _kind(Regular)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 {
a61af66fc99e Initial load
duke
parents:
diff changeset
897 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
898 _counter = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
899 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 virtual int Opcode() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 Node * obj_node() const {return in(TypeFunc::Parms + 0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
903 Node * box_node() const {return in(TypeFunc::Parms + 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
904 Node * fastlock_node() const {return in(TypeFunc::Parms + 2); }
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
905 void set_box_node(Node* box) { set_req(TypeFunc::Parms + 1, box); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
906
0
a61af66fc99e Initial load
duke
parents:
diff changeset
907 const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 virtual uint size_of() const { return sizeof(*this); }
a61af66fc99e Initial load
duke
parents:
diff changeset
910
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
911 bool is_eliminated() const { return (_kind != Regular); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
912 bool is_non_esc_obj() const { return (_kind == NonEscObj); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
913 bool is_coarsened() const { return (_kind == Coarsened); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
914 bool is_nested() const { return (_kind == Nested); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
916 void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
917 void set_coarsened() { _kind = Coarsened; set_eliminated_lock_counter(); }
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
918 void set_nested() { _kind = Nested; set_eliminated_lock_counter(); }
460
424f9bfe6b96 6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
kvn
parents: 420
diff changeset
919
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
920 // locking does not modify its arguments
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
921 virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
65
99269dbf4ba8 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 63
diff changeset
922
0
a61af66fc99e Initial load
duke
parents:
diff changeset
923 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
924 void create_lock_counter(JVMState* s);
a61af66fc99e Initial load
duke
parents:
diff changeset
925 NamedCounter* counter() const { return _counter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
926 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
927 };
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 //------------------------------Lock---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // High-level lock operation
a61af66fc99e Initial load
duke
parents:
diff changeset
931 //
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // This is a subclass of CallNode because it is a macro node which gets expanded
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // into a code sequence containing a call. This node takes 3 "parameters":
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // 0 - object to lock
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // 1 - a BoxLockNode
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // 2 - a FastLockNode
a61af66fc99e Initial load
duke
parents:
diff changeset
937 //
a61af66fc99e Initial load
duke
parents:
diff changeset
938 class LockNode : public AbstractLockNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
939 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 static const TypeFunc *lock_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // create input type (domain)
a61af66fc99e Initial load
duke
parents:
diff changeset
943 const Type **fields = TypeTuple::fields(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
a61af66fc99e Initial load
duke
parents:
diff changeset
945 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
a61af66fc99e Initial load
duke
parents:
diff changeset
946 fields[TypeFunc::Parms+2] = TypeInt::BOOL; // FastLock
a61af66fc99e Initial load
duke
parents:
diff changeset
947 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3,fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // create result type (range)
a61af66fc99e Initial load
duke
parents:
diff changeset
950 fields = TypeTuple::fields(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 return TypeFunc::make(domain,range);
a61af66fc99e Initial load
duke
parents:
diff changeset
955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
959 LockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 init_class_id(Class_Lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 init_flags(Flag_is_macro);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 C->add_macro_node(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964 virtual bool guaranteed_safepoint() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // Expansion modifies the JVMState, so we need to clone it
a61af66fc99e Initial load
duke
parents:
diff changeset
968 virtual void clone_jvms() {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 set_jvms(jvms()->clone_deep(Compile::current()));
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
4777
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
971
e9a5e0a812c8 7125896: Eliminate nested locks
kvn
parents: 4763
diff changeset
972 bool is_nested_lock_region(); // Is this Lock nested?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 };
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 //------------------------------Unlock---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // High-level unlock operation
a61af66fc99e Initial load
duke
parents:
diff changeset
977 class UnlockNode : public AbstractLockNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
979 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
980 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
981 UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 init_class_id(Class_Unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 init_flags(Flag_is_macro);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 C->add_macro_node(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // unlock is never a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
988 virtual bool guaranteed_safepoint() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
989 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
990
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
991 #endif // SHARE_VM_OPTO_CALLNODE_HPP