From f1cc4ed2b28696f940617a0016e781237d734c49 Mon Sep 17 00:00:00 2001 From: "chunyang.dai" Date: Mon, 1 Jun 2015 02:04:41 -0700 Subject: [PATCH] X87: VectorICs: allocating slots for store ics in ast nodes. port 5450fc07ba07615a70f5ed8379dc23c3275d6fe3 (r18659) original commit message: Also adapt code generation to pass the slot to the store/keyed-store ic. AST nodes ObjectLiteral, Assignment, ForEach, Call and CountOperation now include one or more feedback vector ic slot ids. BUG= Review URL: https://codereview.chromium.org/1155383003 Cr-Commit-Position: refs/heads/master@{#28718} --- src/x87/full-codegen-x87.cc | 107 ++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 24 deletions(-) diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc index e8278ef2b4..485abdaf6f 100644 --- a/src/x87/full-codegen-x87.cc +++ b/src/x87/full-codegen-x87.cc @@ -1202,7 +1202,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); } @@ -1263,13 +1263,15 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* 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(); } } @@ -1603,6 +1605,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; @@ -1629,7 +1635,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)) { @@ -1637,6 +1648,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 { @@ -1648,7 +1662,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 { @@ -1682,9 +1697,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); } @@ -1717,7 +1738,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: @@ -1759,6 +1781,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()); } @@ -1877,7 +1903,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) { @@ -1985,7 +2011,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; @@ -2503,17 +2529,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: { @@ -2523,6 +2550,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; } @@ -2569,6 +2597,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 ic = CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); @@ -2590,12 +2619,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) { @@ -2691,7 +2721,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); } @@ -2739,7 +2774,12 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { SetSourcePosition(expr->position()); Handle 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); @@ -2968,7 +3008,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()); @@ -2978,7 +3018,7 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper( __ CallRuntime(Runtime::kThrowReferenceError, 1); __ bind(&uninitialized_this); - EmitVariableAssignment(this_var, Token::INIT_CONST); + EmitVariableAssignment(this_var, Token::INIT_CONST, slot); } @@ -3196,7 +3236,8 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { RecordJSReturnSite(expr); - EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); + EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), + expr->CallFeedbackICSlot()); context()->Plug(eax); } @@ -4529,6 +4570,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); } @@ -4732,7 +4774,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) { @@ -4898,7 +4940,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); } @@ -4910,7 +4952,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); } @@ -4919,7 +4961,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()) { @@ -4957,7 +5004,12 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ pop(StoreDescriptor::ReceiverRegister()); Handle 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 @@ -5291,6 +5343,13 @@ void FullCodeGenerator::ClearPendingMessage() { } +void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { + DCHECK(FLAG_vector_stores && !slot.IsInvalid()); + __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), + Immediate(SmiFromSlot(slot))); +} + + #undef __