Index: src/ast.h |
diff --git a/src/ast.h b/src/ast.h |
index 44339c7c9fce037e747863c44cd96f17d8501dd7..da9be1065fe44acc78a32706effbd9b41cc5636e 100644 |
--- a/src/ast.h |
+++ b/src/ast.h |
@@ -796,13 +796,26 @@ class ForEachStatement : public IterationStatement { |
Expression* each() const { return each_; } |
Expression* subject() const { return subject_; } |
+ 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 +828,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 +1473,44 @@ 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; |
+ |
+#ifdef DEBUG |
+ int slot_count() const { return slot_count_; } |
+#endif |
+ |
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), |
+#ifdef DEBUG |
+ slot_count_(0), |
+#endif |
+ slot_(FeedbackVectorICSlot::Invalid()) { |
+ } |
static int parent_num_ids() { return MaterializedLiteral::num_ids(); } |
private: |
@@ -1479,6 +1522,12 @@ class ObjectLiteral final : public MaterializedLiteral { |
bool has_elements_; |
bool may_store_doubles_; |
bool has_function_; |
+#ifdef DEBUG |
+ // slot_count_ helps validate that the logic to allocate ic slots and the |
+ // logic to use them are in sync. |
+ int slot_count_; |
+#endif |
+ FeedbackVectorICSlot slot_; |
}; |
@@ -1654,6 +1703,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 +1781,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 +1827,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 +1906,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 +1920,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 +2180,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 +2215,7 @@ class CountOperation final : public Expression { |
Type* type_; |
Expression* expression_; |
SmallMapList receiver_types_; |
+ FeedbackVectorICSlot slot_; |
}; |
@@ -2288,6 +2358,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 +2387,7 @@ class Assignment final : public Expression { |
Expression* value_; |
BinaryOperation* binary_operation_; |
SmallMapList receiver_types_; |
+ FeedbackVectorICSlot slot_; |
}; |