Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 0993b6c9739e4e62536f71197e9c195b44f5e3a6..da5776bd1a060604ba18bd5215e4ae507e900acf 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -1191,7 +1191,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
__ mov(result_register(), ebx); |
// Perform the assignment as if via '='. |
{ EffectContext context(this); |
- EmitAssignment(stmt->each()); |
+ EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
} |
@@ -1273,13 +1273,15 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { |
void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
- int offset) { |
+ int offset, |
+ FeedbackVectorICSlot slot) { |
if (NeedsHomeObject(initializer)) { |
__ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
__ mov(StoreDescriptor::NameRegister(), |
Immediate(isolate()->factory()->home_object_symbol())); |
__ mov(StoreDescriptor::ValueRegister(), |
Operand(esp, offset * kPointerSize)); |
+ if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
CallStoreIC(); |
} |
} |
@@ -1613,6 +1615,10 @@ 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. |
+ // ObjectLiteral::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 (; property_index < expr->properties()->length(); property_index++) { |
ObjectLiteral::Property* property = expr->properties()->at(property_index); |
if (property->is_computed_name()) break; |
@@ -1639,7 +1645,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
__ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
__ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
- CallStoreIC(key->LiteralFeedbackId()); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
+ CallStoreIC(); |
+ } else { |
+ CallStoreIC(key->LiteralFeedbackId()); |
+ } |
PrepareForBailoutForId(key->id(), NO_REGISTERS); |
if (NeedsHomeObject(value)) { |
@@ -1647,6 +1658,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
__ mov(StoreDescriptor::NameRegister(), |
Immediate(isolate()->factory()->home_object_symbol())); |
__ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
+ } |
CallStoreIC(); |
} |
} else { |
@@ -1658,7 +1672,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
VisitForStackValue(key); |
VisitForStackValue(value); |
if (property->emit_store()) { |
- EmitSetHomeObjectIfNeeded(value, 2); |
+ EmitSetHomeObjectIfNeeded( |
+ value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
__ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
__ CallRuntime(Runtime::kSetProperty, 4); |
} else { |
@@ -1692,9 +1707,15 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
__ push(Operand(esp, 0)); // Duplicate receiver. |
VisitForStackValue(it->first); |
EmitAccessor(it->second->getter); |
- EmitSetHomeObjectIfNeeded(it->second->getter, 2); |
+ EmitSetHomeObjectIfNeeded( |
+ it->second->getter, 2, |
+ expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
+ |
EmitAccessor(it->second->setter); |
- EmitSetHomeObjectIfNeeded(it->second->setter, 3); |
+ EmitSetHomeObjectIfNeeded( |
+ it->second->setter, 3, |
+ expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
+ |
__ push(Immediate(Smi::FromInt(NONE))); |
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
} |
@@ -1727,7 +1748,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
} else { |
EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
VisitForStackValue(value); |
- EmitSetHomeObjectIfNeeded(value, 2); |
+ EmitSetHomeObjectIfNeeded( |
+ value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
switch (property->kind()) { |
case ObjectLiteral::Property::CONSTANT: |
@@ -1769,6 +1791,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
} else { |
context()->Plug(eax); |
} |
+ |
+ // Verify that compilation exactly consumed the number of store ic slots that |
+ // the ObjectLiteral node had to offer. |
+ DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
} |
@@ -1889,7 +1915,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
Comment cmnt(masm_, "[ Assignment"); |
Property* property = expr->target()->AsProperty(); |
- LhsKind assign_type = GetAssignType(property); |
+ LhsKind assign_type = Property::GetAssignType(property); |
// Evaluate LHS expression. |
switch (assign_type) { |
@@ -1996,7 +2022,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
switch (assign_type) { |
case VARIABLE: |
EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
- expr->op()); |
+ expr->op(), expr->AssignmentSlot()); |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
context()->Plug(eax); |
break; |
@@ -2514,17 +2540,18 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
} |
-void FullCodeGenerator::EmitAssignment(Expression* expr) { |
+void FullCodeGenerator::EmitAssignment(Expression* expr, |
+ FeedbackVectorICSlot slot) { |
DCHECK(expr->IsValidReferenceExpression()); |
Property* prop = expr->AsProperty(); |
- LhsKind assign_type = GetAssignType(prop); |
+ LhsKind assign_type = Property::GetAssignType(prop); |
switch (assign_type) { |
case VARIABLE: { |
Variable* var = expr->AsVariableProxy()->var(); |
EffectContext context(this); |
- EmitVariableAssignment(var, Token::ASSIGN); |
+ EmitVariableAssignment(var, Token::ASSIGN, slot); |
break; |
} |
case NAMED_PROPERTY: { |
@@ -2534,6 +2561,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { |
__ pop(StoreDescriptor::ValueRegister()); // Restore value. |
__ mov(StoreDescriptor::NameRegister(), |
prop->key()->AsLiteral()->value()); |
+ if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
CallStoreIC(); |
break; |
} |
@@ -2580,6 +2608,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { |
__ Move(StoreDescriptor::NameRegister(), eax); |
__ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
__ pop(StoreDescriptor::ValueRegister()); // Restore value. |
+ if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
Handle<Code> ic = |
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
CallIC(ic); |
@@ -2601,12 +2630,13 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
} |
-void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
- Token::Value op) { |
+void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
+ FeedbackVectorICSlot slot) { |
if (var->IsUnallocated()) { |
// Global var, const, or let. |
__ mov(StoreDescriptor::NameRegister(), var->name()); |
__ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
+ if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
CallStoreIC(); |
} else if (var->mode() == LET && op != Token::INIT_LET) { |
@@ -2702,7 +2732,12 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
SetSourcePosition(expr->position()); |
__ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
__ pop(StoreDescriptor::ReceiverRegister()); |
- CallStoreIC(expr->AssignmentFeedbackId()); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->AssignmentSlot()); |
+ CallStoreIC(); |
+ } else { |
+ CallStoreIC(expr->AssignmentFeedbackId()); |
+ } |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
context()->Plug(eax); |
} |
@@ -2750,7 +2785,12 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
SetSourcePosition(expr->position()); |
Handle<Code> ic = |
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
- CallIC(ic, expr->AssignmentFeedbackId()); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->AssignmentSlot()); |
+ CallIC(ic); |
+ } else { |
+ CallIC(ic, expr->AssignmentFeedbackId()); |
+ } |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
context()->Plug(eax); |
@@ -2983,7 +3023,7 @@ void FullCodeGenerator::EmitLoadSuperConstructor() { |
void FullCodeGenerator::EmitInitializeThisAfterSuper( |
- SuperReference* super_ref) { |
+ SuperReference* super_ref, FeedbackVectorICSlot slot) { |
Variable* this_var = super_ref->this_var()->var(); |
GetVar(ecx, this_var); |
__ cmp(ecx, isolate()->factory()->the_hole_value()); |
@@ -2993,7 +3033,7 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper( |
__ CallRuntime(Runtime::kThrowReferenceError, 1); |
__ bind(&uninitialized_this); |
- EmitVariableAssignment(this_var, Token::INIT_CONST); |
+ EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
} |
@@ -3211,7 +3251,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
RecordJSReturnSite(expr); |
- EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); |
+ EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
+ expr->CallFeedbackICSlot()); |
context()->Plug(eax); |
} |
@@ -4545,6 +4586,7 @@ void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
context()->DropAndPlug(1, eax); |
+ // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
EmitInitializeThisAfterSuper(super_reference); |
} |
@@ -4748,7 +4790,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
SetSourcePosition(expr->position()); |
Property* prop = expr->expression()->AsProperty(); |
- LhsKind assign_type = GetAssignType(prop); |
+ LhsKind assign_type = Property::GetAssignType(prop); |
// Evaluate expression and get value. |
if (assign_type == VARIABLE) { |
@@ -4914,7 +4956,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
// Perform the assignment as if via '='. |
{ EffectContext context(this); |
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
- Token::ASSIGN); |
+ Token::ASSIGN, expr->CountSlot()); |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
context.Plug(eax); |
} |
@@ -4926,7 +4968,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
} else { |
// Perform the assignment as if via '='. |
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
- Token::ASSIGN); |
+ Token::ASSIGN, expr->CountSlot()); |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
context()->Plug(eax); |
} |
@@ -4935,7 +4977,12 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
__ mov(StoreDescriptor::NameRegister(), |
prop->key()->AsLiteral()->value()); |
__ pop(StoreDescriptor::ReceiverRegister()); |
- CallStoreIC(expr->CountStoreFeedbackId()); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->CountSlot()); |
+ CallStoreIC(); |
+ } else { |
+ CallStoreIC(expr->CountStoreFeedbackId()); |
+ } |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
if (expr->is_postfix()) { |
if (!context()->IsEffect()) { |
@@ -4973,7 +5020,12 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
__ pop(StoreDescriptor::ReceiverRegister()); |
Handle<Code> ic = |
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
- CallIC(ic, expr->CountStoreFeedbackId()); |
+ if (FLAG_vector_stores) { |
+ EmitLoadStoreICSlot(expr->CountSlot()); |
+ CallIC(ic); |
+ } else { |
+ CallIC(ic, expr->CountStoreFeedbackId()); |
+ } |
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
if (expr->is_postfix()) { |
// Result is on the stack |
@@ -5307,6 +5359,13 @@ void FullCodeGenerator::ClearPendingMessage() { |
} |
+void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
+ DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
+ __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
+ Immediate(SmiFromSlot(slot))); |
+} |
+ |
+ |
#undef __ |