| Index: src/x87/full-codegen-x87.cc
|
| diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc
|
| index fffb4b27a76fc1a81482c3ff3470e0f772a6ac4a..36f2dca80124635293913573c45a839378380759 100644
|
| --- a/src/x87/full-codegen-x87.cc
|
| +++ b/src/x87/full-codegen-x87.cc
|
| @@ -1184,7 +1184,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);
|
| }
|
|
|
| @@ -1266,13 +1266,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();
|
| }
|
| }
|
| @@ -1611,6 +1613,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;
|
| @@ -1637,7 +1643,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)) {
|
| @@ -1645,6 +1656,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 {
|
| @@ -1656,7 +1670,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 {
|
| @@ -1690,9 +1705,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);
|
| }
|
| @@ -1725,7 +1746,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:
|
| @@ -1767,6 +1789,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());
|
| }
|
|
|
|
|
| @@ -1885,7 +1911,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) {
|
| @@ -1992,7 +2018,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;
|
| @@ -2510,17 +2536,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: {
|
| @@ -2530,6 +2557,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;
|
| }
|
| @@ -2576,6 +2604,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);
|
| @@ -2597,12 +2626,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) {
|
| @@ -2698,7 +2728,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);
|
| }
|
| @@ -2746,7 +2781,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);
|
| @@ -2979,7 +3019,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());
|
| @@ -2989,7 +3029,7 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
|
| __ CallRuntime(Runtime::kThrowReferenceError, 1);
|
| __ bind(&uninitialized_this);
|
|
|
| - EmitVariableAssignment(this_var, Token::INIT_CONST);
|
| + EmitVariableAssignment(this_var, Token::INIT_CONST, slot);
|
| }
|
|
|
|
|
| @@ -3207,7 +3247,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
|
|
| RecordJSReturnSite(expr);
|
|
|
| - EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference());
|
| + EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
|
| + expr->CallFeedbackICSlot());
|
| context()->Plug(eax);
|
| }
|
|
|
| @@ -4540,6 +4581,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);
|
| }
|
|
|
| @@ -4743,7 +4785,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) {
|
| @@ -4909,7 +4951,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);
|
| }
|
| @@ -4921,7 +4963,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);
|
| }
|
| @@ -4930,7 +4972,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()) {
|
| @@ -4968,7 +5015,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
|
| @@ -5302,6 +5354,13 @@ void FullCodeGenerator::ClearPendingMessage() {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) {
|
| + DCHECK(FLAG_vector_stores && !slot.IsInvalid());
|
| + __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(),
|
| + Immediate(SmiFromSlot(slot)));
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
|
|
|
|