1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,2291 @@ 1.4 +/* 1.5 + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// Predefined classes 1.29 +class ciField; 1.30 +class ValueStack; 1.31 +class InstructionPrinter; 1.32 +class IRScope; 1.33 +class LIR_OprDesc; 1.34 +typedef LIR_OprDesc* LIR_Opr; 1.35 + 1.36 + 1.37 +// Instruction class hierarchy 1.38 +// 1.39 +// All leaf classes in the class hierarchy are concrete classes 1.40 +// (i.e., are instantiated). All other classes are abstract and 1.41 +// serve factoring. 1.42 + 1.43 +class Instruction; 1.44 +class HiWord; 1.45 +class Phi; 1.46 +class Local; 1.47 +class Constant; 1.48 +class AccessField; 1.49 +class LoadField; 1.50 +class StoreField; 1.51 +class AccessArray; 1.52 +class ArrayLength; 1.53 +class AccessIndexed; 1.54 +class LoadIndexed; 1.55 +class StoreIndexed; 1.56 +class NegateOp; 1.57 +class Op2; 1.58 +class ArithmeticOp; 1.59 +class ShiftOp; 1.60 +class LogicOp; 1.61 +class CompareOp; 1.62 +class IfOp; 1.63 +class Convert; 1.64 +class NullCheck; 1.65 +class OsrEntry; 1.66 +class ExceptionObject; 1.67 +class StateSplit; 1.68 +class Invoke; 1.69 +class NewInstance; 1.70 +class NewArray; 1.71 +class NewTypeArray; 1.72 +class NewObjectArray; 1.73 +class NewMultiArray; 1.74 +class TypeCheck; 1.75 +class CheckCast; 1.76 +class InstanceOf; 1.77 +class AccessMonitor; 1.78 +class MonitorEnter; 1.79 +class MonitorExit; 1.80 +class Intrinsic; 1.81 +class BlockBegin; 1.82 +class BlockEnd; 1.83 +class Goto; 1.84 +class If; 1.85 +class IfInstanceOf; 1.86 +class Switch; 1.87 +class TableSwitch; 1.88 +class LookupSwitch; 1.89 +class Return; 1.90 +class Throw; 1.91 +class Base; 1.92 +class RoundFP; 1.93 +class UnsafeOp; 1.94 +class UnsafeRawOp; 1.95 +class UnsafeGetRaw; 1.96 +class UnsafePutRaw; 1.97 +class UnsafeObjectOp; 1.98 +class UnsafeGetObject; 1.99 +class UnsafePutObject; 1.100 +class UnsafePrefetch; 1.101 +class UnsafePrefetchRead; 1.102 +class UnsafePrefetchWrite; 1.103 +class ProfileCall; 1.104 +class ProfileCounter; 1.105 + 1.106 +// A Value is a reference to the instruction creating the value 1.107 +typedef Instruction* Value; 1.108 +define_array(ValueArray, Value) 1.109 +define_stack(Values, ValueArray) 1.110 + 1.111 +define_array(ValueStackArray, ValueStack*) 1.112 +define_stack(ValueStackStack, ValueStackArray) 1.113 + 1.114 +// BlockClosure is the base class for block traversal/iteration. 1.115 + 1.116 +class BlockClosure: public CompilationResourceObj { 1.117 + public: 1.118 + virtual void block_do(BlockBegin* block) = 0; 1.119 +}; 1.120 + 1.121 + 1.122 +// Some array and list classes 1.123 +define_array(BlockBeginArray, BlockBegin*) 1.124 +define_stack(_BlockList, BlockBeginArray) 1.125 + 1.126 +class BlockList: public _BlockList { 1.127 + public: 1.128 + BlockList(): _BlockList() {} 1.129 + BlockList(const int size): _BlockList(size) {} 1.130 + BlockList(const int size, BlockBegin* init): _BlockList(size, init) {} 1.131 + 1.132 + void iterate_forward(BlockClosure* closure); 1.133 + void iterate_backward(BlockClosure* closure); 1.134 + void blocks_do(void f(BlockBegin*)); 1.135 + void values_do(void f(Value*)); 1.136 + void print(bool cfg_only = false, bool live_only = false) PRODUCT_RETURN; 1.137 +}; 1.138 + 1.139 + 1.140 +// InstructionVisitors provide type-based dispatch for instructions. 1.141 +// For each concrete Instruction class X, a virtual function do_X is 1.142 +// provided. Functionality that needs to be implemented for all classes 1.143 +// (e.g., printing, code generation) is factored out into a specialised 1.144 +// visitor instead of added to the Instruction classes itself. 1.145 + 1.146 +class InstructionVisitor: public StackObj { 1.147 + public: 1.148 + void do_HiWord (HiWord* x) { ShouldNotReachHere(); } 1.149 + virtual void do_Phi (Phi* x) = 0; 1.150 + virtual void do_Local (Local* x) = 0; 1.151 + virtual void do_Constant (Constant* x) = 0; 1.152 + virtual void do_LoadField (LoadField* x) = 0; 1.153 + virtual void do_StoreField (StoreField* x) = 0; 1.154 + virtual void do_ArrayLength (ArrayLength* x) = 0; 1.155 + virtual void do_LoadIndexed (LoadIndexed* x) = 0; 1.156 + virtual void do_StoreIndexed (StoreIndexed* x) = 0; 1.157 + virtual void do_NegateOp (NegateOp* x) = 0; 1.158 + virtual void do_ArithmeticOp (ArithmeticOp* x) = 0; 1.159 + virtual void do_ShiftOp (ShiftOp* x) = 0; 1.160 + virtual void do_LogicOp (LogicOp* x) = 0; 1.161 + virtual void do_CompareOp (CompareOp* x) = 0; 1.162 + virtual void do_IfOp (IfOp* x) = 0; 1.163 + virtual void do_Convert (Convert* x) = 0; 1.164 + virtual void do_NullCheck (NullCheck* x) = 0; 1.165 + virtual void do_Invoke (Invoke* x) = 0; 1.166 + virtual void do_NewInstance (NewInstance* x) = 0; 1.167 + virtual void do_NewTypeArray (NewTypeArray* x) = 0; 1.168 + virtual void do_NewObjectArray (NewObjectArray* x) = 0; 1.169 + virtual void do_NewMultiArray (NewMultiArray* x) = 0; 1.170 + virtual void do_CheckCast (CheckCast* x) = 0; 1.171 + virtual void do_InstanceOf (InstanceOf* x) = 0; 1.172 + virtual void do_MonitorEnter (MonitorEnter* x) = 0; 1.173 + virtual void do_MonitorExit (MonitorExit* x) = 0; 1.174 + virtual void do_Intrinsic (Intrinsic* x) = 0; 1.175 + virtual void do_BlockBegin (BlockBegin* x) = 0; 1.176 + virtual void do_Goto (Goto* x) = 0; 1.177 + virtual void do_If (If* x) = 0; 1.178 + virtual void do_IfInstanceOf (IfInstanceOf* x) = 0; 1.179 + virtual void do_TableSwitch (TableSwitch* x) = 0; 1.180 + virtual void do_LookupSwitch (LookupSwitch* x) = 0; 1.181 + virtual void do_Return (Return* x) = 0; 1.182 + virtual void do_Throw (Throw* x) = 0; 1.183 + virtual void do_Base (Base* x) = 0; 1.184 + virtual void do_OsrEntry (OsrEntry* x) = 0; 1.185 + virtual void do_ExceptionObject(ExceptionObject* x) = 0; 1.186 + virtual void do_RoundFP (RoundFP* x) = 0; 1.187 + virtual void do_UnsafeGetRaw (UnsafeGetRaw* x) = 0; 1.188 + virtual void do_UnsafePutRaw (UnsafePutRaw* x) = 0; 1.189 + virtual void do_UnsafeGetObject(UnsafeGetObject* x) = 0; 1.190 + virtual void do_UnsafePutObject(UnsafePutObject* x) = 0; 1.191 + virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x) = 0; 1.192 + virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; 1.193 + virtual void do_ProfileCall (ProfileCall* x) = 0; 1.194 + virtual void do_ProfileCounter (ProfileCounter* x) = 0; 1.195 +}; 1.196 + 1.197 + 1.198 +// Hashing support 1.199 +// 1.200 +// Note: This hash functions affect the performance 1.201 +// of ValueMap - make changes carefully! 1.202 + 1.203 +#define HASH1(x1 ) ((intx)(x1)) 1.204 +#define HASH2(x1, x2 ) ((HASH1(x1 ) << 7) ^ HASH1(x2)) 1.205 +#define HASH3(x1, x2, x3 ) ((HASH2(x1, x2 ) << 7) ^ HASH1(x3)) 1.206 +#define HASH4(x1, x2, x3, x4) ((HASH3(x1, x2, x3) << 7) ^ HASH1(x4)) 1.207 + 1.208 + 1.209 +// The following macros are used to implement instruction-specific hashing. 1.210 +// By default, each instruction implements hash() and is_equal(Value), used 1.211 +// for value numbering/common subexpression elimination. The default imple- 1.212 +// mentation disables value numbering. Each instruction which can be value- 1.213 +// numbered, should define corresponding hash() and is_equal(Value) functions 1.214 +// via the macros below. The f arguments specify all the values/op codes, etc. 1.215 +// that need to be identical for two instructions to be identical. 1.216 +// 1.217 +// Note: The default implementation of hash() returns 0 in order to indicate 1.218 +// that the instruction should not be considered for value numbering. 1.219 +// The currently used hash functions do not guarantee that never a 0 1.220 +// is produced. While this is still correct, it may be a performance 1.221 +// bug (no value numbering for that node). However, this situation is 1.222 +// so unlikely, that we are not going to handle it specially. 1.223 + 1.224 +#define HASHING1(class_name, enabled, f1) \ 1.225 + virtual intx hash() const { \ 1.226 + return (enabled) ? HASH2(name(), f1) : 0; \ 1.227 + } \ 1.228 + virtual bool is_equal(Value v) const { \ 1.229 + if (!(enabled) ) return false; \ 1.230 + class_name* _v = v->as_##class_name(); \ 1.231 + if (_v == NULL ) return false; \ 1.232 + if (f1 != _v->f1) return false; \ 1.233 + return true; \ 1.234 + } \ 1.235 + 1.236 + 1.237 +#define HASHING2(class_name, enabled, f1, f2) \ 1.238 + virtual intx hash() const { \ 1.239 + return (enabled) ? HASH3(name(), f1, f2) : 0; \ 1.240 + } \ 1.241 + virtual bool is_equal(Value v) const { \ 1.242 + if (!(enabled) ) return false; \ 1.243 + class_name* _v = v->as_##class_name(); \ 1.244 + if (_v == NULL ) return false; \ 1.245 + if (f1 != _v->f1) return false; \ 1.246 + if (f2 != _v->f2) return false; \ 1.247 + return true; \ 1.248 + } \ 1.249 + 1.250 + 1.251 +#define HASHING3(class_name, enabled, f1, f2, f3) \ 1.252 + virtual intx hash() const { \ 1.253 + return (enabled) ? HASH4(name(), f1, f2, f3) : 0; \ 1.254 + } \ 1.255 + virtual bool is_equal(Value v) const { \ 1.256 + if (!(enabled) ) return false; \ 1.257 + class_name* _v = v->as_##class_name(); \ 1.258 + if (_v == NULL ) return false; \ 1.259 + if (f1 != _v->f1) return false; \ 1.260 + if (f2 != _v->f2) return false; \ 1.261 + if (f3 != _v->f3) return false; \ 1.262 + return true; \ 1.263 + } \ 1.264 + 1.265 + 1.266 +// The mother of all instructions... 1.267 + 1.268 +class Instruction: public CompilationResourceObj { 1.269 + private: 1.270 + static int _next_id; // the node counter 1.271 + 1.272 + int _id; // the unique instruction id 1.273 + int _bci; // the instruction bci 1.274 + int _use_count; // the number of instructions refering to this value (w/o prev/next); only roots can have use count = 0 or > 1 1.275 + int _pin_state; // set of PinReason describing the reason for pinning 1.276 + ValueType* _type; // the instruction value type 1.277 + Instruction* _next; // the next instruction if any (NULL for BlockEnd instructions) 1.278 + Instruction* _subst; // the substitution instruction if any 1.279 + LIR_Opr _operand; // LIR specific information 1.280 + unsigned int _flags; // Flag bits 1.281 + 1.282 + XHandlers* _exception_handlers; // Flat list of exception handlers covering this instruction 1.283 + 1.284 +#ifdef ASSERT 1.285 + HiWord* _hi_word; 1.286 +#endif 1.287 + 1.288 + friend class UseCountComputer; 1.289 + 1.290 + protected: 1.291 + void set_bci(int bci) { assert(bci == SynchronizationEntryBCI || bci >= 0, "illegal bci"); _bci = bci; } 1.292 + void set_type(ValueType* type) { 1.293 + assert(type != NULL, "type must exist"); 1.294 + _type = type; 1.295 + } 1.296 + 1.297 + public: 1.298 + enum InstructionFlag { 1.299 + NeedsNullCheckFlag = 0, 1.300 + CanTrapFlag, 1.301 + DirectCompareFlag, 1.302 + IsEliminatedFlag, 1.303 + IsInitializedFlag, 1.304 + IsLoadedFlag, 1.305 + IsSafepointFlag, 1.306 + IsStaticFlag, 1.307 + IsStrictfpFlag, 1.308 + NeedsStoreCheckFlag, 1.309 + NeedsWriteBarrierFlag, 1.310 + PreservesStateFlag, 1.311 + TargetIsFinalFlag, 1.312 + TargetIsLoadedFlag, 1.313 + TargetIsStrictfpFlag, 1.314 + UnorderedIsTrueFlag, 1.315 + NeedsPatchingFlag, 1.316 + ThrowIncompatibleClassChangeErrorFlag, 1.317 + ProfileMDOFlag, 1.318 + InstructionLastFlag 1.319 + }; 1.320 + 1.321 + public: 1.322 + bool check_flag(InstructionFlag id) const { return (_flags & (1 << id)) != 0; } 1.323 + void set_flag(InstructionFlag id, bool f) { _flags = f ? (_flags | (1 << id)) : (_flags & ~(1 << id)); }; 1.324 + 1.325 + // 'globally' used condition values 1.326 + enum Condition { 1.327 + eql, neq, lss, leq, gtr, geq 1.328 + }; 1.329 + 1.330 + // Instructions may be pinned for many reasons and under certain conditions 1.331 + // with enough knowledge it's possible to safely unpin them. 1.332 + enum PinReason { 1.333 + PinUnknown = 1 << 0 1.334 + , PinExplicitNullCheck = 1 << 3 1.335 + , PinStackForStateSplit= 1 << 12 1.336 + , PinStateSplitConstructor= 1 << 13 1.337 + , PinGlobalValueNumbering= 1 << 14 1.338 + }; 1.339 + 1.340 + static Condition mirror(Condition cond); 1.341 + static Condition negate(Condition cond); 1.342 + 1.343 + // initialization 1.344 + static void initialize() { _next_id = 0; } 1.345 + static int number_of_instructions() { return _next_id; } 1.346 + 1.347 + // creation 1.348 + Instruction(ValueType* type, bool type_is_constant = false, bool create_hi = true) 1.349 + : _id(_next_id++) 1.350 + , _bci(-99) 1.351 + , _use_count(0) 1.352 + , _pin_state(0) 1.353 + , _type(type) 1.354 + , _next(NULL) 1.355 + , _subst(NULL) 1.356 + , _flags(0) 1.357 + , _operand(LIR_OprFact::illegalOpr) 1.358 + , _exception_handlers(NULL) 1.359 +#ifdef ASSERT 1.360 + , _hi_word(NULL) 1.361 +#endif 1.362 + { 1.363 + assert(type != NULL && (!type->is_constant() || type_is_constant), "type must exist"); 1.364 +#ifdef ASSERT 1.365 + if (create_hi && type->is_double_word()) { 1.366 + create_hi_word(); 1.367 + } 1.368 +#endif 1.369 + } 1.370 + 1.371 + // accessors 1.372 + int id() const { return _id; } 1.373 + int bci() const { return _bci; } 1.374 + int use_count() const { return _use_count; } 1.375 + int pin_state() const { return _pin_state; } 1.376 + bool is_pinned() const { return _pin_state != 0 || PinAllInstructions; } 1.377 + ValueType* type() const { return _type; } 1.378 + Instruction* prev(BlockBegin* block); // use carefully, expensive operation 1.379 + Instruction* next() const { return _next; } 1.380 + bool has_subst() const { return _subst != NULL; } 1.381 + Instruction* subst() { return _subst == NULL ? this : _subst->subst(); } 1.382 + LIR_Opr operand() const { return _operand; } 1.383 + 1.384 + void set_needs_null_check(bool f) { set_flag(NeedsNullCheckFlag, f); } 1.385 + bool needs_null_check() const { return check_flag(NeedsNullCheckFlag); } 1.386 + 1.387 + bool has_uses() const { return use_count() > 0; } 1.388 + bool is_root() const { return is_pinned() || use_count() > 1; } 1.389 + XHandlers* exception_handlers() const { return _exception_handlers; } 1.390 + 1.391 + // manipulation 1.392 + void pin(PinReason reason) { _pin_state |= reason; } 1.393 + void pin() { _pin_state |= PinUnknown; } 1.394 + // DANGEROUS: only used by EliminateStores 1.395 + void unpin(PinReason reason) { assert((reason & PinUnknown) == 0, "can't unpin unknown state"); _pin_state &= ~reason; } 1.396 + virtual void set_lock_stack(ValueStack* l) { /* do nothing*/ } 1.397 + virtual ValueStack* lock_stack() const { return NULL; } 1.398 + 1.399 + Instruction* set_next(Instruction* next, int bci) { 1.400 + if (next != NULL) { 1.401 + assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next"); 1.402 + assert(next->as_Phi() == NULL && next->as_Local() == NULL, "shouldn't link these instructions into list"); 1.403 + next->set_bci(bci); 1.404 + } 1.405 + _next = next; 1.406 + return next; 1.407 + } 1.408 + 1.409 + void set_subst(Instruction* subst) { 1.410 + assert(subst == NULL || 1.411 + type()->base() == subst->type()->base() || 1.412 + subst->type()->base() == illegalType, "type can't change"); 1.413 + _subst = subst; 1.414 + } 1.415 + void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; } 1.416 + 1.417 +#ifdef ASSERT 1.418 + // HiWord is used for debugging and is allocated early to avoid 1.419 + // allocation at inconvenient points 1.420 + HiWord* hi_word() { return _hi_word; } 1.421 + void create_hi_word(); 1.422 +#endif 1.423 + 1.424 + 1.425 + // machine-specifics 1.426 + void set_operand(LIR_Opr operand) { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; } 1.427 + void clear_operand() { _operand = LIR_OprFact::illegalOpr; } 1.428 + 1.429 + // generic 1.430 + virtual Instruction* as_Instruction() { return this; } // to satisfy HASHING1 macro 1.431 + virtual HiWord* as_HiWord() { return NULL; } 1.432 + virtual Phi* as_Phi() { return NULL; } 1.433 + virtual Local* as_Local() { return NULL; } 1.434 + virtual Constant* as_Constant() { return NULL; } 1.435 + virtual AccessField* as_AccessField() { return NULL; } 1.436 + virtual LoadField* as_LoadField() { return NULL; } 1.437 + virtual StoreField* as_StoreField() { return NULL; } 1.438 + virtual AccessArray* as_AccessArray() { return NULL; } 1.439 + virtual ArrayLength* as_ArrayLength() { return NULL; } 1.440 + virtual AccessIndexed* as_AccessIndexed() { return NULL; } 1.441 + virtual LoadIndexed* as_LoadIndexed() { return NULL; } 1.442 + virtual StoreIndexed* as_StoreIndexed() { return NULL; } 1.443 + virtual NegateOp* as_NegateOp() { return NULL; } 1.444 + virtual Op2* as_Op2() { return NULL; } 1.445 + virtual ArithmeticOp* as_ArithmeticOp() { return NULL; } 1.446 + virtual ShiftOp* as_ShiftOp() { return NULL; } 1.447 + virtual LogicOp* as_LogicOp() { return NULL; } 1.448 + virtual CompareOp* as_CompareOp() { return NULL; } 1.449 + virtual IfOp* as_IfOp() { return NULL; } 1.450 + virtual Convert* as_Convert() { return NULL; } 1.451 + virtual NullCheck* as_NullCheck() { return NULL; } 1.452 + virtual OsrEntry* as_OsrEntry() { return NULL; } 1.453 + virtual StateSplit* as_StateSplit() { return NULL; } 1.454 + virtual Invoke* as_Invoke() { return NULL; } 1.455 + virtual NewInstance* as_NewInstance() { return NULL; } 1.456 + virtual NewArray* as_NewArray() { return NULL; } 1.457 + virtual NewTypeArray* as_NewTypeArray() { return NULL; } 1.458 + virtual NewObjectArray* as_NewObjectArray() { return NULL; } 1.459 + virtual NewMultiArray* as_NewMultiArray() { return NULL; } 1.460 + virtual TypeCheck* as_TypeCheck() { return NULL; } 1.461 + virtual CheckCast* as_CheckCast() { return NULL; } 1.462 + virtual InstanceOf* as_InstanceOf() { return NULL; } 1.463 + virtual AccessMonitor* as_AccessMonitor() { return NULL; } 1.464 + virtual MonitorEnter* as_MonitorEnter() { return NULL; } 1.465 + virtual MonitorExit* as_MonitorExit() { return NULL; } 1.466 + virtual Intrinsic* as_Intrinsic() { return NULL; } 1.467 + virtual BlockBegin* as_BlockBegin() { return NULL; } 1.468 + virtual BlockEnd* as_BlockEnd() { return NULL; } 1.469 + virtual Goto* as_Goto() { return NULL; } 1.470 + virtual If* as_If() { return NULL; } 1.471 + virtual IfInstanceOf* as_IfInstanceOf() { return NULL; } 1.472 + virtual TableSwitch* as_TableSwitch() { return NULL; } 1.473 + virtual LookupSwitch* as_LookupSwitch() { return NULL; } 1.474 + virtual Return* as_Return() { return NULL; } 1.475 + virtual Throw* as_Throw() { return NULL; } 1.476 + virtual Base* as_Base() { return NULL; } 1.477 + virtual RoundFP* as_RoundFP() { return NULL; } 1.478 + virtual ExceptionObject* as_ExceptionObject() { return NULL; } 1.479 + virtual UnsafeOp* as_UnsafeOp() { return NULL; } 1.480 + 1.481 + virtual void visit(InstructionVisitor* v) = 0; 1.482 + 1.483 + virtual bool can_trap() const { return false; } 1.484 + 1.485 + virtual void input_values_do(void f(Value*)) = 0; 1.486 + virtual void state_values_do(void f(Value*)) { /* usually no state - override on demand */ } 1.487 + virtual void other_values_do(void f(Value*)) { /* usually no other - override on demand */ } 1.488 + void values_do(void f(Value*)) { input_values_do(f); state_values_do(f); other_values_do(f); } 1.489 + 1.490 + virtual ciType* exact_type() const { return NULL; } 1.491 + virtual ciType* declared_type() const { return NULL; } 1.492 + 1.493 + // hashing 1.494 + virtual const char* name() const = 0; 1.495 + HASHING1(Instruction, false, id()) // hashing disabled by default 1.496 + 1.497 + // debugging 1.498 + void print() PRODUCT_RETURN; 1.499 + void print_line() PRODUCT_RETURN; 1.500 + void print(InstructionPrinter& ip) PRODUCT_RETURN; 1.501 +}; 1.502 + 1.503 + 1.504 +// The following macros are used to define base (i.e., non-leaf) 1.505 +// and leaf instruction classes. They define class-name related 1.506 +// generic functionality in one place. 1.507 + 1.508 +#define BASE(class_name, super_class_name) \ 1.509 + class class_name: public super_class_name { \ 1.510 + public: \ 1.511 + virtual class_name* as_##class_name() { return this; } \ 1.512 + 1.513 + 1.514 +#define LEAF(class_name, super_class_name) \ 1.515 + BASE(class_name, super_class_name) \ 1.516 + public: \ 1.517 + virtual const char* name() const { return #class_name; } \ 1.518 + virtual void visit(InstructionVisitor* v) { v->do_##class_name(this); } \ 1.519 + 1.520 + 1.521 +// Debugging support 1.522 + 1.523 +#ifdef ASSERT 1.524 + static void assert_value(Value* x) { assert((*x) != NULL, "value must exist"); } 1.525 + #define ASSERT_VALUES values_do(assert_value); 1.526 +#else 1.527 + #define ASSERT_VALUES 1.528 +#endif // ASSERT 1.529 + 1.530 + 1.531 +// A HiWord occupies the 'high word' of a 2-word 1.532 +// expression stack entry. Hi & lo words must be 1.533 +// paired on the expression stack (otherwise the 1.534 +// bytecode sequence is illegal). Note that 'hi' 1.535 +// refers to the IR expression stack format and 1.536 +// does *not* imply a machine word ordering. No 1.537 +// HiWords are used in optimized mode for speed, 1.538 +// but NULL pointers are used instead. 1.539 + 1.540 +LEAF(HiWord, Instruction) 1.541 + private: 1.542 + Value _lo_word; 1.543 + 1.544 + public: 1.545 + // creation 1.546 + HiWord(Value lo_word) 1.547 + : Instruction(illegalType, false, false), 1.548 + _lo_word(lo_word) { 1.549 + // hi-words are also allowed for illegal lo-words 1.550 + assert(lo_word->type()->is_double_word() || lo_word->type()->is_illegal(), 1.551 + "HiWord must be used for 2-word values only"); 1.552 + } 1.553 + 1.554 + // accessors 1.555 + Value lo_word() const { return _lo_word->subst(); } 1.556 + 1.557 + // for invalidating of HiWords 1.558 + void make_illegal() { set_type(illegalType); } 1.559 + 1.560 + // generic 1.561 + virtual void input_values_do(void f(Value*)) { ShouldNotReachHere(); } 1.562 +}; 1.563 + 1.564 + 1.565 +// A Phi is a phi function in the sense of SSA form. It stands for 1.566 +// the value of a local variable at the beginning of a join block. 1.567 +// A Phi consists of n operands, one for every incoming branch. 1.568 + 1.569 +LEAF(Phi, Instruction) 1.570 + private: 1.571 + BlockBegin* _block; // the block to which the phi function belongs 1.572 + int _pf_flags; // the flags of the phi function 1.573 + int _index; // to value on operand stack (index < 0) or to local 1.574 + public: 1.575 + // creation 1.576 + Phi(ValueType* type, BlockBegin* b, int index) 1.577 + : Instruction(type->base()) 1.578 + , _pf_flags(0) 1.579 + , _block(b) 1.580 + , _index(index) 1.581 + { 1.582 + if (type->is_illegal()) { 1.583 + make_illegal(); 1.584 + } 1.585 + } 1.586 + 1.587 + // flags 1.588 + enum Flag { 1.589 + no_flag = 0, 1.590 + visited = 1 << 0, 1.591 + cannot_simplify = 1 << 1 1.592 + }; 1.593 + 1.594 + // accessors 1.595 + bool is_local() const { return _index >= 0; } 1.596 + bool is_on_stack() const { return !is_local(); } 1.597 + int local_index() const { assert(is_local(), ""); return _index; } 1.598 + int stack_index() const { assert(is_on_stack(), ""); return -(_index+1); } 1.599 + 1.600 + Value operand_at(int i) const; 1.601 + int operand_count() const; 1.602 + 1.603 + BlockBegin* block() const { return _block; } 1.604 + 1.605 + void set(Flag f) { _pf_flags |= f; } 1.606 + void clear(Flag f) { _pf_flags &= ~f; } 1.607 + bool is_set(Flag f) const { return (_pf_flags & f) != 0; } 1.608 + 1.609 + // Invalidates phis corresponding to merges of locals of two different types 1.610 + // (these should never be referenced, otherwise the bytecodes are illegal) 1.611 + void make_illegal() { 1.612 + set(cannot_simplify); 1.613 + set_type(illegalType); 1.614 + } 1.615 + 1.616 + bool is_illegal() const { 1.617 + return type()->is_illegal(); 1.618 + } 1.619 + 1.620 + // generic 1.621 + virtual void input_values_do(void f(Value*)) { 1.622 + } 1.623 +}; 1.624 + 1.625 + 1.626 +// A local is a placeholder for an incoming argument to a function call. 1.627 +LEAF(Local, Instruction) 1.628 + private: 1.629 + int _java_index; // the local index within the method to which the local belongs 1.630 + public: 1.631 + // creation 1.632 + Local(ValueType* type, int index) 1.633 + : Instruction(type) 1.634 + , _java_index(index) 1.635 + {} 1.636 + 1.637 + // accessors 1.638 + int java_index() const { return _java_index; } 1.639 + 1.640 + // generic 1.641 + virtual void input_values_do(void f(Value*)) { /* no values */ } 1.642 +}; 1.643 + 1.644 + 1.645 +LEAF(Constant, Instruction) 1.646 + ValueStack* _state; 1.647 + 1.648 + public: 1.649 + // creation 1.650 + Constant(ValueType* type): 1.651 + Instruction(type, true) 1.652 + , _state(NULL) { 1.653 + assert(type->is_constant(), "must be a constant"); 1.654 + } 1.655 + 1.656 + Constant(ValueType* type, ValueStack* state): 1.657 + Instruction(type, true) 1.658 + , _state(state) { 1.659 + assert(state != NULL, "only used for constants which need patching"); 1.660 + assert(type->is_constant(), "must be a constant"); 1.661 + // since it's patching it needs to be pinned 1.662 + pin(); 1.663 + } 1.664 + 1.665 + ValueStack* state() const { return _state; } 1.666 + 1.667 + // generic 1.668 + virtual bool can_trap() const { return state() != NULL; } 1.669 + virtual void input_values_do(void f(Value*)) { /* no values */ } 1.670 + virtual void other_values_do(void f(Value*)); 1.671 + 1.672 + virtual intx hash() const; 1.673 + virtual bool is_equal(Value v) const; 1.674 + 1.675 + virtual BlockBegin* compare(Instruction::Condition condition, Value right, 1.676 + BlockBegin* true_sux, BlockBegin* false_sux); 1.677 +}; 1.678 + 1.679 + 1.680 +BASE(AccessField, Instruction) 1.681 + private: 1.682 + Value _obj; 1.683 + int _offset; 1.684 + ciField* _field; 1.685 + ValueStack* _state_before; // state is set only for unloaded or uninitialized fields 1.686 + ValueStack* _lock_stack; // contains lock and scope information 1.687 + NullCheck* _explicit_null_check; // For explicit null check elimination 1.688 + 1.689 + public: 1.690 + // creation 1.691 + AccessField(Value obj, int offset, ciField* field, bool is_static, ValueStack* lock_stack, 1.692 + ValueStack* state_before, bool is_loaded, bool is_initialized) 1.693 + : Instruction(as_ValueType(field->type()->basic_type())) 1.694 + , _obj(obj) 1.695 + , _offset(offset) 1.696 + , _field(field) 1.697 + , _lock_stack(lock_stack) 1.698 + , _state_before(state_before) 1.699 + , _explicit_null_check(NULL) 1.700 + { 1.701 + set_needs_null_check(!is_static); 1.702 + set_flag(IsLoadedFlag, is_loaded); 1.703 + set_flag(IsInitializedFlag, is_initialized); 1.704 + set_flag(IsStaticFlag, is_static); 1.705 + ASSERT_VALUES 1.706 + if (!is_loaded || (PatchALot && !field->is_volatile())) { 1.707 + // need to patch if the holder wasn't loaded or we're testing 1.708 + // using PatchALot. Don't allow PatchALot for fields which are 1.709 + // known to be volatile they aren't patchable. 1.710 + set_flag(NeedsPatchingFlag, true); 1.711 + } 1.712 + // pin of all instructions with memory access 1.713 + pin(); 1.714 + } 1.715 + 1.716 + // accessors 1.717 + Value obj() const { return _obj; } 1.718 + int offset() const { return _offset; } 1.719 + ciField* field() const { return _field; } 1.720 + BasicType field_type() const { return _field->type()->basic_type(); } 1.721 + bool is_static() const { return check_flag(IsStaticFlag); } 1.722 + bool is_loaded() const { return check_flag(IsLoadedFlag); } 1.723 + bool is_initialized() const { return check_flag(IsInitializedFlag); } 1.724 + ValueStack* state_before() const { return _state_before; } 1.725 + ValueStack* lock_stack() const { return _lock_stack; } 1.726 + NullCheck* explicit_null_check() const { return _explicit_null_check; } 1.727 + bool needs_patching() const { return check_flag(NeedsPatchingFlag); } 1.728 + 1.729 + // manipulation 1.730 + void set_lock_stack(ValueStack* l) { _lock_stack = l; } 1.731 + // Under certain circumstances, if a previous NullCheck instruction 1.732 + // proved the target object non-null, we can eliminate the explicit 1.733 + // null check and do an implicit one, simply specifying the debug 1.734 + // information from the NullCheck. This field should only be consulted 1.735 + // if needs_null_check() is true. 1.736 + void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } 1.737 + 1.738 + // generic 1.739 + virtual bool can_trap() const { return needs_null_check() || needs_patching(); } 1.740 + virtual void input_values_do(void f(Value*)) { f(&_obj); } 1.741 + virtual void other_values_do(void f(Value*)); 1.742 +}; 1.743 + 1.744 + 1.745 +LEAF(LoadField, AccessField) 1.746 + public: 1.747 + // creation 1.748 + LoadField(Value obj, int offset, ciField* field, bool is_static, ValueStack* lock_stack, 1.749 + ValueStack* state_before, bool is_loaded, bool is_initialized) 1.750 + : AccessField(obj, offset, field, is_static, lock_stack, state_before, is_loaded, is_initialized) 1.751 + {} 1.752 + 1.753 + ciType* declared_type() const; 1.754 + ciType* exact_type() const; 1.755 + 1.756 + // generic 1.757 + HASHING2(LoadField, is_loaded() && !field()->is_volatile(), obj()->subst(), offset()) // cannot be eliminated if not yet loaded or if volatile 1.758 +}; 1.759 + 1.760 + 1.761 +LEAF(StoreField, AccessField) 1.762 + private: 1.763 + Value _value; 1.764 + 1.765 + public: 1.766 + // creation 1.767 + StoreField(Value obj, int offset, ciField* field, Value value, bool is_static, ValueStack* lock_stack, 1.768 + ValueStack* state_before, bool is_loaded, bool is_initialized) 1.769 + : AccessField(obj, offset, field, is_static, lock_stack, state_before, is_loaded, is_initialized) 1.770 + , _value(value) 1.771 + { 1.772 + set_flag(NeedsWriteBarrierFlag, as_ValueType(field_type())->is_object()); 1.773 + ASSERT_VALUES 1.774 + pin(); 1.775 + } 1.776 + 1.777 + // accessors 1.778 + Value value() const { return _value; } 1.779 + bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } 1.780 + 1.781 + // generic 1.782 + virtual void input_values_do(void f(Value*)) { AccessField::input_values_do(f); f(&_value); } 1.783 +}; 1.784 + 1.785 + 1.786 +BASE(AccessArray, Instruction) 1.787 + private: 1.788 + Value _array; 1.789 + ValueStack* _lock_stack; 1.790 + 1.791 + public: 1.792 + // creation 1.793 + AccessArray(ValueType* type, Value array, ValueStack* lock_stack) 1.794 + : Instruction(type) 1.795 + , _array(array) 1.796 + , _lock_stack(lock_stack) { 1.797 + set_needs_null_check(true); 1.798 + ASSERT_VALUES 1.799 + pin(); // instruction with side effect (null exception or range check throwing) 1.800 + } 1.801 + 1.802 + Value array() const { return _array; } 1.803 + ValueStack* lock_stack() const { return _lock_stack; } 1.804 + 1.805 + // setters 1.806 + void set_lock_stack(ValueStack* l) { _lock_stack = l; } 1.807 + 1.808 + // generic 1.809 + virtual bool can_trap() const { return needs_null_check(); } 1.810 + virtual void input_values_do(void f(Value*)) { f(&_array); } 1.811 + virtual void other_values_do(void f(Value*)); 1.812 +}; 1.813 + 1.814 + 1.815 +LEAF(ArrayLength, AccessArray) 1.816 + private: 1.817 + NullCheck* _explicit_null_check; // For explicit null check elimination 1.818 + 1.819 + public: 1.820 + // creation 1.821 + ArrayLength(Value array, ValueStack* lock_stack) 1.822 + : AccessArray(intType, array, lock_stack) 1.823 + , _explicit_null_check(NULL) {} 1.824 + 1.825 + // accessors 1.826 + NullCheck* explicit_null_check() const { return _explicit_null_check; } 1.827 + 1.828 + // setters 1.829 + // See LoadField::set_explicit_null_check for documentation 1.830 + void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } 1.831 + 1.832 + // generic 1.833 + HASHING1(ArrayLength, true, array()->subst()) 1.834 +}; 1.835 + 1.836 + 1.837 +BASE(AccessIndexed, AccessArray) 1.838 + private: 1.839 + Value _index; 1.840 + Value _length; 1.841 + BasicType _elt_type; 1.842 + 1.843 + public: 1.844 + // creation 1.845 + AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* lock_stack) 1.846 + : AccessArray(as_ValueType(elt_type), array, lock_stack) 1.847 + , _index(index) 1.848 + , _length(length) 1.849 + , _elt_type(elt_type) 1.850 + { 1.851 + ASSERT_VALUES 1.852 + } 1.853 + 1.854 + // accessors 1.855 + Value index() const { return _index; } 1.856 + Value length() const { return _length; } 1.857 + BasicType elt_type() const { return _elt_type; } 1.858 + 1.859 + // perform elimination of range checks involving constants 1.860 + bool compute_needs_range_check(); 1.861 + 1.862 + // generic 1.863 + virtual void input_values_do(void f(Value*)) { AccessArray::input_values_do(f); f(&_index); if (_length != NULL) f(&_length); } 1.864 +}; 1.865 + 1.866 + 1.867 +LEAF(LoadIndexed, AccessIndexed) 1.868 + private: 1.869 + NullCheck* _explicit_null_check; // For explicit null check elimination 1.870 + 1.871 + public: 1.872 + // creation 1.873 + LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* lock_stack) 1.874 + : AccessIndexed(array, index, length, elt_type, lock_stack) 1.875 + , _explicit_null_check(NULL) {} 1.876 + 1.877 + // accessors 1.878 + NullCheck* explicit_null_check() const { return _explicit_null_check; } 1.879 + 1.880 + // setters 1.881 + // See LoadField::set_explicit_null_check for documentation 1.882 + void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; } 1.883 + 1.884 + ciType* exact_type() const; 1.885 + ciType* declared_type() const; 1.886 + 1.887 + // generic 1.888 + HASHING2(LoadIndexed, true, array()->subst(), index()->subst()) 1.889 +}; 1.890 + 1.891 + 1.892 +LEAF(StoreIndexed, AccessIndexed) 1.893 + private: 1.894 + Value _value; 1.895 + 1.896 + public: 1.897 + // creation 1.898 + StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* lock_stack) 1.899 + : AccessIndexed(array, index, length, elt_type, lock_stack) 1.900 + , _value(value) 1.901 + { 1.902 + set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object())); 1.903 + set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object())); 1.904 + ASSERT_VALUES 1.905 + pin(); 1.906 + } 1.907 + 1.908 + // accessors 1.909 + Value value() const { return _value; } 1.910 + IRScope* scope() const; // the state's scope 1.911 + bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } 1.912 + bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); } 1.913 + 1.914 + // generic 1.915 + virtual void input_values_do(void f(Value*)) { AccessIndexed::input_values_do(f); f(&_value); } 1.916 +}; 1.917 + 1.918 + 1.919 +LEAF(NegateOp, Instruction) 1.920 + private: 1.921 + Value _x; 1.922 + 1.923 + public: 1.924 + // creation 1.925 + NegateOp(Value x) : Instruction(x->type()->base()), _x(x) { 1.926 + ASSERT_VALUES 1.927 + } 1.928 + 1.929 + // accessors 1.930 + Value x() const { return _x; } 1.931 + 1.932 + // generic 1.933 + virtual void input_values_do(void f(Value*)) { f(&_x); } 1.934 +}; 1.935 + 1.936 + 1.937 +BASE(Op2, Instruction) 1.938 + private: 1.939 + Bytecodes::Code _op; 1.940 + Value _x; 1.941 + Value _y; 1.942 + 1.943 + public: 1.944 + // creation 1.945 + Op2(ValueType* type, Bytecodes::Code op, Value x, Value y) : Instruction(type), _op(op), _x(x), _y(y) { 1.946 + ASSERT_VALUES 1.947 + } 1.948 + 1.949 + // accessors 1.950 + Bytecodes::Code op() const { return _op; } 1.951 + Value x() const { return _x; } 1.952 + Value y() const { return _y; } 1.953 + 1.954 + // manipulators 1.955 + void swap_operands() { 1.956 + assert(is_commutative(), "operation must be commutative"); 1.957 + Value t = _x; _x = _y; _y = t; 1.958 + } 1.959 + 1.960 + // generic 1.961 + virtual bool is_commutative() const { return false; } 1.962 + virtual void input_values_do(void f(Value*)) { f(&_x); f(&_y); } 1.963 +}; 1.964 + 1.965 + 1.966 +LEAF(ArithmeticOp, Op2) 1.967 + private: 1.968 + ValueStack* _lock_stack; // used only for division operations 1.969 + public: 1.970 + // creation 1.971 + ArithmeticOp(Bytecodes::Code op, Value x, Value y, bool is_strictfp, ValueStack* lock_stack) 1.972 + : Op2(x->type()->meet(y->type()), op, x, y) 1.973 + , _lock_stack(lock_stack) { 1.974 + set_flag(IsStrictfpFlag, is_strictfp); 1.975 + if (can_trap()) pin(); 1.976 + } 1.977 + 1.978 + // accessors 1.979 + ValueStack* lock_stack() const { return _lock_stack; } 1.980 + bool is_strictfp() const { return check_flag(IsStrictfpFlag); } 1.981 + 1.982 + // setters 1.983 + void set_lock_stack(ValueStack* l) { _lock_stack = l; } 1.984 + 1.985 + // generic 1.986 + virtual bool is_commutative() const; 1.987 + virtual bool can_trap() const; 1.988 + virtual void other_values_do(void f(Value*)); 1.989 + HASHING3(Op2, true, op(), x()->subst(), y()->subst()) 1.990 +}; 1.991 + 1.992 + 1.993 +LEAF(ShiftOp, Op2) 1.994 + public: 1.995 + // creation 1.996 + ShiftOp(Bytecodes::Code op, Value x, Value s) : Op2(x->type()->base(), op, x, s) {} 1.997 + 1.998 + // generic 1.999 + HASHING3(Op2, true, op(), x()->subst(), y()->subst()) 1.1000 +}; 1.1001 + 1.1002 + 1.1003 +LEAF(LogicOp, Op2) 1.1004 + public: 1.1005 + // creation 1.1006 + LogicOp(Bytecodes::Code op, Value x, Value y) : Op2(x->type()->meet(y->type()), op, x, y) {} 1.1007 + 1.1008 + // generic 1.1009 + virtual bool is_commutative() const; 1.1010 + HASHING3(Op2, true, op(), x()->subst(), y()->subst()) 1.1011 +}; 1.1012 + 1.1013 + 1.1014 +LEAF(CompareOp, Op2) 1.1015 + private: 1.1016 + ValueStack* _state_before; // for deoptimization, when canonicalizing 1.1017 + public: 1.1018 + // creation 1.1019 + CompareOp(Bytecodes::Code op, Value x, Value y, ValueStack* state_before) 1.1020 + : Op2(intType, op, x, y) 1.1021 + , _state_before(state_before) 1.1022 + {} 1.1023 + 1.1024 + // accessors 1.1025 + ValueStack* state_before() const { return _state_before; } 1.1026 + 1.1027 + // generic 1.1028 + HASHING3(Op2, true, op(), x()->subst(), y()->subst()) 1.1029 + virtual void other_values_do(void f(Value*)); 1.1030 +}; 1.1031 + 1.1032 + 1.1033 +LEAF(IfOp, Op2) 1.1034 + private: 1.1035 + Value _tval; 1.1036 + Value _fval; 1.1037 + 1.1038 + public: 1.1039 + // creation 1.1040 + IfOp(Value x, Condition cond, Value y, Value tval, Value fval) 1.1041 + : Op2(tval->type()->meet(fval->type()), (Bytecodes::Code)cond, x, y) 1.1042 + , _tval(tval) 1.1043 + , _fval(fval) 1.1044 + { 1.1045 + ASSERT_VALUES 1.1046 + assert(tval->type()->tag() == fval->type()->tag(), "types must match"); 1.1047 + } 1.1048 + 1.1049 + // accessors 1.1050 + virtual bool is_commutative() const; 1.1051 + Bytecodes::Code op() const { ShouldNotCallThis(); return Bytecodes::_illegal; } 1.1052 + Condition cond() const { return (Condition)Op2::op(); } 1.1053 + Value tval() const { return _tval; } 1.1054 + Value fval() const { return _fval; } 1.1055 + 1.1056 + // generic 1.1057 + virtual void input_values_do(void f(Value*)) { Op2::input_values_do(f); f(&_tval); f(&_fval); } 1.1058 +}; 1.1059 + 1.1060 + 1.1061 +LEAF(Convert, Instruction) 1.1062 + private: 1.1063 + Bytecodes::Code _op; 1.1064 + Value _value; 1.1065 + 1.1066 + public: 1.1067 + // creation 1.1068 + Convert(Bytecodes::Code op, Value value, ValueType* to_type) : Instruction(to_type), _op(op), _value(value) { 1.1069 + ASSERT_VALUES 1.1070 + } 1.1071 + 1.1072 + // accessors 1.1073 + Bytecodes::Code op() const { return _op; } 1.1074 + Value value() const { return _value; } 1.1075 + 1.1076 + // generic 1.1077 + virtual void input_values_do(void f(Value*)) { f(&_value); } 1.1078 + HASHING2(Convert, true, op(), value()->subst()) 1.1079 +}; 1.1080 + 1.1081 + 1.1082 +LEAF(NullCheck, Instruction) 1.1083 + private: 1.1084 + Value _obj; 1.1085 + ValueStack* _lock_stack; 1.1086 + 1.1087 + public: 1.1088 + // creation 1.1089 + NullCheck(Value obj, ValueStack* lock_stack) : Instruction(obj->type()->base()), _obj(obj), _lock_stack(lock_stack) { 1.1090 + ASSERT_VALUES 1.1091 + set_can_trap(true); 1.1092 + assert(_obj->type()->is_object(), "null check must be applied to objects only"); 1.1093 + pin(Instruction::PinExplicitNullCheck); 1.1094 + } 1.1095 + 1.1096 + // accessors 1.1097 + Value obj() const { return _obj; } 1.1098 + ValueStack* lock_stack() const { return _lock_stack; } 1.1099 + 1.1100 + // setters 1.1101 + void set_lock_stack(ValueStack* l) { _lock_stack = l; } 1.1102 + void set_can_trap(bool can_trap) { set_flag(CanTrapFlag, can_trap); } 1.1103 + 1.1104 + // generic 1.1105 + virtual bool can_trap() const { return check_flag(CanTrapFlag); /* null-check elimination sets to false */ } 1.1106 + virtual void input_values_do(void f(Value*)) { f(&_obj); } 1.1107 + virtual void other_values_do(void f(Value*)); 1.1108 + HASHING1(NullCheck, true, obj()->subst()) 1.1109 +}; 1.1110 + 1.1111 + 1.1112 +BASE(StateSplit, Instruction) 1.1113 + private: 1.1114 + ValueStack* _state; 1.1115 + 1.1116 + protected: 1.1117 + static void substitute(BlockList& list, BlockBegin* old_block, BlockBegin* new_block); 1.1118 + 1.1119 + public: 1.1120 + // creation 1.1121 + StateSplit(ValueType* type) : Instruction(type), _state(NULL) { 1.1122 + pin(PinStateSplitConstructor); 1.1123 + } 1.1124 + 1.1125 + // accessors 1.1126 + ValueStack* state() const { return _state; } 1.1127 + IRScope* scope() const; // the state's scope 1.1128 + 1.1129 + // manipulation 1.1130 + void set_state(ValueStack* state) { _state = state; } 1.1131 + 1.1132 + // generic 1.1133 + virtual void input_values_do(void f(Value*)) { /* no values */ } 1.1134 + virtual void state_values_do(void f(Value*)); 1.1135 +}; 1.1136 + 1.1137 + 1.1138 +LEAF(Invoke, StateSplit) 1.1139 + private: 1.1140 + Bytecodes::Code _code; 1.1141 + Value _recv; 1.1142 + Values* _args; 1.1143 + BasicTypeList* _signature; 1.1144 + int _vtable_index; 1.1145 + ciMethod* _target; 1.1146 + 1.1147 + public: 1.1148 + // creation 1.1149 + Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, 1.1150 + int vtable_index, ciMethod* target); 1.1151 + 1.1152 + // accessors 1.1153 + Bytecodes::Code code() const { return _code; } 1.1154 + Value receiver() const { return _recv; } 1.1155 + bool has_receiver() const { return receiver() != NULL; } 1.1156 + int number_of_arguments() const { return _args->length(); } 1.1157 + Value argument_at(int i) const { return _args->at(i); } 1.1158 + int vtable_index() const { return _vtable_index; } 1.1159 + BasicTypeList* signature() const { return _signature; } 1.1160 + ciMethod* target() const { return _target; } 1.1161 + 1.1162 + // Returns false if target is not loaded 1.1163 + bool target_is_final() const { return check_flag(TargetIsFinalFlag); } 1.1164 + bool target_is_loaded() const { return check_flag(TargetIsLoadedFlag); } 1.1165 + // Returns false if target is not loaded 1.1166 + bool target_is_strictfp() const { return check_flag(TargetIsStrictfpFlag); } 1.1167 + 1.1168 + // generic 1.1169 + virtual bool can_trap() const { return true; } 1.1170 + virtual void input_values_do(void f(Value*)) { 1.1171 + StateSplit::input_values_do(f); 1.1172 + if (has_receiver()) f(&_recv); 1.1173 + for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i)); 1.1174 + } 1.1175 +}; 1.1176 + 1.1177 + 1.1178 +LEAF(NewInstance, StateSplit) 1.1179 + private: 1.1180 + ciInstanceKlass* _klass; 1.1181 + 1.1182 + public: 1.1183 + // creation 1.1184 + NewInstance(ciInstanceKlass* klass) : StateSplit(instanceType), _klass(klass) {} 1.1185 + 1.1186 + // accessors 1.1187 + ciInstanceKlass* klass() const { return _klass; } 1.1188 + 1.1189 + // generic 1.1190 + virtual bool can_trap() const { return true; } 1.1191 + ciType* exact_type() const; 1.1192 +}; 1.1193 + 1.1194 + 1.1195 +BASE(NewArray, StateSplit) 1.1196 + private: 1.1197 + Value _length; 1.1198 + ValueStack* _state_before; 1.1199 + 1.1200 + public: 1.1201 + // creation 1.1202 + NewArray(Value length, ValueStack* state_before) : StateSplit(objectType), _length(length), _state_before(state_before) { 1.1203 + // Do not ASSERT_VALUES since length is NULL for NewMultiArray 1.1204 + } 1.1205 + 1.1206 + // accessors 1.1207 + ValueStack* state_before() const { return _state_before; } 1.1208 + Value length() const { return _length; } 1.1209 + 1.1210 + // generic 1.1211 + virtual bool can_trap() const { return true; } 1.1212 + virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_length); } 1.1213 + virtual void other_values_do(void f(Value*)); 1.1214 +}; 1.1215 + 1.1216 + 1.1217 +LEAF(NewTypeArray, NewArray) 1.1218 + private: 1.1219 + BasicType _elt_type; 1.1220 + 1.1221 + public: 1.1222 + // creation 1.1223 + NewTypeArray(Value length, BasicType elt_type) : NewArray(length, NULL), _elt_type(elt_type) {} 1.1224 + 1.1225 + // accessors 1.1226 + BasicType elt_type() const { return _elt_type; } 1.1227 + ciType* exact_type() const; 1.1228 +}; 1.1229 + 1.1230 + 1.1231 +LEAF(NewObjectArray, NewArray) 1.1232 + private: 1.1233 + ciKlass* _klass; 1.1234 + 1.1235 + public: 1.1236 + // creation 1.1237 + NewObjectArray(ciKlass* klass, Value length, ValueStack* state_before) : NewArray(length, state_before), _klass(klass) {} 1.1238 + 1.1239 + // accessors 1.1240 + ciKlass* klass() const { return _klass; } 1.1241 + ciType* exact_type() const; 1.1242 +}; 1.1243 + 1.1244 + 1.1245 +LEAF(NewMultiArray, NewArray) 1.1246 + private: 1.1247 + ciKlass* _klass; 1.1248 + Values* _dims; 1.1249 + 1.1250 + public: 1.1251 + // creation 1.1252 + NewMultiArray(ciKlass* klass, Values* dims, ValueStack* state_before) : NewArray(NULL, state_before), _klass(klass), _dims(dims) { 1.1253 + ASSERT_VALUES 1.1254 + } 1.1255 + 1.1256 + // accessors 1.1257 + ciKlass* klass() const { return _klass; } 1.1258 + Values* dims() const { return _dims; } 1.1259 + int rank() const { return dims()->length(); } 1.1260 + 1.1261 + // generic 1.1262 + virtual void input_values_do(void f(Value*)) { 1.1263 + // NOTE: we do not call NewArray::input_values_do since "length" 1.1264 + // is meaningless for a multi-dimensional array; passing the 1.1265 + // zeroth element down to NewArray as its length is a bad idea 1.1266 + // since there will be a copy in the "dims" array which doesn't 1.1267 + // get updated, and the value must not be traversed twice. Was bug 1.1268 + // - kbr 4/10/2001 1.1269 + StateSplit::input_values_do(f); 1.1270 + for (int i = 0; i < _dims->length(); i++) f(_dims->adr_at(i)); 1.1271 + } 1.1272 +}; 1.1273 + 1.1274 + 1.1275 +BASE(TypeCheck, StateSplit) 1.1276 + private: 1.1277 + ciKlass* _klass; 1.1278 + Value _obj; 1.1279 + ValueStack* _state_before; 1.1280 + 1.1281 + public: 1.1282 + // creation 1.1283 + TypeCheck(ciKlass* klass, Value obj, ValueType* type, ValueStack* state_before) : StateSplit(type), _klass(klass), _obj(obj), _state_before(state_before) { 1.1284 + ASSERT_VALUES 1.1285 + set_direct_compare(false); 1.1286 + } 1.1287 + 1.1288 + // accessors 1.1289 + ValueStack* state_before() const { return _state_before; } 1.1290 + ciKlass* klass() const { return _klass; } 1.1291 + Value obj() const { return _obj; } 1.1292 + bool is_loaded() const { return klass() != NULL; } 1.1293 + bool direct_compare() const { return check_flag(DirectCompareFlag); } 1.1294 + 1.1295 + // manipulation 1.1296 + void set_direct_compare(bool flag) { set_flag(DirectCompareFlag, flag); } 1.1297 + 1.1298 + // generic 1.1299 + virtual bool can_trap() const { return true; } 1.1300 + virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_obj); } 1.1301 + virtual void other_values_do(void f(Value*)); 1.1302 +}; 1.1303 + 1.1304 + 1.1305 +LEAF(CheckCast, TypeCheck) 1.1306 + private: 1.1307 + ciMethod* _profiled_method; 1.1308 + int _profiled_bci; 1.1309 + 1.1310 + public: 1.1311 + // creation 1.1312 + CheckCast(ciKlass* klass, Value obj, ValueStack* state_before) 1.1313 + : TypeCheck(klass, obj, objectType, state_before) 1.1314 + , _profiled_method(NULL) 1.1315 + , _profiled_bci(0) {} 1.1316 + 1.1317 + void set_incompatible_class_change_check() { 1.1318 + set_flag(ThrowIncompatibleClassChangeErrorFlag, true); 1.1319 + } 1.1320 + bool is_incompatible_class_change_check() const { 1.1321 + return check_flag(ThrowIncompatibleClassChangeErrorFlag); 1.1322 + } 1.1323 + 1.1324 + // Helpers for methodDataOop profiling 1.1325 + void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } 1.1326 + void set_profiled_method(ciMethod* method) { _profiled_method = method; } 1.1327 + void set_profiled_bci(int bci) { _profiled_bci = bci; } 1.1328 + bool should_profile() const { return check_flag(ProfileMDOFlag); } 1.1329 + ciMethod* profiled_method() const { return _profiled_method; } 1.1330 + int profiled_bci() const { return _profiled_bci; } 1.1331 + 1.1332 + ciType* declared_type() const; 1.1333 + ciType* exact_type() const; 1.1334 + 1.1335 +}; 1.1336 + 1.1337 + 1.1338 +LEAF(InstanceOf, TypeCheck) 1.1339 + public: 1.1340 + // creation 1.1341 + InstanceOf(ciKlass* klass, Value obj, ValueStack* state_before) : TypeCheck(klass, obj, intType, state_before) {} 1.1342 +}; 1.1343 + 1.1344 + 1.1345 +BASE(AccessMonitor, StateSplit) 1.1346 + private: 1.1347 + Value _obj; 1.1348 + int _monitor_no; 1.1349 + 1.1350 + public: 1.1351 + // creation 1.1352 + AccessMonitor(Value obj, int monitor_no) 1.1353 + : StateSplit(illegalType) 1.1354 + , _obj(obj) 1.1355 + , _monitor_no(monitor_no) 1.1356 + { 1.1357 + set_needs_null_check(true); 1.1358 + ASSERT_VALUES 1.1359 + } 1.1360 + 1.1361 + // accessors 1.1362 + Value obj() const { return _obj; } 1.1363 + int monitor_no() const { return _monitor_no; } 1.1364 + 1.1365 + // generic 1.1366 + virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_obj); } 1.1367 +}; 1.1368 + 1.1369 + 1.1370 +LEAF(MonitorEnter, AccessMonitor) 1.1371 + private: 1.1372 + ValueStack* _lock_stack_before; 1.1373 + 1.1374 + public: 1.1375 + // creation 1.1376 + MonitorEnter(Value obj, int monitor_no, ValueStack* lock_stack_before) 1.1377 + : AccessMonitor(obj, monitor_no) 1.1378 + , _lock_stack_before(lock_stack_before) 1.1379 + { 1.1380 + ASSERT_VALUES 1.1381 + } 1.1382 + 1.1383 + // accessors 1.1384 + ValueStack* lock_stack_before() const { return _lock_stack_before; } 1.1385 + virtual void state_values_do(void f(Value*)); 1.1386 + 1.1387 + // generic 1.1388 + virtual bool can_trap() const { return true; } 1.1389 +}; 1.1390 + 1.1391 + 1.1392 +LEAF(MonitorExit, AccessMonitor) 1.1393 + public: 1.1394 + // creation 1.1395 + MonitorExit(Value obj, int monitor_no) : AccessMonitor(obj, monitor_no) {} 1.1396 +}; 1.1397 + 1.1398 + 1.1399 +LEAF(Intrinsic, StateSplit) 1.1400 + private: 1.1401 + vmIntrinsics::ID _id; 1.1402 + Values* _args; 1.1403 + ValueStack* _lock_stack; 1.1404 + Value _recv; 1.1405 + 1.1406 + public: 1.1407 + // preserves_state can be set to true for Intrinsics 1.1408 + // which are guaranteed to preserve register state across any slow 1.1409 + // cases; setting it to true does not mean that the Intrinsic can 1.1410 + // not trap, only that if we continue execution in the same basic 1.1411 + // block after the Intrinsic, all of the registers are intact. This 1.1412 + // allows load elimination and common expression elimination to be 1.1413 + // performed across the Intrinsic. The default value is false. 1.1414 + Intrinsic(ValueType* type, 1.1415 + vmIntrinsics::ID id, 1.1416 + Values* args, 1.1417 + bool has_receiver, 1.1418 + ValueStack* lock_stack, 1.1419 + bool preserves_state, 1.1420 + bool cantrap = true) 1.1421 + : StateSplit(type) 1.1422 + , _id(id) 1.1423 + , _args(args) 1.1424 + , _lock_stack(lock_stack) 1.1425 + , _recv(NULL) 1.1426 + { 1.1427 + assert(args != NULL, "args must exist"); 1.1428 + ASSERT_VALUES 1.1429 + set_flag(PreservesStateFlag, preserves_state); 1.1430 + set_flag(CanTrapFlag, cantrap); 1.1431 + if (has_receiver) { 1.1432 + _recv = argument_at(0); 1.1433 + } 1.1434 + set_needs_null_check(has_receiver); 1.1435 + 1.1436 + // some intrinsics can't trap, so don't force them to be pinned 1.1437 + if (!can_trap()) { 1.1438 + unpin(PinStateSplitConstructor); 1.1439 + } 1.1440 + } 1.1441 + 1.1442 + // accessors 1.1443 + vmIntrinsics::ID id() const { return _id; } 1.1444 + int number_of_arguments() const { return _args->length(); } 1.1445 + Value argument_at(int i) const { return _args->at(i); } 1.1446 + ValueStack* lock_stack() const { return _lock_stack; } 1.1447 + 1.1448 + bool has_receiver() const { return (_recv != NULL); } 1.1449 + Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; } 1.1450 + bool preserves_state() const { return check_flag(PreservesStateFlag); } 1.1451 + 1.1452 + // generic 1.1453 + virtual bool can_trap() const { return check_flag(CanTrapFlag); } 1.1454 + virtual void input_values_do(void f(Value*)) { 1.1455 + StateSplit::input_values_do(f); 1.1456 + for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i)); 1.1457 + } 1.1458 + virtual void state_values_do(void f(Value*)); 1.1459 + 1.1460 +}; 1.1461 + 1.1462 + 1.1463 +class LIR_List; 1.1464 + 1.1465 +LEAF(BlockBegin, StateSplit) 1.1466 + private: 1.1467 + static int _next_block_id; // the block counter 1.1468 + 1.1469 + int _block_id; // the unique block id 1.1470 + int _depth_first_number; // number of this block in a depth-first ordering 1.1471 + int _linear_scan_number; // number of this block in linear-scan ordering 1.1472 + int _loop_depth; // the loop nesting level of this block 1.1473 + int _loop_index; // number of the innermost loop of this block 1.1474 + int _flags; // the flags associated with this block 1.1475 + 1.1476 + // fields used by BlockListBuilder 1.1477 + int _total_preds; // number of predecessors found by BlockListBuilder 1.1478 + BitMap _stores_to_locals; // bit is set when a local variable is stored in the block 1.1479 + 1.1480 + // SSA specific fields: (factor out later) 1.1481 + BlockList _successors; // the successors of this block 1.1482 + BlockList _predecessors; // the predecessors of this block 1.1483 + BlockBegin* _dominator; // the dominator of this block 1.1484 + // SSA specific ends 1.1485 + BlockEnd* _end; // the last instruction of this block 1.1486 + BlockList _exception_handlers; // the exception handlers potentially invoked by this block 1.1487 + ValueStackStack* _exception_states; // only for xhandler entries: states of all instructions that have an edge to this xhandler 1.1488 + int _exception_handler_pco; // if this block is the start of an exception handler, 1.1489 + // this records the PC offset in the assembly code of the 1.1490 + // first instruction in this block 1.1491 + Label _label; // the label associated with this block 1.1492 + LIR_List* _lir; // the low level intermediate representation for this block 1.1493 + 1.1494 + BitMap _live_in; // set of live LIR_Opr registers at entry to this block 1.1495 + BitMap _live_out; // set of live LIR_Opr registers at exit from this block 1.1496 + BitMap _live_gen; // set of registers used before any redefinition in this block 1.1497 + BitMap _live_kill; // set of registers defined in this block 1.1498 + 1.1499 + BitMap _fpu_register_usage; 1.1500 + intArray* _fpu_stack_state; // For x86 FPU code generation with UseLinearScan 1.1501 + int _first_lir_instruction_id; // ID of first LIR instruction in this block 1.1502 + int _last_lir_instruction_id; // ID of last LIR instruction in this block 1.1503 + 1.1504 + void iterate_preorder (boolArray& mark, BlockClosure* closure); 1.1505 + void iterate_postorder(boolArray& mark, BlockClosure* closure); 1.1506 + 1.1507 + friend class SuxAndWeightAdjuster; 1.1508 + 1.1509 + public: 1.1510 + // initialization/counting 1.1511 + static void initialize() { _next_block_id = 0; } 1.1512 + static int number_of_blocks() { return _next_block_id; } 1.1513 + 1.1514 + // creation 1.1515 + BlockBegin(int bci) 1.1516 + : StateSplit(illegalType) 1.1517 + , _block_id(_next_block_id++) 1.1518 + , _depth_first_number(-1) 1.1519 + , _linear_scan_number(-1) 1.1520 + , _loop_depth(0) 1.1521 + , _flags(0) 1.1522 + , _dominator(NULL) 1.1523 + , _end(NULL) 1.1524 + , _predecessors(2) 1.1525 + , _successors(2) 1.1526 + , _exception_handlers(1) 1.1527 + , _exception_states(NULL) 1.1528 + , _exception_handler_pco(-1) 1.1529 + , _lir(NULL) 1.1530 + , _loop_index(-1) 1.1531 + , _live_in() 1.1532 + , _live_out() 1.1533 + , _live_gen() 1.1534 + , _live_kill() 1.1535 + , _fpu_register_usage() 1.1536 + , _fpu_stack_state(NULL) 1.1537 + , _first_lir_instruction_id(-1) 1.1538 + , _last_lir_instruction_id(-1) 1.1539 + , _total_preds(0) 1.1540 + , _stores_to_locals() 1.1541 + { 1.1542 + set_bci(bci); 1.1543 + } 1.1544 + 1.1545 + // accessors 1.1546 + int block_id() const { return _block_id; } 1.1547 + BlockList* successors() { return &_successors; } 1.1548 + BlockBegin* dominator() const { return _dominator; } 1.1549 + int loop_depth() const { return _loop_depth; } 1.1550 + int depth_first_number() const { return _depth_first_number; } 1.1551 + int linear_scan_number() const { return _linear_scan_number; } 1.1552 + BlockEnd* end() const { return _end; } 1.1553 + Label* label() { return &_label; } 1.1554 + LIR_List* lir() const { return _lir; } 1.1555 + int exception_handler_pco() const { return _exception_handler_pco; } 1.1556 + BitMap& live_in() { return _live_in; } 1.1557 + BitMap& live_out() { return _live_out; } 1.1558 + BitMap& live_gen() { return _live_gen; } 1.1559 + BitMap& live_kill() { return _live_kill; } 1.1560 + BitMap& fpu_register_usage() { return _fpu_register_usage; } 1.1561 + intArray* fpu_stack_state() const { return _fpu_stack_state; } 1.1562 + int first_lir_instruction_id() const { return _first_lir_instruction_id; } 1.1563 + int last_lir_instruction_id() const { return _last_lir_instruction_id; } 1.1564 + int total_preds() const { return _total_preds; } 1.1565 + BitMap& stores_to_locals() { return _stores_to_locals; } 1.1566 + 1.1567 + // manipulation 1.1568 + void set_bci(int bci) { Instruction::set_bci(bci); } 1.1569 + void set_dominator(BlockBegin* dom) { _dominator = dom; } 1.1570 + void set_loop_depth(int d) { _loop_depth = d; } 1.1571 + void set_depth_first_number(int dfn) { _depth_first_number = dfn; } 1.1572 + void set_linear_scan_number(int lsn) { _linear_scan_number = lsn; } 1.1573 + void set_end(BlockEnd* end); 1.1574 + void disconnect_from_graph(); 1.1575 + static void disconnect_edge(BlockBegin* from, BlockBegin* to); 1.1576 + BlockBegin* insert_block_between(BlockBegin* sux); 1.1577 + void substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux); 1.1578 + void set_lir(LIR_List* lir) { _lir = lir; } 1.1579 + void set_exception_handler_pco(int pco) { _exception_handler_pco = pco; } 1.1580 + void set_live_in (BitMap map) { _live_in = map; } 1.1581 + void set_live_out (BitMap map) { _live_out = map; } 1.1582 + void set_live_gen (BitMap map) { _live_gen = map; } 1.1583 + void set_live_kill (BitMap map) { _live_kill = map; } 1.1584 + void set_fpu_register_usage(BitMap map) { _fpu_register_usage = map; } 1.1585 + void set_fpu_stack_state(intArray* state) { _fpu_stack_state = state; } 1.1586 + void set_first_lir_instruction_id(int id) { _first_lir_instruction_id = id; } 1.1587 + void set_last_lir_instruction_id(int id) { _last_lir_instruction_id = id; } 1.1588 + void increment_total_preds(int n = 1) { _total_preds += n; } 1.1589 + void init_stores_to_locals(int locals_count) { _stores_to_locals = BitMap(locals_count); _stores_to_locals.clear(); } 1.1590 + 1.1591 + // generic 1.1592 + virtual void state_values_do(void f(Value*)); 1.1593 + 1.1594 + // successors and predecessors 1.1595 + int number_of_sux() const; 1.1596 + BlockBegin* sux_at(int i) const; 1.1597 + void add_successor(BlockBegin* sux); 1.1598 + void remove_successor(BlockBegin* pred); 1.1599 + bool is_successor(BlockBegin* sux) const { return _successors.contains(sux); } 1.1600 + 1.1601 + void add_predecessor(BlockBegin* pred); 1.1602 + void remove_predecessor(BlockBegin* pred); 1.1603 + bool is_predecessor(BlockBegin* pred) const { return _predecessors.contains(pred); } 1.1604 + int number_of_preds() const { return _predecessors.length(); } 1.1605 + BlockBegin* pred_at(int i) const { return _predecessors[i]; } 1.1606 + 1.1607 + // exception handlers potentially invoked by this block 1.1608 + void add_exception_handler(BlockBegin* b); 1.1609 + bool is_exception_handler(BlockBegin* b) const { return _exception_handlers.contains(b); } 1.1610 + int number_of_exception_handlers() const { return _exception_handlers.length(); } 1.1611 + BlockBegin* exception_handler_at(int i) const { return _exception_handlers.at(i); } 1.1612 + 1.1613 + // states of the instructions that have an edge to this exception handler 1.1614 + int number_of_exception_states() { assert(is_set(exception_entry_flag), "only for xhandlers"); return _exception_states == NULL ? 0 : _exception_states->length(); } 1.1615 + ValueStack* exception_state_at(int idx) const { assert(is_set(exception_entry_flag), "only for xhandlers"); return _exception_states->at(idx); } 1.1616 + int add_exception_state(ValueStack* state); 1.1617 + 1.1618 + // flags 1.1619 + enum Flag { 1.1620 + no_flag = 0, 1.1621 + std_entry_flag = 1 << 0, 1.1622 + osr_entry_flag = 1 << 1, 1.1623 + exception_entry_flag = 1 << 2, 1.1624 + subroutine_entry_flag = 1 << 3, 1.1625 + backward_branch_target_flag = 1 << 4, 1.1626 + is_on_work_list_flag = 1 << 5, 1.1627 + was_visited_flag = 1 << 6, 1.1628 + default_exception_handler_flag = 1 << 8, // identify block which represents the default exception handler 1.1629 + parser_loop_header_flag = 1 << 9, // set by parser to identify blocks where phi functions can not be created on demand 1.1630 + critical_edge_split_flag = 1 << 10, // set for all blocks that are introduced when critical edges are split 1.1631 + linear_scan_loop_header_flag = 1 << 11, // set during loop-detection for LinearScan 1.1632 + linear_scan_loop_end_flag = 1 << 12 // set during loop-detection for LinearScan 1.1633 + }; 1.1634 + 1.1635 + void set(Flag f) { _flags |= f; } 1.1636 + void clear(Flag f) { _flags &= ~f; } 1.1637 + bool is_set(Flag f) const { return (_flags & f) != 0; } 1.1638 + bool is_entry_block() const { 1.1639 + const int entry_mask = std_entry_flag | osr_entry_flag | exception_entry_flag; 1.1640 + return (_flags & entry_mask) != 0; 1.1641 + } 1.1642 + 1.1643 + // iteration 1.1644 + void iterate_preorder (BlockClosure* closure); 1.1645 + void iterate_postorder (BlockClosure* closure); 1.1646 + 1.1647 + void block_values_do(void f(Value*)); 1.1648 + 1.1649 + // loops 1.1650 + void set_loop_index(int ix) { _loop_index = ix; } 1.1651 + int loop_index() const { return _loop_index; } 1.1652 + 1.1653 + // merging 1.1654 + bool try_merge(ValueStack* state); // try to merge states at block begin 1.1655 + void merge(ValueStack* state) { bool b = try_merge(state); assert(b, "merge failed"); } 1.1656 + 1.1657 + // debugging 1.1658 + void print_block() PRODUCT_RETURN; 1.1659 + void print_block(InstructionPrinter& ip, bool live_only = false) PRODUCT_RETURN; 1.1660 +}; 1.1661 + 1.1662 + 1.1663 +BASE(BlockEnd, StateSplit) 1.1664 + private: 1.1665 + BlockBegin* _begin; 1.1666 + BlockList* _sux; 1.1667 + ValueStack* _state_before; 1.1668 + 1.1669 + protected: 1.1670 + BlockList* sux() const { return _sux; } 1.1671 + 1.1672 + void set_sux(BlockList* sux) { 1.1673 +#ifdef ASSERT 1.1674 + assert(sux != NULL, "sux must exist"); 1.1675 + for (int i = sux->length() - 1; i >= 0; i--) assert(sux->at(i) != NULL, "sux must exist"); 1.1676 +#endif 1.1677 + _sux = sux; 1.1678 + } 1.1679 + 1.1680 + public: 1.1681 + // creation 1.1682 + BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint) 1.1683 + : StateSplit(type) 1.1684 + , _begin(NULL) 1.1685 + , _sux(NULL) 1.1686 + , _state_before(state_before) { 1.1687 + set_flag(IsSafepointFlag, is_safepoint); 1.1688 + } 1.1689 + 1.1690 + // accessors 1.1691 + ValueStack* state_before() const { return _state_before; } 1.1692 + bool is_safepoint() const { return check_flag(IsSafepointFlag); } 1.1693 + BlockBegin* begin() const { return _begin; } 1.1694 + 1.1695 + // manipulation 1.1696 + void set_begin(BlockBegin* begin); 1.1697 + 1.1698 + // generic 1.1699 + virtual void other_values_do(void f(Value*)); 1.1700 + 1.1701 + // successors 1.1702 + int number_of_sux() const { return _sux != NULL ? _sux->length() : 0; } 1.1703 + BlockBegin* sux_at(int i) const { return _sux->at(i); } 1.1704 + BlockBegin* default_sux() const { return sux_at(number_of_sux() - 1); } 1.1705 + BlockBegin** addr_sux_at(int i) const { return _sux->adr_at(i); } 1.1706 + int sux_index(BlockBegin* sux) const { return _sux->find(sux); } 1.1707 + void substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux); 1.1708 +}; 1.1709 + 1.1710 + 1.1711 +LEAF(Goto, BlockEnd) 1.1712 + public: 1.1713 + // creation 1.1714 + Goto(BlockBegin* sux, ValueStack* state_before, bool is_safepoint = false) : BlockEnd(illegalType, state_before, is_safepoint) { 1.1715 + BlockList* s = new BlockList(1); 1.1716 + s->append(sux); 1.1717 + set_sux(s); 1.1718 + } 1.1719 + 1.1720 + Goto(BlockBegin* sux, bool is_safepoint) : BlockEnd(illegalType, NULL, is_safepoint) { 1.1721 + BlockList* s = new BlockList(1); 1.1722 + s->append(sux); 1.1723 + set_sux(s); 1.1724 + } 1.1725 + 1.1726 +}; 1.1727 + 1.1728 + 1.1729 +LEAF(If, BlockEnd) 1.1730 + private: 1.1731 + Value _x; 1.1732 + Condition _cond; 1.1733 + Value _y; 1.1734 + ciMethod* _profiled_method; 1.1735 + int _profiled_bci; // Canonicalizer may alter bci of If node 1.1736 + public: 1.1737 + // creation 1.1738 + // unordered_is_true is valid for float/double compares only 1.1739 + If(Value x, Condition cond, bool unordered_is_true, Value y, BlockBegin* tsux, BlockBegin* fsux, ValueStack* state_before, bool is_safepoint) 1.1740 + : BlockEnd(illegalType, state_before, is_safepoint) 1.1741 + , _x(x) 1.1742 + , _cond(cond) 1.1743 + , _y(y) 1.1744 + , _profiled_method(NULL) 1.1745 + , _profiled_bci(0) 1.1746 + { 1.1747 + ASSERT_VALUES 1.1748 + set_flag(UnorderedIsTrueFlag, unordered_is_true); 1.1749 + assert(x->type()->tag() == y->type()->tag(), "types must match"); 1.1750 + BlockList* s = new BlockList(2); 1.1751 + s->append(tsux); 1.1752 + s->append(fsux); 1.1753 + set_sux(s); 1.1754 + } 1.1755 + 1.1756 + // accessors 1.1757 + Value x() const { return _x; } 1.1758 + Condition cond() const { return _cond; } 1.1759 + bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } 1.1760 + Value y() const { return _y; } 1.1761 + BlockBegin* sux_for(bool is_true) const { return sux_at(is_true ? 0 : 1); } 1.1762 + BlockBegin* tsux() const { return sux_for(true); } 1.1763 + BlockBegin* fsux() const { return sux_for(false); } 1.1764 + BlockBegin* usux() const { return sux_for(unordered_is_true()); } 1.1765 + bool should_profile() const { return check_flag(ProfileMDOFlag); } 1.1766 + ciMethod* profiled_method() const { return _profiled_method; } // set only for profiled branches 1.1767 + int profiled_bci() const { return _profiled_bci; } // set only for profiled branches 1.1768 + 1.1769 + // manipulation 1.1770 + void swap_operands() { 1.1771 + Value t = _x; _x = _y; _y = t; 1.1772 + _cond = mirror(_cond); 1.1773 + } 1.1774 + 1.1775 + void swap_sux() { 1.1776 + assert(number_of_sux() == 2, "wrong number of successors"); 1.1777 + BlockList* s = sux(); 1.1778 + BlockBegin* t = s->at(0); s->at_put(0, s->at(1)); s->at_put(1, t); 1.1779 + _cond = negate(_cond); 1.1780 + set_flag(UnorderedIsTrueFlag, !check_flag(UnorderedIsTrueFlag)); 1.1781 + } 1.1782 + 1.1783 + void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } 1.1784 + void set_profiled_method(ciMethod* method) { _profiled_method = method; } 1.1785 + void set_profiled_bci(int bci) { _profiled_bci = bci; } 1.1786 + 1.1787 + // generic 1.1788 + virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_x); f(&_y); } 1.1789 +}; 1.1790 + 1.1791 + 1.1792 +LEAF(IfInstanceOf, BlockEnd) 1.1793 + private: 1.1794 + ciKlass* _klass; 1.1795 + Value _obj; 1.1796 + bool _test_is_instance; // jump if instance 1.1797 + int _instanceof_bci; 1.1798 + 1.1799 + public: 1.1800 + IfInstanceOf(ciKlass* klass, Value obj, bool test_is_instance, int instanceof_bci, BlockBegin* tsux, BlockBegin* fsux) 1.1801 + : BlockEnd(illegalType, NULL, false) // temporary set to false 1.1802 + , _klass(klass) 1.1803 + , _obj(obj) 1.1804 + , _test_is_instance(test_is_instance) 1.1805 + , _instanceof_bci(instanceof_bci) 1.1806 + { 1.1807 + ASSERT_VALUES 1.1808 + assert(instanceof_bci >= 0, "illegal bci"); 1.1809 + BlockList* s = new BlockList(2); 1.1810 + s->append(tsux); 1.1811 + s->append(fsux); 1.1812 + set_sux(s); 1.1813 + } 1.1814 + 1.1815 + // accessors 1.1816 + // 1.1817 + // Note 1: If test_is_instance() is true, IfInstanceOf tests if obj *is* an 1.1818 + // instance of klass; otherwise it tests if it is *not* and instance 1.1819 + // of klass. 1.1820 + // 1.1821 + // Note 2: IfInstanceOf instructions are created by combining an InstanceOf 1.1822 + // and an If instruction. The IfInstanceOf bci() corresponds to the 1.1823 + // bci that the If would have had; the (this->) instanceof_bci() is 1.1824 + // the bci of the original InstanceOf instruction. 1.1825 + ciKlass* klass() const { return _klass; } 1.1826 + Value obj() const { return _obj; } 1.1827 + int instanceof_bci() const { return _instanceof_bci; } 1.1828 + bool test_is_instance() const { return _test_is_instance; } 1.1829 + BlockBegin* sux_for(bool is_true) const { return sux_at(is_true ? 0 : 1); } 1.1830 + BlockBegin* tsux() const { return sux_for(true); } 1.1831 + BlockBegin* fsux() const { return sux_for(false); } 1.1832 + 1.1833 + // manipulation 1.1834 + void swap_sux() { 1.1835 + assert(number_of_sux() == 2, "wrong number of successors"); 1.1836 + BlockList* s = sux(); 1.1837 + BlockBegin* t = s->at(0); s->at_put(0, s->at(1)); s->at_put(1, t); 1.1838 + _test_is_instance = !_test_is_instance; 1.1839 + } 1.1840 + 1.1841 + // generic 1.1842 + virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_obj); } 1.1843 +}; 1.1844 + 1.1845 + 1.1846 +BASE(Switch, BlockEnd) 1.1847 + private: 1.1848 + Value _tag; 1.1849 + 1.1850 + public: 1.1851 + // creation 1.1852 + Switch(Value tag, BlockList* sux, ValueStack* state_before, bool is_safepoint) 1.1853 + : BlockEnd(illegalType, state_before, is_safepoint) 1.1854 + , _tag(tag) { 1.1855 + ASSERT_VALUES 1.1856 + set_sux(sux); 1.1857 + } 1.1858 + 1.1859 + // accessors 1.1860 + Value tag() const { return _tag; } 1.1861 + int length() const { return number_of_sux() - 1; } 1.1862 + 1.1863 + // generic 1.1864 + virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_tag); } 1.1865 +}; 1.1866 + 1.1867 + 1.1868 +LEAF(TableSwitch, Switch) 1.1869 + private: 1.1870 + int _lo_key; 1.1871 + 1.1872 + public: 1.1873 + // creation 1.1874 + TableSwitch(Value tag, BlockList* sux, int lo_key, ValueStack* state_before, bool is_safepoint) 1.1875 + : Switch(tag, sux, state_before, is_safepoint) 1.1876 + , _lo_key(lo_key) {} 1.1877 + 1.1878 + // accessors 1.1879 + int lo_key() const { return _lo_key; } 1.1880 + int hi_key() const { return _lo_key + length() - 1; } 1.1881 +}; 1.1882 + 1.1883 + 1.1884 +LEAF(LookupSwitch, Switch) 1.1885 + private: 1.1886 + intArray* _keys; 1.1887 + 1.1888 + public: 1.1889 + // creation 1.1890 + LookupSwitch(Value tag, BlockList* sux, intArray* keys, ValueStack* state_before, bool is_safepoint) 1.1891 + : Switch(tag, sux, state_before, is_safepoint) 1.1892 + , _keys(keys) { 1.1893 + assert(keys != NULL, "keys must exist"); 1.1894 + assert(keys->length() == length(), "sux & keys have incompatible lengths"); 1.1895 + } 1.1896 + 1.1897 + // accessors 1.1898 + int key_at(int i) const { return _keys->at(i); } 1.1899 +}; 1.1900 + 1.1901 + 1.1902 +LEAF(Return, BlockEnd) 1.1903 + private: 1.1904 + Value _result; 1.1905 + 1.1906 + public: 1.1907 + // creation 1.1908 + Return(Value result) : 1.1909 + BlockEnd(result == NULL ? voidType : result->type()->base(), NULL, true), 1.1910 + _result(result) {} 1.1911 + 1.1912 + // accessors 1.1913 + Value result() const { return _result; } 1.1914 + bool has_result() const { return result() != NULL; } 1.1915 + 1.1916 + // generic 1.1917 + virtual void input_values_do(void f(Value*)) { 1.1918 + BlockEnd::input_values_do(f); 1.1919 + if (has_result()) f(&_result); 1.1920 + } 1.1921 +}; 1.1922 + 1.1923 + 1.1924 +LEAF(Throw, BlockEnd) 1.1925 + private: 1.1926 + Value _exception; 1.1927 + 1.1928 + public: 1.1929 + // creation 1.1930 + Throw(Value exception, ValueStack* state_before) : BlockEnd(illegalType, state_before, true), _exception(exception) { 1.1931 + ASSERT_VALUES 1.1932 + } 1.1933 + 1.1934 + // accessors 1.1935 + Value exception() const { return _exception; } 1.1936 + 1.1937 + // generic 1.1938 + virtual bool can_trap() const { return true; } 1.1939 + virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_exception); } 1.1940 + virtual void state_values_do(void f(Value*)); 1.1941 +}; 1.1942 + 1.1943 + 1.1944 +LEAF(Base, BlockEnd) 1.1945 + public: 1.1946 + // creation 1.1947 + Base(BlockBegin* std_entry, BlockBegin* osr_entry) : BlockEnd(illegalType, NULL, false) { 1.1948 + assert(std_entry->is_set(BlockBegin::std_entry_flag), "std entry must be flagged"); 1.1949 + assert(osr_entry == NULL || osr_entry->is_set(BlockBegin::osr_entry_flag), "osr entry must be flagged"); 1.1950 + BlockList* s = new BlockList(2); 1.1951 + if (osr_entry != NULL) s->append(osr_entry); 1.1952 + s->append(std_entry); // must be default sux! 1.1953 + set_sux(s); 1.1954 + } 1.1955 + 1.1956 + // accessors 1.1957 + BlockBegin* std_entry() const { return default_sux(); } 1.1958 + BlockBegin* osr_entry() const { return number_of_sux() < 2 ? NULL : sux_at(0); } 1.1959 +}; 1.1960 + 1.1961 + 1.1962 +LEAF(OsrEntry, Instruction) 1.1963 + public: 1.1964 + // creation 1.1965 +#ifdef _LP64 1.1966 + OsrEntry() : Instruction(longType, false) { pin(); } 1.1967 +#else 1.1968 + OsrEntry() : Instruction(intType, false) { pin(); } 1.1969 +#endif 1.1970 + 1.1971 + // generic 1.1972 + virtual void input_values_do(void f(Value*)) { } 1.1973 +}; 1.1974 + 1.1975 + 1.1976 +// Models the incoming exception at a catch site 1.1977 +LEAF(ExceptionObject, Instruction) 1.1978 + public: 1.1979 + // creation 1.1980 + ExceptionObject() : Instruction(objectType, false) { 1.1981 + pin(); 1.1982 + } 1.1983 + 1.1984 + // generic 1.1985 + virtual void input_values_do(void f(Value*)) { } 1.1986 +}; 1.1987 + 1.1988 + 1.1989 +// Models needed rounding for floating-point values on Intel. 1.1990 +// Currently only used to represent rounding of double-precision 1.1991 +// values stored into local variables, but could be used to model 1.1992 +// intermediate rounding of single-precision values as well. 1.1993 +LEAF(RoundFP, Instruction) 1.1994 + private: 1.1995 + Value _input; // floating-point value to be rounded 1.1996 + 1.1997 + public: 1.1998 + RoundFP(Value input) 1.1999 + : Instruction(input->type()) // Note: should not be used for constants 1.2000 + , _input(input) 1.2001 + { 1.2002 + ASSERT_VALUES 1.2003 + } 1.2004 + 1.2005 + // accessors 1.2006 + Value input() const { return _input; } 1.2007 + 1.2008 + // generic 1.2009 + virtual void input_values_do(void f(Value*)) { f(&_input); } 1.2010 +}; 1.2011 + 1.2012 + 1.2013 +BASE(UnsafeOp, Instruction) 1.2014 + private: 1.2015 + BasicType _basic_type; // ValueType can not express byte-sized integers 1.2016 + 1.2017 + protected: 1.2018 + // creation 1.2019 + UnsafeOp(BasicType basic_type, bool is_put) 1.2020 + : Instruction(is_put ? voidType : as_ValueType(basic_type)) 1.2021 + , _basic_type(basic_type) 1.2022 + { 1.2023 + //Note: Unsafe ops are not not guaranteed to throw NPE. 1.2024 + // Convservatively, Unsafe operations must be pinned though we could be 1.2025 + // looser about this if we wanted to.. 1.2026 + pin(); 1.2027 + } 1.2028 + 1.2029 + public: 1.2030 + // accessors 1.2031 + BasicType basic_type() { return _basic_type; } 1.2032 + 1.2033 + // generic 1.2034 + virtual void input_values_do(void f(Value*)) { } 1.2035 + virtual void other_values_do(void f(Value*)) { } 1.2036 +}; 1.2037 + 1.2038 + 1.2039 +BASE(UnsafeRawOp, UnsafeOp) 1.2040 + private: 1.2041 + Value _base; // Base address (a Java long) 1.2042 + Value _index; // Index if computed by optimizer; initialized to NULL 1.2043 + int _log2_scale; // Scale factor: 0, 1, 2, or 3. 1.2044 + // Indicates log2 of number of bytes (1, 2, 4, or 8) 1.2045 + // to scale index by. 1.2046 + 1.2047 + protected: 1.2048 + UnsafeRawOp(BasicType basic_type, Value addr, bool is_put) 1.2049 + : UnsafeOp(basic_type, is_put) 1.2050 + , _base(addr) 1.2051 + , _index(NULL) 1.2052 + , _log2_scale(0) 1.2053 + { 1.2054 + // Can not use ASSERT_VALUES because index may be NULL 1.2055 + assert(addr != NULL && addr->type()->is_long(), "just checking"); 1.2056 + } 1.2057 + 1.2058 + UnsafeRawOp(BasicType basic_type, Value base, Value index, int log2_scale, bool is_put) 1.2059 + : UnsafeOp(basic_type, is_put) 1.2060 + , _base(base) 1.2061 + , _index(index) 1.2062 + , _log2_scale(log2_scale) 1.2063 + { 1.2064 + } 1.2065 + 1.2066 + public: 1.2067 + // accessors 1.2068 + Value base() { return _base; } 1.2069 + Value index() { return _index; } 1.2070 + bool has_index() { return (_index != NULL); } 1.2071 + int log2_scale() { return _log2_scale; } 1.2072 + 1.2073 + // setters 1.2074 + void set_base (Value base) { _base = base; } 1.2075 + void set_index(Value index) { _index = index; } 1.2076 + void set_log2_scale(int log2_scale) { _log2_scale = log2_scale; } 1.2077 + 1.2078 + // generic 1.2079 + virtual void input_values_do(void f(Value*)) { UnsafeOp::input_values_do(f); 1.2080 + f(&_base); 1.2081 + if (has_index()) f(&_index); } 1.2082 +}; 1.2083 + 1.2084 + 1.2085 +LEAF(UnsafeGetRaw, UnsafeRawOp) 1.2086 + private: 1.2087 + bool _may_be_unaligned; // For OSREntry 1.2088 + 1.2089 + public: 1.2090 + UnsafeGetRaw(BasicType basic_type, Value addr, bool may_be_unaligned) 1.2091 + : UnsafeRawOp(basic_type, addr, false) { 1.2092 + _may_be_unaligned = may_be_unaligned; 1.2093 + } 1.2094 + 1.2095 + UnsafeGetRaw(BasicType basic_type, Value base, Value index, int log2_scale, bool may_be_unaligned) 1.2096 + : UnsafeRawOp(basic_type, base, index, log2_scale, false) { 1.2097 + _may_be_unaligned = may_be_unaligned; 1.2098 + } 1.2099 + 1.2100 + bool may_be_unaligned() { return _may_be_unaligned; } 1.2101 +}; 1.2102 + 1.2103 + 1.2104 +LEAF(UnsafePutRaw, UnsafeRawOp) 1.2105 + private: 1.2106 + Value _value; // Value to be stored 1.2107 + 1.2108 + public: 1.2109 + UnsafePutRaw(BasicType basic_type, Value addr, Value value) 1.2110 + : UnsafeRawOp(basic_type, addr, true) 1.2111 + , _value(value) 1.2112 + { 1.2113 + assert(value != NULL, "just checking"); 1.2114 + ASSERT_VALUES 1.2115 + } 1.2116 + 1.2117 + UnsafePutRaw(BasicType basic_type, Value base, Value index, int log2_scale, Value value) 1.2118 + : UnsafeRawOp(basic_type, base, index, log2_scale, true) 1.2119 + , _value(value) 1.2120 + { 1.2121 + assert(value != NULL, "just checking"); 1.2122 + ASSERT_VALUES 1.2123 + } 1.2124 + 1.2125 + // accessors 1.2126 + Value value() { return _value; } 1.2127 + 1.2128 + // generic 1.2129 + virtual void input_values_do(void f(Value*)) { UnsafeRawOp::input_values_do(f); 1.2130 + f(&_value); } 1.2131 +}; 1.2132 + 1.2133 + 1.2134 +BASE(UnsafeObjectOp, UnsafeOp) 1.2135 + private: 1.2136 + Value _object; // Object to be fetched from or mutated 1.2137 + Value _offset; // Offset within object 1.2138 + bool _is_volatile; // true if volatile - dl/JSR166 1.2139 + public: 1.2140 + UnsafeObjectOp(BasicType basic_type, Value object, Value offset, bool is_put, bool is_volatile) 1.2141 + : UnsafeOp(basic_type, is_put), _object(object), _offset(offset), _is_volatile(is_volatile) 1.2142 + { 1.2143 + } 1.2144 + 1.2145 + // accessors 1.2146 + Value object() { return _object; } 1.2147 + Value offset() { return _offset; } 1.2148 + bool is_volatile() { return _is_volatile; } 1.2149 + // generic 1.2150 + virtual void input_values_do(void f(Value*)) { UnsafeOp::input_values_do(f); 1.2151 + f(&_object); 1.2152 + f(&_offset); } 1.2153 +}; 1.2154 + 1.2155 + 1.2156 +LEAF(UnsafeGetObject, UnsafeObjectOp) 1.2157 + public: 1.2158 + UnsafeGetObject(BasicType basic_type, Value object, Value offset, bool is_volatile) 1.2159 + : UnsafeObjectOp(basic_type, object, offset, false, is_volatile) 1.2160 + { 1.2161 + ASSERT_VALUES 1.2162 + } 1.2163 +}; 1.2164 + 1.2165 + 1.2166 +LEAF(UnsafePutObject, UnsafeObjectOp) 1.2167 + private: 1.2168 + Value _value; // Value to be stored 1.2169 + public: 1.2170 + UnsafePutObject(BasicType basic_type, Value object, Value offset, Value value, bool is_volatile) 1.2171 + : UnsafeObjectOp(basic_type, object, offset, true, is_volatile) 1.2172 + , _value(value) 1.2173 + { 1.2174 + ASSERT_VALUES 1.2175 + } 1.2176 + 1.2177 + // accessors 1.2178 + Value value() { return _value; } 1.2179 + 1.2180 + // generic 1.2181 + virtual void input_values_do(void f(Value*)) { UnsafeObjectOp::input_values_do(f); 1.2182 + f(&_value); } 1.2183 +}; 1.2184 + 1.2185 + 1.2186 +BASE(UnsafePrefetch, UnsafeObjectOp) 1.2187 + public: 1.2188 + UnsafePrefetch(Value object, Value offset) 1.2189 + : UnsafeObjectOp(T_VOID, object, offset, false, false) 1.2190 + { 1.2191 + } 1.2192 +}; 1.2193 + 1.2194 + 1.2195 +LEAF(UnsafePrefetchRead, UnsafePrefetch) 1.2196 + public: 1.2197 + UnsafePrefetchRead(Value object, Value offset) 1.2198 + : UnsafePrefetch(object, offset) 1.2199 + { 1.2200 + ASSERT_VALUES 1.2201 + } 1.2202 +}; 1.2203 + 1.2204 + 1.2205 +LEAF(UnsafePrefetchWrite, UnsafePrefetch) 1.2206 + public: 1.2207 + UnsafePrefetchWrite(Value object, Value offset) 1.2208 + : UnsafePrefetch(object, offset) 1.2209 + { 1.2210 + ASSERT_VALUES 1.2211 + } 1.2212 +}; 1.2213 + 1.2214 + 1.2215 +LEAF(ProfileCall, Instruction) 1.2216 + private: 1.2217 + ciMethod* _method; 1.2218 + int _bci_of_invoke; 1.2219 + Value _recv; 1.2220 + ciKlass* _known_holder; 1.2221 + 1.2222 + public: 1.2223 + ProfileCall(ciMethod* method, int bci, Value recv, ciKlass* known_holder) 1.2224 + : Instruction(voidType) 1.2225 + , _method(method) 1.2226 + , _bci_of_invoke(bci) 1.2227 + , _recv(recv) 1.2228 + , _known_holder(known_holder) 1.2229 + { 1.2230 + // The ProfileCall has side-effects and must occur precisely where located 1.2231 + pin(); 1.2232 + } 1.2233 + 1.2234 + ciMethod* method() { return _method; } 1.2235 + int bci_of_invoke() { return _bci_of_invoke; } 1.2236 + Value recv() { return _recv; } 1.2237 + ciKlass* known_holder() { return _known_holder; } 1.2238 + 1.2239 + virtual void input_values_do(void f(Value*)) { if (_recv != NULL) f(&_recv); } 1.2240 +}; 1.2241 + 1.2242 + 1.2243 +// 1.2244 +// Simple node representing a counter update generally used for updating MDOs 1.2245 +// 1.2246 +LEAF(ProfileCounter, Instruction) 1.2247 + private: 1.2248 + Value _mdo; 1.2249 + int _offset; 1.2250 + int _increment; 1.2251 + 1.2252 + public: 1.2253 + ProfileCounter(Value mdo, int offset, int increment = 1) 1.2254 + : Instruction(voidType) 1.2255 + , _mdo(mdo) 1.2256 + , _offset(offset) 1.2257 + , _increment(increment) 1.2258 + { 1.2259 + // The ProfileCounter has side-effects and must occur precisely where located 1.2260 + pin(); 1.2261 + } 1.2262 + 1.2263 + Value mdo() { return _mdo; } 1.2264 + int offset() { return _offset; } 1.2265 + int increment() { return _increment; } 1.2266 + 1.2267 + virtual void input_values_do(void f(Value*)) { f(&_mdo); } 1.2268 +}; 1.2269 + 1.2270 + 1.2271 +class BlockPair: public CompilationResourceObj { 1.2272 + private: 1.2273 + BlockBegin* _from; 1.2274 + BlockBegin* _to; 1.2275 + public: 1.2276 + BlockPair(BlockBegin* from, BlockBegin* to): _from(from), _to(to) {} 1.2277 + BlockBegin* from() const { return _from; } 1.2278 + BlockBegin* to() const { return _to; } 1.2279 + bool is_same(BlockBegin* from, BlockBegin* to) const { return _from == from && _to == to; } 1.2280 + bool is_same(BlockPair* p) const { return _from == p->from() && _to == p->to(); } 1.2281 + void set_to(BlockBegin* b) { _to = b; } 1.2282 + void set_from(BlockBegin* b) { _from = b; } 1.2283 +}; 1.2284 + 1.2285 + 1.2286 +define_array(BlockPairArray, BlockPair*) 1.2287 +define_stack(BlockPairList, BlockPairArray) 1.2288 + 1.2289 + 1.2290 +inline int BlockBegin::number_of_sux() const { assert(_end == NULL || _end->number_of_sux() == _successors.length(), "mismatch"); return _successors.length(); } 1.2291 +inline BlockBegin* BlockBegin::sux_at(int i) const { assert(_end == NULL || _end->sux_at(i) == _successors.at(i), "mismatch"); return _successors.at(i); } 1.2292 +inline void BlockBegin::add_successor(BlockBegin* sux) { assert(_end == NULL, "Would create mismatch with successors of BlockEnd"); _successors.append(sux); } 1.2293 + 1.2294 +#undef ASSERT_VALUES