Mercurial > hg > truffle
annotate src/share/vm/c1/c1_Instruction.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | ac637b7220d1 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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:
1378
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
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:
1378
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_C1_C1_INSTRUCTION_HPP |
26 #define SHARE_VM_C1_C1_INSTRUCTION_HPP | |
27 | |
28 #include "c1/c1_Compilation.hpp" | |
29 #include "c1/c1_LIR.hpp" | |
30 #include "c1/c1_ValueType.hpp" | |
31 #include "ci/ciField.hpp" | |
32 | |
0 | 33 // Predefined classes |
34 class ciField; | |
35 class ValueStack; | |
36 class InstructionPrinter; | |
37 class IRScope; | |
38 class LIR_OprDesc; | |
39 typedef LIR_OprDesc* LIR_Opr; | |
40 | |
41 | |
42 // Instruction class hierarchy | |
43 // | |
44 // All leaf classes in the class hierarchy are concrete classes | |
45 // (i.e., are instantiated). All other classes are abstract and | |
46 // serve factoring. | |
47 | |
48 class Instruction; | |
49 class Phi; | |
50 class Local; | |
51 class Constant; | |
52 class AccessField; | |
53 class LoadField; | |
54 class StoreField; | |
55 class AccessArray; | |
56 class ArrayLength; | |
57 class AccessIndexed; | |
58 class LoadIndexed; | |
59 class StoreIndexed; | |
60 class NegateOp; | |
61 class Op2; | |
62 class ArithmeticOp; | |
63 class ShiftOp; | |
64 class LogicOp; | |
65 class CompareOp; | |
66 class IfOp; | |
67 class Convert; | |
68 class NullCheck; | |
69 class OsrEntry; | |
70 class ExceptionObject; | |
71 class StateSplit; | |
72 class Invoke; | |
73 class NewInstance; | |
74 class NewArray; | |
75 class NewTypeArray; | |
76 class NewObjectArray; | |
77 class NewMultiArray; | |
78 class TypeCheck; | |
79 class CheckCast; | |
80 class InstanceOf; | |
81 class AccessMonitor; | |
82 class MonitorEnter; | |
83 class MonitorExit; | |
84 class Intrinsic; | |
85 class BlockBegin; | |
86 class BlockEnd; | |
87 class Goto; | |
88 class If; | |
89 class IfInstanceOf; | |
90 class Switch; | |
91 class TableSwitch; | |
92 class LookupSwitch; | |
93 class Return; | |
94 class Throw; | |
95 class Base; | |
96 class RoundFP; | |
97 class UnsafeOp; | |
98 class UnsafeRawOp; | |
99 class UnsafeGetRaw; | |
100 class UnsafePutRaw; | |
101 class UnsafeObjectOp; | |
102 class UnsafeGetObject; | |
103 class UnsafePutObject; | |
104 class UnsafePrefetch; | |
105 class UnsafePrefetchRead; | |
106 class UnsafePrefetchWrite; | |
107 class ProfileCall; | |
1783 | 108 class ProfileInvoke; |
0 | 109 |
110 // A Value is a reference to the instruction creating the value | |
111 typedef Instruction* Value; | |
112 define_array(ValueArray, Value) | |
113 define_stack(Values, ValueArray) | |
114 | |
115 define_array(ValueStackArray, ValueStack*) | |
116 define_stack(ValueStackStack, ValueStackArray) | |
117 | |
118 // BlockClosure is the base class for block traversal/iteration. | |
119 | |
120 class BlockClosure: public CompilationResourceObj { | |
121 public: | |
122 virtual void block_do(BlockBegin* block) = 0; | |
123 }; | |
124 | |
125 | |
1584 | 126 // A simple closure class for visiting the values of an Instruction |
127 class ValueVisitor: public StackObj { | |
128 public: | |
129 virtual void visit(Value* v) = 0; | |
130 }; | |
131 | |
132 | |
0 | 133 // Some array and list classes |
134 define_array(BlockBeginArray, BlockBegin*) | |
135 define_stack(_BlockList, BlockBeginArray) | |
136 | |
137 class BlockList: public _BlockList { | |
138 public: | |
139 BlockList(): _BlockList() {} | |
140 BlockList(const int size): _BlockList(size) {} | |
141 BlockList(const int size, BlockBegin* init): _BlockList(size, init) {} | |
142 | |
143 void iterate_forward(BlockClosure* closure); | |
144 void iterate_backward(BlockClosure* closure); | |
145 void blocks_do(void f(BlockBegin*)); | |
1584 | 146 void values_do(ValueVisitor* f); |
0 | 147 void print(bool cfg_only = false, bool live_only = false) PRODUCT_RETURN; |
148 }; | |
149 | |
150 | |
151 // InstructionVisitors provide type-based dispatch for instructions. | |
152 // For each concrete Instruction class X, a virtual function do_X is | |
153 // provided. Functionality that needs to be implemented for all classes | |
154 // (e.g., printing, code generation) is factored out into a specialised | |
155 // visitor instead of added to the Instruction classes itself. | |
156 | |
157 class InstructionVisitor: public StackObj { | |
158 public: | |
159 virtual void do_Phi (Phi* x) = 0; | |
160 virtual void do_Local (Local* x) = 0; | |
161 virtual void do_Constant (Constant* x) = 0; | |
162 virtual void do_LoadField (LoadField* x) = 0; | |
163 virtual void do_StoreField (StoreField* x) = 0; | |
164 virtual void do_ArrayLength (ArrayLength* x) = 0; | |
165 virtual void do_LoadIndexed (LoadIndexed* x) = 0; | |
166 virtual void do_StoreIndexed (StoreIndexed* x) = 0; | |
167 virtual void do_NegateOp (NegateOp* x) = 0; | |
168 virtual void do_ArithmeticOp (ArithmeticOp* x) = 0; | |
169 virtual void do_ShiftOp (ShiftOp* x) = 0; | |
170 virtual void do_LogicOp (LogicOp* x) = 0; | |
171 virtual void do_CompareOp (CompareOp* x) = 0; | |
172 virtual void do_IfOp (IfOp* x) = 0; | |
173 virtual void do_Convert (Convert* x) = 0; | |
174 virtual void do_NullCheck (NullCheck* x) = 0; | |
175 virtual void do_Invoke (Invoke* x) = 0; | |
176 virtual void do_NewInstance (NewInstance* x) = 0; | |
177 virtual void do_NewTypeArray (NewTypeArray* x) = 0; | |
178 virtual void do_NewObjectArray (NewObjectArray* x) = 0; | |
179 virtual void do_NewMultiArray (NewMultiArray* x) = 0; | |
180 virtual void do_CheckCast (CheckCast* x) = 0; | |
181 virtual void do_InstanceOf (InstanceOf* x) = 0; | |
182 virtual void do_MonitorEnter (MonitorEnter* x) = 0; | |
183 virtual void do_MonitorExit (MonitorExit* x) = 0; | |
184 virtual void do_Intrinsic (Intrinsic* x) = 0; | |
185 virtual void do_BlockBegin (BlockBegin* x) = 0; | |
186 virtual void do_Goto (Goto* x) = 0; | |
187 virtual void do_If (If* x) = 0; | |
188 virtual void do_IfInstanceOf (IfInstanceOf* x) = 0; | |
189 virtual void do_TableSwitch (TableSwitch* x) = 0; | |
190 virtual void do_LookupSwitch (LookupSwitch* x) = 0; | |
191 virtual void do_Return (Return* x) = 0; | |
192 virtual void do_Throw (Throw* x) = 0; | |
193 virtual void do_Base (Base* x) = 0; | |
194 virtual void do_OsrEntry (OsrEntry* x) = 0; | |
195 virtual void do_ExceptionObject(ExceptionObject* x) = 0; | |
196 virtual void do_RoundFP (RoundFP* x) = 0; | |
197 virtual void do_UnsafeGetRaw (UnsafeGetRaw* x) = 0; | |
198 virtual void do_UnsafePutRaw (UnsafePutRaw* x) = 0; | |
199 virtual void do_UnsafeGetObject(UnsafeGetObject* x) = 0; | |
200 virtual void do_UnsafePutObject(UnsafePutObject* x) = 0; | |
201 virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x) = 0; | |
202 virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; | |
203 virtual void do_ProfileCall (ProfileCall* x) = 0; | |
1783 | 204 virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; |
0 | 205 }; |
206 | |
207 | |
208 // Hashing support | |
209 // | |
210 // Note: This hash functions affect the performance | |
211 // of ValueMap - make changes carefully! | |
212 | |
213 #define HASH1(x1 ) ((intx)(x1)) | |
214 #define HASH2(x1, x2 ) ((HASH1(x1 ) << 7) ^ HASH1(x2)) | |
215 #define HASH3(x1, x2, x3 ) ((HASH2(x1, x2 ) << 7) ^ HASH1(x3)) | |
216 #define HASH4(x1, x2, x3, x4) ((HASH3(x1, x2, x3) << 7) ^ HASH1(x4)) | |
217 | |
218 | |
219 // The following macros are used to implement instruction-specific hashing. | |
220 // By default, each instruction implements hash() and is_equal(Value), used | |
221 // for value numbering/common subexpression elimination. The default imple- | |
222 // mentation disables value numbering. Each instruction which can be value- | |
223 // numbered, should define corresponding hash() and is_equal(Value) functions | |
224 // via the macros below. The f arguments specify all the values/op codes, etc. | |
225 // that need to be identical for two instructions to be identical. | |
226 // | |
227 // Note: The default implementation of hash() returns 0 in order to indicate | |
228 // that the instruction should not be considered for value numbering. | |
229 // The currently used hash functions do not guarantee that never a 0 | |
230 // is produced. While this is still correct, it may be a performance | |
231 // bug (no value numbering for that node). However, this situation is | |
232 // so unlikely, that we are not going to handle it specially. | |
233 | |
234 #define HASHING1(class_name, enabled, f1) \ | |
235 virtual intx hash() const { \ | |
236 return (enabled) ? HASH2(name(), f1) : 0; \ | |
237 } \ | |
238 virtual bool is_equal(Value v) const { \ | |
239 if (!(enabled) ) return false; \ | |
240 class_name* _v = v->as_##class_name(); \ | |
241 if (_v == NULL ) return false; \ | |
242 if (f1 != _v->f1) return false; \ | |
243 return true; \ | |
244 } \ | |
245 | |
246 | |
247 #define HASHING2(class_name, enabled, f1, f2) \ | |
248 virtual intx hash() const { \ | |
249 return (enabled) ? HASH3(name(), f1, f2) : 0; \ | |
250 } \ | |
251 virtual bool is_equal(Value v) const { \ | |
252 if (!(enabled) ) return false; \ | |
253 class_name* _v = v->as_##class_name(); \ | |
254 if (_v == NULL ) return false; \ | |
255 if (f1 != _v->f1) return false; \ | |
256 if (f2 != _v->f2) return false; \ | |
257 return true; \ | |
258 } \ | |
259 | |
260 | |
261 #define HASHING3(class_name, enabled, f1, f2, f3) \ | |
262 virtual intx hash() const { \ | |
263 return (enabled) ? HASH4(name(), f1, f2, f3) : 0; \ | |
264 } \ | |
265 virtual bool is_equal(Value v) const { \ | |
266 if (!(enabled) ) return false; \ | |
267 class_name* _v = v->as_##class_name(); \ | |
268 if (_v == NULL ) return false; \ | |
269 if (f1 != _v->f1) return false; \ | |
270 if (f2 != _v->f2) return false; \ | |
271 if (f3 != _v->f3) return false; \ | |
272 return true; \ | |
273 } \ | |
274 | |
275 | |
276 // The mother of all instructions... | |
277 | |
278 class Instruction: public CompilationResourceObj { | |
279 private: | |
280 int _id; // the unique instruction id | |
1819 | 281 #ifndef PRODUCT |
282 int _printable_bci; // the bci of the instruction for printing | |
283 #endif | |
0 | 284 int _use_count; // the number of instructions refering to this value (w/o prev/next); only roots can have use count = 0 or > 1 |
285 int _pin_state; // set of PinReason describing the reason for pinning | |
286 ValueType* _type; // the instruction value type | |
287 Instruction* _next; // the next instruction if any (NULL for BlockEnd instructions) | |
288 Instruction* _subst; // the substitution instruction if any | |
289 LIR_Opr _operand; // LIR specific information | |
290 unsigned int _flags; // Flag bits | |
291 | |
1819 | 292 ValueStack* _state_before; // Copy of state with input operands still on stack (or NULL) |
293 ValueStack* _exception_state; // Copy of state for exception handling | |
0 | 294 XHandlers* _exception_handlers; // Flat list of exception handlers covering this instruction |
295 | |
296 friend class UseCountComputer; | |
1584 | 297 friend class BlockBegin; |
0 | 298 |
1819 | 299 void update_exception_state(ValueStack* state); |
300 | |
301 bool has_printable_bci() const { return NOT_PRODUCT(_printable_bci != -99) PRODUCT_ONLY(false); } | |
302 | |
0 | 303 protected: |
304 void set_type(ValueType* type) { | |
305 assert(type != NULL, "type must exist"); | |
306 _type = type; | |
307 } | |
308 | |
309 public: | |
1584 | 310 void* operator new(size_t size) { |
311 Compilation* c = Compilation::current(); | |
312 void* res = c->arena()->Amalloc(size); | |
313 ((Instruction*)res)->_id = c->get_next_id(); | |
314 return res; | |
315 } | |
316 | |
0 | 317 enum InstructionFlag { |
318 NeedsNullCheckFlag = 0, | |
319 CanTrapFlag, | |
320 DirectCompareFlag, | |
321 IsEliminatedFlag, | |
322 IsInitializedFlag, | |
323 IsLoadedFlag, | |
324 IsSafepointFlag, | |
325 IsStaticFlag, | |
326 IsStrictfpFlag, | |
327 NeedsStoreCheckFlag, | |
328 NeedsWriteBarrierFlag, | |
329 PreservesStateFlag, | |
330 TargetIsFinalFlag, | |
331 TargetIsLoadedFlag, | |
332 TargetIsStrictfpFlag, | |
333 UnorderedIsTrueFlag, | |
334 NeedsPatchingFlag, | |
335 ThrowIncompatibleClassChangeErrorFlag, | |
336 ProfileMDOFlag, | |
1819 | 337 IsLinkedInBlockFlag, |
0 | 338 InstructionLastFlag |
339 }; | |
340 | |
341 public: | |
342 bool check_flag(InstructionFlag id) const { return (_flags & (1 << id)) != 0; } | |
343 void set_flag(InstructionFlag id, bool f) { _flags = f ? (_flags | (1 << id)) : (_flags & ~(1 << id)); }; | |
344 | |
345 // 'globally' used condition values | |
346 enum Condition { | |
347 eql, neq, lss, leq, gtr, geq | |
348 }; | |
349 | |
350 // Instructions may be pinned for many reasons and under certain conditions | |
351 // with enough knowledge it's possible to safely unpin them. | |
352 enum PinReason { | |
353 PinUnknown = 1 << 0 | |
354 , PinExplicitNullCheck = 1 << 3 | |
355 , PinStackForStateSplit= 1 << 12 | |
356 , PinStateSplitConstructor= 1 << 13 | |
357 , PinGlobalValueNumbering= 1 << 14 | |
358 }; | |
359 | |
360 static Condition mirror(Condition cond); | |
361 static Condition negate(Condition cond); | |
362 | |
363 // initialization | |
1584 | 364 static int number_of_instructions() { |
365 return Compilation::current()->number_of_instructions(); | |
366 } | |
0 | 367 |
368 // creation | |
1824 | 369 Instruction(ValueType* type, ValueStack* state_before = NULL, bool type_is_constant = false) |
1819 | 370 : _use_count(0) |
371 #ifndef PRODUCT | |
372 , _printable_bci(-99) | |
373 #endif | |
0 | 374 , _pin_state(0) |
375 , _type(type) | |
376 , _next(NULL) | |
377 , _subst(NULL) | |
378 , _flags(0) | |
379 , _operand(LIR_OprFact::illegalOpr) | |
1819 | 380 , _state_before(state_before) |
0 | 381 , _exception_handlers(NULL) |
382 { | |
1819 | 383 check_state(state_before); |
0 | 384 assert(type != NULL && (!type->is_constant() || type_is_constant), "type must exist"); |
1819 | 385 update_exception_state(_state_before); |
0 | 386 } |
387 | |
388 // accessors | |
389 int id() const { return _id; } | |
1819 | 390 #ifndef PRODUCT |
391 int printable_bci() const { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; } | |
392 void set_printable_bci(int bci) { NOT_PRODUCT(_printable_bci = bci;) } | |
393 #endif | |
0 | 394 int use_count() const { return _use_count; } |
395 int pin_state() const { return _pin_state; } | |
396 bool is_pinned() const { return _pin_state != 0 || PinAllInstructions; } | |
397 ValueType* type() const { return _type; } | |
398 Instruction* prev(BlockBegin* block); // use carefully, expensive operation | |
399 Instruction* next() const { return _next; } | |
400 bool has_subst() const { return _subst != NULL; } | |
401 Instruction* subst() { return _subst == NULL ? this : _subst->subst(); } | |
402 LIR_Opr operand() const { return _operand; } | |
403 | |
404 void set_needs_null_check(bool f) { set_flag(NeedsNullCheckFlag, f); } | |
405 bool needs_null_check() const { return check_flag(NeedsNullCheckFlag); } | |
1819 | 406 bool is_linked() const { return check_flag(IsLinkedInBlockFlag); } |
407 bool can_be_linked() { return as_Local() == NULL && as_Phi() == NULL; } | |
0 | 408 |
409 bool has_uses() const { return use_count() > 0; } | |
1819 | 410 ValueStack* state_before() const { return _state_before; } |
411 ValueStack* exception_state() const { return _exception_state; } | |
412 virtual bool needs_exception_state() const { return true; } | |
0 | 413 XHandlers* exception_handlers() const { return _exception_handlers; } |
414 | |
415 // manipulation | |
416 void pin(PinReason reason) { _pin_state |= reason; } | |
417 void pin() { _pin_state |= PinUnknown; } | |
418 // DANGEROUS: only used by EliminateStores | |
419 void unpin(PinReason reason) { assert((reason & PinUnknown) == 0, "can't unpin unknown state"); _pin_state &= ~reason; } | |
1819 | 420 |
421 Instruction* set_next(Instruction* next) { | |
422 assert(next->has_printable_bci(), "_printable_bci should have been set"); | |
423 assert(next != NULL, "must not be NULL"); | |
424 assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next"); | |
425 assert(next->can_be_linked(), "shouldn't link these instructions into list"); | |
426 | |
427 next->set_flag(Instruction::IsLinkedInBlockFlag, true); | |
428 _next = next; | |
429 return next; | |
430 } | |
0 | 431 |
432 Instruction* set_next(Instruction* next, int bci) { | |
1819 | 433 #ifndef PRODUCT |
434 next->set_printable_bci(bci); | |
435 #endif | |
436 return set_next(next); | |
0 | 437 } |
438 | |
439 void set_subst(Instruction* subst) { | |
440 assert(subst == NULL || | |
441 type()->base() == subst->type()->base() || | |
442 subst->type()->base() == illegalType, "type can't change"); | |
443 _subst = subst; | |
444 } | |
445 void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; } | |
1819 | 446 void set_exception_state(ValueStack* s) { check_state(s); _exception_state = s; } |
0 | 447 |
448 // machine-specifics | |
449 void set_operand(LIR_Opr operand) { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; } | |
450 void clear_operand() { _operand = LIR_OprFact::illegalOpr; } | |
451 | |
452 // generic | |
453 virtual Instruction* as_Instruction() { return this; } // to satisfy HASHING1 macro | |
1899 | 454 virtual Phi* as_Phi() { return NULL; } |
0 | 455 virtual Local* as_Local() { return NULL; } |
456 virtual Constant* as_Constant() { return NULL; } | |
457 virtual AccessField* as_AccessField() { return NULL; } | |
458 virtual LoadField* as_LoadField() { return NULL; } | |
459 virtual StoreField* as_StoreField() { return NULL; } | |
460 virtual AccessArray* as_AccessArray() { return NULL; } | |
461 virtual ArrayLength* as_ArrayLength() { return NULL; } | |
462 virtual AccessIndexed* as_AccessIndexed() { return NULL; } | |
463 virtual LoadIndexed* as_LoadIndexed() { return NULL; } | |
464 virtual StoreIndexed* as_StoreIndexed() { return NULL; } | |
465 virtual NegateOp* as_NegateOp() { return NULL; } | |
466 virtual Op2* as_Op2() { return NULL; } | |
467 virtual ArithmeticOp* as_ArithmeticOp() { return NULL; } | |
468 virtual ShiftOp* as_ShiftOp() { return NULL; } | |
469 virtual LogicOp* as_LogicOp() { return NULL; } | |
470 virtual CompareOp* as_CompareOp() { return NULL; } | |
471 virtual IfOp* as_IfOp() { return NULL; } | |
472 virtual Convert* as_Convert() { return NULL; } | |
473 virtual NullCheck* as_NullCheck() { return NULL; } | |
474 virtual OsrEntry* as_OsrEntry() { return NULL; } | |
475 virtual StateSplit* as_StateSplit() { return NULL; } | |
476 virtual Invoke* as_Invoke() { return NULL; } | |
477 virtual NewInstance* as_NewInstance() { return NULL; } | |
478 virtual NewArray* as_NewArray() { return NULL; } | |
479 virtual NewTypeArray* as_NewTypeArray() { return NULL; } | |
480 virtual NewObjectArray* as_NewObjectArray() { return NULL; } | |
481 virtual NewMultiArray* as_NewMultiArray() { return NULL; } | |
482 virtual TypeCheck* as_TypeCheck() { return NULL; } | |
483 virtual CheckCast* as_CheckCast() { return NULL; } | |
484 virtual InstanceOf* as_InstanceOf() { return NULL; } | |
485 virtual AccessMonitor* as_AccessMonitor() { return NULL; } | |
486 virtual MonitorEnter* as_MonitorEnter() { return NULL; } | |
487 virtual MonitorExit* as_MonitorExit() { return NULL; } | |
488 virtual Intrinsic* as_Intrinsic() { return NULL; } | |
489 virtual BlockBegin* as_BlockBegin() { return NULL; } | |
490 virtual BlockEnd* as_BlockEnd() { return NULL; } | |
491 virtual Goto* as_Goto() { return NULL; } | |
492 virtual If* as_If() { return NULL; } | |
493 virtual IfInstanceOf* as_IfInstanceOf() { return NULL; } | |
494 virtual TableSwitch* as_TableSwitch() { return NULL; } | |
495 virtual LookupSwitch* as_LookupSwitch() { return NULL; } | |
496 virtual Return* as_Return() { return NULL; } | |
497 virtual Throw* as_Throw() { return NULL; } | |
498 virtual Base* as_Base() { return NULL; } | |
499 virtual RoundFP* as_RoundFP() { return NULL; } | |
500 virtual ExceptionObject* as_ExceptionObject() { return NULL; } | |
501 virtual UnsafeOp* as_UnsafeOp() { return NULL; } | |
502 | |
503 virtual void visit(InstructionVisitor* v) = 0; | |
504 | |
505 virtual bool can_trap() const { return false; } | |
506 | |
1584 | 507 virtual void input_values_do(ValueVisitor* f) = 0; |
1819 | 508 virtual void state_values_do(ValueVisitor* f); |
1584 | 509 virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ } |
510 void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); } | |
0 | 511 |
512 virtual ciType* exact_type() const { return NULL; } | |
513 virtual ciType* declared_type() const { return NULL; } | |
514 | |
515 // hashing | |
516 virtual const char* name() const = 0; | |
517 HASHING1(Instruction, false, id()) // hashing disabled by default | |
518 | |
519 // debugging | |
1819 | 520 static void check_state(ValueStack* state) PRODUCT_RETURN; |
0 | 521 void print() PRODUCT_RETURN; |
522 void print_line() PRODUCT_RETURN; | |
523 void print(InstructionPrinter& ip) PRODUCT_RETURN; | |
524 }; | |
525 | |
526 | |
527 // The following macros are used to define base (i.e., non-leaf) | |
528 // and leaf instruction classes. They define class-name related | |
529 // generic functionality in one place. | |
530 | |
531 #define BASE(class_name, super_class_name) \ | |
532 class class_name: public super_class_name { \ | |
533 public: \ | |
534 virtual class_name* as_##class_name() { return this; } \ | |
535 | |
536 | |
537 #define LEAF(class_name, super_class_name) \ | |
538 BASE(class_name, super_class_name) \ | |
539 public: \ | |
540 virtual const char* name() const { return #class_name; } \ | |
541 virtual void visit(InstructionVisitor* v) { v->do_##class_name(this); } \ | |
542 | |
543 | |
544 // Debugging support | |
545 | |
1584 | 546 |
0 | 547 #ifdef ASSERT |
1584 | 548 class AssertValues: public ValueVisitor { |
549 void visit(Value* x) { assert((*x) != NULL, "value must exist"); } | |
550 }; | |
551 #define ASSERT_VALUES { AssertValues assert_value; values_do(&assert_value); } | |
0 | 552 #else |
553 #define ASSERT_VALUES | |
554 #endif // ASSERT | |
555 | |
556 | |
557 // A Phi is a phi function in the sense of SSA form. It stands for | |
558 // the value of a local variable at the beginning of a join block. | |
559 // A Phi consists of n operands, one for every incoming branch. | |
560 | |
561 LEAF(Phi, Instruction) | |
562 private: | |
563 BlockBegin* _block; // the block to which the phi function belongs | |
564 int _pf_flags; // the flags of the phi function | |
565 int _index; // to value on operand stack (index < 0) or to local | |
566 public: | |
567 // creation | |
568 Phi(ValueType* type, BlockBegin* b, int index) | |
569 : Instruction(type->base()) | |
570 , _pf_flags(0) | |
571 , _block(b) | |
572 , _index(index) | |
573 { | |
574 if (type->is_illegal()) { | |
575 make_illegal(); | |
576 } | |
577 } | |
578 | |
579 // flags | |
580 enum Flag { | |
581 no_flag = 0, | |
582 visited = 1 << 0, | |
583 cannot_simplify = 1 << 1 | |
584 }; | |
585 | |
586 // accessors | |
587 bool is_local() const { return _index >= 0; } | |
588 bool is_on_stack() const { return !is_local(); } | |
589 int local_index() const { assert(is_local(), ""); return _index; } | |
590 int stack_index() const { assert(is_on_stack(), ""); return -(_index+1); } | |
591 | |
592 Value operand_at(int i) const; | |
593 int operand_count() const; | |
594 | |
595 BlockBegin* block() const { return _block; } | |
596 | |
597 void set(Flag f) { _pf_flags |= f; } | |
598 void clear(Flag f) { _pf_flags &= ~f; } | |
599 bool is_set(Flag f) const { return (_pf_flags & f) != 0; } | |
600 | |
601 // Invalidates phis corresponding to merges of locals of two different types | |
602 // (these should never be referenced, otherwise the bytecodes are illegal) | |
603 void make_illegal() { | |
604 set(cannot_simplify); | |
605 set_type(illegalType); | |
606 } | |
607 | |
608 bool is_illegal() const { | |
609 return type()->is_illegal(); | |
610 } | |
611 | |
612 // generic | |
1584 | 613 virtual void input_values_do(ValueVisitor* f) { |
0 | 614 } |
615 }; | |
616 | |
617 | |
618 // A local is a placeholder for an incoming argument to a function call. | |
619 LEAF(Local, Instruction) | |
620 private: | |
621 int _java_index; // the local index within the method to which the local belongs | |
622 public: | |
623 // creation | |
624 Local(ValueType* type, int index) | |
625 : Instruction(type) | |
626 , _java_index(index) | |
627 {} | |
628 | |
629 // accessors | |
630 int java_index() const { return _java_index; } | |
631 | |
632 // generic | |
1584 | 633 virtual void input_values_do(ValueVisitor* f) { /* no values */ } |
0 | 634 }; |
635 | |
636 | |
637 LEAF(Constant, Instruction) | |
638 public: | |
639 // creation | |
640 Constant(ValueType* type): | |
1819 | 641 Instruction(type, NULL, true) |
642 { | |
0 | 643 assert(type->is_constant(), "must be a constant"); |
644 } | |
645 | |
1819 | 646 Constant(ValueType* type, ValueStack* state_before): |
647 Instruction(type, state_before, true) | |
648 { | |
649 assert(state_before != NULL, "only used for constants which need patching"); | |
0 | 650 assert(type->is_constant(), "must be a constant"); |
651 // since it's patching it needs to be pinned | |
652 pin(); | |
653 } | |
654 | |
1819 | 655 virtual bool can_trap() const { return state_before() != NULL; } |
1584 | 656 virtual void input_values_do(ValueVisitor* f) { /* no values */ } |
0 | 657 |
658 virtual intx hash() const; | |
659 virtual bool is_equal(Value v) const; | |
660 | |
1899 | 661 |
662 enum CompareResult { not_comparable = -1, cond_false, cond_true }; | |
663 | |
664 virtual CompareResult compare(Instruction::Condition condition, Value right) const; | |
665 BlockBegin* compare(Instruction::Condition cond, Value right, | |
666 BlockBegin* true_sux, BlockBegin* false_sux) const { | |
667 switch (compare(cond, right)) { | |
668 case not_comparable: | |
669 return NULL; | |
670 case cond_false: | |
671 return false_sux; | |
672 case cond_true: | |
673 return true_sux; | |
674 default: | |
675 ShouldNotReachHere(); | |
676 return NULL; | |
677 } | |
678 } | |
0 | 679 }; |
680 | |
681 | |
682 BASE(AccessField, Instruction) | |
683 private: | |
684 Value _obj; | |
685 int _offset; | |
686 ciField* _field; | |
687 NullCheck* _explicit_null_check; // For explicit null check elimination | |
688 | |
689 public: | |
690 // creation | |
1819 | 691 AccessField(Value obj, int offset, ciField* field, bool is_static, |
0 | 692 ValueStack* state_before, bool is_loaded, bool is_initialized) |
1819 | 693 : Instruction(as_ValueType(field->type()->basic_type()), state_before) |
0 | 694 , _obj(obj) |
695 , _offset(offset) | |
696 , _field(field) | |
697 , _explicit_null_check(NULL) | |
698 { | |
699 set_needs_null_check(!is_static); | |
700 set_flag(IsLoadedFlag, is_loaded); | |
701 set_flag(IsInitializedFlag, is_initialized); | |
702 set_flag(IsStaticFlag, is_static); | |
703 ASSERT_VALUES | |
704 if (!is_loaded || (PatchALot && !field->is_volatile())) { | |
705 // need to patch if the holder wasn't loaded or we're testing | |
706 // using PatchALot. Don't allow PatchALot for fields which are | |
707 // known to be volatile they aren't patchable. | |
708 set_flag(NeedsPatchingFlag, true); | |
709 } | |
710 // pin of all instructions with memory access | |
711 pin(); | |
712 } | |
713 | |
714 // accessors | |
715 Value obj() const { return _obj; } | |
716 int offset() const { return _offset; } | |
717 ciField* field() const { return _field; } | |
718 BasicType field_type() const { return _field->type()->basic_type(); } | |
719 bool is_static() const { return check_flag(IsStaticFlag); } | |
720 bool is_loaded() const { return check_flag(IsLoadedFlag); } | |
721 bool is_initialized() const { return check_flag(IsInitializedFlag); } | |
722 NullCheck* explicit_null_check() const { return _explicit_null_check; } | |
723 bool needs_patching() const { return check_flag(NeedsPatchingFlag); } | |
724 | |
725 // manipulation | |
1819 | 726 |
0 | 727 // Under certain circumstances, if a previous NullCheck instruction |
728 // proved the target object non-null, we can eliminate the explicit | |
729 // null check and do an implicit one, simply specifying the debug | |
730 // information from the NullCheck. This field should only be consulted | |
731 // if needs_null_check() is true. | |
732 void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } | |
733 | |
734 // generic | |
735 virtual bool can_trap() const { return needs_null_check() || needs_patching(); } | |
1584 | 736 virtual void input_values_do(ValueVisitor* f) { f->visit(&_obj); } |
0 | 737 }; |
738 | |
739 | |
740 LEAF(LoadField, AccessField) | |
741 public: | |
742 // creation | |
1819 | 743 LoadField(Value obj, int offset, ciField* field, bool is_static, |
0 | 744 ValueStack* state_before, bool is_loaded, bool is_initialized) |
1819 | 745 : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized) |
0 | 746 {} |
747 | |
748 ciType* declared_type() const; | |
749 ciType* exact_type() const; | |
750 | |
751 // generic | |
752 HASHING2(LoadField, is_loaded() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if not yet loaded or if volatile | |
753 }; | |
754 | |
755 | |
756 LEAF(StoreField, AccessField) | |
757 private: | |
758 Value _value; | |
759 | |
760 public: | |
761 // creation | |
1819 | 762 StoreField(Value obj, int offset, ciField* field, Value value, bool is_static, |
0 | 763 ValueStack* state_before, bool is_loaded, bool is_initialized) |
1819 | 764 : AccessField(obj, offset, field, is_static, state_before, is_loaded, is_initialized) |
0 | 765 , _value(value) |
766 { | |
767 set_flag(NeedsWriteBarrierFlag, as_ValueType(field_type())->is_object()); | |
768 ASSERT_VALUES | |
769 pin(); | |
770 } | |
771 | |
772 // accessors | |
773 Value value() const { return _value; } | |
774 bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } | |
775 | |
776 // generic | |
1584 | 777 virtual void input_values_do(ValueVisitor* f) { AccessField::input_values_do(f); f->visit(&_value); } |
0 | 778 }; |
779 | |
780 | |
781 BASE(AccessArray, Instruction) | |
782 private: | |
783 Value _array; | |
784 | |
785 public: | |
786 // creation | |
1819 | 787 AccessArray(ValueType* type, Value array, ValueStack* state_before) |
788 : Instruction(type, state_before) | |
0 | 789 , _array(array) |
1819 | 790 { |
0 | 791 set_needs_null_check(true); |
792 ASSERT_VALUES | |
793 pin(); // instruction with side effect (null exception or range check throwing) | |
794 } | |
795 | |
796 Value array() const { return _array; } | |
797 | |
798 // generic | |
799 virtual bool can_trap() const { return needs_null_check(); } | |
1584 | 800 virtual void input_values_do(ValueVisitor* f) { f->visit(&_array); } |
0 | 801 }; |
802 | |
803 | |
804 LEAF(ArrayLength, AccessArray) | |
805 private: | |
806 NullCheck* _explicit_null_check; // For explicit null check elimination | |
807 | |
808 public: | |
809 // creation | |
1819 | 810 ArrayLength(Value array, ValueStack* state_before) |
811 : AccessArray(intType, array, state_before) | |
0 | 812 , _explicit_null_check(NULL) {} |
813 | |
814 // accessors | |
815 NullCheck* explicit_null_check() const { return _explicit_null_check; } | |
816 | |
817 // setters | |
818 // See LoadField::set_explicit_null_check for documentation | |
819 void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } | |
820 | |
821 // generic | |
822 HASHING1(ArrayLength, true, array()->subst()) | |
823 }; | |
824 | |
825 | |
826 BASE(AccessIndexed, AccessArray) | |
827 private: | |
828 Value _index; | |
829 Value _length; | |
830 BasicType _elt_type; | |
831 | |
832 public: | |
833 // creation | |
1819 | 834 AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before) |
835 : AccessArray(as_ValueType(elt_type), array, state_before) | |
0 | 836 , _index(index) |
837 , _length(length) | |
838 , _elt_type(elt_type) | |
839 { | |
840 ASSERT_VALUES | |
841 } | |
842 | |
843 // accessors | |
844 Value index() const { return _index; } | |
845 Value length() const { return _length; } | |
846 BasicType elt_type() const { return _elt_type; } | |
847 | |
848 // perform elimination of range checks involving constants | |
849 bool compute_needs_range_check(); | |
850 | |
851 // generic | |
1584 | 852 virtual void input_values_do(ValueVisitor* f) { AccessArray::input_values_do(f); f->visit(&_index); if (_length != NULL) f->visit(&_length); } |
0 | 853 }; |
854 | |
855 | |
856 LEAF(LoadIndexed, AccessIndexed) | |
857 private: | |
858 NullCheck* _explicit_null_check; // For explicit null check elimination | |
859 | |
860 public: | |
861 // creation | |
1819 | 862 LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before) |
863 : AccessIndexed(array, index, length, elt_type, state_before) | |
0 | 864 , _explicit_null_check(NULL) {} |
865 | |
866 // accessors | |
867 NullCheck* explicit_null_check() const { return _explicit_null_check; } | |
868 | |
869 // setters | |
870 // See LoadField::set_explicit_null_check for documentation | |
871 void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } | |
872 | |
873 ciType* exact_type() const; | |
874 ciType* declared_type() const; | |
875 | |
876 // generic | |
877 HASHING2(LoadIndexed, true, array()->subst(), index()->subst()) | |
878 }; | |
879 | |
880 | |
881 LEAF(StoreIndexed, AccessIndexed) | |
882 private: | |
883 Value _value; | |
884 | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
885 ciMethod* _profiled_method; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
886 int _profiled_bci; |
0 | 887 public: |
888 // creation | |
1819 | 889 StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before) |
890 : AccessIndexed(array, index, length, elt_type, state_before) | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
891 , _value(value), _profiled_method(NULL), _profiled_bci(0) |
0 | 892 { |
893 set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object())); | |
894 set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object())); | |
895 ASSERT_VALUES | |
896 pin(); | |
897 } | |
898 | |
899 // accessors | |
900 Value value() const { return _value; } | |
901 bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } | |
902 bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); } | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
903 // Helpers for methodDataOop profiling |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
904 void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
905 void set_profiled_method(ciMethod* method) { _profiled_method = method; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
906 void set_profiled_bci(int bci) { _profiled_bci = bci; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
907 bool should_profile() const { return check_flag(ProfileMDOFlag); } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
908 ciMethod* profiled_method() const { return _profiled_method; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
909 int profiled_bci() const { return _profiled_bci; } |
0 | 910 // generic |
1584 | 911 virtual void input_values_do(ValueVisitor* f) { AccessIndexed::input_values_do(f); f->visit(&_value); } |
0 | 912 }; |
913 | |
914 | |
915 LEAF(NegateOp, Instruction) | |
916 private: | |
917 Value _x; | |
918 | |
919 public: | |
920 // creation | |
921 NegateOp(Value x) : Instruction(x->type()->base()), _x(x) { | |
922 ASSERT_VALUES | |
923 } | |
924 | |
925 // accessors | |
926 Value x() const { return _x; } | |
927 | |
928 // generic | |
1584 | 929 virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); } |
0 | 930 }; |
931 | |
932 | |
933 BASE(Op2, Instruction) | |
934 private: | |
935 Bytecodes::Code _op; | |
936 Value _x; | |
937 Value _y; | |
938 | |
939 public: | |
940 // creation | |
1819 | 941 Op2(ValueType* type, Bytecodes::Code op, Value x, Value y, ValueStack* state_before = NULL) |
942 : Instruction(type, state_before) | |
943 , _op(op) | |
944 , _x(x) | |
945 , _y(y) | |
946 { | |
0 | 947 ASSERT_VALUES |
948 } | |
949 | |
950 // accessors | |
951 Bytecodes::Code op() const { return _op; } | |
952 Value x() const { return _x; } | |
953 Value y() const { return _y; } | |
954 | |
955 // manipulators | |
956 void swap_operands() { | |
957 assert(is_commutative(), "operation must be commutative"); | |
958 Value t = _x; _x = _y; _y = t; | |
959 } | |
960 | |
961 // generic | |
962 virtual bool is_commutative() const { return false; } | |
1584 | 963 virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); f->visit(&_y); } |
0 | 964 }; |
965 | |
966 | |
967 LEAF(ArithmeticOp, Op2) | |
968 public: | |
969 // creation | |
1819 | 970 ArithmeticOp(Bytecodes::Code op, Value x, Value y, bool is_strictfp, ValueStack* state_before) |
971 : Op2(x->type()->meet(y->type()), op, x, y, state_before) | |
972 { | |
0 | 973 set_flag(IsStrictfpFlag, is_strictfp); |
974 if (can_trap()) pin(); | |
975 } | |
976 | |
977 // accessors | |
978 bool is_strictfp() const { return check_flag(IsStrictfpFlag); } | |
979 | |
980 // generic | |
981 virtual bool is_commutative() const; | |
982 virtual bool can_trap() const; | |
983 HASHING3(Op2, true, op(), x()->subst(), y()->subst()) | |
984 }; | |
985 | |
986 | |
987 LEAF(ShiftOp, Op2) | |
988 public: | |
989 // creation | |
990 ShiftOp(Bytecodes::Code op, Value x, Value s) : Op2(x->type()->base(), op, x, s) {} | |
991 | |
992 // generic | |
993 HASHING3(Op2, true, op(), x()->subst(), y()->subst()) | |
994 }; | |
995 | |
996 | |
997 LEAF(LogicOp, Op2) | |
998 public: | |
999 // creation | |
1000 LogicOp(Bytecodes::Code op, Value x, Value y) : Op2(x->type()->meet(y->type()), op, x, y) {} | |
1001 | |
1002 // generic | |
1003 virtual bool is_commutative() const; | |
1004 HASHING3(Op2, true, op(), x()->subst(), y()->subst()) | |
1005 }; | |
1006 | |
1007 | |
1008 LEAF(CompareOp, Op2) | |
1009 public: | |
1010 // creation | |
1011 CompareOp(Bytecodes::Code op, Value x, Value y, ValueStack* state_before) | |
1819 | 1012 : Op2(intType, op, x, y, state_before) |
0 | 1013 {} |
1014 | |
1015 // generic | |
1016 HASHING3(Op2, true, op(), x()->subst(), y()->subst()) | |
1017 }; | |
1018 | |
1019 | |
1020 LEAF(IfOp, Op2) | |
1021 private: | |
1022 Value _tval; | |
1023 Value _fval; | |
1024 | |
1025 public: | |
1026 // creation | |
1027 IfOp(Value x, Condition cond, Value y, Value tval, Value fval) | |
1028 : Op2(tval->type()->meet(fval->type()), (Bytecodes::Code)cond, x, y) | |
1029 , _tval(tval) | |
1030 , _fval(fval) | |
1031 { | |
1032 ASSERT_VALUES | |
1033 assert(tval->type()->tag() == fval->type()->tag(), "types must match"); | |
1034 } | |
1035 | |
1036 // accessors | |
1037 virtual bool is_commutative() const; | |
1038 Bytecodes::Code op() const { ShouldNotCallThis(); return Bytecodes::_illegal; } | |
1039 Condition cond() const { return (Condition)Op2::op(); } | |
1040 Value tval() const { return _tval; } | |
1041 Value fval() const { return _fval; } | |
1042 | |
1043 // generic | |
1584 | 1044 virtual void input_values_do(ValueVisitor* f) { Op2::input_values_do(f); f->visit(&_tval); f->visit(&_fval); } |
0 | 1045 }; |
1046 | |
1047 | |
1048 LEAF(Convert, Instruction) | |
1049 private: | |
1050 Bytecodes::Code _op; | |
1051 Value _value; | |
1052 | |
1053 public: | |
1054 // creation | |
1055 Convert(Bytecodes::Code op, Value value, ValueType* to_type) : Instruction(to_type), _op(op), _value(value) { | |
1056 ASSERT_VALUES | |
1057 } | |
1058 | |
1059 // accessors | |
1060 Bytecodes::Code op() const { return _op; } | |
1061 Value value() const { return _value; } | |
1062 | |
1063 // generic | |
1584 | 1064 virtual void input_values_do(ValueVisitor* f) { f->visit(&_value); } |
0 | 1065 HASHING2(Convert, true, op(), value()->subst()) |
1066 }; | |
1067 | |
1068 | |
1069 LEAF(NullCheck, Instruction) | |
1070 private: | |
1071 Value _obj; | |
1072 | |
1073 public: | |
1074 // creation | |
1819 | 1075 NullCheck(Value obj, ValueStack* state_before) |
1076 : Instruction(obj->type()->base(), state_before) | |
1077 , _obj(obj) | |
1078 { | |
0 | 1079 ASSERT_VALUES |
1080 set_can_trap(true); | |
1081 assert(_obj->type()->is_object(), "null check must be applied to objects only"); | |
1082 pin(Instruction::PinExplicitNullCheck); | |
1083 } | |
1084 | |
1085 // accessors | |
1086 Value obj() const { return _obj; } | |
1087 | |
1088 // setters | |
1089 void set_can_trap(bool can_trap) { set_flag(CanTrapFlag, can_trap); } | |
1090 | |
1091 // generic | |
1092 virtual bool can_trap() const { return check_flag(CanTrapFlag); /* null-check elimination sets to false */ } | |
1584 | 1093 virtual void input_values_do(ValueVisitor* f) { f->visit(&_obj); } |
0 | 1094 HASHING1(NullCheck, true, obj()->subst()) |
1095 }; | |
1096 | |
1097 | |
1098 BASE(StateSplit, Instruction) | |
1099 private: | |
1100 ValueStack* _state; | |
1101 | |
1102 protected: | |
1103 static void substitute(BlockList& list, BlockBegin* old_block, BlockBegin* new_block); | |
1104 | |
1105 public: | |
1106 // creation | |
1819 | 1107 StateSplit(ValueType* type, ValueStack* state_before = NULL) |
1108 : Instruction(type, state_before) | |
1109 , _state(NULL) | |
1110 { | |
0 | 1111 pin(PinStateSplitConstructor); |
1112 } | |
1113 | |
1114 // accessors | |
1115 ValueStack* state() const { return _state; } | |
1116 IRScope* scope() const; // the state's scope | |
1117 | |
1118 // manipulation | |
1819 | 1119 void set_state(ValueStack* state) { assert(_state == NULL, "overwriting existing state"); check_state(state); _state = state; } |
0 | 1120 |
1121 // generic | |
1584 | 1122 virtual void input_values_do(ValueVisitor* f) { /* no values */ } |
1123 virtual void state_values_do(ValueVisitor* f); | |
0 | 1124 }; |
1125 | |
1126 | |
1127 LEAF(Invoke, StateSplit) | |
1128 private: | |
1295 | 1129 Bytecodes::Code _code; |
1130 Value _recv; | |
1131 Values* _args; | |
1132 BasicTypeList* _signature; | |
1133 int _vtable_index; | |
1134 ciMethod* _target; | |
0 | 1135 |
1136 public: | |
1137 // creation | |
1138 Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, | |
1295 | 1139 int vtable_index, ciMethod* target, ValueStack* state_before); |
0 | 1140 |
1141 // accessors | |
1142 Bytecodes::Code code() const { return _code; } | |
1143 Value receiver() const { return _recv; } | |
1144 bool has_receiver() const { return receiver() != NULL; } | |
1145 int number_of_arguments() const { return _args->length(); } | |
1146 Value argument_at(int i) const { return _args->at(i); } | |
1147 int vtable_index() const { return _vtable_index; } | |
1148 BasicTypeList* signature() const { return _signature; } | |
1149 ciMethod* target() const { return _target; } | |
1150 | |
1151 // Returns false if target is not loaded | |
1152 bool target_is_final() const { return check_flag(TargetIsFinalFlag); } | |
1153 bool target_is_loaded() const { return check_flag(TargetIsLoadedFlag); } | |
1154 // Returns false if target is not loaded | |
1155 bool target_is_strictfp() const { return check_flag(TargetIsStrictfpFlag); } | |
1156 | |
1295 | 1157 // JSR 292 support |
1158 bool is_invokedynamic() const { return code() == Bytecodes::_invokedynamic; } | |
1159 | |
1819 | 1160 virtual bool needs_exception_state() const { return false; } |
1161 | |
0 | 1162 // generic |
1163 virtual bool can_trap() const { return true; } | |
1584 | 1164 virtual void input_values_do(ValueVisitor* f) { |
0 | 1165 StateSplit::input_values_do(f); |
1584 | 1166 if (has_receiver()) f->visit(&_recv); |
1167 for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i)); | |
0 | 1168 } |
1584 | 1169 virtual void state_values_do(ValueVisitor *f); |
0 | 1170 }; |
1171 | |
1172 | |
1173 LEAF(NewInstance, StateSplit) | |
1174 private: | |
1175 ciInstanceKlass* _klass; | |
1176 | |
1177 public: | |
1178 // creation | |
1819 | 1179 NewInstance(ciInstanceKlass* klass, ValueStack* state_before) |
1180 : StateSplit(instanceType, state_before) | |
1181 , _klass(klass) | |
1182 {} | |
0 | 1183 |
1184 // accessors | |
1185 ciInstanceKlass* klass() const { return _klass; } | |
1186 | |
1819 | 1187 virtual bool needs_exception_state() const { return false; } |
1188 | |
0 | 1189 // generic |
1190 virtual bool can_trap() const { return true; } | |
1191 ciType* exact_type() const; | |
1192 }; | |
1193 | |
1194 | |
1195 BASE(NewArray, StateSplit) | |
1196 private: | |
1197 Value _length; | |
1198 | |
1199 public: | |
1200 // creation | |
1819 | 1201 NewArray(Value length, ValueStack* state_before) |
1202 : StateSplit(objectType, state_before) | |
1203 , _length(length) | |
1204 { | |
0 | 1205 // Do not ASSERT_VALUES since length is NULL for NewMultiArray |
1206 } | |
1207 | |
1208 // accessors | |
1209 Value length() const { return _length; } | |
1210 | |
1819 | 1211 virtual bool needs_exception_state() const { return false; } |
1212 | |
0 | 1213 // generic |
1214 virtual bool can_trap() const { return true; } | |
1584 | 1215 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_length); } |
0 | 1216 }; |
1217 | |
1218 | |
1219 LEAF(NewTypeArray, NewArray) | |
1220 private: | |
1221 BasicType _elt_type; | |
1222 | |
1223 public: | |
1224 // creation | |
1819 | 1225 NewTypeArray(Value length, BasicType elt_type, ValueStack* state_before) |
1226 : NewArray(length, state_before) | |
1227 , _elt_type(elt_type) | |
1228 {} | |
0 | 1229 |
1230 // accessors | |
1231 BasicType elt_type() const { return _elt_type; } | |
1232 ciType* exact_type() const; | |
1233 }; | |
1234 | |
1235 | |
1236 LEAF(NewObjectArray, NewArray) | |
1237 private: | |
1238 ciKlass* _klass; | |
1239 | |
1240 public: | |
1241 // creation | |
1242 NewObjectArray(ciKlass* klass, Value length, ValueStack* state_before) : NewArray(length, state_before), _klass(klass) {} | |
1243 | |
1244 // accessors | |
1245 ciKlass* klass() const { return _klass; } | |
1246 ciType* exact_type() const; | |
1247 }; | |
1248 | |
1249 | |
1250 LEAF(NewMultiArray, NewArray) | |
1251 private: | |
1252 ciKlass* _klass; | |
1253 Values* _dims; | |
1254 | |
1255 public: | |
1256 // creation | |
1257 NewMultiArray(ciKlass* klass, Values* dims, ValueStack* state_before) : NewArray(NULL, state_before), _klass(klass), _dims(dims) { | |
1258 ASSERT_VALUES | |
1259 } | |
1260 | |
1261 // accessors | |
1262 ciKlass* klass() const { return _klass; } | |
1263 Values* dims() const { return _dims; } | |
1264 int rank() const { return dims()->length(); } | |
1265 | |
1266 // generic | |
1584 | 1267 virtual void input_values_do(ValueVisitor* f) { |
0 | 1268 // NOTE: we do not call NewArray::input_values_do since "length" |
1269 // is meaningless for a multi-dimensional array; passing the | |
1270 // zeroth element down to NewArray as its length is a bad idea | |
1271 // since there will be a copy in the "dims" array which doesn't | |
1272 // get updated, and the value must not be traversed twice. Was bug | |
1273 // - kbr 4/10/2001 | |
1274 StateSplit::input_values_do(f); | |
1584 | 1275 for (int i = 0; i < _dims->length(); i++) f->visit(_dims->adr_at(i)); |
0 | 1276 } |
1277 }; | |
1278 | |
1279 | |
1280 BASE(TypeCheck, StateSplit) | |
1281 private: | |
1282 ciKlass* _klass; | |
1283 Value _obj; | |
1284 | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1285 ciMethod* _profiled_method; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1286 int _profiled_bci; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1287 |
0 | 1288 public: |
1289 // creation | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1290 TypeCheck(ciKlass* klass, Value obj, ValueType* type, ValueStack* state_before) |
1819 | 1291 : StateSplit(type, state_before), _klass(klass), _obj(obj), |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1292 _profiled_method(NULL), _profiled_bci(0) { |
0 | 1293 ASSERT_VALUES |
1294 set_direct_compare(false); | |
1295 } | |
1296 | |
1297 // accessors | |
1298 ciKlass* klass() const { return _klass; } | |
1299 Value obj() const { return _obj; } | |
1300 bool is_loaded() const { return klass() != NULL; } | |
1301 bool direct_compare() const { return check_flag(DirectCompareFlag); } | |
1302 | |
1303 // manipulation | |
1304 void set_direct_compare(bool flag) { set_flag(DirectCompareFlag, flag); } | |
1305 | |
1306 // generic | |
1307 virtual bool can_trap() const { return true; } | |
1584 | 1308 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_obj); } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1309 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1310 // Helpers for methodDataOop profiling |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1311 void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1312 void set_profiled_method(ciMethod* method) { _profiled_method = method; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1313 void set_profiled_bci(int bci) { _profiled_bci = bci; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1314 bool should_profile() const { return check_flag(ProfileMDOFlag); } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1315 ciMethod* profiled_method() const { return _profiled_method; } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1316 int profiled_bci() const { return _profiled_bci; } |
0 | 1317 }; |
1318 | |
1319 | |
1320 LEAF(CheckCast, TypeCheck) | |
1321 public: | |
1322 // creation | |
1323 CheckCast(ciKlass* klass, Value obj, ValueStack* state_before) | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1324 : TypeCheck(klass, obj, objectType, state_before) {} |
0 | 1325 |
1326 void set_incompatible_class_change_check() { | |
1327 set_flag(ThrowIncompatibleClassChangeErrorFlag, true); | |
1328 } | |
1329 bool is_incompatible_class_change_check() const { | |
1330 return check_flag(ThrowIncompatibleClassChangeErrorFlag); | |
1331 } | |
1332 | |
1333 ciType* declared_type() const; | |
1334 ciType* exact_type() const; | |
1335 }; | |
1336 | |
1337 | |
1338 LEAF(InstanceOf, TypeCheck) | |
1339 public: | |
1340 // creation | |
1341 InstanceOf(ciKlass* klass, Value obj, ValueStack* state_before) : TypeCheck(klass, obj, intType, state_before) {} | |
1819 | 1342 |
1343 virtual bool needs_exception_state() const { return false; } | |
0 | 1344 }; |
1345 | |
1346 | |
1347 BASE(AccessMonitor, StateSplit) | |
1348 private: | |
1349 Value _obj; | |
1350 int _monitor_no; | |
1351 | |
1352 public: | |
1353 // creation | |
1819 | 1354 AccessMonitor(Value obj, int monitor_no, ValueStack* state_before = NULL) |
1355 : StateSplit(illegalType, state_before) | |
0 | 1356 , _obj(obj) |
1357 , _monitor_no(monitor_no) | |
1358 { | |
1359 set_needs_null_check(true); | |
1360 ASSERT_VALUES | |
1361 } | |
1362 | |
1363 // accessors | |
1364 Value obj() const { return _obj; } | |
1365 int monitor_no() const { return _monitor_no; } | |
1366 | |
1367 // generic | |
1584 | 1368 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_obj); } |
0 | 1369 }; |
1370 | |
1371 | |
1372 LEAF(MonitorEnter, AccessMonitor) | |
1373 public: | |
1374 // creation | |
1819 | 1375 MonitorEnter(Value obj, int monitor_no, ValueStack* state_before) |
1376 : AccessMonitor(obj, monitor_no, state_before) | |
0 | 1377 { |
1378 ASSERT_VALUES | |
1379 } | |
1380 | |
1381 // generic | |
1382 virtual bool can_trap() const { return true; } | |
1383 }; | |
1384 | |
1385 | |
1386 LEAF(MonitorExit, AccessMonitor) | |
1387 public: | |
1388 // creation | |
1819 | 1389 MonitorExit(Value obj, int monitor_no) |
1390 : AccessMonitor(obj, monitor_no, NULL) | |
1391 { | |
1392 ASSERT_VALUES | |
1393 } | |
0 | 1394 }; |
1395 | |
1396 | |
1397 LEAF(Intrinsic, StateSplit) | |
1398 private: | |
1399 vmIntrinsics::ID _id; | |
1400 Values* _args; | |
1401 Value _recv; | |
1402 | |
1403 public: | |
1404 // preserves_state can be set to true for Intrinsics | |
1405 // which are guaranteed to preserve register state across any slow | |
1406 // cases; setting it to true does not mean that the Intrinsic can | |
1407 // not trap, only that if we continue execution in the same basic | |
1408 // block after the Intrinsic, all of the registers are intact. This | |
1409 // allows load elimination and common expression elimination to be | |
1410 // performed across the Intrinsic. The default value is false. | |
1411 Intrinsic(ValueType* type, | |
1412 vmIntrinsics::ID id, | |
1413 Values* args, | |
1414 bool has_receiver, | |
1819 | 1415 ValueStack* state_before, |
0 | 1416 bool preserves_state, |
1417 bool cantrap = true) | |
1819 | 1418 : StateSplit(type, state_before) |
0 | 1419 , _id(id) |
1420 , _args(args) | |
1421 , _recv(NULL) | |
1422 { | |
1423 assert(args != NULL, "args must exist"); | |
1424 ASSERT_VALUES | |
1425 set_flag(PreservesStateFlag, preserves_state); | |
1426 set_flag(CanTrapFlag, cantrap); | |
1427 if (has_receiver) { | |
1428 _recv = argument_at(0); | |
1429 } | |
1430 set_needs_null_check(has_receiver); | |
1431 | |
1432 // some intrinsics can't trap, so don't force them to be pinned | |
1433 if (!can_trap()) { | |
1434 unpin(PinStateSplitConstructor); | |
1435 } | |
1436 } | |
1437 | |
1438 // accessors | |
1439 vmIntrinsics::ID id() const { return _id; } | |
1440 int number_of_arguments() const { return _args->length(); } | |
1441 Value argument_at(int i) const { return _args->at(i); } | |
1442 | |
1443 bool has_receiver() const { return (_recv != NULL); } | |
1444 Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; } | |
1445 bool preserves_state() const { return check_flag(PreservesStateFlag); } | |
1446 | |
1447 // generic | |
1448 virtual bool can_trap() const { return check_flag(CanTrapFlag); } | |
1584 | 1449 virtual void input_values_do(ValueVisitor* f) { |
0 | 1450 StateSplit::input_values_do(f); |
1584 | 1451 for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i)); |
0 | 1452 } |
1453 }; | |
1454 | |
1455 | |
1456 class LIR_List; | |
1457 | |
1458 LEAF(BlockBegin, StateSplit) | |
1459 private: | |
1460 int _block_id; // the unique block id | |
1819 | 1461 int _bci; // start-bci of block |
0 | 1462 int _depth_first_number; // number of this block in a depth-first ordering |
1463 int _linear_scan_number; // number of this block in linear-scan ordering | |
1464 int _loop_depth; // the loop nesting level of this block | |
1465 int _loop_index; // number of the innermost loop of this block | |
1466 int _flags; // the flags associated with this block | |
1467 | |
1468 // fields used by BlockListBuilder | |
1469 int _total_preds; // number of predecessors found by BlockListBuilder | |
1470 BitMap _stores_to_locals; // bit is set when a local variable is stored in the block | |
1471 | |
1472 // SSA specific fields: (factor out later) | |
1473 BlockList _successors; // the successors of this block | |
1474 BlockList _predecessors; // the predecessors of this block | |
1475 BlockBegin* _dominator; // the dominator of this block | |
1476 // SSA specific ends | |
1477 BlockEnd* _end; // the last instruction of this block | |
1478 BlockList _exception_handlers; // the exception handlers potentially invoked by this block | |
1479 ValueStackStack* _exception_states; // only for xhandler entries: states of all instructions that have an edge to this xhandler | |
1480 int _exception_handler_pco; // if this block is the start of an exception handler, | |
1481 // this records the PC offset in the assembly code of the | |
1482 // first instruction in this block | |
1483 Label _label; // the label associated with this block | |
1484 LIR_List* _lir; // the low level intermediate representation for this block | |
1485 | |
1486 BitMap _live_in; // set of live LIR_Opr registers at entry to this block | |
1487 BitMap _live_out; // set of live LIR_Opr registers at exit from this block | |
1488 BitMap _live_gen; // set of registers used before any redefinition in this block | |
1489 BitMap _live_kill; // set of registers defined in this block | |
1490 | |
1491 BitMap _fpu_register_usage; | |
1492 intArray* _fpu_stack_state; // For x86 FPU code generation with UseLinearScan | |
1493 int _first_lir_instruction_id; // ID of first LIR instruction in this block | |
1494 int _last_lir_instruction_id; // ID of last LIR instruction in this block | |
1495 | |
1496 void iterate_preorder (boolArray& mark, BlockClosure* closure); | |
1497 void iterate_postorder(boolArray& mark, BlockClosure* closure); | |
1498 | |
1499 friend class SuxAndWeightAdjuster; | |
1500 | |
1501 public: | |
1584 | 1502 void* operator new(size_t size) { |
1503 Compilation* c = Compilation::current(); | |
1504 void* res = c->arena()->Amalloc(size); | |
1505 ((BlockBegin*)res)->_id = c->get_next_id(); | |
1506 ((BlockBegin*)res)->_block_id = c->get_next_block_id(); | |
1507 return res; | |
1508 } | |
1509 | |
0 | 1510 // initialization/counting |
1584 | 1511 static int number_of_blocks() { |
1512 return Compilation::current()->number_of_blocks(); | |
1513 } | |
0 | 1514 |
1515 // creation | |
1516 BlockBegin(int bci) | |
1517 : StateSplit(illegalType) | |
1819 | 1518 , _bci(bci) |
0 | 1519 , _depth_first_number(-1) |
1520 , _linear_scan_number(-1) | |
1521 , _loop_depth(0) | |
1522 , _flags(0) | |
1523 , _dominator(NULL) | |
1524 , _end(NULL) | |
1525 , _predecessors(2) | |
1526 , _successors(2) | |
1527 , _exception_handlers(1) | |
1528 , _exception_states(NULL) | |
1529 , _exception_handler_pco(-1) | |
1530 , _lir(NULL) | |
1531 , _loop_index(-1) | |
1532 , _live_in() | |
1533 , _live_out() | |
1534 , _live_gen() | |
1535 , _live_kill() | |
1536 , _fpu_register_usage() | |
1537 , _fpu_stack_state(NULL) | |
1538 , _first_lir_instruction_id(-1) | |
1539 , _last_lir_instruction_id(-1) | |
1540 , _total_preds(0) | |
1541 , _stores_to_locals() | |
1542 { | |
1819 | 1543 #ifndef PRODUCT |
1544 set_printable_bci(bci); | |
1545 #endif | |
0 | 1546 } |
1547 | |
1548 // accessors | |
1549 int block_id() const { return _block_id; } | |
1819 | 1550 int bci() const { return _bci; } |
0 | 1551 BlockList* successors() { return &_successors; } |
1552 BlockBegin* dominator() const { return _dominator; } | |
1553 int loop_depth() const { return _loop_depth; } | |
1554 int depth_first_number() const { return _depth_first_number; } | |
1555 int linear_scan_number() const { return _linear_scan_number; } | |
1556 BlockEnd* end() const { return _end; } | |
1557 Label* label() { return &_label; } | |
1558 LIR_List* lir() const { return _lir; } | |
1559 int exception_handler_pco() const { return _exception_handler_pco; } | |
1560 BitMap& live_in() { return _live_in; } | |
1561 BitMap& live_out() { return _live_out; } | |
1562 BitMap& live_gen() { return _live_gen; } | |
1563 BitMap& live_kill() { return _live_kill; } | |
1564 BitMap& fpu_register_usage() { return _fpu_register_usage; } | |
1565 intArray* fpu_stack_state() const { return _fpu_stack_state; } | |
1566 int first_lir_instruction_id() const { return _first_lir_instruction_id; } | |
1567 int last_lir_instruction_id() const { return _last_lir_instruction_id; } | |
1568 int total_preds() const { return _total_preds; } | |
1569 BitMap& stores_to_locals() { return _stores_to_locals; } | |
1570 | |
1571 // manipulation | |
1572 void set_dominator(BlockBegin* dom) { _dominator = dom; } | |
1573 void set_loop_depth(int d) { _loop_depth = d; } | |
1574 void set_depth_first_number(int dfn) { _depth_first_number = dfn; } | |
1575 void set_linear_scan_number(int lsn) { _linear_scan_number = lsn; } | |
1576 void set_end(BlockEnd* end); | |
1577 void disconnect_from_graph(); | |
1578 static void disconnect_edge(BlockBegin* from, BlockBegin* to); | |
1579 BlockBegin* insert_block_between(BlockBegin* sux); | |
1580 void substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux); | |
1581 void set_lir(LIR_List* lir) { _lir = lir; } | |
1582 void set_exception_handler_pco(int pco) { _exception_handler_pco = pco; } | |
1583 void set_live_in (BitMap map) { _live_in = map; } | |
1584 void set_live_out (BitMap map) { _live_out = map; } | |
1585 void set_live_gen (BitMap map) { _live_gen = map; } | |
1586 void set_live_kill (BitMap map) { _live_kill = map; } | |
1587 void set_fpu_register_usage(BitMap map) { _fpu_register_usage = map; } | |
1588 void set_fpu_stack_state(intArray* state) { _fpu_stack_state = state; } | |
1589 void set_first_lir_instruction_id(int id) { _first_lir_instruction_id = id; } | |
1590 void set_last_lir_instruction_id(int id) { _last_lir_instruction_id = id; } | |
1591 void increment_total_preds(int n = 1) { _total_preds += n; } | |
1592 void init_stores_to_locals(int locals_count) { _stores_to_locals = BitMap(locals_count); _stores_to_locals.clear(); } | |
1593 | |
1594 // generic | |
1584 | 1595 virtual void state_values_do(ValueVisitor* f); |
0 | 1596 |
1597 // successors and predecessors | |
1598 int number_of_sux() const; | |
1599 BlockBegin* sux_at(int i) const; | |
1600 void add_successor(BlockBegin* sux); | |
1601 void remove_successor(BlockBegin* pred); | |
1602 bool is_successor(BlockBegin* sux) const { return _successors.contains(sux); } | |
1603 | |
1604 void add_predecessor(BlockBegin* pred); | |
1605 void remove_predecessor(BlockBegin* pred); | |
1606 bool is_predecessor(BlockBegin* pred) const { return _predecessors.contains(pred); } | |
1607 int number_of_preds() const { return _predecessors.length(); } | |
1608 BlockBegin* pred_at(int i) const { return _predecessors[i]; } | |
1609 | |
1610 // exception handlers potentially invoked by this block | |
1611 void add_exception_handler(BlockBegin* b); | |
1612 bool is_exception_handler(BlockBegin* b) const { return _exception_handlers.contains(b); } | |
1613 int number_of_exception_handlers() const { return _exception_handlers.length(); } | |
1614 BlockBegin* exception_handler_at(int i) const { return _exception_handlers.at(i); } | |
1615 | |
1616 // states of the instructions that have an edge to this exception handler | |
1617 int number_of_exception_states() { assert(is_set(exception_entry_flag), "only for xhandlers"); return _exception_states == NULL ? 0 : _exception_states->length(); } | |
1618 ValueStack* exception_state_at(int idx) const { assert(is_set(exception_entry_flag), "only for xhandlers"); return _exception_states->at(idx); } | |
1619 int add_exception_state(ValueStack* state); | |
1620 | |
1621 // flags | |
1622 enum Flag { | |
1623 no_flag = 0, | |
1624 std_entry_flag = 1 << 0, | |
1625 osr_entry_flag = 1 << 1, | |
1626 exception_entry_flag = 1 << 2, | |
1627 subroutine_entry_flag = 1 << 3, | |
1628 backward_branch_target_flag = 1 << 4, | |
1629 is_on_work_list_flag = 1 << 5, | |
1630 was_visited_flag = 1 << 6, | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
1631 parser_loop_header_flag = 1 << 7, // set by parser to identify blocks where phi functions can not be created on demand |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
1632 critical_edge_split_flag = 1 << 8, // set for all blocks that are introduced when critical edges are split |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
1633 linear_scan_loop_header_flag = 1 << 9, // set during loop-detection for LinearScan |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
1634 linear_scan_loop_end_flag = 1 << 10 // set during loop-detection for LinearScan |
0 | 1635 }; |
1636 | |
1637 void set(Flag f) { _flags |= f; } | |
1638 void clear(Flag f) { _flags &= ~f; } | |
1639 bool is_set(Flag f) const { return (_flags & f) != 0; } | |
1640 bool is_entry_block() const { | |
1641 const int entry_mask = std_entry_flag | osr_entry_flag | exception_entry_flag; | |
1642 return (_flags & entry_mask) != 0; | |
1643 } | |
1644 | |
1645 // iteration | |
1646 void iterate_preorder (BlockClosure* closure); | |
1647 void iterate_postorder (BlockClosure* closure); | |
1648 | |
1584 | 1649 void block_values_do(ValueVisitor* f); |
0 | 1650 |
1651 // loops | |
1652 void set_loop_index(int ix) { _loop_index = ix; } | |
1653 int loop_index() const { return _loop_index; } | |
1654 | |
1655 // merging | |
1656 bool try_merge(ValueStack* state); // try to merge states at block begin | |
1657 void merge(ValueStack* state) { bool b = try_merge(state); assert(b, "merge failed"); } | |
1658 | |
1659 // debugging | |
1660 void print_block() PRODUCT_RETURN; | |
1661 void print_block(InstructionPrinter& ip, bool live_only = false) PRODUCT_RETURN; | |
1662 }; | |
1663 | |
1664 | |
1665 BASE(BlockEnd, StateSplit) | |
1666 private: | |
1667 BlockBegin* _begin; | |
1668 BlockList* _sux; | |
1669 | |
1670 protected: | |
1671 BlockList* sux() const { return _sux; } | |
1672 | |
1673 void set_sux(BlockList* sux) { | |
1674 #ifdef ASSERT | |
1675 assert(sux != NULL, "sux must exist"); | |
1676 for (int i = sux->length() - 1; i >= 0; i--) assert(sux->at(i) != NULL, "sux must exist"); | |
1677 #endif | |
1678 _sux = sux; | |
1679 } | |
1680 | |
1681 public: | |
1682 // creation | |
1683 BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint) | |
1819 | 1684 : StateSplit(type, state_before) |
0 | 1685 , _begin(NULL) |
1686 , _sux(NULL) | |
1819 | 1687 { |
0 | 1688 set_flag(IsSafepointFlag, is_safepoint); |
1689 } | |
1690 | |
1691 // accessors | |
1692 bool is_safepoint() const { return check_flag(IsSafepointFlag); } | |
1693 BlockBegin* begin() const { return _begin; } | |
1694 | |
1695 // manipulation | |
1696 void set_begin(BlockBegin* begin); | |
1697 | |
1698 // successors | |
1699 int number_of_sux() const { return _sux != NULL ? _sux->length() : 0; } | |
1700 BlockBegin* sux_at(int i) const { return _sux->at(i); } | |
1701 BlockBegin* default_sux() const { return sux_at(number_of_sux() - 1); } | |
1702 BlockBegin** addr_sux_at(int i) const { return _sux->adr_at(i); } | |
1703 int sux_index(BlockBegin* sux) const { return _sux->find(sux); } | |
1704 void substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux); | |
1705 }; | |
1706 | |
1707 | |
1708 LEAF(Goto, BlockEnd) | |
1709 public: | |
1783 | 1710 enum Direction { |
1711 none, // Just a regular goto | |
1712 taken, not_taken // Goto produced from If | |
1713 }; | |
1714 private: | |
1715 ciMethod* _profiled_method; | |
1716 int _profiled_bci; | |
1717 Direction _direction; | |
1718 public: | |
0 | 1719 // creation |
1783 | 1720 Goto(BlockBegin* sux, ValueStack* state_before, bool is_safepoint = false) |
1721 : BlockEnd(illegalType, state_before, is_safepoint) | |
1722 , _direction(none) | |
1723 , _profiled_method(NULL) | |
1724 , _profiled_bci(0) { | |
0 | 1725 BlockList* s = new BlockList(1); |
1726 s->append(sux); | |
1727 set_sux(s); | |
1728 } | |
1729 | |
1783 | 1730 Goto(BlockBegin* sux, bool is_safepoint) : BlockEnd(illegalType, NULL, is_safepoint) |
1731 , _direction(none) | |
1732 , _profiled_method(NULL) | |
1733 , _profiled_bci(0) { | |
0 | 1734 BlockList* s = new BlockList(1); |
1735 s->append(sux); | |
1736 set_sux(s); | |
1737 } | |
1738 | |
1783 | 1739 bool should_profile() const { return check_flag(ProfileMDOFlag); } |
1740 ciMethod* profiled_method() const { return _profiled_method; } // set only for profiled branches | |
1741 int profiled_bci() const { return _profiled_bci; } | |
1742 Direction direction() const { return _direction; } | |
1743 | |
1744 void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } | |
1745 void set_profiled_method(ciMethod* method) { _profiled_method = method; } | |
1746 void set_profiled_bci(int bci) { _profiled_bci = bci; } | |
1747 void set_direction(Direction d) { _direction = d; } | |
0 | 1748 }; |
1749 | |
1750 | |
1751 LEAF(If, BlockEnd) | |
1752 private: | |
1753 Value _x; | |
1754 Condition _cond; | |
1755 Value _y; | |
1756 ciMethod* _profiled_method; | |
1757 int _profiled_bci; // Canonicalizer may alter bci of If node | |
1783 | 1758 bool _swapped; // Is the order reversed with respect to the original If in the |
1759 // bytecode stream? | |
0 | 1760 public: |
1761 // creation | |
1762 // unordered_is_true is valid for float/double compares only | |
1763 If(Value x, Condition cond, bool unordered_is_true, Value y, BlockBegin* tsux, BlockBegin* fsux, ValueStack* state_before, bool is_safepoint) | |
1764 : BlockEnd(illegalType, state_before, is_safepoint) | |
1765 , _x(x) | |
1766 , _cond(cond) | |
1767 , _y(y) | |
1768 , _profiled_method(NULL) | |
1769 , _profiled_bci(0) | |
1783 | 1770 , _swapped(false) |
0 | 1771 { |
1772 ASSERT_VALUES | |
1773 set_flag(UnorderedIsTrueFlag, unordered_is_true); | |
1774 assert(x->type()->tag() == y->type()->tag(), "types must match"); | |
1775 BlockList* s = new BlockList(2); | |
1776 s->append(tsux); | |
1777 s->append(fsux); | |
1778 set_sux(s); | |
1779 } | |
1780 | |
1781 // accessors | |
1782 Value x() const { return _x; } | |
1783 Condition cond() const { return _cond; } | |
1784 bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } | |
1785 Value y() const { return _y; } | |
1786 BlockBegin* sux_for(bool is_true) const { return sux_at(is_true ? 0 : 1); } | |
1787 BlockBegin* tsux() const { return sux_for(true); } | |
1788 BlockBegin* fsux() const { return sux_for(false); } | |
1789 BlockBegin* usux() const { return sux_for(unordered_is_true()); } | |
1790 bool should_profile() const { return check_flag(ProfileMDOFlag); } | |
1791 ciMethod* profiled_method() const { return _profiled_method; } // set only for profiled branches | |
1783 | 1792 int profiled_bci() const { return _profiled_bci; } // set for profiled branches and tiered |
1793 bool is_swapped() const { return _swapped; } | |
0 | 1794 |
1795 // manipulation | |
1796 void swap_operands() { | |
1797 Value t = _x; _x = _y; _y = t; | |
1798 _cond = mirror(_cond); | |
1799 } | |
1800 | |
1801 void swap_sux() { | |
1802 assert(number_of_sux() == 2, "wrong number of successors"); | |
1803 BlockList* s = sux(); | |
1804 BlockBegin* t = s->at(0); s->at_put(0, s->at(1)); s->at_put(1, t); | |
1805 _cond = negate(_cond); | |
1806 set_flag(UnorderedIsTrueFlag, !check_flag(UnorderedIsTrueFlag)); | |
1807 } | |
1808 | |
1809 void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } | |
1810 void set_profiled_method(ciMethod* method) { _profiled_method = method; } | |
1811 void set_profiled_bci(int bci) { _profiled_bci = bci; } | |
1783 | 1812 void set_swapped(bool value) { _swapped = value; } |
0 | 1813 // generic |
1584 | 1814 virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_x); f->visit(&_y); } |
0 | 1815 }; |
1816 | |
1817 | |
1818 LEAF(IfInstanceOf, BlockEnd) | |
1819 private: | |
1820 ciKlass* _klass; | |
1821 Value _obj; | |
1822 bool _test_is_instance; // jump if instance | |
1823 int _instanceof_bci; | |
1824 | |
1825 public: | |
1826 IfInstanceOf(ciKlass* klass, Value obj, bool test_is_instance, int instanceof_bci, BlockBegin* tsux, BlockBegin* fsux) | |
1827 : BlockEnd(illegalType, NULL, false) // temporary set to false | |
1828 , _klass(klass) | |
1829 , _obj(obj) | |
1830 , _test_is_instance(test_is_instance) | |
1831 , _instanceof_bci(instanceof_bci) | |
1832 { | |
1833 ASSERT_VALUES | |
1834 assert(instanceof_bci >= 0, "illegal bci"); | |
1835 BlockList* s = new BlockList(2); | |
1836 s->append(tsux); | |
1837 s->append(fsux); | |
1838 set_sux(s); | |
1839 } | |
1840 | |
1841 // accessors | |
1842 // | |
1843 // Note 1: If test_is_instance() is true, IfInstanceOf tests if obj *is* an | |
1844 // instance of klass; otherwise it tests if it is *not* and instance | |
1845 // of klass. | |
1846 // | |
1847 // Note 2: IfInstanceOf instructions are created by combining an InstanceOf | |
1848 // and an If instruction. The IfInstanceOf bci() corresponds to the | |
1849 // bci that the If would have had; the (this->) instanceof_bci() is | |
1850 // the bci of the original InstanceOf instruction. | |
1851 ciKlass* klass() const { return _klass; } | |
1852 Value obj() const { return _obj; } | |
1853 int instanceof_bci() const { return _instanceof_bci; } | |
1854 bool test_is_instance() const { return _test_is_instance; } | |
1855 BlockBegin* sux_for(bool is_true) const { return sux_at(is_true ? 0 : 1); } | |
1856 BlockBegin* tsux() const { return sux_for(true); } | |
1857 BlockBegin* fsux() const { return sux_for(false); } | |
1858 | |
1859 // manipulation | |
1860 void swap_sux() { | |
1861 assert(number_of_sux() == 2, "wrong number of successors"); | |
1862 BlockList* s = sux(); | |
1863 BlockBegin* t = s->at(0); s->at_put(0, s->at(1)); s->at_put(1, t); | |
1864 _test_is_instance = !_test_is_instance; | |
1865 } | |
1866 | |
1867 // generic | |
1584 | 1868 virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_obj); } |
0 | 1869 }; |
1870 | |
1871 | |
1872 BASE(Switch, BlockEnd) | |
1873 private: | |
1874 Value _tag; | |
1875 | |
1876 public: | |
1877 // creation | |
1878 Switch(Value tag, BlockList* sux, ValueStack* state_before, bool is_safepoint) | |
1879 : BlockEnd(illegalType, state_before, is_safepoint) | |
1880 , _tag(tag) { | |
1881 ASSERT_VALUES | |
1882 set_sux(sux); | |
1883 } | |
1884 | |
1885 // accessors | |
1886 Value tag() const { return _tag; } | |
1887 int length() const { return number_of_sux() - 1; } | |
1888 | |
1819 | 1889 virtual bool needs_exception_state() const { return false; } |
1890 | |
0 | 1891 // generic |
1584 | 1892 virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_tag); } |
0 | 1893 }; |
1894 | |
1895 | |
1896 LEAF(TableSwitch, Switch) | |
1897 private: | |
1898 int _lo_key; | |
1899 | |
1900 public: | |
1901 // creation | |
1902 TableSwitch(Value tag, BlockList* sux, int lo_key, ValueStack* state_before, bool is_safepoint) | |
1903 : Switch(tag, sux, state_before, is_safepoint) | |
1904 , _lo_key(lo_key) {} | |
1905 | |
1906 // accessors | |
1907 int lo_key() const { return _lo_key; } | |
1908 int hi_key() const { return _lo_key + length() - 1; } | |
1909 }; | |
1910 | |
1911 | |
1912 LEAF(LookupSwitch, Switch) | |
1913 private: | |
1914 intArray* _keys; | |
1915 | |
1916 public: | |
1917 // creation | |
1918 LookupSwitch(Value tag, BlockList* sux, intArray* keys, ValueStack* state_before, bool is_safepoint) | |
1919 : Switch(tag, sux, state_before, is_safepoint) | |
1920 , _keys(keys) { | |
1921 assert(keys != NULL, "keys must exist"); | |
1922 assert(keys->length() == length(), "sux & keys have incompatible lengths"); | |
1923 } | |
1924 | |
1925 // accessors | |
1926 int key_at(int i) const { return _keys->at(i); } | |
1927 }; | |
1928 | |
1929 | |
1930 LEAF(Return, BlockEnd) | |
1931 private: | |
1932 Value _result; | |
1933 | |
1934 public: | |
1935 // creation | |
1936 Return(Value result) : | |
1937 BlockEnd(result == NULL ? voidType : result->type()->base(), NULL, true), | |
1938 _result(result) {} | |
1939 | |
1940 // accessors | |
1941 Value result() const { return _result; } | |
1942 bool has_result() const { return result() != NULL; } | |
1943 | |
1944 // generic | |
1584 | 1945 virtual void input_values_do(ValueVisitor* f) { |
0 | 1946 BlockEnd::input_values_do(f); |
1584 | 1947 if (has_result()) f->visit(&_result); |
0 | 1948 } |
1949 }; | |
1950 | |
1951 | |
1952 LEAF(Throw, BlockEnd) | |
1953 private: | |
1954 Value _exception; | |
1955 | |
1956 public: | |
1957 // creation | |
1958 Throw(Value exception, ValueStack* state_before) : BlockEnd(illegalType, state_before, true), _exception(exception) { | |
1959 ASSERT_VALUES | |
1960 } | |
1961 | |
1962 // accessors | |
1963 Value exception() const { return _exception; } | |
1964 | |
1965 // generic | |
1966 virtual bool can_trap() const { return true; } | |
1584 | 1967 virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_exception); } |
0 | 1968 }; |
1969 | |
1970 | |
1971 LEAF(Base, BlockEnd) | |
1972 public: | |
1973 // creation | |
1974 Base(BlockBegin* std_entry, BlockBegin* osr_entry) : BlockEnd(illegalType, NULL, false) { | |
1975 assert(std_entry->is_set(BlockBegin::std_entry_flag), "std entry must be flagged"); | |
1976 assert(osr_entry == NULL || osr_entry->is_set(BlockBegin::osr_entry_flag), "osr entry must be flagged"); | |
1977 BlockList* s = new BlockList(2); | |
1978 if (osr_entry != NULL) s->append(osr_entry); | |
1979 s->append(std_entry); // must be default sux! | |
1980 set_sux(s); | |
1981 } | |
1982 | |
1983 // accessors | |
1984 BlockBegin* std_entry() const { return default_sux(); } | |
1985 BlockBegin* osr_entry() const { return number_of_sux() < 2 ? NULL : sux_at(0); } | |
1986 }; | |
1987 | |
1988 | |
1989 LEAF(OsrEntry, Instruction) | |
1990 public: | |
1991 // creation | |
1992 #ifdef _LP64 | |
1824 | 1993 OsrEntry() : Instruction(longType) { pin(); } |
0 | 1994 #else |
1824 | 1995 OsrEntry() : Instruction(intType) { pin(); } |
0 | 1996 #endif |
1997 | |
1998 // generic | |
1584 | 1999 virtual void input_values_do(ValueVisitor* f) { } |
0 | 2000 }; |
2001 | |
2002 | |
2003 // Models the incoming exception at a catch site | |
2004 LEAF(ExceptionObject, Instruction) | |
2005 public: | |
2006 // creation | |
1824 | 2007 ExceptionObject() : Instruction(objectType) { |
0 | 2008 pin(); |
2009 } | |
2010 | |
2011 // generic | |
1584 | 2012 virtual void input_values_do(ValueVisitor* f) { } |
0 | 2013 }; |
2014 | |
2015 | |
2016 // Models needed rounding for floating-point values on Intel. | |
2017 // Currently only used to represent rounding of double-precision | |
2018 // values stored into local variables, but could be used to model | |
2019 // intermediate rounding of single-precision values as well. | |
2020 LEAF(RoundFP, Instruction) | |
2021 private: | |
2022 Value _input; // floating-point value to be rounded | |
2023 | |
2024 public: | |
2025 RoundFP(Value input) | |
2026 : Instruction(input->type()) // Note: should not be used for constants | |
2027 , _input(input) | |
2028 { | |
2029 ASSERT_VALUES | |
2030 } | |
2031 | |
2032 // accessors | |
2033 Value input() const { return _input; } | |
2034 | |
2035 // generic | |
1584 | 2036 virtual void input_values_do(ValueVisitor* f) { f->visit(&_input); } |
0 | 2037 }; |
2038 | |
2039 | |
2040 BASE(UnsafeOp, Instruction) | |
2041 private: | |
2042 BasicType _basic_type; // ValueType can not express byte-sized integers | |
2043 | |
2044 protected: | |
2045 // creation | |
2046 UnsafeOp(BasicType basic_type, bool is_put) | |
2047 : Instruction(is_put ? voidType : as_ValueType(basic_type)) | |
2048 , _basic_type(basic_type) | |
2049 { | |
2050 //Note: Unsafe ops are not not guaranteed to throw NPE. | |
2051 // Convservatively, Unsafe operations must be pinned though we could be | |
2052 // looser about this if we wanted to.. | |
2053 pin(); | |
2054 } | |
2055 | |
2056 public: | |
2057 // accessors | |
2058 BasicType basic_type() { return _basic_type; } | |
2059 | |
2060 // generic | |
1584 | 2061 virtual void input_values_do(ValueVisitor* f) { } |
0 | 2062 }; |
2063 | |
2064 | |
2065 BASE(UnsafeRawOp, UnsafeOp) | |
2066 private: | |
2067 Value _base; // Base address (a Java long) | |
2068 Value _index; // Index if computed by optimizer; initialized to NULL | |
2069 int _log2_scale; // Scale factor: 0, 1, 2, or 3. | |
2070 // Indicates log2 of number of bytes (1, 2, 4, or 8) | |
2071 // to scale index by. | |
2072 | |
2073 protected: | |
2074 UnsafeRawOp(BasicType basic_type, Value addr, bool is_put) | |
2075 : UnsafeOp(basic_type, is_put) | |
2076 , _base(addr) | |
2077 , _index(NULL) | |
2078 , _log2_scale(0) | |
2079 { | |
2080 // Can not use ASSERT_VALUES because index may be NULL | |
2081 assert(addr != NULL && addr->type()->is_long(), "just checking"); | |
2082 } | |
2083 | |
2084 UnsafeRawOp(BasicType basic_type, Value base, Value index, int log2_scale, bool is_put) | |
2085 : UnsafeOp(basic_type, is_put) | |
2086 , _base(base) | |
2087 , _index(index) | |
2088 , _log2_scale(log2_scale) | |
2089 { | |
2090 } | |
2091 | |
2092 public: | |
2093 // accessors | |
2094 Value base() { return _base; } | |
2095 Value index() { return _index; } | |
2096 bool has_index() { return (_index != NULL); } | |
2097 int log2_scale() { return _log2_scale; } | |
2098 | |
2099 // setters | |
2100 void set_base (Value base) { _base = base; } | |
2101 void set_index(Value index) { _index = index; } | |
2102 void set_log2_scale(int log2_scale) { _log2_scale = log2_scale; } | |
2103 | |
2104 // generic | |
1584 | 2105 virtual void input_values_do(ValueVisitor* f) { UnsafeOp::input_values_do(f); |
2106 f->visit(&_base); | |
2107 if (has_index()) f->visit(&_index); } | |
0 | 2108 }; |
2109 | |
2110 | |
2111 LEAF(UnsafeGetRaw, UnsafeRawOp) | |
2112 private: | |
2113 bool _may_be_unaligned; // For OSREntry | |
2114 | |
2115 public: | |
2116 UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned) | |
2117 : UnsafeRawOp(basic_type, addr, false) { | |
2118 _may_be_unaligned = may_be_unaligned; | |
2119 } | |
2120 | |
2121 UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned) | |
2122 : UnsafeRawOp(basic_type, base, index, log2_scale, false) { | |
2123 _may_be_unaligned = may_be_unaligned; | |
2124 } | |
2125 | |
2126 bool may_be_unaligned() { return _may_be_unaligned; } | |
2127 }; | |
2128 | |
2129 | |
2130 LEAF(UnsafePutRaw, UnsafeRawOp) | |
2131 private: | |
2132 Value _value; // Value to be stored | |
2133 | |
2134 public: | |
2135 UnsafePutRaw(BasicType basic_type, Value addr, Value value) | |
2136 : UnsafeRawOp(basic_type, addr, true) | |
2137 , _value(value) | |
2138 { | |
2139 assert(value != NULL, "just checking"); | |
2140 ASSERT_VALUES | |
2141 } | |
2142 | |
2143 UnsafePutRaw(BasicType basic_type, Value base, Value index, int log2_scale, Value value) | |
2144 : UnsafeRawOp(basic_type, base, index, log2_scale, true) | |
2145 , _value(value) | |
2146 { | |
2147 assert(value != NULL, "just checking"); | |
2148 ASSERT_VALUES | |
2149 } | |
2150 | |
2151 // accessors | |
2152 Value value() { return _value; } | |
2153 | |
2154 // generic | |
1584 | 2155 virtual void input_values_do(ValueVisitor* f) { UnsafeRawOp::input_values_do(f); |
2156 f->visit(&_value); } | |
0 | 2157 }; |
2158 | |
2159 | |
2160 BASE(UnsafeObjectOp, UnsafeOp) | |
2161 private: | |
2162 Value _object; // Object to be fetched from or mutated | |
2163 Value _offset; // Offset within object | |
2164 bool _is_volatile; // true if volatile - dl/JSR166 | |
2165 public: | |
2166 UnsafeObjectOp(BasicType basic_type, Value object, Value offset, bool is_put, bool is_volatile) | |
2167 : UnsafeOp(basic_type, is_put), _object(object), _offset(offset), _is_volatile(is_volatile) | |
2168 { | |
2169 } | |
2170 | |
2171 // accessors | |
2172 Value object() { return _object; } | |
2173 Value offset() { return _offset; } | |
2174 bool is_volatile() { return _is_volatile; } | |
2175 // generic | |
1584 | 2176 virtual void input_values_do(ValueVisitor* f) { UnsafeOp::input_values_do(f); |
2177 f->visit(&_object); | |
2178 f->visit(&_offset); } | |
0 | 2179 }; |
2180 | |
2181 | |
2182 LEAF(UnsafeGetObject, UnsafeObjectOp) | |
2183 public: | |
2184 UnsafeGetObject(BasicType basic_type, Value object, Value offset, bool is_volatile) | |
2185 : UnsafeObjectOp(basic_type, object, offset, false, is_volatile) | |
2186 { | |
2187 ASSERT_VALUES | |
2188 } | |
2189 }; | |
2190 | |
2191 | |
2192 LEAF(UnsafePutObject, UnsafeObjectOp) | |
2193 private: | |
2194 Value _value; // Value to be stored | |
2195 public: | |
2196 UnsafePutObject(BasicType basic_type, Value object, Value offset, Value value, bool is_volatile) | |
2197 : UnsafeObjectOp(basic_type, object, offset, true, is_volatile) | |
2198 , _value(value) | |
2199 { | |
2200 ASSERT_VALUES | |
2201 } | |
2202 | |
2203 // accessors | |
2204 Value value() { return _value; } | |
2205 | |
2206 // generic | |
1584 | 2207 virtual void input_values_do(ValueVisitor* f) { UnsafeObjectOp::input_values_do(f); |
2208 f->visit(&_value); } | |
0 | 2209 }; |
2210 | |
2211 | |
2212 BASE(UnsafePrefetch, UnsafeObjectOp) | |
2213 public: | |
2214 UnsafePrefetch(Value object, Value offset) | |
2215 : UnsafeObjectOp(T_VOID, object, offset, false, false) | |
2216 { | |
2217 } | |
2218 }; | |
2219 | |
2220 | |
2221 LEAF(UnsafePrefetchRead, UnsafePrefetch) | |
2222 public: | |
2223 UnsafePrefetchRead(Value object, Value offset) | |
2224 : UnsafePrefetch(object, offset) | |
2225 { | |
2226 ASSERT_VALUES | |
2227 } | |
2228 }; | |
2229 | |
2230 | |
2231 LEAF(UnsafePrefetchWrite, UnsafePrefetch) | |
2232 public: | |
2233 UnsafePrefetchWrite(Value object, Value offset) | |
2234 : UnsafePrefetch(object, offset) | |
2235 { | |
2236 ASSERT_VALUES | |
2237 } | |
2238 }; | |
2239 | |
2240 LEAF(ProfileCall, Instruction) | |
2241 private: | |
2242 ciMethod* _method; | |
2243 int _bci_of_invoke; | |
2244 Value _recv; | |
2245 ciKlass* _known_holder; | |
2246 | |
2247 public: | |
2248 ProfileCall(ciMethod* method, int bci, Value recv, ciKlass* known_holder) | |
2249 : Instruction(voidType) | |
2250 , _method(method) | |
2251 , _bci_of_invoke(bci) | |
2252 , _recv(recv) | |
2253 , _known_holder(known_holder) | |
2254 { | |
2255 // The ProfileCall has side-effects and must occur precisely where located | |
2256 pin(); | |
2257 } | |
2258 | |
2259 ciMethod* method() { return _method; } | |
2260 int bci_of_invoke() { return _bci_of_invoke; } | |
2261 Value recv() { return _recv; } | |
2262 ciKlass* known_holder() { return _known_holder; } | |
2263 | |
1584 | 2264 virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); } |
0 | 2265 }; |
2266 | |
1783 | 2267 // Use to trip invocation counter of an inlined method |
0 | 2268 |
1783 | 2269 LEAF(ProfileInvoke, Instruction) |
0 | 2270 private: |
1783 | 2271 ciMethod* _inlinee; |
2272 ValueStack* _state; | |
0 | 2273 |
2274 public: | |
1825 | 2275 ProfileInvoke(ciMethod* inlinee, ValueStack* state) |
0 | 2276 : Instruction(voidType) |
1783 | 2277 , _inlinee(inlinee) |
2278 , _state(state) | |
0 | 2279 { |
1783 | 2280 // The ProfileInvoke has side-effects and must occur precisely where located QQQ??? |
0 | 2281 pin(); |
2282 } | |
2283 | |
1783 | 2284 ciMethod* inlinee() { return _inlinee; } |
2285 ValueStack* state() { return _state; } | |
2286 virtual void input_values_do(ValueVisitor*) {} | |
2287 virtual void state_values_do(ValueVisitor*); | |
0 | 2288 }; |
2289 | |
2290 class BlockPair: public CompilationResourceObj { | |
2291 private: | |
2292 BlockBegin* _from; | |
2293 BlockBegin* _to; | |
2294 public: | |
2295 BlockPair(BlockBegin* from, BlockBegin* to): _from(from), _to(to) {} | |
2296 BlockBegin* from() const { return _from; } | |
2297 BlockBegin* to() const { return _to; } | |
2298 bool is_same(BlockBegin* from, BlockBegin* to) const { return _from == from && _to == to; } | |
2299 bool is_same(BlockPair* p) const { return _from == p->from() && _to == p->to(); } | |
2300 void set_to(BlockBegin* b) { _to = b; } | |
2301 void set_from(BlockBegin* b) { _from = b; } | |
2302 }; | |
2303 | |
2304 | |
2305 define_array(BlockPairArray, BlockPair*) | |
2306 define_stack(BlockPairList, BlockPairArray) | |
2307 | |
2308 | |
2309 inline int BlockBegin::number_of_sux() const { assert(_end == NULL || _end->number_of_sux() == _successors.length(), "mismatch"); return _successors.length(); } | |
2310 inline BlockBegin* BlockBegin::sux_at(int i) const { assert(_end == NULL || _end->sux_at(i) == _successors.at(i), "mismatch"); return _successors.at(i); } | |
2311 inline void BlockBegin::add_successor(BlockBegin* sux) { assert(_end == NULL, "Would create mismatch with successors of BlockEnd"); _successors.append(sux); } | |
2312 | |
2313 #undef ASSERT_VALUES | |
1972 | 2314 |
2315 #endif // SHARE_VM_C1_C1_INSTRUCTION_HPP |