Chromium Code Reviews| Index: src/ast/ast.h |
| diff --git a/src/ast/ast.h b/src/ast/ast.h |
| index 7ea466ccb569444b0afd4c4e52938adc0816b2f5..b83dd5e1b1bd306136e5be268dd623a54b55f328 100644 |
| --- a/src/ast/ast.h |
| +++ b/src/ast/ast.h |
| @@ -192,7 +192,7 @@ class AstNode: public ZoneObject { |
| void* operator new(size_t size, Zone* zone) { return zone->New(size); } |
| - NodeType node_type() const { return node_type_; } |
| + NodeType node_type() const { return NodeTypeField::decode(bit_field_); } |
| int position() const { return position_; } |
| #ifdef DEBUG |
| @@ -211,19 +211,20 @@ class AstNode: public ZoneObject { |
| IterationStatement* AsIterationStatement(); |
| MaterializedLiteral* AsMaterializedLiteral(); |
| - protected: |
| - AstNode(int position, NodeType type) |
| - : position_(position), node_type_(type) {} |
| - |
| private: |
| // Hidden to prevent accidental usage. It would have to load the |
| // current zone from the TLS. |
| void* operator new(size_t size); |
| int position_; |
| - NodeType node_type_; |
| - // Ends with NodeType which is uint8_t sized. Deriving classes in turn begin |
| - // sub-int32_t-sized fields for optimum packing efficiency. |
| + class NodeTypeField : public BitField<NodeType, 0, 7> {}; |
| + |
| + protected: |
| + uint32_t bit_field_; |
| + static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext; |
| + |
| + AstNode(int position, NodeType type) |
| + : position_(position), bit_field_(NodeTypeField::encode(type)) {} |
| }; |
| @@ -234,6 +235,8 @@ class Statement : public AstNode { |
| protected: |
| Statement(int position, NodeType type) : AstNode(position, type) {} |
| + |
| + static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; |
| }; |
| @@ -349,11 +352,17 @@ class Expression : public AstNode { |
| BailoutId id() const { return BailoutId(local_id(0)); } |
| TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); } |
| + private: |
| + int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| + |
| + int base_id_; |
| + class ToBooleanTypesField : public BitField16<uint16_t, 0, 9> {}; |
| + |
| protected: |
| Expression(int pos, NodeType type) |
| - : AstNode(pos, type), |
| - bit_field_(0), |
| - base_id_(BailoutId::None().ToInt()) {} |
| + : AstNode(pos, type), base_id_(BailoutId::None().ToInt()) { |
| + bit_field_ = ToBooleanTypesField::update(bit_field_, 0); |
|
Toon Verwaest
2016/08/26 14:55:02
Huh? why is this 0-9 rather tahn kNextBitFieldInde
|
| + } |
| static int parent_num_ids() { return 0; } |
| void set_to_boolean_types(uint16_t types) { |
| @@ -364,12 +373,7 @@ class Expression : public AstNode { |
| return base_id_; |
| } |
| - private: |
| - int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - |
| - uint16_t bit_field_; |
| - int base_id_; |
| - class ToBooleanTypesField : public BitField16<uint16_t, 0, 9> {}; |
| + static const uint8_t kNextBitFieldIndex = ToBooleanTypesField::kNext; |
| }; |
| @@ -389,7 +393,7 @@ class BreakableStatement : public Statement { |
| // Testers. |
| bool is_target_for_anonymous() const { |
| - return breakable_type_ == TARGET_FOR_ANONYMOUS; |
| + return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS; |
| } |
| void set_base_id(int id) { base_id_ = id; } |
| @@ -397,14 +401,28 @@ class BreakableStatement : public Statement { |
| BailoutId EntryId() const { return BailoutId(local_id(0)); } |
| BailoutId ExitId() const { return BailoutId(local_id(1)); } |
| + private: |
| + int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| + |
| + BreakableType breakableType() const { |
| + return BreakableTypeField::decode(bit_field_); |
| + } |
| + |
| + int base_id_; |
| + Label break_target_; |
| + ZoneList<const AstRawString*>* labels_; |
| + |
| + class BreakableTypeField |
| + : public BitField<BreakableType, Statement::kNextBitFieldIndex, 1> {}; |
| + |
| protected: |
| BreakableStatement(ZoneList<const AstRawString*>* labels, |
| BreakableType breakable_type, int position, NodeType type) |
| : Statement(position, type), |
| - breakable_type_(breakable_type), |
| base_id_(BailoutId::None().ToInt()), |
| labels_(labels) { |
| DCHECK(labels == NULL || labels->length() > 0); |
| + bit_field_ |= BreakableTypeField::encode(breakable_type); |
| } |
| static int parent_num_ids() { return 0; } |
| @@ -413,13 +431,7 @@ class BreakableStatement : public Statement { |
| return base_id_; |
| } |
| - private: |
| - int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - |
| - BreakableType breakable_type_; |
| - int base_id_; |
| - Label break_target_; |
| - ZoneList<const AstRawString*>* labels_; |
| + static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext; |
| }; |
| @@ -446,14 +458,21 @@ class Block final : public BreakableStatement { |
| bool ignore_completion_value, int pos) |
| : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY, pos, kBlock), |
| statements_(capacity, zone), |
| - ignore_completion_value_(ignore_completion_value), |
| - scope_(NULL) {} |
| + scope_(NULL) { |
| + bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value); |
| + } |
| static int parent_num_ids() { return BreakableStatement::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| ZoneList<Statement*> statements_; |
| bool ignore_completion_value_; |
| Scope* scope_; |
| + |
| + class IgnoreCompletionField |
| + : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {}; |
| + |
| + protected: |
| + static const uint8_t kNextBitFieldIndex = IgnoreCompletionField::kNext; |
| }; |
| @@ -469,6 +488,9 @@ class DoExpression final : public Expression { |
| } |
| bool IsAnonymousFunctionDefinition() const; |
| + protected: |
| + static const uint8_t kNextBitFieldIndex = Expression::kNextBitFieldIndex; |
| + |
| private: |
| friend class AstNodeFactory; |
| @@ -498,6 +520,8 @@ class Declaration : public AstNode { |
| Declaration(VariableProxy* proxy, Scope* scope, int pos, NodeType type) |
| : AstNode(pos, type), proxy_(proxy), scope_(scope) {} |
| + static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; |
| + |
| private: |
| VariableProxy* proxy_; |
| @@ -561,6 +585,9 @@ class IterationStatement : public BreakableStatement { |
| static int parent_num_ids() { return BreakableStatement::num_ids(); } |
| void Initialize(Statement* body) { body_ = body; } |
| + static const uint8_t kNextBitFieldIndex = |
| + BreakableStatement::kNextBitFieldIndex; |
| + |
| private: |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| @@ -715,8 +742,10 @@ class ForInStatement final : public ForEachStatement { |
| } |
| enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; |
| - ForInType for_in_type() const { return for_in_type_; } |
| - void set_for_in_type(ForInType type) { for_in_type_ = type; } |
| + ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); } |
| + void set_for_in_type(ForInType type) { |
| + bit_field_ = ForInTypeField::update(bit_field_, type); |
| + } |
| static int num_ids() { return parent_num_ids() + 6; } |
| BailoutId BodyId() const { return BailoutId(local_id(0)); } |
| @@ -734,16 +763,23 @@ class ForInStatement final : public ForEachStatement { |
| ForInStatement(ZoneList<const AstRawString*>* labels, int pos) |
| : ForEachStatement(labels, pos, kForInStatement), |
| each_(nullptr), |
| - subject_(nullptr), |
| - for_in_type_(SLOW_FOR_IN) {} |
| + subject_(nullptr) { |
| + bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN); |
| + } |
| + |
| static int parent_num_ids() { return ForEachStatement::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| Expression* each_; |
| Expression* subject_; |
| - ForInType for_in_type_; |
| FeedbackVectorSlot each_slot_; |
| FeedbackVectorSlot for_in_feedback_slot_; |
| + |
| + class ForInTypeField |
| + : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {}; |
| + |
| + protected: |
| + static const uint8_t kNextBitFieldIndex = ForInTypeField::kNext; |
| }; |
| @@ -1241,17 +1277,27 @@ class MaterializedLiteral : public Expression { |
| return depth_; |
| } |
| + private: |
| + int depth_ : 31; |
| + int literal_index_; |
| + |
| + friend class AstLiteralReindexer; |
| + |
| + class IsSimpleField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| + |
| protected: |
| MaterializedLiteral(int literal_index, int pos, NodeType type) |
| - : Expression(pos, type), |
| - is_simple_(false), |
| - depth_(0), |
| - literal_index_(literal_index) {} |
| + : Expression(pos, type), depth_(0), literal_index_(literal_index) { |
| + bit_field_ |= IsSimpleField::encode(false); |
| + } |
| // A materialized literal is simple if the values consist of only |
| // constants and simple object and array literals. |
| - bool is_simple() const { return is_simple_; } |
| - void set_is_simple(bool is_simple) { is_simple_ = is_simple; } |
| + bool is_simple() const { return IsSimpleField::decode(bit_field_); } |
| + void set_is_simple(bool is_simple) { |
| + bit_field_ = IsSimpleField::update(bit_field_, is_simple); |
| + } |
| friend class CompileTimeValue; |
| void set_depth(int depth) { |
| @@ -1271,12 +1317,7 @@ class MaterializedLiteral : public Expression { |
| // in the object literal boilerplate. |
| Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate); |
| - private: |
| - bool is_simple_ : 1; |
| - int depth_ : 31; |
| - int literal_index_; |
| - |
| - friend class AstLiteralReindexer; |
| + static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext; |
| }; |
| @@ -1357,9 +1398,11 @@ class ObjectLiteral final : public MaterializedLiteral { |
| } |
| int properties_count() const { return boilerplate_properties_; } |
| ZoneList<Property*>* properties() const { return properties_; } |
| - bool fast_elements() const { return fast_elements_; } |
| - bool may_store_doubles() const { return may_store_doubles_; } |
| - bool has_elements() const { return has_elements_; } |
| + bool fast_elements() const { return FastElementsField::decode(bit_field_); } |
| + bool may_store_doubles() const { |
| + return MayStoreDoublesField::decode(bit_field_); |
| + } |
| + bool has_elements() const { return HasElementsField::decode(bit_field_); } |
| bool has_shallow_properties() const { |
| return depth() == 1 && !has_elements() && !may_store_doubles(); |
| } |
| @@ -1429,21 +1472,29 @@ class ObjectLiteral final : public MaterializedLiteral { |
| uint32_t boilerplate_properties, int pos) |
| : MaterializedLiteral(literal_index, pos, kObjectLiteral), |
| boilerplate_properties_(boilerplate_properties), |
| - fast_elements_(false), |
| - has_elements_(false), |
| - may_store_doubles_(false), |
| - properties_(properties) {} |
| + properties_(properties) { |
| + bit_field_ |= FastElementsField::encode(false) | |
| + HasElementsField::encode(false) | |
| + MayStoreDoublesField::encode(false); |
| + } |
| static int parent_num_ids() { return MaterializedLiteral::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - uint32_t boilerplate_properties_ : 29; |
| - bool fast_elements_ : 1; |
| - bool has_elements_ : 1; |
| - bool may_store_doubles_ : 1; |
| + uint32_t boilerplate_properties_; |
| FeedbackVectorSlot slot_; |
| Handle<FixedArray> constant_properties_; |
| ZoneList<Property*>* properties_; |
| + |
| + class FastElementsField |
| + : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {}; |
| + class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> { |
| + }; |
| + class MayStoreDoublesField |
| + : public BitField<bool, HasElementsField::kNext, 1> {}; |
| + |
| + protected: |
| + static const uint8_t kNextBitFieldIndex = MayStoreDoublesField::kNext; |
| }; |
| @@ -1635,12 +1686,12 @@ class VariableProxy final : public Expression { |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - class IsThisField : public BitField8<bool, 0, 1> {}; |
| - class IsAssignedField : public BitField8<bool, 1, 1> {}; |
| - class IsResolvedField : public BitField8<bool, 2, 1> {}; |
| - class IsNewTargetField : public BitField8<bool, 3, 1> {}; |
| + class IsThisField : public BitField<bool, Expression::kNextBitFieldIndex, 1> { |
| + }; |
| + class IsAssignedField : public BitField<bool, IsThisField::kNext, 1> {}; |
| + class IsResolvedField : public BitField<bool, IsAssignedField::kNext, 1> {}; |
| + class IsNewTargetField : public BitField<bool, IsResolvedField::kNext, 1> {}; |
| - uint8_t bit_field_; |
| // Position is stored in the AstNode superclass, but VariableProxy needs to |
| // know its end position too (for error messages). It cannot be inferred from |
| // the variable name length because it can contain escapes. |
| @@ -1737,22 +1788,24 @@ class Property final : public Expression { |
| friend class AstNodeFactory; |
| Property(Expression* obj, Expression* key, int pos) |
| - : Expression(pos, kProperty), |
| - bit_field_(IsForCallField::encode(false) | |
| - IsStringAccessField::encode(false) | |
| - InlineCacheStateField::encode(UNINITIALIZED)), |
| - obj_(obj), |
| - key_(key) {} |
| + : Expression(pos, kProperty), obj_(obj), key_(key) { |
| + bit_field_ |= IsForCallField::encode(false) | |
| + IsStringAccessField::encode(false) | |
| + InlineCacheStateField::encode(UNINITIALIZED); |
| + } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - class IsForCallField : public BitField8<bool, 0, 1> {}; |
| - class IsStringAccessField : public BitField8<bool, 1, 1> {}; |
| - class KeyTypeField : public BitField8<IcCheckType, 2, 1> {}; |
| - class InlineCacheStateField : public BitField8<InlineCacheState, 3, 4> {}; |
| + class IsForCallField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| + class IsStringAccessField : public BitField<bool, IsForCallField::kNext, 1> { |
| + }; |
| + class KeyTypeField |
| + : public BitField<IcCheckType, IsStringAccessField::kNext, 1> {}; |
| + class InlineCacheStateField |
| + : public BitField<InlineCacheState, KeyTypeField::kNext, 4> {}; |
| - uint8_t bit_field_; |
| FeedbackVectorSlot property_feedback_slot_; |
| Expression* obj_; |
| Expression* key_; |
| @@ -1867,11 +1920,12 @@ class Call final : public Expression { |
| Call(Expression* expression, ZoneList<Expression*>* arguments, int pos, |
| PossiblyEval possibly_eval) |
| : Expression(pos, kCall), |
| - bit_field_( |
| - IsUninitializedField::encode(false) | |
| - IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL)), |
| expression_(expression), |
| arguments_(arguments) { |
| + bit_field_ |= |
| + IsUninitializedField::encode(false) | |
| + IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL); |
| + |
| if (expression->IsProperty()) { |
| expression->AsProperty()->mark_for_call(); |
| } |
| @@ -1880,11 +1934,11 @@ class Call final : public Expression { |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - class IsUninitializedField : public BitField8<bool, 0, 1> {}; |
| - class IsTailField : public BitField8<bool, 1, 1> {}; |
| - class IsPossiblyEvalField : public BitField8<bool, 2, 1> {}; |
| + class IsUninitializedField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| + class IsTailField : public BitField<bool, IsUninitializedField::kNext, 1> {}; |
| + class IsPossiblyEvalField : public BitField<bool, IsTailField::kNext, 1> {}; |
| - uint8_t bit_field_; |
| FeedbackVectorSlot ic_slot_; |
| FeedbackVectorSlot stub_slot_; |
| Expression* expression_; |
| @@ -1915,7 +1969,7 @@ class CallNew final : public Expression { |
| return callnew_feedback_slot_; |
| } |
| - bool IsMonomorphic() const { return is_monomorphic_; } |
| + bool IsMonomorphic() const { return IsMonomorphicField::decode(bit_field_); } |
| Handle<JSFunction> target() const { return target_; } |
| Handle<AllocationSite> allocation_site() const { |
| return allocation_site_; |
| @@ -1928,11 +1982,13 @@ class CallNew final : public Expression { |
| void set_allocation_site(Handle<AllocationSite> site) { |
| allocation_site_ = site; |
| } |
| - void set_is_monomorphic(bool monomorphic) { is_monomorphic_ = monomorphic; } |
| + void set_is_monomorphic(bool monomorphic) { |
| + bit_field_ = IsMonomorphicField::update(bit_field_, monomorphic); |
| + } |
| void set_target(Handle<JSFunction> target) { target_ = target; } |
| void SetKnownGlobalTarget(Handle<JSFunction> target) { |
| target_ = target; |
| - is_monomorphic_ = true; |
| + set_is_monomorphic(true); |
| } |
| private: |
| @@ -1940,19 +1996,22 @@ class CallNew final : public Expression { |
| CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos) |
| : Expression(pos, kCallNew), |
| - is_monomorphic_(false), |
| expression_(expression), |
| - arguments_(arguments) {} |
| + arguments_(arguments) { |
| + bit_field_ |= IsMonomorphicField::encode(false); |
| + } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - bool is_monomorphic_; |
| FeedbackVectorSlot callnew_feedback_slot_; |
| Expression* expression_; |
| ZoneList<Expression*>* arguments_; |
| Handle<JSFunction> target_; |
| Handle<AllocationSite> allocation_site_; |
| + |
| + class IsMonomorphicField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| }; |
| @@ -2006,7 +2065,7 @@ class CallRuntime final : public Expression { |
| class UnaryOperation final : public Expression { |
| public: |
| - Token::Value op() const { return op_; } |
| + Token::Value op() const { return OperatorField::decode(bit_field_); } |
| Expression* expression() const { return expression_; } |
| void set_expression(Expression* e) { expression_ = e; } |
| @@ -2022,21 +2081,24 @@ class UnaryOperation final : public Expression { |
| friend class AstNodeFactory; |
| UnaryOperation(Token::Value op, Expression* expression, int pos) |
| - : Expression(pos, kUnaryOperation), op_(op), expression_(expression) { |
| + : Expression(pos, kUnaryOperation), expression_(expression) { |
| + bit_field_ |= OperatorField::encode(op); |
| DCHECK(Token::IsUnaryOp(op)); |
| } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - Token::Value op_; |
| Expression* expression_; |
| + |
| + class OperatorField |
| + : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; |
| }; |
| class BinaryOperation final : public Expression { |
| public: |
| - Token::Value op() const { return static_cast<Token::Value>(op_); } |
| + Token::Value op() const { return OperatorField::decode(bit_field_); } |
| Expression* left() const { return left_; } |
| void set_left(Expression* e) { left_ = e; } |
| Expression* right() const { return right_; } |
| @@ -2090,18 +2152,17 @@ class BinaryOperation final : public Expression { |
| BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos) |
| : Expression(pos, kBinaryOperation), |
| - op_(static_cast<byte>(op)), |
| has_fixed_right_arg_(false), |
| fixed_right_arg_value_(0), |
| left_(left), |
| right_(right) { |
| + bit_field_ |= OperatorField::encode(op); |
| DCHECK(Token::IsBinaryOp(op)); |
| } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - const byte op_; // actually Token::Value |
| // TODO(rossberg): the fixed arg should probably be represented as a Constant |
| // type for the RHS. Currenty it's actually a Maybe<int> |
| bool has_fixed_right_arg_; |
| @@ -2110,6 +2171,9 @@ class BinaryOperation final : public Expression { |
| Expression* right_; |
| Handle<AllocationSite> allocation_site_; |
| FeedbackVectorSlot type_feedback_slot_; |
| + |
| + class OperatorField |
| + : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; |
| }; |
| @@ -2164,24 +2228,22 @@ class CountOperation final : public Expression { |
| friend class AstNodeFactory; |
| CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos) |
| - : Expression(pos, kCountOperation), |
| - bit_field_( |
| - IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) | |
| - StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), |
| - type_(NULL), |
| - expression_(expr) {} |
| + : Expression(pos, kCountOperation), type_(NULL), expression_(expr) { |
| + bit_field_ |= |
| + IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) | |
| + StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op); |
| + } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - class IsPrefixField : public BitField16<bool, 0, 1> {}; |
| - class KeyTypeField : public BitField16<IcCheckType, 1, 1> {}; |
| - class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 3> {}; |
| - class TokenField : public BitField16<Token::Value, 5, 8> {}; |
| + class IsPrefixField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| + class KeyTypeField : public BitField<IcCheckType, IsPrefixField::kNext, 1> {}; |
| + class StoreModeField |
| + : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {}; |
| + class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {}; |
| - // Starts with 16-bit field, which should get packed together with |
| - // Expression's trailing 16-bit field. |
| - uint16_t bit_field_; |
| FeedbackVectorSlot slot_; |
| FeedbackVectorSlot binary_operation_slot_; |
| Type* type_; |
| @@ -2192,7 +2254,7 @@ class CountOperation final : public Expression { |
| class CompareOperation final : public Expression { |
| public: |
| - Token::Value op() const { return op_; } |
| + Token::Value op() const { return OperatorField::decode(bit_field_); } |
| Expression* left() const { return left_; } |
| Expression* right() const { return right_; } |
| @@ -2218,21 +2280,23 @@ class CompareOperation final : public Expression { |
| CompareOperation(Token::Value op, Expression* left, Expression* right, |
| int pos) |
| : Expression(pos, kCompareOperation), |
| - op_(op), |
| left_(left), |
| right_(right), |
| combined_type_(Type::None()) { |
| + bit_field_ |= OperatorField::encode(op); |
| DCHECK(Token::IsCompareOp(op)); |
| } |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - Token::Value op_; |
| Expression* left_; |
| Expression* right_; |
| Type* combined_type_; |
| + |
| + class OperatorField |
| + : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; |
| }; |
| @@ -2356,17 +2420,14 @@ class Assignment final : public Expression { |
| static int parent_num_ids() { return Expression::num_ids(); } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - class IsUninitializedField : public BitField16<bool, 0, 1> {}; |
| + class IsUninitializedField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| class KeyTypeField |
| - : public BitField16<IcCheckType, IsUninitializedField::kNext, 1> {}; |
| + : public BitField<IcCheckType, IsUninitializedField::kNext, 1> {}; |
| class StoreModeField |
| - : public BitField16<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {}; |
| - class TokenField : public BitField16<Token::Value, StoreModeField::kNext, 8> { |
| - }; |
| + : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {}; |
| + class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {}; |
| - // Starts with 16-bit field, which should get packed together with |
| - // Expression's trailing 16-bit field. |
| - uint16_t bit_field_; |
| FeedbackVectorSlot slot_; |
| Expression* target_; |
| Expression* value_; |
| @@ -2393,14 +2454,14 @@ class Assignment final : public Expression { |
| class RewritableExpression final : public Expression { |
| public: |
| Expression* expression() const { return expr_; } |
| - bool is_rewritten() const { return is_rewritten_; } |
| + bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); } |
| void Rewrite(Expression* new_expression) { |
| DCHECK(!is_rewritten()); |
| DCHECK_NOT_NULL(new_expression); |
| DCHECK(!new_expression->IsRewritableExpression()); |
| expr_ = new_expression; |
| - is_rewritten_ = true; |
| + bit_field_ = IsRewrittenField::update(bit_field_, true); |
| } |
| static int num_ids() { return parent_num_ids(); } |
| @@ -2410,15 +2471,17 @@ class RewritableExpression final : public Expression { |
| explicit RewritableExpression(Expression* expression) |
| : Expression(expression->position(), kRewritableExpression), |
| - is_rewritten_(false), |
| expr_(expression) { |
| + bit_field_ |= IsRewrittenField::encode(false); |
| DCHECK(!expression->IsRewritableExpression()); |
| } |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - bool is_rewritten_; |
| Expression* expr_; |
| + |
| + class IsRewrittenField |
| + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; |
| }; |
| // Our Yield is different from the JS yield in that it "returns" its argument as |
| @@ -2430,8 +2493,11 @@ class Yield final : public Expression { |
| Expression* generator_object() const { return generator_object_; } |
| Expression* expression() const { return expression_; } |
| + OnException on_exception() const { |
| + return OnExceptionField::decode(bit_field_); |
| + } |
| bool rethrow_on_exception() const { |
| - return on_exception_ == kOnExceptionRethrow; |
| + return on_exception() == kOnExceptionRethrow; |
| } |
| int yield_id() const { return yield_id_; } |
| @@ -2445,15 +2511,18 @@ class Yield final : public Expression { |
| Yield(Expression* generator_object, Expression* expression, int pos, |
| OnException on_exception) |
| : Expression(pos, kYield), |
| - on_exception_(on_exception), |
| yield_id_(-1), |
| generator_object_(generator_object), |
| - expression_(expression) {} |
| + expression_(expression) { |
| + bit_field_ |= OnExceptionField::encode(on_exception); |
| + } |
| - OnException on_exception_; |
| int yield_id_; |
| Expression* generator_object_; |
| Expression* expression_; |
| + |
| + class OnExceptionField |
| + : public BitField<OnException, Expression::kNextBitFieldIndex, 1> {}; |
| }; |
| @@ -2547,14 +2616,14 @@ class FunctionLiteral final : public Expression { |
| inferred_name_ = Handle<String>(); |
| } |
| - bool pretenure() const { return Pretenure::decode(bitfield_); } |
| - void set_pretenure() { bitfield_ = Pretenure::update(bitfield_, true); } |
| + bool pretenure() const { return Pretenure::decode(bit_field_); } |
| + void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); } |
| bool has_duplicate_parameters() const { |
| - return HasDuplicateParameters::decode(bitfield_); |
| + return HasDuplicateParameters::decode(bit_field_); |
| } |
| - bool is_function() const { return IsFunction::decode(bitfield_); } |
| + bool is_function() const { return IsFunction::decode(bit_field_); } |
| // This is used as a heuristic on when to eagerly compile a function |
| // literal. We consider the following constructs as hints that the |
| @@ -2562,25 +2631,21 @@ class FunctionLiteral final : public Expression { |
| // - (function() { ... })(); |
| // - var x = function() { ... }(); |
| bool should_eager_compile() const { |
| - return ShouldEagerCompile::decode(bitfield_); |
| + return ShouldEagerCompile::decode(bit_field_); |
| } |
| void set_should_eager_compile() { |
| - bitfield_ = ShouldEagerCompile::update(bitfield_, true); |
| + bit_field_ = ShouldEagerCompile::update(bit_field_, true); |
| } |
| // A hint that we expect this function to be called (exactly) once, |
| // i.e. we suspect it's an initialization function. |
| - bool should_be_used_once_hint() const { |
| - return ShouldBeUsedOnceHint::decode(bitfield_); |
| - } |
| - void set_should_be_used_once_hint() { |
| - bitfield_ = ShouldBeUsedOnceHint::update(bitfield_, true); |
| - } |
| + bool should_be_used_once_hint() const { return should_be_used_once_hint_; } |
| + void set_should_be_used_once_hint() { should_be_used_once_hint_ = true; } |
| FunctionType function_type() const { |
| - return FunctionTypeBits::decode(bitfield_); |
| + return FunctionTypeBits::decode(bit_field_); |
| } |
| - FunctionKind kind() const { return FunctionKindBits::decode(bitfield_); } |
| + FunctionKind kind() const { return FunctionKindBits::decode(bit_field_); } |
| int ast_node_count() { return ast_properties_.node_count(); } |
| AstProperties::Flags flags() const { return ast_properties_.flags(); } |
| @@ -2616,6 +2681,7 @@ class FunctionLiteral final : public Expression { |
| int position, bool is_function) |
| : Expression(position, kFunctionLiteral), |
| dont_optimize_reason_(kNoReason), |
| + should_be_used_once_hint_(false), |
| materialized_literal_count_(materialized_literal_count), |
| expected_property_count_(expected_property_count), |
| parameter_count_(parameter_count), |
| @@ -2626,29 +2692,27 @@ class FunctionLiteral final : public Expression { |
| body_(body), |
| raw_inferred_name_(ast_value_factory->empty_string()), |
| ast_properties_(zone) { |
| - bitfield_ = |
| + bit_field_ |= |
| FunctionTypeBits::encode(function_type) | Pretenure::encode(false) | |
| HasDuplicateParameters::encode(has_duplicate_parameters == |
| kHasDuplicateParameters) | |
| IsFunction::encode(is_function) | |
| ShouldEagerCompile::encode(eager_compile_hint == kShouldEagerCompile) | |
| - FunctionKindBits::encode(kind) | ShouldBeUsedOnceHint::encode(false); |
| + FunctionKindBits::encode(kind); |
| DCHECK(IsValidFunctionKind(kind)); |
| } |
| - class FunctionTypeBits : public BitField16<FunctionType, 0, 2> {}; |
| - class Pretenure : public BitField16<bool, 2, 1> {}; |
| - class HasDuplicateParameters : public BitField16<bool, 3, 1> {}; |
| - class IsFunction : public BitField16<bool, 4, 1> {}; |
| - class ShouldEagerCompile : public BitField16<bool, 5, 1> {}; |
| - class ShouldBeUsedOnceHint : public BitField16<bool, 6, 1> {}; |
| - class FunctionKindBits : public BitField16<FunctionKind, 7, 9> {}; |
| - |
| - // Start with 16-bit field, which should get packed together |
| - // with Expression's trailing 16-bit field. |
| - uint16_t bitfield_; |
| + class FunctionTypeBits |
| + : public BitField<FunctionType, Expression::kNextBitFieldIndex, 2> {}; |
| + class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {}; |
| + class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {}; |
| + class IsFunction : public BitField<bool, HasDuplicateParameters::kNext, 1> {}; |
| + class ShouldEagerCompile : public BitField<bool, IsFunction::kNext, 1> {}; |
| + class FunctionKindBits |
| + : public BitField<FunctionKind, ShouldEagerCompile::kNext, 9> {}; |
| BailoutReason dont_optimize_reason_; |
|
Toon Verwaest
2016/08/26 14:55:02
We should probably annotate BailoutReason with uin
|
| + bool should_be_used_once_hint_; |
|
Toon Verwaest
2016/08/26 14:55:02
bool should_be_used_once_hint_ : 1
|
| int materialized_literal_count_; |
| int expected_property_count_; |