diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index f530708aeb..86c36b8313 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -472,6 +472,7 @@ class HBasicBlock : public ArenaObject { M(ArrayLength, Instruction) \ M(ArraySet, Instruction) \ M(BoundsCheck, Instruction) \ + M(ClinitCheck, Instruction) \ M(Compare, BinaryOperation) \ M(Condition, BinaryOperation) \ M(Div, BinaryOperation) \ @@ -488,6 +489,7 @@ class HBasicBlock : public ArenaObject { M(IntConstant, Constant) \ M(InvokeStatic, Invoke) \ M(InvokeVirtual, Invoke) \ + M(LoadClass, Instruction) \ M(LessThan, Condition) \ M(LessThanOrEqual, Condition) \ M(LoadLocal, Instruction) \ @@ -505,6 +507,8 @@ class HBasicBlock : public ArenaObject { M(Phi, Instruction) \ M(Return, Instruction) \ M(ReturnVoid, Instruction) \ + M(StaticFieldGet, Instruction) \ + M(StaticFieldSet, Instruction) \ M(StoreLocal, Instruction) \ M(Sub, BinaryOperation) \ M(SuspendCheck, Instruction) \ @@ -2017,6 +2021,132 @@ class HSuspendCheck : public HTemplateInstruction<0> { DISALLOW_COPY_AND_ASSIGN(HSuspendCheck); }; +// TODO: Make this class handle the case the load is null (dex cache +// is null). +/** + * Instruction to load a Class object. + */ +class HLoadClass : public HExpression<0> { + public: + HLoadClass(uint16_t type_index, + bool is_referrers_class, + bool is_initialized, + uint32_t dex_pc) + : HExpression(Primitive::kPrimNot, SideEffects::None()), + type_index_(type_index), + is_referrers_class_(is_referrers_class), + is_initialized_(is_initialized), + dex_pc_(dex_pc) {} + + bool InstructionDataEquals(HInstruction* other) const OVERRIDE { + return other->AsLoadClass()->type_index_ == type_index_; + } + + size_t ComputeHashCode() const OVERRIDE { return type_index_; } + + uint32_t GetDexPc() const { return dex_pc_; } + uint16_t GetTypeIndex() const { return type_index_; } + + bool NeedsInitialization() const { + return !is_initialized_ && !is_referrers_class_; + } + + bool IsReferrersClass() const { return is_referrers_class_; } + + DECLARE_INSTRUCTION(LoadClass); + + private: + const uint16_t type_index_; + const bool is_referrers_class_; + const bool is_initialized_; + const uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HLoadClass); +}; + +// TODO: Pass this check to HInvokeStatic nodes. +/** + * Performs an initialization check on its Class object input. + */ +class HClinitCheck : public HExpression<1> { + public: + explicit HClinitCheck(HLoadClass* constant, uint32_t dex_pc) + : HExpression(Primitive::kPrimNot, SideEffects::All()), + dex_pc_(dex_pc) { + SetRawInputAt(0, constant); + } + + bool NeedsEnvironment() const OVERRIDE { + // May call runtime to initialize the class. + return true; + } + + uint32_t GetDexPc() const { return dex_pc_; } + + HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); } + + DECLARE_INSTRUCTION(ClinitCheck); + + private: + const uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HClinitCheck); +}; + +class HStaticFieldGet : public HExpression<1> { + public: + HStaticFieldGet(HInstruction* cls, + Primitive::Type field_type, + MemberOffset field_offset) + : HExpression(field_type, SideEffects::DependsOnSomething()), + field_info_(field_offset, field_type) { + SetRawInputAt(0, cls); + } + + bool CanBeMoved() const OVERRIDE { return true; } + bool InstructionDataEquals(HInstruction* other) const OVERRIDE { + size_t other_offset = other->AsStaticFieldGet()->GetFieldOffset().SizeValue(); + return other_offset == GetFieldOffset().SizeValue(); + } + + size_t ComputeHashCode() const OVERRIDE { + return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue(); + } + + MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } + Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } + + DECLARE_INSTRUCTION(StaticFieldGet); + + private: + const FieldInfo field_info_; + + DISALLOW_COPY_AND_ASSIGN(HStaticFieldGet); +}; + +class HStaticFieldSet : public HTemplateInstruction<2> { + public: + HStaticFieldSet(HInstruction* cls, + HInstruction* value, + Primitive::Type field_type, + MemberOffset field_offset) + : HTemplateInstruction(SideEffects::ChangesSomething()), + field_info_(field_offset, field_type) { + SetRawInputAt(0, cls); + SetRawInputAt(1, value); + } + + MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } + Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } + + DECLARE_INSTRUCTION(StaticFieldSet); + + private: + const FieldInfo field_info_; + + DISALLOW_COPY_AND_ASSIGN(HStaticFieldSet); +}; + class MoveOperands : public ArenaObject { public: MoveOperands(Location source, Location destination, HInstruction* instruction) |