Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
| index c7771ee81d3dddf11335b5425dce8aaeb796db14..6209badbee98e4b39de86b4cdc85cc6406a719f9 100644 |
| --- a/runtime/vm/intermediate_language.h |
| +++ b/runtime/vm/intermediate_language.h |
| @@ -142,6 +142,8 @@ class CompileType : public ValueObject { |
| return *this; |
| } |
| + bool is_nullable() const { return is_nullable_; } |
| + |
| // Return type such that concrete value's type in runtime is guaranteed to |
| // be subtype of it. |
| const AbstractType* ToAbstractType(); |
| @@ -176,6 +178,14 @@ class CompileType : public ValueObject { |
| // abstract type. The pair is assumed to be coherent. |
| static CompileType Create(intptr_t cid, const AbstractType& type); |
| + CompileType CopyNonNullable() const { |
| + return CompileType(kNonNullable, cid_, type_); |
| + } |
| + |
| + static CompileType CreateNullable(bool is_nullable, intptr_t cid) { |
| + return CompileType(is_nullable, cid, NULL); |
| + } |
| + |
| // Create a new CompileType representing given abstract type. By default |
| // values as assumed to be nullable. |
| static CompileType FromAbstractType(const AbstractType& type, |
| @@ -236,16 +246,44 @@ class ZoneCompileType : public ZoneAllocated { |
| public: |
| static CompileType* Wrap(const CompileType& type) { |
| ZoneCompileType* zone_type = new ZoneCompileType(type); |
| - return &zone_type->type_; |
| + return zone_type->ToCompileType(); |
| } |
| - private: |
| + CompileType* ToCompileType() { |
| + return &type_; |
| + } |
| + |
| + protected: |
| explicit ZoneCompileType(const CompileType& type) : type_(type) { } |
| CompileType type_; |
| }; |
| +class ConstrainedCompileType : public ZoneCompileType { |
|
srdjan
2013/03/18 18:54:35
Please add comments, documenting the two added cla
Vyacheslav Egorov (Google)
2013/03/18 19:41:18
Done.
|
| + public: |
| + virtual void Update() = 0; |
| + |
| + protected: |
| + explicit ConstrainedCompileType(const CompileType& type) |
| + : ZoneCompileType(type) { } |
| +}; |
| + |
| + |
| +class NotNullConstrainedCompileType : public ConstrainedCompileType { |
| + public: |
| + explicit NotNullConstrainedCompileType(CompileType* source) |
| + : ConstrainedCompileType(source->CopyNonNullable()), source_(source) { } |
| + |
| + virtual void Update() { |
| + type_ = source_->CopyNonNullable(); |
| + } |
| + |
| + private: |
| + CompileType* source_; |
| +}; |
| + |
| + |
| class Value : public ZoneAllocated { |
| public: |
| // A forward iterator that allows removing the current value from the |
| @@ -481,6 +519,7 @@ class EmbeddedArray<T, 0> { |
| M(Constraint) \ |
| M(StringFromCharCode) \ |
| M(InvokeMathCFunction) \ |
| + M(GuardField) \ |
| #define FORWARD_DECLARATION(type) class type##Instr; |
| @@ -730,6 +769,7 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| friend class UnaryMintOpInstr; |
| friend class MathSqrtInstr; |
| friend class CheckClassInstr; |
| + friend class GuardFieldInstr; |
| friend class CheckSmiInstr; |
| friend class CheckArrayBoundInstr; |
| friend class CheckEitherNonSmiInstr; |
| @@ -740,6 +780,7 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| friend class FlowGraphOptimizer; |
| friend class LoadIndexedInstr; |
| friend class StoreIndexedInstr; |
| + friend class StoreInstanceFieldInstr; |
| virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
| @@ -1766,12 +1807,22 @@ class BranchInstr : public ControlInstruction { |
| virtual void PrintTo(BufferFormatter* f) const; |
| + ConstrainedCompileType* constrained_type() const { |
| + return constrained_type_; |
| + } |
| + |
| + void set_constrained_type(ConstrainedCompileType* type) { |
| + constrained_type_ = type; |
| + } |
| + |
| private: |
| virtual void RawSetInputAt(intptr_t i, Value* value); |
| ComparisonInstr* comparison_; |
| const bool is_checked_; |
| + ConstrainedCompileType* constrained_type_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| }; |
| @@ -2756,11 +2807,17 @@ class StoreInstanceFieldInstr : public TemplateDefinition<2> { |
| Value* instance, |
| Value* value, |
| StoreBarrierType emit_store_barrier) |
| - : field_(field), emit_store_barrier_(emit_store_barrier) { |
| + : field_(field), |
| + emit_store_barrier_(emit_store_barrier) { |
| SetInputAt(0, instance); |
| SetInputAt(1, value); |
| } |
| + void SetDeoptId(intptr_t deopt_id) { |
| + ASSERT(CanDeoptimize()); |
| + deopt_id_ = deopt_id; |
| + } |
| + |
| DECLARE_INSTRUCTION(StoreInstanceField) |
| virtual CompileType* ComputeInitialType() const; |
| @@ -2787,6 +2844,43 @@ class StoreInstanceFieldInstr : public TemplateDefinition<2> { |
| }; |
| +class GuardFieldInstr : public TemplateInstruction<1> { |
| + public: |
| + GuardFieldInstr(Value* value, |
| + const Field& field, |
| + intptr_t deopt_id) |
| + : field_(field) { |
| + deopt_id_ = deopt_id; |
| + SetInputAt(0, value); |
| + } |
| + |
| + DECLARE_INSTRUCTION(GuardField) |
| + |
| + virtual intptr_t ArgumentCount() const { return 0; } |
| + |
| + virtual bool CanDeoptimize() const { return true; } |
| + |
| + virtual bool HasSideEffect() const { return false; } |
| + |
| + virtual bool AttributesEqual(Instruction* other) const; |
| + |
| + virtual bool AffectedBySideEffect() const; |
| + |
| + Value* value() const { return inputs_[0]; } |
| + |
| + virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); |
| + |
| + virtual void PrintOperandsTo(BufferFormatter* f) const; |
| + |
| + const Field& field() const { return field_; } |
| + |
| + private: |
| + const Field& field_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr); |
| +}; |
| + |
| + |
| class LoadStaticFieldInstr : public TemplateDefinition<0> { |
| public: |
| explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} |
| @@ -3180,7 +3274,9 @@ class LoadFieldInstr : public TemplateDefinition<1> { |
| type_(type), |
| result_cid_(kDynamicCid), |
| immutable_(immutable), |
| - recognized_kind_(MethodRecognizer::kUnknown) { |
| + recognized_kind_(MethodRecognizer::kUnknown), |
| + field_name_(NULL), |
| + field_(NULL) { |
| ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. |
| SetInputAt(0, value); |
| } |
| @@ -3221,6 +3317,12 @@ class LoadFieldInstr : public TemplateDefinition<1> { |
| static bool IsFixedLengthArrayCid(intptr_t cid); |
| + void set_field_name(const char* name) { field_name_ = name; } |
| + const char* field_name() const { return field_name_; } |
| + |
| + Field* field() const { return field_; } |
| + void set_field(Field* field) { field_ = field; } |
| + |
| private: |
| const intptr_t offset_in_bytes_; |
| const AbstractType& type_; |
| @@ -3229,6 +3331,9 @@ class LoadFieldInstr : public TemplateDefinition<1> { |
| MethodRecognizer::Kind recognized_kind_; |
| + const char* field_name_; |
| + Field* field_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr); |
| }; |
| @@ -4213,9 +4318,15 @@ class CheckClassInstr : public TemplateInstruction<1> { |
| virtual void PrintOperandsTo(BufferFormatter* f) const; |
| + void set_null_check(bool flag) { null_check_ = flag; } |
| + |
| + bool null_check() const { return null_check_; } |
| + |
| private: |
| const ICData& unary_checks_; |
| + bool null_check_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
| }; |