Commit b27016b7 authored by mvstanton's avatar mvstanton Committed by Commit bot

Vector ICs: ClassLiterals need to allocate a vector slot for home objects.

BUG=

Review URL: https://codereview.chromium.org/1160173004

Cr-Commit-Position: refs/heads/master@{#28827}
parent 9127d4ee
......@@ -1680,9 +1680,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2565,6 +2565,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
__ push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2587,7 +2591,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2620,6 +2625,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
......@@ -1652,9 +1652,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2255,6 +2255,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
FieldMemOperand(x0, JSFunction::kPrototypeOrInitialMapOffset));
__ Push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2277,7 +2281,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2310,6 +2315,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
......@@ -437,6 +437,7 @@ void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
for (int i = 0; i < node->properties()->length(); i++) {
VisitObjectLiteralProperty(node->properties()->at(i));
}
ReserveFeedbackSlots(node);
}
......
......@@ -294,6 +294,41 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
}
FeedbackVectorRequirements ClassLiteral::ComputeFeedbackRequirements(
Isolate* isolate, const ICSlotCache* cache) {
if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0);
// This logic that computes the number of slots needed for vector store
// ICs must mirror FullCodeGenerator::VisitClassLiteral.
int ic_slots = 0;
for (int i = 0; i < properties()->length(); i++) {
ObjectLiteral::Property* property = properties()->at(i);
Expression* value = property->value();
if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++;
}
#ifdef DEBUG
// FullCodeGenerator::VisitClassLiteral verifies that it consumes slot_count_
// slots.
slot_count_ = ic_slots;
#endif
return FeedbackVectorRequirements(0, ic_slots);
}
FeedbackVectorICSlot ClassLiteral::SlotForHomeObject(Expression* value,
int* slot_index) const {
if (FLAG_vector_stores && FunctionLiteral::NeedsHomeObject(value)) {
DCHECK(slot_index != NULL && *slot_index >= 0 && *slot_index < slot_count_);
FeedbackVectorICSlot slot = GetNthSlot(*slot_index);
*slot_index += 1;
return slot;
}
return FeedbackVectorICSlot::Invalid();
}
bool ObjectLiteral::Property::IsCompileTimeValue() {
return kind_ == CONSTANT ||
(kind_ == MATERIALIZED_LITERAL &&
......
......@@ -2705,6 +2705,28 @@ class ClassLiteral final : public Expression {
// ClassLiteral can vary, so num_ids() is not a static method.
int num_ids() const { return parent_num_ids() + 4 + 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:
ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope,
VariableProxy* class_variable_proxy, Expression* extends,
......@@ -2717,7 +2739,13 @@ class ClassLiteral final : public Expression {
extends_(extends),
constructor_(constructor),
properties_(properties),
end_position_(end_position) {}
end_position_(end_position),
#ifdef DEBUG
slot_count_(0),
#endif
slot_(FeedbackVectorICSlot::Invalid()) {
}
static int parent_num_ids() { return Expression::num_ids(); }
private:
......@@ -2730,6 +2758,12 @@ class ClassLiteral final : public Expression {
FunctionLiteral* constructor_;
ZoneList<Property*>* properties_;
int end_position_;
#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_;
};
......
......@@ -1612,9 +1612,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2477,6 +2477,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
__ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
__ Push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2498,7 +2502,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2526,6 +2531,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
......@@ -1664,9 +1664,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2541,6 +2541,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
__ push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2563,7 +2567,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2596,6 +2601,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
......@@ -1663,9 +1663,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2540,6 +2540,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
__ push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2562,7 +2566,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2595,6 +2600,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
......@@ -1644,9 +1644,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
AccessorTable accessor_table(zone());
int property_index = 0;
// store_slot_index points to the vector ic slot for the next store ic used.
// store_slot_index points to the vector IC slot for the next store IC used.
// ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ics emitted here changes.
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property = expr->properties()->at(property_index);
......@@ -2472,6 +2472,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
__ movp(scratch, FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset));
__ Push(scratch);
// store_slot_index points to the vector IC slot for the next store IC used.
// ClassLiteral::ComputeFeedbackRequirements controls the allocation of slots
// and must be updated if the number of store ICs emitted here changes.
int store_slot_index = 0;
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
......@@ -2493,7 +2497,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
EmitSetHomeObjectIfNeeded(value, 2,
lit->SlotForHomeObject(value, &store_slot_index));
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
......@@ -2524,6 +2529,10 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
// constructor
__ CallRuntime(Runtime::kToFastProperties, 1);
// Verify that compilation exactly consumed the number of store ic slots that
// the ClassLiteral node had to offer.
DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment