Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
| index 21eb34da6cf7482ab2ef601f809debe2518c0052..ccac3494bce22900ba7031a7b9b91752ced87d56 100644 |
| --- a/runtime/vm/intermediate_language.h |
| +++ b/runtime/vm/intermediate_language.h |
| @@ -79,6 +79,8 @@ class Computation : public ZoneAllocated { |
| // Visiting support. |
| virtual void Accept(FlowGraphVisitor* visitor) = 0; |
| + virtual intptr_t InputCount() const = 0; |
| + |
| private: |
| friend class Instruction; |
| static intptr_t GetNextCid() { |
| @@ -94,7 +96,49 @@ class Computation : public ZoneAllocated { |
| }; |
|
srdjan
2012/05/02 22:07:32
I think templates below are nifty but an overkill
Kevin Millikin (Google)
2012/05/03 08:26:23
The primary advantage is that it eliminates a lot
|
| -class Value : public Computation { |
| +// An embedded container with N elements of type T. Used (with partial |
| +// specialization for N=0) because embedded arrays cannot have size 0. |
| +template<typename T, intptr_t N> |
| +class EmbeddedArray { |
| + public: |
| + EmbeddedArray() : elements_() { } |
| + |
| + intptr_t length() { return N; } |
| + T& operator[](intptr_t i) { |
| + ASSERT(i < length()); |
| + return elements_[i]; |
| + } |
| + |
| + private: |
| + T elements_[N]; |
| +}; |
| + |
| + |
| +template<typename T> |
| +class EmbeddedArray<T, 0> { |
| + public: |
| + int length() { return 0; } |
| + T& operator[](intptr_t i) { |
| + UNREACHABLE(); |
| + static T sentinel = 0; |
| + return sentinel; |
| + } |
| +}; |
| + |
| + |
| +class Value; |
| + |
| +template<intptr_t N> |
| +class TemplateComputation : public Computation { |
| + public: |
| + virtual intptr_t InputCount() const { return N; } |
| + |
| + protected: |
| + EmbeddedArray<Value*, N> inputs_; |
| +}; |
| + |
| + |
| +class Value : public TemplateComputation<0> { |
| public: |
| Value() { } |
| @@ -112,7 +156,7 @@ class Value : public Computation { |
| // Functions defined in all concrete computation classes. |
| #define DECLARE_COMPUTATION(ShortName) \ |
| - virtual void Accept(FlowGraphVisitor* visitor); |
| + virtual void Accept(FlowGraphVisitor* visitor); \ |
| // Functions defined in all concrete value classes. |
| #define DECLARE_VALUE(ShortName) \ |
| @@ -202,6 +246,8 @@ class AssertAssignableComp : public Computation { |
| const AbstractType& dst_type() const { return dst_type_; } |
| const String& dst_name() const { return dst_name_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -214,27 +260,26 @@ class AssertAssignableComp : public Computation { |
| }; |
| -class AssertBooleanComp : public Computation { |
| +class AssertBooleanComp : public TemplateComputation<1> { |
| public: |
| AssertBooleanComp(intptr_t token_index, |
| intptr_t try_index, |
| Value* value) |
| : token_index_(token_index), |
| - try_index_(try_index), |
| - value_(value) { |
| - ASSERT(value_ != NULL); |
| + try_index_(try_index) { |
| + ASSERT(value != NULL); |
| + inputs_[0] = value; |
| } |
| DECLARE_COMPUTATION(AssertBoolean) |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| - Value* value_; |
| DISALLOW_COPY_AND_ASSIGN(AssertBooleanComp); |
| }; |
| @@ -242,7 +287,7 @@ class AssertBooleanComp : public Computation { |
| // Denotes the current context, normally held in a register. This is |
| // a computation, not a value, because it's mutable. |
| -class CurrentContextComp : public Computation { |
| +class CurrentContextComp : public TemplateComputation<0> { |
| public: |
| CurrentContextComp() { } |
| @@ -253,19 +298,18 @@ class CurrentContextComp : public Computation { |
| }; |
| -class StoreContextComp : public Computation { |
| +class StoreContextComp : public TemplateComputation<1> { |
| public: |
| - explicit StoreContextComp(Value* value) : value_(value) { |
| - ASSERT(value_ != NULL); |
| + explicit StoreContextComp(Value* value) { |
| + ASSERT(value != NULL); |
| + inputs_[0] = value; |
| } |
| DECLARE_COMPUTATION(StoreContext); |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| private: |
| - Value* value_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(StoreContextComp); |
| }; |
| @@ -293,6 +337,8 @@ class ClosureCallComp : public Computation { |
| intptr_t ArgumentCount() const { return arguments_->length(); } |
| Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const ClosureCallNode& ast_node_; |
| const intptr_t try_index_; |
| @@ -332,6 +378,8 @@ class InstanceCallComp : public Computation { |
| const Array& argument_names() const { return argument_names_; } |
| intptr_t checked_argument_count() const { return checked_argument_count_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -344,54 +392,52 @@ class InstanceCallComp : public Computation { |
| }; |
| -class StrictCompareComp : public Computation { |
| +class StrictCompareComp : public TemplateComputation<2> { |
| public: |
| StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
| - : kind_(kind), left_(left), right_(right) { |
| + : kind_(kind) { |
| ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
| + inputs_[0] = left; |
| + inputs_[1] = right; |
| } |
| DECLARE_COMPUTATION(StrictCompare) |
| Token::Kind kind() const { return kind_; } |
| - Value* left() const { return left_; } |
| - Value* right() const { return right_; } |
| + Value* left() { return inputs_[0]; } |
| + Value* right() { return inputs_[1]; } |
| private: |
| const Token::Kind kind_; |
| - Value* left_; |
| - Value* right_; |
| DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
| }; |
| -class EqualityCompareComp : public Computation { |
| +class EqualityCompareComp : public TemplateComputation<2> { |
| public: |
| EqualityCompareComp(intptr_t token_index, |
| intptr_t try_index, |
| Value* left, |
| Value* right) |
| : token_index_(token_index), |
| - try_index_(try_index), |
| - left_(left), |
| - right_(right) { |
| - ASSERT(left_ != NULL); |
| - ASSERT(right_ != NULL); |
| + try_index_(try_index) { |
| + ASSERT(left != NULL); |
| + ASSERT(right != NULL); |
| + inputs_[0] = left; |
| + inputs_[1] = right; |
| } |
| DECLARE_COMPUTATION(EqualityCompareComp) |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* left() const { return left_; } |
| - Value* right() const { return right_; } |
| + Value* left() { return inputs_[0]; } |
| + Value* right() { return inputs_[1]; } |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| - Value* left_; |
| - Value* right_; |
| DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
| }; |
| @@ -424,6 +470,8 @@ class StaticCallComp : public Computation { |
| intptr_t ArgumentCount() const { return arguments_->length(); } |
| Value* ArgumentAt(intptr_t index) const { return (*arguments_)[index]; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -435,7 +483,7 @@ class StaticCallComp : public Computation { |
| }; |
| -class LoadLocalComp : public Computation { |
| +class LoadLocalComp : public TemplateComputation<0> { |
| public: |
| LoadLocalComp(const LocalVariable& local, intptr_t context_level) |
| : local_(local), context_level_(context_level) { } |
| @@ -453,29 +501,30 @@ class LoadLocalComp : public Computation { |
| }; |
| -class StoreLocalComp : public Computation { |
| +class StoreLocalComp : public TemplateComputation<1> { |
| public: |
| StoreLocalComp(const LocalVariable& local, |
| Value* value, |
| intptr_t context_level) |
| - : local_(local), value_(value), context_level_(context_level) { } |
| + : local_(local), context_level_(context_level) { |
| + inputs_[0] = value; |
| + } |
| DECLARE_COMPUTATION(StoreLocal) |
| const LocalVariable& local() const { return local_; } |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| intptr_t context_level() const { return context_level_; } |
| private: |
| const LocalVariable& local_; |
| - Value* value_; |
| const intptr_t context_level_; |
| DISALLOW_COPY_AND_ASSIGN(StoreLocalComp); |
| }; |
| -class NativeCallComp : public Computation { |
| +class NativeCallComp : public TemplateComputation<0> { |
| public: |
| NativeCallComp(NativeBodyNode* node, intptr_t try_index) |
| : ast_node_(*node), try_index_(try_index) {} |
| @@ -507,35 +556,37 @@ class NativeCallComp : public Computation { |
| }; |
| -class LoadInstanceFieldComp : public Computation { |
| +class LoadInstanceFieldComp : public TemplateComputation<1> { |
| public: |
| LoadInstanceFieldComp(LoadInstanceFieldNode* ast_node, Value* instance) |
| - : ast_node_(*ast_node), instance_(instance) { |
| - ASSERT(instance_ != NULL); |
| + : ast_node_(*ast_node) { |
| + ASSERT(instance != NULL); |
| + inputs_[0] = instance; |
| } |
| DECLARE_COMPUTATION(LoadInstanceField) |
| const Field& field() const { return ast_node_.field(); } |
| - Value* instance() const { return instance_; } |
| + Value* instance() { return inputs_[0]; } |
| private: |
| const LoadInstanceFieldNode& ast_node_; |
| - Value* instance_; |
| DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); |
| }; |
| -class StoreInstanceFieldComp : public Computation { |
| +class StoreInstanceFieldComp : public TemplateComputation<2> { |
| public: |
| StoreInstanceFieldComp(StoreInstanceFieldNode* ast_node, |
| Value* instance, |
| Value* value) |
| - : ast_node_(*ast_node), instance_(instance), value_(value) { |
| - ASSERT(instance_ != NULL); |
| - ASSERT(value_ != NULL); |
| + : ast_node_(*ast_node) { |
| + ASSERT(instance != NULL); |
| + ASSERT(value != NULL); |
| + inputs_[0] = instance; |
| + inputs_[1] = value; |
| } |
| DECLARE_COMPUTATION(StoreInstanceField) |
| @@ -543,19 +594,17 @@ class StoreInstanceFieldComp : public Computation { |
| intptr_t token_index() const { return ast_node_.token_index(); } |
| const Field& field() const { return ast_node_.field(); } |
| - Value* instance() const { return instance_; } |
| - Value* value() const { return value_; } |
| + Value* instance() { return inputs_[0]; } |
| + Value* value() { return inputs_[1]; } |
| private: |
| const StoreInstanceFieldNode& ast_node_; |
| - Value* instance_; |
| - Value* value_; |
| DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldComp); |
| }; |
| -class LoadStaticFieldComp : public Computation { |
| +class LoadStaticFieldComp : public TemplateComputation<0> { |
| public: |
| explicit LoadStaticFieldComp(const Field& field) : field_(field) {} |
| @@ -570,23 +619,22 @@ class LoadStaticFieldComp : public Computation { |
| }; |
| -class StoreStaticFieldComp : public Computation { |
| +class StoreStaticFieldComp : public TemplateComputation<1> { |
| public: |
| StoreStaticFieldComp(const Field& field, Value* value) |
| - : field_(field), |
| - value_(value) { |
| + : field_(field) { |
| ASSERT(field.IsZoneHandle()); |
| ASSERT(value != NULL); |
| + inputs_[0] = value; |
| } |
| DECLARE_COMPUTATION(StoreStaticField); |
| const Field& field() const { return field_; } |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| private: |
| const Field& field_; |
| - Value* const value_; |
| DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldComp); |
| }; |
| @@ -594,7 +642,7 @@ class StoreStaticFieldComp : public Computation { |
| // Not simply an InstanceCall because it has somewhat more complicated |
| // semantics: the value operand is preserved before the call. |
| -class StoreIndexedComp : public Computation { |
| +class StoreIndexedComp : public TemplateComputation<3> { |
| public: |
| StoreIndexedComp(intptr_t token_index, |
| intptr_t try_index, |
| @@ -602,25 +650,23 @@ class StoreIndexedComp : public Computation { |
| Value* index, |
| Value* value) |
| : token_index_(token_index), |
| - try_index_(try_index), |
| - array_(array), |
| - index_(index), |
| - value_(value) { } |
| + try_index_(try_index) { |
| + inputs_[0] = array; |
| + inputs_[1] = index; |
| + inputs_[2] = value; |
| + } |
| DECLARE_COMPUTATION(StoreIndexed) |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* array() const { return array_; } |
| - Value* index() const { return index_; } |
| - Value* value() const { return value_; } |
| + Value* array() { return inputs_[0]; } |
| + Value* index() { return inputs_[1]; } |
| + Value* value() { return inputs_[2]; } |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| - Value* array_; |
| - Value* index_; |
| - Value* value_; |
| DISALLOW_COPY_AND_ASSIGN(StoreIndexedComp); |
| }; |
| @@ -628,7 +674,7 @@ class StoreIndexedComp : public Computation { |
| // Not simply an InstanceCall because it has somewhat more complicated |
| // semantics: the value operand is preserved before the call. |
| -class InstanceSetterComp : public Computation { |
| +class InstanceSetterComp : public TemplateComputation<2> { |
| public: |
| InstanceSetterComp(intptr_t token_index, |
| intptr_t try_index, |
| @@ -637,24 +683,23 @@ class InstanceSetterComp : public Computation { |
| Value* value) |
| : token_index_(token_index), |
| try_index_(try_index), |
| - field_name_(field_name), |
| - receiver_(receiver), |
| - value_(value) { } |
| + field_name_(field_name) { |
| + inputs_[0] = receiver; |
| + inputs_[1] = value; |
| + } |
| DECLARE_COMPUTATION(InstanceSetter) |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| const String& field_name() const { return field_name_; } |
| - Value* receiver() const { return receiver_; } |
| - Value* value() const { return value_; } |
| + Value* receiver() { return inputs_[0]; } |
| + Value* value() { return inputs_[1]; } |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| const String& field_name_; |
| - Value* const receiver_; |
| - Value* const value_; |
| DISALLOW_COPY_AND_ASSIGN(InstanceSetterComp); |
| }; |
| @@ -662,7 +707,7 @@ class InstanceSetterComp : public Computation { |
| // Not simply a StaticCall because it has somewhat more complicated |
| // semantics: the value operand is preserved before the call. |
| -class StaticSetterComp : public Computation { |
| +class StaticSetterComp : public TemplateComputation<1> { |
| public: |
| StaticSetterComp(intptr_t token_index, |
| intptr_t try_index, |
| @@ -670,38 +715,38 @@ class StaticSetterComp : public Computation { |
| Value* value) |
| : token_index_(token_index), |
| try_index_(try_index), |
| - setter_function_(setter_function), |
| - value_(value) { } |
| + setter_function_(setter_function) { |
| + inputs_[0] = value; |
| + } |
| DECLARE_COMPUTATION(StaticSetter) |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| const Function& setter_function() const { return setter_function_; } |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| const Function& setter_function_; |
| - Value* const value_; |
| DISALLOW_COPY_AND_ASSIGN(StaticSetterComp); |
| }; |
| // Note overrideable, built-in: value? false : true. |
| -class BooleanNegateComp : public Computation { |
| +class BooleanNegateComp : public TemplateComputation<1> { |
| public: |
| - explicit BooleanNegateComp(Value* value) : value_(value) {} |
| + explicit BooleanNegateComp(Value* value) { |
| + inputs_[0] = value; |
| + } |
| DECLARE_COMPUTATION(BooleanNegate) |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| private: |
| - Value* value_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(BooleanNegateComp); |
| }; |
| @@ -733,6 +778,8 @@ class InstanceOfComp : public Computation { |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| @@ -762,6 +809,8 @@ class AllocateObjectComp : public Computation { |
| intptr_t try_index() const { return try_index_; } |
| const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const ConstructorCallNode& ast_node_; |
| const intptr_t try_index_; |
| @@ -787,6 +836,8 @@ class AllocateObjectWithBoundsCheckComp : public Computation { |
| intptr_t try_index() const { return try_index_; } |
| const ZoneGrowableArray<Value*>& arguments() const { return *arguments_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const ConstructorCallNode& ast_node_; |
| const intptr_t try_index_; |
| @@ -818,6 +869,8 @@ class CreateArrayComp : public Computation { |
| intptr_t ElementCount() const { return elements_->length(); } |
| Value* ElementAt(intptr_t i) const { return (*elements_)[i]; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const ArrayNode& ast_node_; |
| const intptr_t try_index_; |
| @@ -844,6 +897,8 @@ class CreateClosureComp : public Computation { |
| const Function& function() const { return ast_node_.function(); } |
| Value* type_arguments() const { return type_arguments_; } |
| + virtual intptr_t InputCount() const; |
| + |
| private: |
| const ClosureNode& ast_node_; |
| const intptr_t try_index_; |
| @@ -853,40 +908,40 @@ class CreateClosureComp : public Computation { |
| }; |
| -class NativeLoadFieldComp : public Computation { |
| +class NativeLoadFieldComp : public TemplateComputation<1> { |
| public: |
| NativeLoadFieldComp(Value* value, intptr_t offset_in_bytes) |
| - : value_(value), offset_in_bytes_(offset_in_bytes) { |
| + : offset_in_bytes_(offset_in_bytes) { |
| ASSERT(value != NULL); |
| + inputs_[0] = value; |
| } |
| DECLARE_COMPUTATION(NativeLoadField) |
| - Value* value() const { return value_; } |
| + Value* value() { return inputs_[0]; } |
| intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
| private: |
| - Value* value_; |
| intptr_t offset_in_bytes_; |
| DISALLOW_COPY_AND_ASSIGN(NativeLoadFieldComp); |
| }; |
| -class ExtractFactoryTypeArgumentsComp : public Computation { |
| +class ExtractFactoryTypeArgumentsComp : public TemplateComputation<1> { |
| public: |
| ExtractFactoryTypeArgumentsComp(ConstructorCallNode* ast_node, |
| intptr_t try_index, |
| Value* instantiator) |
| : ast_node_(*ast_node), |
| - try_index_(try_index), |
| - instantiator_(instantiator) { |
| - ASSERT(instantiator_ != NULL); |
| + try_index_(try_index) { |
| + ASSERT(instantiator != NULL); |
| + inputs_[0] = instantiator; |
| } |
| DECLARE_COMPUTATION(ExtractFactoryTypeArguments) |
| - Value* instantiator() const { return instantiator_; } |
| + Value* instantiator() { return inputs_[0]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return ast_node_.type_arguments(); |
| } |
| @@ -897,23 +952,23 @@ class ExtractFactoryTypeArgumentsComp : public Computation { |
| private: |
| const ConstructorCallNode& ast_node_; |
| const intptr_t try_index_; |
| - Value* instantiator_; |
| DISALLOW_COPY_AND_ASSIGN(ExtractFactoryTypeArgumentsComp); |
| }; |
| -class ExtractConstructorTypeArgumentsComp : public Computation { |
| +class ExtractConstructorTypeArgumentsComp : public TemplateComputation<1> { |
| public: |
| ExtractConstructorTypeArgumentsComp(ConstructorCallNode* ast_node, |
| Value* instantiator) |
| - : ast_node_(*ast_node), instantiator_(instantiator) { |
| - ASSERT(instantiator_ != NULL); |
| + : ast_node_(*ast_node) { |
| + ASSERT(instantiator != NULL); |
| + inputs_[0] = instantiator; |
| } |
| DECLARE_COMPUTATION(ExtractConstructorTypeArguments) |
| - Value* instantiator() const { return instantiator_; } |
| + Value* instantiator() { return inputs_[0]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return ast_node_.type_arguments(); |
| } |
| @@ -922,27 +977,26 @@ class ExtractConstructorTypeArgumentsComp : public Computation { |
| private: |
| const ConstructorCallNode& ast_node_; |
| - Value* instantiator_; |
| DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsComp); |
| }; |
| -class ExtractConstructorInstantiatorComp : public Computation { |
| +class ExtractConstructorInstantiatorComp : public TemplateComputation<2> { |
| public: |
| ExtractConstructorInstantiatorComp(ConstructorCallNode* ast_node, |
| Value* instantiator, |
| Value* discard_value) |
| - : ast_node_(*ast_node), |
| - instantiator_(instantiator), |
| - discard_value_(discard_value) { |
| - ASSERT(instantiator_ != NULL); |
| + : ast_node_(*ast_node) { |
| + ASSERT(instantiator != NULL); |
| + inputs_[0] = instantiator; |
| + inputs_[1] = discard_value; |
| } |
| DECLARE_COMPUTATION(ExtractConstructorInstantiator) |
| - Value* instantiator() const { return instantiator_; } |
| - Value* discard_value() const { return discard_value_; } |
| + Value* instantiator() { return inputs_[0]; } |
| + Value* discard_value() { return inputs_[1]; } |
| const AbstractTypeArguments& type_arguments() const { |
| return ast_node_.type_arguments(); |
| } |
| @@ -951,14 +1005,12 @@ class ExtractConstructorInstantiatorComp : public Computation { |
| private: |
| const ConstructorCallNode& ast_node_; |
| - Value* instantiator_; |
| - Value* discard_value_; |
| DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorComp); |
| }; |
| -class AllocateContextComp : public Computation { |
| +class AllocateContextComp : public TemplateComputation<0> { |
| public: |
| AllocateContextComp(intptr_t token_index, |
| intptr_t try_index, |
| @@ -982,51 +1034,48 @@ class AllocateContextComp : public Computation { |
| }; |
| -class ChainContextComp : public Computation { |
| +class ChainContextComp : public TemplateComputation<1> { |
| public: |
| - explicit ChainContextComp(Value* context_value) |
| - : context_value_(context_value) { |
| - ASSERT(context_value_ != NULL); |
| + explicit ChainContextComp(Value* context_value) { |
| + ASSERT(context_value != NULL); |
| + inputs_[0] = context_value; |
| } |
| DECLARE_COMPUTATION(ChainContext) |
| - Value* context_value() const { return context_value_; } |
| + Value* context_value() { return inputs_[0]; } |
| private: |
| - Value* context_value_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(ChainContextComp); |
| }; |
| -class CloneContextComp : public Computation { |
| +class CloneContextComp : public TemplateComputation<1> { |
| public: |
| CloneContextComp(intptr_t token_index, |
| intptr_t try_index, |
| Value* context_value) |
| : token_index_(token_index), |
| - try_index_(try_index), |
| - context_value_(context_value) { |
| - ASSERT(context_value_ != NULL); |
| + try_index_(try_index) { |
| + ASSERT(context_value != NULL); |
| + inputs_[0] = context_value; |
| } |
| intptr_t token_index() const { return token_index_; } |
| intptr_t try_index() const { return try_index_; } |
| - Value* context_value() const { return context_value_; } |
| + Value* context_value() { return inputs_[0]; } |
| DECLARE_COMPUTATION(CloneContext) |
| private: |
| const intptr_t token_index_; |
| const intptr_t try_index_; |
| - Value* context_value_; |
| DISALLOW_COPY_AND_ASSIGN(CloneContextComp); |
| }; |
| -class CatchEntryComp : public Computation { |
| +class CatchEntryComp : public TemplateComputation<0> { |
| public: |
| CatchEntryComp(const LocalVariable& exception_var, |
| const LocalVariable& stacktrace_var) |
| @@ -1087,6 +1136,7 @@ FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| virtual Instruction* Accept(FlowGraphVisitor* visitor); \ |
| virtual bool Is##type() const { return true; } \ |
| virtual type##Instr* As##type() { return this; } \ |
| + virtual intptr_t InputCount() const; \ |
| class Instruction : public ZoneAllocated { |
| @@ -1101,6 +1151,12 @@ class Instruction : public ZoneAllocated { |
| BlockEntryInstr* AsBlockEntry() { |
| return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; |
| } |
| + virtual bool IsDefinition() const { return false; } |
| + Definition* AsDefinition() { |
| + return IsDefinition() ? reinterpret_cast<Definition*>(this) : NULL; |
| + } |
| + |
| + virtual intptr_t InputCount() const = 0; |
| // Visiting support. |
| virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; |
| @@ -1300,12 +1356,15 @@ class DoInstr : public Instruction { |
| class Definition : public Instruction { |
| public: |
| - explicit Definition(intptr_t temp_index) : temp_index_(temp_index) { } |
| + Definition() : temp_index_(-1) { } |
| + |
| + virtual bool IsDefinition() const { return true; } |
| intptr_t temp_index() const { return temp_index_; } |
| + void set_temp_index(intptr_t index) { temp_index_ = index; } |
| private: |
| - const intptr_t temp_index_; |
| + intptr_t temp_index_; |
| DISALLOW_COPY_AND_ASSIGN(Definition); |
| }; |
| @@ -1313,8 +1372,8 @@ class Definition : public Instruction { |
| class BindInstr : public Definition { |
| public: |
| - BindInstr(intptr_t temp_index, Computation* computation) |
| - : Definition(temp_index), computation_(computation), successor_(NULL) { } |
| + explicit BindInstr(Computation* computation) |
| + : Definition(), computation_(computation), successor_(NULL) { } |
| DECLARE_INSTRUCTION(Bind) |
| @@ -1345,8 +1404,8 @@ class BindInstr : public Definition { |
| // (named 'source') without counting as the use of the source. |
| class PickTempInstr : public Definition { |
| public: |
| - PickTempInstr(intptr_t temp_index, intptr_t source) |
| - : Definition(temp_index), source_(source), successor_(NULL) { } |
| + explicit PickTempInstr(intptr_t source) |
| + : Definition(), source_(source), successor_(NULL) { } |
| DECLARE_INSTRUCTION(PickTemp) |