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