Mercurial > hg > truffle
annotate src/share/vm/opto/graphKit.hpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 55fb97c4c58d |
children | abec000618bf b8413a9cbb84 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12966
diff
changeset
|
2 * Copyright (c) 2001, 2013, 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. | |
12869
d9043b88eeb3
8024067: Missing replace_in_map() calls following null checks
roland
parents:
12190
diff
changeset
|
381 // If safe_for_replace, then we can replace the value with the cast |
d9043b88eeb3
8024067: Missing replace_in_map() calls following null checks
roland
parents:
12190
diff
changeset
|
382 // in the parsing map (the cast is guaranteed to dominate the map) |
0 | 383 Node* null_check_oop(Node* value, Node* *null_control, |
12869
d9043b88eeb3
8024067: Missing replace_in_map() calls following null checks
roland
parents:
12190
diff
changeset
|
384 bool never_see_null = false, bool safe_for_replace = false); |
0 | 385 |
1746
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
386 // Check the null_seen bit. |
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
387 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
|
388 |
12966 | 389 // Check for unique class for receiver at call |
390 ciKlass* profile_has_unique_klass() { | |
391 ciCallProfile profile = method()->call_profile_at_bci(bci()); | |
392 if (profile.count() >= 0 && // no cast failures here | |
393 profile.has_receiver(0) && | |
394 profile.morphism() == 1) { | |
395 return profile.receiver(0); | |
396 } | |
397 return NULL; | |
398 } | |
399 | |
400 // record type from profiling with the type system | |
401 Node* record_profile_for_speculation(Node* n, ciKlass* exact_kls); | |
402 Node* record_profiled_receiver_for_speculation(Node* n); | |
403 void record_profiled_arguments_for_speculation(ciMethod* dest_method, Bytecodes::Code bc); | |
404 void record_profiled_parameters_for_speculation(); | |
405 | |
1746
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
406 // 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
|
407 Node* maybe_cast_profiled_receiver(Node* not_null_obj, |
12966 | 408 ciKlass* require_klass, |
409 ciKlass* spec, | |
410 bool safe_for_replace); | |
411 | |
412 // Cast obj to type and emit guard unless we had too many traps here already | |
413 Node* maybe_cast_profiled_obj(Node* obj, | |
414 ciKlass* type, | |
415 bool not_null = false); | |
1746
4b29a725c43c
6912064: type profiles need to be exploited more for dynamic language support
jrose
parents:
1552
diff
changeset
|
416 |
0 | 417 // Cast obj to not-null on this path |
418 Node* cast_not_null(Node* obj, bool do_replace_in_map = true); | |
419 // Replace all occurrences of one node by another. | |
420 void replace_in_map(Node* old, Node* neww); | |
421 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
422 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
|
423 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
|
424 Node* peek(int off = 0) { map_not_null(); return _map->stack( _map->_jvms, _sp - off - 1 ); } |
0 | 425 |
426 void push_pair(Node* ldval) { | |
427 push(ldval); | |
428 push(top()); // the halfword is merely a placeholder | |
429 } | |
430 void push_pair_local(int i) { | |
431 // longs are stored in locals in "push" order | |
432 push( local(i+0) ); // the real value | |
433 assert(local(i+1) == top(), ""); | |
434 push(top()); // halfword placeholder | |
435 } | |
436 Node* pop_pair() { | |
437 // the second half is pushed last & popped first; it contains exactly nothing | |
438 Node* halfword = pop(); | |
439 assert(halfword == top(), ""); | |
440 // the long bits are pushed first & popped last: | |
441 return pop(); | |
442 } | |
443 void set_pair_local(int i, Node* lval) { | |
444 // longs are stored in locals as a value/half pair (like doubles) | |
445 set_local(i+0, lval); | |
446 set_local(i+1, top()); | |
447 } | |
448 | |
449 // Push the node, which may be zero, one, or two words. | |
450 void push_node(BasicType n_type, Node* n) { | |
451 int n_size = type2size[n_type]; | |
452 if (n_size == 1) push( n ); // T_INT, ... | |
453 else if (n_size == 2) push_pair( n ); // T_DOUBLE, T_LONG | |
454 else { assert(n_size == 0, "must be T_VOID"); } | |
455 } | |
456 | |
457 Node* pop_node(BasicType n_type) { | |
458 int n_size = type2size[n_type]; | |
459 if (n_size == 1) return pop(); | |
460 else if (n_size == 2) return pop_pair(); | |
461 else return NULL; | |
462 } | |
463 | |
464 Node* control() const { return map_not_null()->control(); } | |
465 Node* i_o() const { return map_not_null()->i_o(); } | |
466 Node* returnadr() const { return map_not_null()->returnadr(); } | |
467 Node* frameptr() const { return map_not_null()->frameptr(); } | |
468 Node* local(uint idx) const { map_not_null(); return _map->local( _map->_jvms, idx); } | |
469 Node* stack(uint idx) const { map_not_null(); return _map->stack( _map->_jvms, idx); } | |
470 Node* argument(uint idx) const { map_not_null(); return _map->argument( _map->_jvms, idx); } | |
471 Node* monitor_box(uint idx) const { map_not_null(); return _map->monitor_box(_map->_jvms, idx); } | |
472 Node* monitor_obj(uint idx) const { map_not_null(); return _map->monitor_obj(_map->_jvms, idx); } | |
473 | |
474 void set_control (Node* c) { map_not_null()->set_control(c); } | |
475 void set_i_o (Node* c) { map_not_null()->set_i_o(c); } | |
476 void set_local(uint idx, Node* c) { map_not_null(); _map->set_local( _map->_jvms, idx, c); } | |
477 void set_stack(uint idx, Node* c) { map_not_null(); _map->set_stack( _map->_jvms, idx, c); } | |
478 void set_argument(uint idx, Node* c){ map_not_null(); _map->set_argument(_map->_jvms, idx, c); } | |
479 void ensure_stack(uint stk_size) { map_not_null(); _map->ensure_stack(_map->_jvms, stk_size); } | |
480 | |
481 // Access unaliased memory | |
482 Node* memory(uint alias_idx); | |
483 Node* memory(const TypePtr *tp) { return memory(C->get_alias_index(tp)); } | |
484 Node* memory(Node* adr) { return memory(_gvn.type(adr)->is_ptr()); } | |
485 | |
486 // Access immutable memory | |
487 Node* immutable_memory() { return C->immutable_memory(); } | |
488 | |
489 // Set unaliased memory | |
490 void set_memory(Node* c, uint alias_idx) { merged_memory()->set_memory_at(alias_idx, c); } | |
491 void set_memory(Node* c, const TypePtr *tp) { set_memory(c,C->get_alias_index(tp)); } | |
492 void set_memory(Node* c, Node* adr) { set_memory(c,_gvn.type(adr)->is_ptr()); } | |
493 | |
494 // Get the entire memory state (probably a MergeMemNode), and reset it | |
495 // (The resetting prevents somebody from using the dangling Node pointer.) | |
496 Node* reset_memory(); | |
497 | |
498 // Get the entire memory state, asserted to be a MergeMemNode. | |
499 MergeMemNode* merged_memory() { | |
500 Node* mem = map_not_null()->memory(); | |
501 assert(mem->is_MergeMem(), "parse memory is always pre-split"); | |
502 return mem->as_MergeMem(); | |
503 } | |
504 | |
505 // Set the entire memory state; produce a new MergeMemNode. | |
506 void set_all_memory(Node* newmem); | |
507 | |
508 // 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
|
509 void set_all_memory_call(Node* call, bool separate_io_proj = false); |
0 | 510 |
511 // Create a LoadNode, reading from the parser's memory state. | |
512 // (Note: require_atomic_access is useful only with T_LONG.) | |
513 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, | |
514 bool require_atomic_access = false) { | |
515 // This version computes alias_index from bottom_type | |
516 return make_load(ctl, adr, t, bt, adr->bottom_type()->is_ptr(), | |
517 require_atomic_access); | |
518 } | |
519 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type, bool require_atomic_access = false) { | |
520 // This version computes alias_index from an address type | |
521 assert(adr_type != NULL, "use other make_load factory"); | |
522 return make_load(ctl, adr, t, bt, C->get_alias_index(adr_type), | |
523 require_atomic_access); | |
524 } | |
525 // This is the base version which is given an alias index. | |
526 Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx, bool require_atomic_access = false); | |
527 | |
528 // Create & transform a StoreNode and store the effect into the | |
529 // parser's memory state. | |
530 Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt, | |
531 const TypePtr* adr_type, | |
532 bool require_atomic_access = false) { | |
533 // This version computes alias_index from an address type | |
534 assert(adr_type != NULL, "use other store_to_memory factory"); | |
535 return store_to_memory(ctl, adr, val, bt, | |
536 C->get_alias_index(adr_type), | |
537 require_atomic_access); | |
538 } | |
539 // This is the base version which is given alias index | |
540 // Return the new StoreXNode | |
541 Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt, | |
542 int adr_idx, | |
543 bool require_atomic_access = false); | |
544 | |
545 | |
546 // All in one pre-barrier, store, post_barrier | |
547 // Insert a write-barrier'd store. This is to let generational GC | |
548 // work; we have to flag all oop-stores before the next GC point. | |
549 // | |
550 // It comes in 3 flavors of store to an object, array, or unknown. | |
551 // We use precise card marks for arrays to avoid scanning the entire | |
552 // array. We use imprecise for object. We use precise for unknown | |
553 // since we don't know if we have an array or and object or even | |
554 // where the object starts. | |
555 // | |
556 // If val==NULL, it is taken to be a completely unknown value. QQQ | |
557 | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
558 Node* store_oop(Node* ctl, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
559 Node* obj, // containing obj |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
560 Node* adr, // actual adress to store val at |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
561 const TypePtr* adr_type, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
562 Node* val, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
563 const TypeOopPtr* val_type, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
564 BasicType bt, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
565 bool use_precise); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
566 |
0 | 567 Node* store_oop_to_object(Node* ctl, |
568 Node* obj, // containing obj | |
569 Node* adr, // actual adress to store val at | |
570 const TypePtr* adr_type, | |
571 Node* val, | |
825 | 572 const TypeOopPtr* val_type, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
573 BasicType bt) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
574 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
|
575 } |
0 | 576 |
577 Node* store_oop_to_array(Node* ctl, | |
578 Node* obj, // containing obj | |
579 Node* adr, // actual adress to store val at | |
580 const TypePtr* adr_type, | |
581 Node* val, | |
825 | 582 const TypeOopPtr* val_type, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
583 BasicType bt) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
584 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
|
585 } |
0 | 586 |
587 // Could be an array or object we don't know at compile time (unsafe ref.) | |
588 Node* store_oop_to_unknown(Node* ctl, | |
589 Node* obj, // containing obj | |
590 Node* adr, // actual adress to store val at | |
591 const TypePtr* adr_type, | |
592 Node* val, | |
593 BasicType bt); | |
594 | |
595 // 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
|
596 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
|
597 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
|
598 Node* pre_val, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
599 BasicType bt); |
0 | 600 |
601 void post_barrier(Node* ctl, Node* store, Node* obj, Node* adr, uint adr_idx, | |
602 Node* val, BasicType bt, bool use_precise); | |
603 | |
604 // Return addressing for an array element. | |
605 Node* array_element_address(Node* ary, Node* idx, BasicType elembt, | |
606 // Optional constraint on the array size: | |
607 const TypeInt* sizetype = NULL); | |
608 | |
609 // Return a load of array element at idx. | |
610 Node* load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype); | |
611 | |
612 //---------------- Dtrace support -------------------- | |
613 void make_dtrace_method_entry_exit(ciMethod* method, bool is_entry); | |
614 void make_dtrace_method_entry(ciMethod* method) { | |
615 make_dtrace_method_entry_exit(method, true); | |
616 } | |
617 void make_dtrace_method_exit(ciMethod* method) { | |
618 make_dtrace_method_entry_exit(method, false); | |
619 } | |
620 | |
621 //--------------- stub generation ------------------- | |
622 public: | |
623 void gen_stub(address C_function, | |
624 const char *name, | |
625 int is_fancy_jump, | |
626 bool pass_tls, | |
627 bool return_pc); | |
628 | |
629 //---------- help for generating calls -------------- | |
630 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
631 // 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
|
632 // 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
|
633 Node* null_check_receiver_before_call(ciMethod* callee) { |
0 | 634 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
|
635 const int nargs = callee->arg_size(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
636 inc_sp(nargs); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
637 Node* n = null_check_receiver(); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
638 dec_sp(nargs); |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
639 return n; |
0 | 640 } |
641 | |
642 // Fill in argument edges for the call from argument(0), argument(1), ... | |
643 // (The next step is to call set_edges_for_java_call.) | |
644 void set_arguments_for_java_call(CallJavaNode* call); | |
645 | |
646 // Fill in non-argument edges for the call. | |
647 // Transform the call, and update the basics: control, i_o, memory. | |
648 // (The next step is usually to call set_results_for_java_call.) | |
649 void set_edges_for_java_call(CallJavaNode* call, | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
650 bool must_throw = false, bool separate_io_proj = false); |
0 | 651 |
652 // Finish up a java call that was started by set_edges_for_java_call. | |
653 // Call add_exception on any throw arising from the call. | |
654 // Return the call result (transformed). | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
655 Node* set_results_for_java_call(CallJavaNode* call, bool separate_io_proj = false); |
0 | 656 |
657 // Similar to set_edges_for_java_call, but simplified for runtime calls. | |
658 void set_predefined_output_for_runtime_call(Node* call) { | |
659 set_predefined_output_for_runtime_call(call, NULL, NULL); | |
660 } | |
661 void set_predefined_output_for_runtime_call(Node* call, | |
662 Node* keep_mem, | |
663 const TypePtr* hook_mem); | |
664 Node* set_predefined_input_for_runtime_call(SafePointNode* call); | |
665 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
666 // Replace the call with the current state of the kit. Requires |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
667 // that the call was generated with separate io_projs so that |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
668 // exceptional control flow can be handled properly. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
669 void replace_call(CallNode* call, Node* result); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
985
diff
changeset
|
670 |
0 | 671 // helper functions for statistics |
672 void increment_counter(address counter_addr); // increment a debug counter | |
673 void increment_counter(Node* counter_addr); // increment a debug counter | |
674 | |
675 // Bail out to the interpreter right now | |
676 // The optional klass is the one causing the trap. | |
677 // The optional reason is debug information written to the compile log. | |
678 // Optional must_throw is the same as with add_safepoint_edges. | |
679 void uncommon_trap(int trap_request, | |
680 ciKlass* klass = NULL, const char* reason_string = NULL, | |
681 bool must_throw = false, bool keep_exact_action = false); | |
682 | |
683 // Shorthand, to avoid saying "Deoptimization::" so many times. | |
684 void uncommon_trap(Deoptimization::DeoptReason reason, | |
685 Deoptimization::DeoptAction action, | |
686 ciKlass* klass = NULL, const char* reason_string = NULL, | |
687 bool must_throw = false, bool keep_exact_action = false) { | |
688 uncommon_trap(Deoptimization::make_trap_request(reason, action), | |
689 klass, reason_string, must_throw, keep_exact_action); | |
690 } | |
691 | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
692 // 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
|
693 virtual int reexecute_sp() { return sp(); } |
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6804
diff
changeset
|
694 |
0 | 695 // Report if there were too many traps at the current method and bci. |
696 // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. | |
697 // If there is no MDO at all, report no trap unless told to assume it. | |
698 bool too_many_traps(Deoptimization::DeoptReason reason) { | |
699 return C->too_many_traps(method(), bci(), reason); | |
700 } | |
701 | |
702 // Report if there were too many recompiles at the current method and bci. | |
703 bool too_many_recompiles(Deoptimization::DeoptReason reason) { | |
704 return C->too_many_recompiles(method(), bci(), reason); | |
705 } | |
706 | |
707 // Returns the object (if any) which was created the moment before. | |
708 Node* just_allocated_object(Node* current_control); | |
709 | |
710 static bool use_ReduceInitialCardMarks() { | |
711 return (ReduceInitialCardMarks | |
712 && Universe::heap()->can_elide_tlab_store_barriers()); | |
713 } | |
714 | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
715 // Sync Ideal and Graph kits. |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
716 void sync_kit(IdealKit& ideal); |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
717 void final_sync(IdealKit& ideal); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
718 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
825
diff
changeset
|
719 // 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
|
720 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
|
721 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
|
722 |
12169
29aa8936f03c
8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents:
7194
diff
changeset
|
723 // Allow reordering of pre-barrier with oop store and/or post-barrier. |
29aa8936f03c
8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents:
7194
diff
changeset
|
724 // Used for load_store operations which loads old value. |
29aa8936f03c
8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents:
7194
diff
changeset
|
725 bool can_move_pre_barrier() const; |
29aa8936f03c
8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents:
7194
diff
changeset
|
726 |
342 | 727 // G1 pre/post barriers |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
728 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
|
729 Node* obj, |
342 | 730 Node* adr, |
731 uint alias_idx, | |
732 Node* val, | |
825 | 733 const TypeOopPtr* val_type, |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2383
diff
changeset
|
734 Node* pre_val, |
342 | 735 BasicType bt); |
736 | |
737 void g1_write_barrier_post(Node* store, | |
738 Node* obj, | |
739 Node* adr, | |
740 uint alias_idx, | |
741 Node* val, | |
742 BasicType bt, | |
743 bool use_precise); | |
744 // Helper function for g1 | |
745 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
|
746 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
|
747 Node* index, Node* index_adr, |
342 | 748 Node* buffer, const TypeFunc* tf); |
749 | |
750 public: | |
0 | 751 // Helper function to round double arguments before a call |
752 void round_double_arguments(ciMethod* dest_method); | |
753 void round_double_result(ciMethod* dest_method); | |
754 | |
755 // rounding for strict float precision conformance | |
756 Node* precision_rounding(Node* n); | |
757 | |
758 // rounding for strict double precision conformance | |
759 Node* dprecision_rounding(Node* n); | |
760 | |
761 // rounding for non-strict double stores | |
762 Node* dstore_rounding(Node* n); | |
763 | |
764 // Helper functions for fast/slow path codes | |
765 Node* opt_iff(Node* region, Node* iff); | |
766 Node* make_runtime_call(int flags, | |
767 const TypeFunc* call_type, address call_addr, | |
768 const char* call_name, | |
769 const TypePtr* adr_type, // NULL if no memory effects | |
770 Node* parm0 = NULL, Node* parm1 = NULL, | |
771 Node* parm2 = NULL, Node* parm3 = NULL, | |
772 Node* parm4 = NULL, Node* parm5 = NULL, | |
773 Node* parm6 = NULL, Node* parm7 = NULL); | |
774 enum { // flag values for make_runtime_call | |
775 RC_NO_FP = 1, // CallLeafNoFPNode | |
776 RC_NO_IO = 2, // do not hook IO edges | |
777 RC_NO_LEAF = 4, // CallStaticJavaNode | |
778 RC_MUST_THROW = 8, // flag passed to add_safepoint_edges | |
779 RC_NARROW_MEM = 16, // input memory is same as output | |
780 RC_UNCOMMON = 32, // freq. expected to be like uncommon trap | |
781 RC_LEAF = 0 // null value: no flags set | |
782 }; | |
783 | |
784 // merge in all memory slices from new_mem, along the given path | |
785 void merge_memory(Node* new_mem, Node* region, int new_path); | |
786 void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj); | |
787 | |
788 // Helper functions to build synchronizations | |
789 int next_monitor(); | |
790 Node* insert_mem_bar(int opcode, Node* precedent = NULL); | |
791 Node* insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent = NULL); | |
792 // Optional 'precedent' is appended as an extra edge, to force ordering. | |
793 FastLockNode* shared_lock(Node* obj); | |
794 void shared_unlock(Node* box, Node* obj); | |
795 | |
796 // 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
|
797 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 | 798 |
799 // Generate an instance-of idiom. Used by both the instance-of bytecode | |
800 // and the reflective instance-of call. | |
12966 | 801 Node* gen_instanceof(Node *subobj, Node* superkls, bool safe_for_replace = false); |
0 | 802 |
803 // Generate a check-cast idiom. Used by both the check-cast bytecode | |
804 // and the array-store bytecode | |
805 Node* gen_checkcast( Node *subobj, Node* superkls, | |
806 Node* *failure_control = NULL ); | |
807 | |
808 // Generate a subtyping check. Takes as input the subtype and supertype. | |
809 // Returns 2 values: sets the default control() to the true path and | |
810 // returns the false path. Only reads from constant memory taken from the | |
811 // default memory; does not write anything. It also doesn't take in an | |
812 // Object; if you wish to check an Object you need to load the Object's | |
813 // class prior to coming here. | |
814 Node* gen_subtype_check(Node* subklass, Node* superklass); | |
815 | |
816 // Static parse-time type checking logic for gen_subtype_check: | |
817 enum { SSC_always_false, SSC_always_true, SSC_easy_test, SSC_full_test }; | |
818 int static_subtype_check(ciKlass* superk, ciKlass* subk); | |
819 | |
820 // Exact type check used for predicted calls and casts. | |
821 // Rewrites (*casted_receiver) to be casted to the stronger type. | |
822 // (Caller is responsible for doing replace_in_map.) | |
823 Node* type_check_receiver(Node* receiver, ciKlass* klass, float prob, | |
824 Node* *casted_receiver); | |
825 | |
826 // implementation of object creation | |
827 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
|
828 const TypeOopPtr* oop_type); |
0 | 829 Node* get_layout_helper(Node* klass_node, jint& constant_value); |
830 Node* new_instance(Node* klass_node, | |
831 Node* slow_test = NULL, | |
832 Node* *return_size_val = NULL); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
579
diff
changeset
|
833 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
|
834 Node* *return_size_val = NULL); |
0 | 835 |
6057 | 836 // java.lang.String helpers |
837 Node* load_String_offset(Node* ctrl, Node* str); | |
838 Node* load_String_length(Node* ctrl, Node* str); | |
839 Node* load_String_value(Node* ctrl, Node* str); | |
840 void store_String_offset(Node* ctrl, Node* str, Node* value); | |
841 void store_String_length(Node* ctrl, Node* str, Node* value); | |
842 void store_String_value(Node* ctrl, Node* str, Node* value); | |
843 | |
0 | 844 // Handy for making control flow |
845 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
|
846 IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's |
0 | 847 _gvn.set_type(iff, iff->Value(&_gvn)); // Value may be known at parse-time |
848 // Place 'if' on worklist if it will be in graph | |
849 if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later | |
850 return iff; | |
851 } | |
852 | |
853 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
|
854 IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's |
0 | 855 _gvn.transform(iff); // Value may be known at parse-time |
856 // Place 'if' on worklist if it will be in graph | |
857 if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later | |
858 return iff; | |
859 } | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
860 |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
861 // Insert a loop predicate into the graph |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
862 void add_predicate(int nargs = 0); |
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
863 void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs); |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12169
diff
changeset
|
864 |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12169
diff
changeset
|
865 // Produce new array node of stable type |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12169
diff
changeset
|
866 Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type); |
0 | 867 }; |
868 | |
869 // Helper class to support building of control flow branches. Upon | |
870 // creation the map and sp at bci are cloned and restored upon de- | |
871 // struction. Typical use: | |
872 // | |
873 // { PreserveJVMState pjvms(this); | |
874 // // code of new branch | |
875 // } | |
876 // // here the JVM state at bci is established | |
877 | |
878 class PreserveJVMState: public StackObj { | |
879 protected: | |
880 GraphKit* _kit; | |
881 #ifdef ASSERT | |
882 int _block; // PO of current block, if a Parse | |
883 int _bci; | |
884 #endif | |
885 SafePointNode* _map; | |
886 uint _sp; | |
887 | |
888 public: | |
889 PreserveJVMState(GraphKit* kit, bool clone_map = true); | |
890 ~PreserveJVMState(); | |
891 }; | |
892 | |
893 // Helper class to build cutouts of the form if (p) ; else {x...}. | |
894 // The code {x...} must not fall through. | |
895 // The kit's main flow of control is set to the "then" continuation of if(p). | |
896 class BuildCutout: public PreserveJVMState { | |
897 public: | |
898 BuildCutout(GraphKit* kit, Node* p, float prob, float cnt = COUNT_UNKNOWN); | |
899 ~BuildCutout(); | |
900 }; | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
901 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
902 // 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
|
903 // them back |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
904 class PreserveReexecuteState: public StackObj { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
905 protected: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
906 GraphKit* _kit; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
907 uint _sp; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
908 JVMState::ReexecuteState _reexecute; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
909 |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
910 public: |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
911 PreserveReexecuteState(GraphKit* kit); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
912 ~PreserveReexecuteState(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
851
diff
changeset
|
913 }; |
1972 | 914 |
915 #endif // SHARE_VM_OPTO_GRAPHKIT_HPP |