Mercurial > hg > truffle
annotate src/share/vm/opto/graphKit.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 | beebba0acc11 |
children | 29aa8936f03c |
rev | line source |
---|---|
0 | 1 /* |
6057 | 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1213
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1213
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:
1213
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_GRAPHKIT_HPP |
26 #define SHARE_VM_OPTO_GRAPHKIT_HPP | |
27 | |
28 #include "ci/ciEnv.hpp" | |
29 #include "ci/ciMethodData.hpp" | |
30 #include "opto/addnode.hpp" | |
31 #include "opto/callnode.hpp" | |
32 #include "opto/cfgnode.hpp" | |
33 #include "opto/compile.hpp" | |
34 #include "opto/divnode.hpp" | |
35 #include "opto/mulnode.hpp" | |
36 #include "opto/phaseX.hpp" | |
37 #include "opto/subnode.hpp" | |
38 #include "opto/type.hpp" | |
39 #include "runtime/deoptimization.hpp" | |
40 | |
0 | 41 class FastLockNode; |
42 class FastUnlockNode; | |
342 | 43 class IdealKit; |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
44 class LibraryCallKit; |
0 | 45 class Parse; |
46 class RootNode; | |
47 | |
48 //----------------------------------------------------------------------------- | |
49 //----------------------------GraphKit----------------------------------------- | |
50 // Toolkit for building the common sorts of subgraphs. | |
51 // Does not know about bytecode parsing or type-flow results. | |
52 // It is able to create graphs implementing the semantics of most | |
53 // or all bytecodes, so that it can expand intrinsics and calls. | |
54 // It may depend on JVMState structure, but it must not depend | |
55 // on specific bytecode streams. | |
56 class GraphKit : public Phase { | |
57 friend class PreserveJVMState; | |
58 | |
59 protected: | |
60 ciEnv* _env; // Compilation environment | |
61 PhaseGVN &_gvn; // Some optimizations while parsing | |
62 SafePointNode* _map; // Parser map from JVM to Nodes | |
63 SafePointNode* _exceptions;// Parser map(s) for exception state(s) | |
64 int _bci; // JVM Bytecode Pointer | |
65 ciMethod* _method; // JVM Current Method | |
66 | |
67 private: | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
68 int _sp; // JVM Expression Stack Pointer; don't modify directly! |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
69 |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
70 private: |
0 | 71 SafePointNode* map_not_null() const { |
72 assert(_map != NULL, "must call stopped() to test for reset compiler map"); | |
73 return _map; | |
74 } | |
75 | |
76 public: | |
77 GraphKit(); // empty constructor | |
78 GraphKit(JVMState* jvms); // the JVM state on which to operate | |
79 | |
80 #ifdef ASSERT | |
81 ~GraphKit() { | |
82 assert(!has_exceptions(), "user must call transfer_exceptions_into_jvms"); | |
83 } | |
84 #endif | |
85 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
86 virtual Parse* is_Parse() const { return NULL; } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
87 virtual LibraryCallKit* is_LibraryCallKit() const { return NULL; } |
0 | 88 |
89 ciEnv* env() const { return _env; } | |
90 PhaseGVN& gvn() const { return _gvn; } | |
91 | |
92 void record_for_igvn(Node* n) const { C->record_for_igvn(n); } // delegate to Compile | |
93 | |
94 // Handy well-known nodes: | |
95 Node* null() const { return zerocon(T_OBJECT); } | |
96 Node* top() const { return C->top(); } | |
97 RootNode* root() const { return C->root(); } | |
98 | |
99 // Create or find a constant node | |
100 Node* intcon(jint con) const { return _gvn.intcon(con); } | |
101 Node* longcon(jlong con) const { return _gvn.longcon(con); } | |
102 Node* makecon(const Type *t) const { return _gvn.makecon(t); } | |
103 Node* zerocon(BasicType bt) const { return _gvn.zerocon(bt); } | |
104 // (See also macro MakeConX in type.hpp, which uses intcon or longcon.) | |
105 | |
563
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
106 // Helper for byte_map_base |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
107 Node* byte_map_base_node() { |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
108 // Get base of card map |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
109 CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set()); |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
110 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code"); |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
111 if (ct->byte_map_base != NULL) { |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
112 return makecon(TypeRawPtr::make((address)ct->byte_map_base)); |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
113 } else { |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
114 return null(); |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
115 } |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
116 } |
1b9fc6e3171b
6442502: assert(bits,"Use TypePtr for NULL") on linux-x86
never
parents:
342
diff
changeset
|
117 |
0 | 118 jint find_int_con(Node* n, jint value_if_unknown) { |
119 return _gvn.find_int_con(n, value_if_unknown); | |
120 } | |
121 jlong find_long_con(Node* n, jlong value_if_unknown) { | |
122 return _gvn.find_long_con(n, value_if_unknown); | |
123 } | |
124 // (See also macro find_intptr_t_con in type.hpp, which uses one of these.) | |
125 | |
126 // JVM State accessors: | |
127 // Parser mapping from JVM indices into Nodes. | |
128 // Low slots are accessed by the StartNode::enum. | |
129 // Then come the locals at StartNode::Parms to StartNode::Parms+max_locals(); | |
130 // Then come JVM stack slots. | |
131 // Finally come the monitors, if any. | |
132 // See layout accessors in class JVMState. | |
133 | |
134 SafePointNode* map() const { return _map; } | |
135 bool has_exceptions() const { return _exceptions != NULL; } | |
136 JVMState* jvms() const { return map_not_null()->_jvms; } | |
137 int sp() const { return _sp; } | |
138 int bci() const { return _bci; } | |
139 Bytecodes::Code java_bc() const; | |
140 ciMethod* method() const { return _method; } | |
141 | |
142 void set_jvms(JVMState* jvms) { set_map(jvms->map()); | |
143 assert(jvms == this->jvms(), "sanity"); | |
144 _sp = jvms->sp(); | |
145 _bci = jvms->bci(); | |
146 _method = jvms->has_method() ? jvms->method() : NULL; } | |
147 void set_map(SafePointNode* m) { _map = m; debug_only(verify_map()); } | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
148 void set_sp(int sp) { assert(sp >= 0, err_msg_res("sp must be non-negative: %d", sp)); _sp = sp; } |
0 | 149 void clean_stack(int from_sp); // clear garbage beyond from_sp to top |
150 | |
151 void inc_sp(int i) { set_sp(sp() + i); } | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6057
diff
changeset
|
152 void dec_sp(int i) { set_sp(sp() - i); } |
0 | 153 void set_bci(int bci) { _bci = bci; } |
154 | |
155 // Make sure jvms has current bci & sp. | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
156 JVMState* sync_jvms() const; |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
157 JVMState* sync_jvms_for_reexecute(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
158 |
0 | 159 #ifdef ASSERT |
160 // Make sure JVMS has an updated copy of bci and sp. | |
161 // Also sanity-check method, depth, and monitor depth. | |
162 bool jvms_in_sync() const; | |
163 | |
164 // Make sure the map looks OK. | |
165 void verify_map() const; | |
166 | |
167 // Make sure a proposed exception state looks OK. | |
168 static void verify_exception_state(SafePointNode* ex_map); | |
169 #endif | |
170 | |
171 // Clone the existing map state. (Implements PreserveJVMState.) | |
172 SafePointNode* clone_map(); | |
173 | |
174 // Set the map to a clone of the given one. | |
175 void set_map_clone(SafePointNode* m); | |
176 | |
177 // Tell if the compilation is failing. | |
178 bool failing() const { return C->failing(); } | |
179 | |
180 // Set _map to NULL, signalling a stop to further bytecode execution. | |
181 // Preserve the map intact for future use, and return it back to the caller. | |
182 SafePointNode* stop() { SafePointNode* m = map(); set_map(NULL); return m; } | |
183 | |
184 // Stop, but first smash the map's inputs to NULL, to mark it dead. | |
185 void stop_and_kill_map(); | |
186 | |
187 // Tell if _map is NULL, or control is top. | |
188 bool stopped(); | |
189 | |
190 // Tell if this method or any caller method has exception handlers. | |
191 bool has_ex_handler(); | |
192 | |
193 // Save an exception without blowing stack contents or other JVM state. | |
194 // (The extra pointer is stuck with add_req on the map, beyond the JVMS.) | |
195 static void set_saved_ex_oop(SafePointNode* ex_map, Node* ex_oop); | |
196 | |
197 // Recover a saved exception from its map. | |
198 static Node* saved_ex_oop(SafePointNode* ex_map); | |
199 | |
200 // Recover a saved exception from its map, and remove it from the map. | |
201 static Node* clear_saved_ex_oop(SafePointNode* ex_map); | |
202 | |
203 #ifdef ASSERT | |
204 // Recover a saved exception from its map, and remove it from the map. | |
205 static bool has_saved_ex_oop(SafePointNode* ex_map); | |
206 #endif | |
207 | |
208 // Push an exception in the canonical position for handlers (stack(0)). | |
209 void push_ex_oop(Node* ex_oop) { | |
210 ensure_stack(1); // ensure room to push the exception | |
211 set_stack(0, ex_oop); | |
212 set_sp(1); | |
213 clean_stack(1); | |
214 } | |
215 | |
216 // Detach and return an exception state. | |
217 SafePointNode* pop_exception_state() { | |
218 SafePointNode* ex_map = _exceptions; | |
219 if (ex_map != NULL) { | |
220 _exceptions = ex_map->next_exception(); | |
221 ex_map->set_next_exception(NULL); | |
222 debug_only(verify_exception_state(ex_map)); | |
223 } | |
224 return ex_map; | |
225 } | |
226 | |
227 // Add an exception, using the given JVM state, without commoning. | |
228 void push_exception_state(SafePointNode* ex_map) { | |
229 debug_only(verify_exception_state(ex_map)); | |
230 ex_map->set_next_exception(_exceptions); | |
231 _exceptions = ex_map; | |
232 } | |
233 | |
234 // Turn the current JVM state into an exception state, appending the ex_oop. | |
235 SafePointNode* make_exception_state(Node* ex_oop); | |
236 | |
237 // Add an exception, using the given JVM state. | |
238 // Combine all exceptions with a common exception type into a single state. | |
239 // (This is done via combine_exception_states.) | |
240 void add_exception_state(SafePointNode* ex_map); | |
241 | |
242 // Combine all exceptions of any sort whatever into a single master state. | |
243 SafePointNode* combine_and_pop_all_exception_states() { | |
244 if (_exceptions == NULL) return NULL; | |
245 SafePointNode* phi_map = pop_exception_state(); | |
246 SafePointNode* ex_map; | |
247 while ((ex_map = pop_exception_state()) != NULL) { | |
248 combine_exception_states(ex_map, phi_map); | |
249 } | |
250 return phi_map; | |
251 } | |
252 | |
253 // Combine the two exception states, building phis as necessary. | |
254 // The second argument is updated to include contributions from the first. | |
255 void combine_exception_states(SafePointNode* ex_map, SafePointNode* phi_map); | |
256 | |
257 // Reset the map to the given state. If there are any half-finished phis | |
258 // in it (created by combine_exception_states), transform them now. | |
259 // Returns the exception oop. (Caller must call push_ex_oop if required.) | |
260 Node* use_exception_state(SafePointNode* ex_map); | |
261 | |
262 // Collect exceptions from a given JVM state into my exception list. | |
263 void add_exception_states_from(JVMState* jvms); | |
264 | |
265 // Collect all raised exceptions into the current JVM state. | |
266 // Clear the current exception list and map, returns the combined states. | |
267 JVMState* transfer_exceptions_into_jvms(); | |
268 | |
269 // Helper to throw a built-in exception. | |
270 // Range checks take the offending index. | |
271 // Cast and array store checks take the offending class. | |
272 // Others do not take the optional argument. | |
273 // The JVMS must allow the bytecode to be re-executed | |
274 // via an uncommon trap. | |
275 void builtin_throw(Deoptimization::DeoptReason reason, Node* arg = NULL); | |
276 | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1080
diff
changeset
|
277 // Helper to check the JavaThread::_should_post_on_exceptions flag |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1080
diff
changeset
|
278 // and branch to an uncommon_trap if it is true (with the specified reason and must_throw) |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1080
diff
changeset
|
279 void uncommon_trap_if_should_post_on_exceptions(Deoptimization::DeoptReason reason, |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1080
diff
changeset
|
280 bool must_throw) ; |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1080
diff
changeset
|
281 |
0 | 282 // Helper Functions for adding debug information |
283 void kill_dead_locals(); | |
284 #ifdef ASSERT | |
285 bool dead_locals_are_killed(); | |
286 #endif | |
287 // The call may deoptimize. Supply required JVM state as debug info. | |
288 // If must_throw is true, the call is guaranteed not to return normally. | |
289 void add_safepoint_edges(SafePointNode* call, | |
290 bool must_throw = false); | |
291 | |
292 // How many stack inputs does the current BC consume? | |
293 // And, how does the stack change after the bytecode? | |
294 // Returns false if unknown. | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
295 bool compute_stack_effects(int& inputs, int& depth); |
0 | 296 |
297 // Add a fixed offset to a pointer | |
298 Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset) { | |
299 return basic_plus_adr(base, ptr, MakeConX(offset)); | |
300 } | |
301 Node* basic_plus_adr(Node* base, intptr_t offset) { | |
302 return basic_plus_adr(base, base, MakeConX(offset)); | |
303 } | |
304 // Add a variable offset to a pointer | |
305 Node* basic_plus_adr(Node* base, Node* offset) { | |
306 return basic_plus_adr(base, base, offset); | |
307 } | |
308 Node* basic_plus_adr(Node* base, Node* ptr, Node* offset); | |
309 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
310 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
311 // Some convenient shortcuts for common nodes |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
312 Node* IfTrue(IfNode* iff) { return _gvn.transform(new (C) IfTrueNode(iff)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
313 Node* IfFalse(IfNode* iff) { return _gvn.transform(new (C) IfFalseNode(iff)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
314 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
315 Node* AddI(Node* l, Node* r) { return _gvn.transform(new (C) AddINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
316 Node* SubI(Node* l, Node* r) { return _gvn.transform(new (C) SubINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
317 Node* MulI(Node* l, Node* r) { return _gvn.transform(new (C) MulINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
318 Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new (C) DivINode(ctl, l, r)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
319 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
320 Node* AndI(Node* l, Node* r) { return _gvn.transform(new (C) AndINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
321 Node* OrI(Node* l, Node* r) { return _gvn.transform(new (C) OrINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
322 Node* XorI(Node* l, Node* r) { return _gvn.transform(new (C) XorINode(l, r)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
323 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
324 Node* MaxI(Node* l, Node* r) { return _gvn.transform(new (C) MaxINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
325 Node* MinI(Node* l, Node* r) { return _gvn.transform(new (C) MinINode(l, r)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
326 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
327 Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new (C) LShiftINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
328 Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new (C) RShiftINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
329 Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new (C) URShiftINode(l, r)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
330 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
331 Node* CmpI(Node* l, Node* r) { return _gvn.transform(new (C) CmpINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
332 Node* CmpL(Node* l, Node* r) { return _gvn.transform(new (C) CmpLNode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
333 Node* CmpP(Node* l, Node* r) { return _gvn.transform(new (C) CmpPNode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
334 Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
335 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
336 Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new (C) AddPNode(b, a, o)); } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
337 |
0 | 338 // Convert between int and long, and size_t. |
339 // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.) | |
340 Node* ConvI2L(Node* offset); | |
341 Node* ConvL2I(Node* offset); | |
342 // Find out the klass of an object. | |
343 Node* load_object_klass(Node* object); | |
344 // Find out the length of an array. | |
345 Node* load_array_length(Node* array); | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
346 |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
347 |
0 | 348 // Helper function to do a NULL pointer check or ZERO check based on type. |
349 // Throw an exception if a given value is null. | |
350 // Return the value cast to not-null. | |
351 // Be clever about equivalent dominating null checks. | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
352 Node* null_check_common(Node* value, BasicType type, |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
353 bool assert_null = false, Node* *null_control = NULL); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
354 Node* null_check(Node* value, BasicType type = T_OBJECT) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
355 return null_check_common(value, type); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
356 } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
357 Node* null_check_receiver() { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
358 assert(argument(0)->bottom_type()->isa_ptr(), "must be"); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
359 return null_check(argument(0)); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
360 } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
361 Node* zero_check_int(Node* value) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
362 assert(value->bottom_type()->basic_type() == T_INT, |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
363 err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type()))); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
364 return null_check_common(value, T_INT); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
365 } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
366 Node* zero_check_long(Node* value) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
367 assert(value->bottom_type()->basic_type() == T_LONG, |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
368 err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type()))); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
369 return null_check_common(value, T_LONG); |
0 | 370 } |
371 // Throw an uncommon trap if a given value is __not__ null. | |
372 // Return the value cast to null, and be clever about dominating checks. | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
373 Node* null_assert(Node* value, BasicType type = T_OBJECT) { |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
374 return null_check_common(value, type, true); |
0 | 375 } |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
376 |
0 | 377 // Null check oop. Return null-path control into (*null_control). |
378 // Return a cast-not-null node which depends on the not-null control. | |
379 // If never_see_null, use an uncommon trap (*null_control sees a top). | |
380 // The cast is not valid along the null path; keep a copy of the original. | |
381 Node* null_check_oop(Node* value, Node* *null_control, | |
382 bool never_see_null = false); | |
383 | |
1746
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
384 // Check the null_seen bit. |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
385 bool seems_never_null(Node* obj, ciProfileData* data); |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
386 |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
387 // Use the type profile to narrow an object type. |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
388 Node* maybe_cast_profiled_receiver(Node* not_null_obj, |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
389 ciProfileData* data, |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
390 ciKlass* require_klass); |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
391 |
0 | 392 // Cast obj to not-null on this path |
393 Node* cast_not_null(Node* obj, bool do_replace_in_map = true); | |
394 // Replace all occurrences of one node by another. | |
395 void replace_in_map(Node* old, Node* neww); | |
396 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
397 void push(Node* n) { map_not_null(); _map->set_stack(_map->_jvms, _sp++ , n); } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
398 Node* pop() { map_not_null(); return _map->stack( _map->_jvms, --_sp ); } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
399 Node* peek(int off = 0) { map_not_null(); return _map->stack( _map->_jvms, _sp - off - 1 ); } |
0 | 400 |
401 void push_pair(Node* ldval) { | |
402 push(ldval); | |
403 push(top()); // the halfword is merely a placeholder | |
404 } | |
405 void push_pair_local(int i) { | |
406 // longs are stored in locals in "push" order | |
407 push( local(i+0) ); // the real value | |
408 assert(local(i+1) == top(), ""); | |
409 push(top()); // halfword placeholder | |
410 } | |
411 Node* pop_pair() { | |
412 // the second half is pushed last & popped first; it contains exactly nothing | |
413 Node* halfword = pop(); | |
414 assert(halfword == top(), ""); | |
415 // the long bits are pushed first & popped last: | |
416 return pop(); | |
417 } | |
418 void set_pair_local(int i, Node* lval) { | |
419 // longs are stored in locals as a value/half pair (like doubles) | |
420 set_local(i+0, lval); | |
421 set_local(i+1, top()); | |
422 } | |
423 | |
424 // Push the node, which may be zero, one, or two words. | |
425 void push_node(BasicType n_type, Node* n) { | |
426 int n_size = type2size[n_type]; | |
427 if (n_size == 1) push( n ); // T_INT, ... | |
428 else if (n_size == 2) push_pair( n ); // T_DOUBLE, T_LONG | |
429 else { assert(n_size == 0, "must be T_VOID"); } | |
430 } | |
431 | |
432 Node* pop_node(BasicType n_type) { | |
433 int n_size = type2size[n_type]; | |
434 if (n_size == 1) return pop(); | |
435 else if (n_size == 2) return pop_pair(); | |
436 else return NULL; | |
437 } | |
438 | |
439 Node* control() const { return map_not_null()->control(); } | |
440 Node* i_o() const { return map_not_null()->i_o(); } | |
441 Node* returnadr() const { return map_not_null()->returnadr(); } | |
442 Node* frameptr() const { return map_not_null()->frameptr(); } | |
443 Node* local(uint idx) const { map_not_null(); return _map->local( _map->_jvms, idx); } | |
444 Node* stack(uint idx) const { map_not_null(); return _map->stack( _map->_jvms, idx); } | |
445 Node* argument(uint idx) const { map_not_null(); return _map->argument( _map->_jvms, idx); } | |
446 Node* monitor_box(uint idx) const { map_not_null(); return _map->monitor_box(_map->_jvms, idx); } | |
447 Node* monitor_obj(uint idx) const { map_not_null(); return _map->monitor_obj(_map->_jvms, idx); } | |
448 | |
449 void set_control (Node* c) { map_not_null()->set_control(c); } | |
450 void set_i_o (Node* c) { map_not_null()->set_i_o(c); } | |
451 void set_local(uint idx, Node* c) { map_not_null(); _map->set_local( _map->_jvms, idx, c); } | |
452 void set_stack(uint idx, Node* c) { map_not_null(); _map->set_stack( _map->_jvms, idx, c); } | |
453 void set_argument(uint idx, Node* c){ map_not_null(); _map->set_argument(_map->_jvms, idx, c); } | |
454 void ensure_stack(uint stk_size) { map_not_null(); _map->ensure_stack(_map->_jvms, stk_size); } | |
455 | |
456 // Access unaliased memory | |
457 Node* memory(uint alias_idx); | |
458 Node* memory(const TypePtr *tp) { return memory(C->get_alias_index(tp)); } | |
459 Node* memory(Node* adr) { return memory(_gvn.type(adr)->is_ptr()); } | |
460 | |
461 // Access immutable memory | |
462 Node* immutable_memory() { return C->immutable_memory(); } | |
463 | |
464 // Set unaliased memory | |
465 void set_memory(Node* c, uint alias_idx) { merged_memory()->set_memory_at(alias_idx, c); } | |
466 void set_memory(Node* c, const TypePtr *tp) { set_memory(c,C->get_alias_index(tp)); } | |
467 void set_memory(Node* c, Node* adr) { set_memory(c,_gvn.type(adr)->is_ptr()); } | |
468 | |
469 // Get the entire memory state (probably a MergeMemNode), and reset it | |
470 // (The resetting prevents somebody from using the dangling Node pointer.) | |
471 Node* reset_memory(); | |
472 | |
473 // Get the entire memory state, asserted to be a MergeMemNode. | |
474 MergeMemNode* merged_memory() { | |
475 Node* mem = map_not_null()->memory(); | |
476 assert(mem->is_MergeMem(), "parse memory is always pre-split"); | |
477 return mem->as_MergeMem(); | |
478 } | |
479 | |
480 // Set the entire memory state; produce a new MergeMemNode. | |
481 void set_all_memory(Node* newmem); | |
482 | |
483 // Create a memory projection from the call, then set_all_memory. | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
484 void set_all_memory_call(Node* call, bool separate_io_proj = false); |
0 | 485 |
486 // Create a LoadNode, reading from the parser's memory state. | |
487 // (Note: require_atomic_access is useful only with T_LONG.) | |
488 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, | |
489 bool require_atomic_access = false) { | |
490 // This version computes alias_index from bottom_type | |
491 return make_load(ctl, adr, t, bt, adr->bottom_type()->is_ptr(), | |
492 require_atomic_access); | |
493 } | |
494 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type, bool require_atomic_access = false) { | |
495 // This version computes alias_index from an address type | |
496 assert(adr_type != NULL, "use other make_load factory"); | |
497 return make_load(ctl, adr, t, bt, C->get_alias_index(adr_type), | |
498 require_atomic_access); | |
499 } | |
500 // This is the base version which is given an alias index. | |
501 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx, bool require_atomic_access = false); | |
502 | |
503 // Create & transform a StoreNode and store the effect into the | |
504 // parser's memory state. | |
505 Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt, | |
506 const TypePtr* adr_type, | |
507 bool require_atomic_access = false) { | |
508 // This version computes alias_index from an address type | |
509 assert(adr_type != NULL, "use other store_to_memory factory"); | |
510 return store_to_memory(ctl, adr, val, bt, | |
511 C->get_alias_index(adr_type), | |
512 require_atomic_access); | |
513 } | |
514 // This is the base version which is given alias index | |
515 // Return the new StoreXNode | |
516 Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt, | |
517 int adr_idx, | |
518 bool require_atomic_access = false); | |
519 | |
520 | |
521 // All in one pre-barrier, store, post_barrier | |
522 // Insert a write-barrier'd store. This is to let generational GC | |
523 // work; we have to flag all oop-stores before the next GC point. | |
524 // | |
525 // It comes in 3 flavors of store to an object, array, or unknown. | |
526 // We use precise card marks for arrays to avoid scanning the entire | |
527 // array. We use imprecise for object. We use precise for unknown | |
528 // since we don't know if we have an array or and object or even | |
529 // where the object starts. | |
530 // | |
531 // If val==NULL, it is taken to be a completely unknown value. QQQ | |
532 | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
533 Node* store_oop(Node* ctl, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
534 Node* obj, // containing obj |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
535 Node* adr, // actual adress to store val at |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
536 const TypePtr* adr_type, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
537 Node* val, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
538 const TypeOopPtr* val_type, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
539 BasicType bt, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
540 bool use_precise); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
541 |
0 | 542 Node* store_oop_to_object(Node* ctl, |
543 Node* obj, // containing obj | |
544 Node* adr, // actual adress to store val at | |
545 const TypePtr* adr_type, | |
546 Node* val, | |
825 | 547 const TypeOopPtr* val_type, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
548 BasicType bt) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
549 return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, false); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
550 } |
0 | 551 |
552 Node* store_oop_to_array(Node* ctl, | |
553 Node* obj, // containing obj | |
554 Node* adr, // actual adress to store val at | |
555 const TypePtr* adr_type, | |
556 Node* val, | |
825 | 557 const TypeOopPtr* val_type, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
558 BasicType bt) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
559 return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
560 } |
0 | 561 |
562 // Could be an array or object we don't know at compile time (unsafe ref.) | |
563 Node* store_oop_to_unknown(Node* ctl, | |
564 Node* obj, // containing obj | |
565 Node* adr, // actual adress to store val at | |
566 const TypePtr* adr_type, | |
567 Node* val, | |
568 BasicType bt); | |
569 | |
570 // For the few case where the barriers need special help | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
571 void pre_barrier(bool do_load, Node* ctl, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
572 Node* obj, Node* adr, uint adr_idx, Node* val, const TypeOopPtr* val_type, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
573 Node* pre_val, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
574 BasicType bt); |
0 | 575 |
576 void post_barrier(Node* ctl, Node* store, Node* obj, Node* adr, uint adr_idx, | |
577 Node* val, BasicType bt, bool use_precise); | |
578 | |
579 // Return addressing for an array element. | |
580 Node* array_element_address(Node* ary, Node* idx, BasicType elembt, | |
581 // Optional constraint on the array size: | |
582 const TypeInt* sizetype = NULL); | |
583 | |
584 // Return a load of array element at idx. | |
585 Node* load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype); | |
586 | |
587 //---------------- Dtrace support -------------------- | |
588 void make_dtrace_method_entry_exit(ciMethod* method, bool is_entry); | |
589 void make_dtrace_method_entry(ciMethod* method) { | |
590 make_dtrace_method_entry_exit(method, true); | |
591 } | |
592 void make_dtrace_method_exit(ciMethod* method) { | |
593 make_dtrace_method_entry_exit(method, false); | |
594 } | |
595 | |
596 //--------------- stub generation ------------------- | |
597 public: | |
598 void gen_stub(address C_function, | |
599 const char *name, | |
600 int is_fancy_jump, | |
601 bool pass_tls, | |
602 bool return_pc); | |
603 | |
604 //---------- help for generating calls -------------- | |
605 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
606 // Do a null check on the receiver as it would happen before the call to |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
607 // callee (with all arguments still on the stack). |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
608 Node* null_check_receiver_before_call(ciMethod* callee) { |
0 | 609 assert(!callee->is_static(), "must be a virtual method"); |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
610 const int nargs = callee->arg_size(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
611 inc_sp(nargs); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
612 Node* n = null_check_receiver(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
613 dec_sp(nargs); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
614 return n; |
0 | 615 } |
616 | |
617 // Fill in argument edges for the call from argument(0), argument(1), ... | |
618 // (The next step is to call set_edges_for_java_call.) | |
619 void set_arguments_for_java_call(CallJavaNode* call); | |
620 | |
621 // Fill in non-argument edges for the call. | |
622 // Transform the call, and update the basics: control, i_o, memory. | |
623 // (The next step is usually to call set_results_for_java_call.) | |
624 void set_edges_for_java_call(CallJavaNode* call, | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
625 bool must_throw = false, bool separate_io_proj = false); |
0 | 626 |
627 // Finish up a java call that was started by set_edges_for_java_call. | |
628 // Call add_exception on any throw arising from the call. | |
629 // Return the call result (transformed). | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
630 Node* set_results_for_java_call(CallJavaNode* call, bool separate_io_proj = false); |
0 | 631 |
632 // Similar to set_edges_for_java_call, but simplified for runtime calls. | |
633 void set_predefined_output_for_runtime_call(Node* call) { | |
634 set_predefined_output_for_runtime_call(call, NULL, NULL); | |
635 } | |
636 void set_predefined_output_for_runtime_call(Node* call, | |
637 Node* keep_mem, | |
638 const TypePtr* hook_mem); | |
639 Node* set_predefined_input_for_runtime_call(SafePointNode* call); | |
640 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
641 // Replace the call with the current state of the kit. Requires |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
642 // that the call was generated with separate io_projs so that |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
643 // exceptional control flow can be handled properly. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
644 void replace_call(CallNode* call, Node* result); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
645 |
0 | 646 // helper functions for statistics |
647 void increment_counter(address counter_addr); // increment a debug counter | |
648 void increment_counter(Node* counter_addr); // increment a debug counter | |
649 | |
650 // Bail out to the interpreter right now | |
651 // The optional klass is the one causing the trap. | |
652 // The optional reason is debug information written to the compile log. | |
653 // Optional must_throw is the same as with add_safepoint_edges. | |
654 void uncommon_trap(int trap_request, | |
655 ciKlass* klass = NULL, const char* reason_string = NULL, | |
656 bool must_throw = false, bool keep_exact_action = false); | |
657 | |
658 // Shorthand, to avoid saying "Deoptimization::" so many times. | |
659 void uncommon_trap(Deoptimization::DeoptReason reason, | |
660 Deoptimization::DeoptAction action, | |
661 ciKlass* klass = NULL, const char* reason_string = NULL, | |
662 bool must_throw = false, bool keep_exact_action = false) { | |
663 uncommon_trap(Deoptimization::make_trap_request(reason, action), | |
664 klass, reason_string, must_throw, keep_exact_action); | |
665 } | |
666 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
667 // SP when bytecode needs to be reexecuted. |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
668 virtual int reexecute_sp() { return sp(); } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
669 |
0 | 670 // Report if there were too many traps at the current method and bci. |
671 // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. | |
672 // If there is no MDO at all, report no trap unless told to assume it. | |
673 bool too_many_traps(Deoptimization::DeoptReason reason) { | |
674 return C->too_many_traps(method(), bci(), reason); | |
675 } | |
676 | |
677 // Report if there were too many recompiles at the current method and bci. | |
678 bool too_many_recompiles(Deoptimization::DeoptReason reason) { | |
679 return C->too_many_recompiles(method(), bci(), reason); | |
680 } | |
681 | |
682 // Returns the object (if any) which was created the moment before. | |
683 Node* just_allocated_object(Node* current_control); | |
684 | |
685 static bool use_ReduceInitialCardMarks() { | |
686 return (ReduceInitialCardMarks | |
687 && Universe::heap()->can_elide_tlab_store_barriers()); | |
688 } | |
689 | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
690 // Sync Ideal and Graph kits. |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
691 void sync_kit(IdealKit& ideal); |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
692 void final_sync(IdealKit& ideal); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
693 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
694 // vanilla/CMS post barrier |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
900
diff
changeset
|
695 void write_barrier_post(Node *store, Node* obj, |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
900
diff
changeset
|
696 Node* adr, uint adr_idx, Node* val, bool use_precise); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
697 |
342 | 698 // G1 pre/post barriers |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
699 void g1_write_barrier_pre(bool do_load, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
700 Node* obj, |
342 | 701 Node* adr, |
702 uint alias_idx, | |
703 Node* val, | |
825 | 704 const TypeOopPtr* val_type, |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
705 Node* pre_val, |
342 | 706 BasicType bt); |
707 | |
708 void g1_write_barrier_post(Node* store, | |
709 Node* obj, | |
710 Node* adr, | |
711 uint alias_idx, | |
712 Node* val, | |
713 BasicType bt, | |
714 bool use_precise); | |
715 // Helper function for g1 | |
716 private: | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
900
diff
changeset
|
717 void g1_mark_card(IdealKit& ideal, Node* card_adr, Node* store, uint oop_alias_idx, |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
900
diff
changeset
|
718 Node* index, Node* index_adr, |
342 | 719 Node* buffer, const TypeFunc* tf); |
720 | |
721 public: | |
0 | 722 // Helper function to round double arguments before a call |
723 void round_double_arguments(ciMethod* dest_method); | |
724 void round_double_result(ciMethod* dest_method); | |
725 | |
726 // rounding for strict float precision conformance | |
727 Node* precision_rounding(Node* n); | |
728 | |
729 // rounding for strict double precision conformance | |
730 Node* dprecision_rounding(Node* n); | |
731 | |
732 // rounding for non-strict double stores | |
733 Node* dstore_rounding(Node* n); | |
734 | |
735 // Helper functions for fast/slow path codes | |
736 Node* opt_iff(Node* region, Node* iff); | |
737 Node* make_runtime_call(int flags, | |
738 const TypeFunc* call_type, address call_addr, | |
739 const char* call_name, | |
740 const TypePtr* adr_type, // NULL if no memory effects | |
741 Node* parm0 = NULL, Node* parm1 = NULL, | |
742 Node* parm2 = NULL, Node* parm3 = NULL, | |
743 Node* parm4 = NULL, Node* parm5 = NULL, | |
744 Node* parm6 = NULL, Node* parm7 = NULL); | |
745 enum { // flag values for make_runtime_call | |
746 RC_NO_FP = 1, // CallLeafNoFPNode | |
747 RC_NO_IO = 2, // do not hook IO edges | |
748 RC_NO_LEAF = 4, // CallStaticJavaNode | |
749 RC_MUST_THROW = 8, // flag passed to add_safepoint_edges | |
750 RC_NARROW_MEM = 16, // input memory is same as output | |
751 RC_UNCOMMON = 32, // freq. expected to be like uncommon trap | |
752 RC_LEAF = 0 // null value: no flags set | |
753 }; | |
754 | |
755 // merge in all memory slices from new_mem, along the given path | |
756 void merge_memory(Node* new_mem, Node* region, int new_path); | |
757 void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj); | |
758 | |
759 // Helper functions to build synchronizations | |
760 int next_monitor(); | |
761 Node* insert_mem_bar(int opcode, Node* precedent = NULL); | |
762 Node* insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent = NULL); | |
763 // Optional 'precedent' is appended as an extra edge, to force ordering. | |
764 FastLockNode* shared_lock(Node* obj); | |
765 void shared_unlock(Node* box, Node* obj); | |
766 | |
767 // helper functions for the fast path/slow path idioms | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
768 Node* fast_and_slow(Node* in, const Type *result_type, Node* null_result, IfNode* fast_test, Node* fast_result, address slow_call, const TypeFunc *slow_call_type, Node* slow_arg, Klass* ex_klass, Node* slow_result); |
0 | 769 |
770 // Generate an instance-of idiom. Used by both the instance-of bytecode | |
771 // and the reflective instance-of call. | |
772 Node* gen_instanceof( Node *subobj, Node* superkls ); | |
773 | |
774 // Generate a check-cast idiom. Used by both the check-cast bytecode | |
775 // and the array-store bytecode | |
776 Node* gen_checkcast( Node *subobj, Node* superkls, | |
777 Node* *failure_control = NULL ); | |
778 | |
779 // Generate a subtyping check. Takes as input the subtype and supertype. | |
780 // Returns 2 values: sets the default control() to the true path and | |
781 // returns the false path. Only reads from constant memory taken from the | |
782 // default memory; does not write anything. It also doesn't take in an | |
783 // Object; if you wish to check an Object you need to load the Object's | |
784 // class prior to coming here. | |
785 Node* gen_subtype_check(Node* subklass, Node* superklass); | |
786 | |
787 // Static parse-time type checking logic for gen_subtype_check: | |
788 enum { SSC_always_false, SSC_always_true, SSC_easy_test, SSC_full_test }; | |
789 int static_subtype_check(ciKlass* superk, ciKlass* subk); | |
790 | |
791 // Exact type check used for predicted calls and casts. | |
792 // Rewrites (*casted_receiver) to be casted to the stronger type. | |
793 // (Caller is responsible for doing replace_in_map.) | |
794 Node* type_check_receiver(Node* receiver, ciKlass* klass, float prob, | |
795 Node* *casted_receiver); | |
796 | |
797 // implementation of object creation | |
798 Node* set_output_for_allocation(AllocateNode* alloc, | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2468
diff
changeset
|
799 const TypeOopPtr* oop_type); |
0 | 800 Node* get_layout_helper(Node* klass_node, jint& constant_value); |
801 Node* new_instance(Node* klass_node, | |
802 Node* slow_test = NULL, | |
803 Node* *return_size_val = NULL); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
579
diff
changeset
|
804 Node* new_array(Node* klass_node, Node* count_val, int nargs, |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2468
diff
changeset
|
805 Node* *return_size_val = NULL); |
0 | 806 |
6057 | 807 // java.lang.String helpers |
808 Node* load_String_offset(Node* ctrl, Node* str); | |
809 Node* load_String_length(Node* ctrl, Node* str); | |
810 Node* load_String_value(Node* ctrl, Node* str); | |
811 void store_String_offset(Node* ctrl, Node* str, Node* value); | |
812 void store_String_length(Node* ctrl, Node* str, Node* value); | |
813 void store_String_value(Node* ctrl, Node* str, Node* value); | |
814 | |
0 | 815 // Handy for making control flow |
816 IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
817 IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's |
0 | 818 _gvn.set_type(iff, iff->Value(&_gvn)); // Value may be known at parse-time |
819 // Place 'if' on worklist if it will be in graph | |
820 if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later | |
821 return iff; | |
822 } | |
823 | |
824 IfNode* create_and_xform_if(Node* ctrl, Node* tst, float prob, float cnt) { | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6725
diff
changeset
|
825 IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's |
0 | 826 _gvn.transform(iff); // Value may be known at parse-time |
827 // Place 'if' on worklist if it will be in graph | |
828 if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later | |
829 return iff; | |
830 } | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
831 |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
832 // Insert a loop predicate into the graph |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
833 void add_predicate(int nargs = 0); |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
834 void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs); |
0 | 835 }; |
836 | |
837 // Helper class to support building of control flow branches. Upon | |
838 // creation the map and sp at bci are cloned and restored upon de- | |
839 // struction. Typical use: | |
840 // | |
841 // { PreserveJVMState pjvms(this); | |
842 // // code of new branch | |
843 // } | |
844 // // here the JVM state at bci is established | |
845 | |
846 class PreserveJVMState: public StackObj { | |
847 protected: | |
848 GraphKit* _kit; | |
849 #ifdef ASSERT | |
850 int _block; // PO of current block, if a Parse | |
851 int _bci; | |
852 #endif | |
853 SafePointNode* _map; | |
854 uint _sp; | |
855 | |
856 public: | |
857 PreserveJVMState(GraphKit* kit, bool clone_map = true); | |
858 ~PreserveJVMState(); | |
859 }; | |
860 | |
861 // Helper class to build cutouts of the form if (p) ; else {x...}. | |
862 // The code {x...} must not fall through. | |
863 // The kit's main flow of control is set to the "then" continuation of if(p). | |
864 class BuildCutout: public PreserveJVMState { | |
865 public: | |
866 BuildCutout(GraphKit* kit, Node* p, float prob, float cnt = COUNT_UNKNOWN); | |
867 ~BuildCutout(); | |
868 }; | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
869 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
870 // Helper class to preserve the original _reexecute bit and _sp and restore |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
871 // them back |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
872 class PreserveReexecuteState: public StackObj { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
873 protected: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
874 GraphKit* _kit; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
875 uint _sp; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
876 JVMState::ReexecuteState _reexecute; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
877 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
878 public: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
879 PreserveReexecuteState(GraphKit* kit); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
880 ~PreserveReexecuteState(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
881 }; |
1972 | 882 |
883 #endif // SHARE_VM_OPTO_GRAPHKIT_HPP |