Chromium Code Reviews| Index: src/ast.h |
| diff --git a/src/ast.h b/src/ast.h |
| index 44339c7c9fce037e747863c44cd96f17d8501dd7..f1c4e6fcafaa31ba43d779f745bb6fe3a68aa9df 100644 |
| --- a/src/ast.h |
| +++ b/src/ast.h |
| @@ -796,13 +796,28 @@ class ForEachStatement : public IterationStatement { |
| Expression* each() const { return each_; } |
| Expression* subject() const { return subject_; } |
| + // Object literals need one feedback slot for each non-trivial value, as well |
|
Jakob Kummerow
2015/05/27 13:24:36
Object literals? Huh?
mvstanton
2015/05/27 14:00:18
Doh...copy/paste. Removed.
|
| + // as some slots for home objects. |
| + FeedbackVectorRequirements ComputeFeedbackRequirements( |
| + Isolate* isolate, const ICSlotCache* cache) override; |
| + void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, |
| + ICSlotCache* cache) override { |
| + each_slot_ = slot; |
| + } |
| + Code::Kind FeedbackICSlotKind(int index) override; |
| + FeedbackVectorICSlot EachFeedbackSlot() const { return each_slot_; } |
| + |
| protected: |
| ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos) |
| - : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {} |
| + : IterationStatement(zone, labels, pos), |
| + each_(NULL), |
| + subject_(NULL), |
| + each_slot_(FeedbackVectorICSlot::Invalid()) {} |
| private: |
| Expression* each_; |
| Expression* subject_; |
| + FeedbackVectorICSlot each_slot_; |
| }; |
| @@ -815,9 +830,12 @@ class ForInStatement final : public ForEachStatement { |
| } |
| // Type feedback information. |
| - virtual FeedbackVectorRequirements ComputeFeedbackRequirements( |
| + FeedbackVectorRequirements ComputeFeedbackRequirements( |
| Isolate* isolate, const ICSlotCache* cache) override { |
| - return FeedbackVectorRequirements(1, 0); |
| + FeedbackVectorRequirements base = |
| + ForEachStatement::ComputeFeedbackRequirements(isolate, cache); |
| + DCHECK(base.slots() == 0 && base.ic_slots() <= 1); |
| + return FeedbackVectorRequirements(1, base.ic_slots()); |
| } |
| void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override { |
| for_in_feedback_slot_ = slot; |
| @@ -1457,17 +1475,36 @@ class ObjectLiteral final : public MaterializedLiteral { |
| // ObjectLiteral can vary, so num_ids() is not a static method. |
| int num_ids() const { return parent_num_ids() + 1 + properties()->length(); } |
| + // Object literals need one feedback slot for each non-trivial value, as well |
| + // as some slots for home objects. |
| + FeedbackVectorRequirements ComputeFeedbackRequirements( |
| + Isolate* isolate, const ICSlotCache* cache) override; |
| + void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, |
| + ICSlotCache* cache) override { |
| + slot_ = slot; |
| + } |
| + Code::Kind FeedbackICSlotKind(int index) override { return Code::STORE_IC; } |
| + FeedbackVectorICSlot GetNthSlot(int n) const { |
| + return FeedbackVectorICSlot(slot_.ToInt() + n); |
| + } |
| + |
| + // If value needs a home object, returns a valid feedback vector ic slot |
| + // given by slot_index, and increments slot_index. |
| + FeedbackVectorICSlot SlotForHomeObject(Expression* value, |
| + int* slot_index) const; |
| + |
| protected: |
| ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index, |
| - int boilerplate_properties, bool has_function, |
| - bool is_strong, int pos) |
| + int boilerplate_properties, bool has_function, bool is_strong, |
| + int pos) |
| : MaterializedLiteral(zone, literal_index, is_strong, pos), |
| properties_(properties), |
| boilerplate_properties_(boilerplate_properties), |
| fast_elements_(false), |
| has_elements_(false), |
| may_store_doubles_(false), |
| - has_function_(has_function) {} |
| + has_function_(has_function), |
| + slot_(FeedbackVectorICSlot::Invalid()) {} |
| static int parent_num_ids() { return MaterializedLiteral::num_ids(); } |
| private: |
| @@ -1479,6 +1516,7 @@ class ObjectLiteral final : public MaterializedLiteral { |
| bool has_elements_; |
| bool may_store_doubles_; |
| bool has_function_; |
| + FeedbackVectorICSlot slot_; |
| }; |
| @@ -1654,6 +1692,17 @@ class VariableProxy final : public Expression { |
| }; |
| +// Left-hand side can only be a property, a global or a (parameter or local) |
| +// slot. |
| +enum LhsKind { |
| + VARIABLE, |
| + NAMED_PROPERTY, |
| + KEYED_PROPERTY, |
| + NAMED_SUPER_PROPERTY, |
| + KEYED_SUPER_PROPERTY |
| +}; |
| + |
| + |
| class Property final : public Expression { |
| public: |
| DECLARE_NODE_TYPE(Property) |
| @@ -1721,6 +1770,14 @@ class Property final : public Expression { |
| return property_feedback_slot_; |
| } |
| + static LhsKind GetAssignType(Property* property) { |
| + if (property == NULL) return VARIABLE; |
| + bool super_access = property->IsSuperAccess(); |
| + return (property->key()->IsPropertyName()) |
| + ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) |
| + : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY); |
| + } |
| + |
| protected: |
| Property(Zone* zone, Expression* obj, Expression* key, int pos) |
| : Expression(zone, pos), |
| @@ -1759,22 +1816,14 @@ class Call final : public Expression { |
| Isolate* isolate, const ICSlotCache* cache) override; |
| void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, |
| ICSlotCache* cache) override { |
| - ic_slot_or_slot_ = slot.ToInt(); |
| - } |
| - void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override { |
| - ic_slot_or_slot_ = slot.ToInt(); |
| + ic_slot_ = slot; |
| } |
| + void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override { slot_ = slot; } |
| Code::Kind FeedbackICSlotKind(int index) override { return Code::CALL_IC; } |
| - FeedbackVectorSlot CallFeedbackSlot() const { |
| - DCHECK(ic_slot_or_slot_ != FeedbackVectorSlot::Invalid().ToInt()); |
| - return FeedbackVectorSlot(ic_slot_or_slot_); |
| - } |
| + FeedbackVectorSlot CallFeedbackSlot() const { return slot_; } |
| - FeedbackVectorICSlot CallFeedbackICSlot() const { |
| - DCHECK(ic_slot_or_slot_ != FeedbackVectorICSlot::Invalid().ToInt()); |
| - return FeedbackVectorICSlot(ic_slot_or_slot_); |
| - } |
| + FeedbackVectorICSlot CallFeedbackICSlot() const { return ic_slot_; } |
| SmallMapList* GetReceiverTypes() override { |
| if (expression()->IsProperty()) { |
| @@ -1846,7 +1895,8 @@ class Call final : public Expression { |
| Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments, |
| int pos) |
| : Expression(zone, pos), |
| - ic_slot_or_slot_(FeedbackVectorICSlot::Invalid().ToInt()), |
| + ic_slot_(FeedbackVectorICSlot::Invalid()), |
| + slot_(FeedbackVectorSlot::Invalid()), |
| expression_(expression), |
| arguments_(arguments), |
| bit_field_(IsUninitializedField::encode(false)) { |
| @@ -1859,9 +1909,8 @@ class Call final : public Expression { |
| private: |
| int local_id(int n) const { return base_id() + parent_num_ids() + n; } |
| - // We store this as an integer because we don't know if we have a slot or |
| - // an ic slot until scoping time. |
| - int ic_slot_or_slot_; |
| + FeedbackVectorICSlot ic_slot_; |
| + FeedbackVectorSlot slot_; |
| Expression* expression_; |
| ZoneList<Expression*>* arguments_; |
| Handle<JSFunction> target_; |
| @@ -2120,16 +2169,25 @@ class CountOperation final : public Expression { |
| return TypeFeedbackId(local_id(3)); |
| } |
| + FeedbackVectorRequirements ComputeFeedbackRequirements( |
| + Isolate* isolate, const ICSlotCache* cache) override; |
| + void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, |
| + ICSlotCache* cache) override { |
| + slot_ = slot; |
| + } |
| + Code::Kind FeedbackICSlotKind(int index) override; |
| + FeedbackVectorICSlot CountSlot() const { return slot_; } |
| + |
| protected: |
| CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr, |
| int pos) |
| : Expression(zone, pos), |
| - bit_field_(IsPrefixField::encode(is_prefix) | |
| - KeyTypeField::encode(ELEMENT) | |
| - StoreModeField::encode(STANDARD_STORE) | |
| - TokenField::encode(op)), |
| + bit_field_( |
| + IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) | |
| + StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), |
| type_(NULL), |
| - expression_(expr) {} |
| + expression_(expr), |
| + slot_(FeedbackVectorICSlot::Invalid()) {} |
| static int parent_num_ids() { return Expression::num_ids(); } |
| private: |
| @@ -2146,6 +2204,7 @@ class CountOperation final : public Expression { |
| Type* type_; |
| Expression* expression_; |
| SmallMapList receiver_types_; |
| + FeedbackVectorICSlot slot_; |
| }; |
| @@ -2288,6 +2347,15 @@ class Assignment final : public Expression { |
| bit_field_ = StoreModeField::update(bit_field_, mode); |
| } |
| + FeedbackVectorRequirements ComputeFeedbackRequirements( |
| + Isolate* isolate, const ICSlotCache* cache) override; |
| + void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, |
| + ICSlotCache* cache) override { |
| + slot_ = slot; |
| + } |
| + Code::Kind FeedbackICSlotKind(int index) override; |
| + FeedbackVectorICSlot AssignmentSlot() const { return slot_; } |
| + |
| protected: |
| Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value, |
| int pos); |
| @@ -2308,6 +2376,7 @@ class Assignment final : public Expression { |
| Expression* value_; |
| BinaryOperation* binary_operation_; |
| SmallMapList receiver_types_; |
| + FeedbackVectorICSlot slot_; |
| }; |