X87: VectorICs: allocating slots for store ics in ast nodes.
port 5450fc07ba
(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}
This commit is contained in:
parent
b471651e96
commit
f1cc4ed2b2
@ -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<Code> 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<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);
|
||||
@ -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<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
|
||||
@ -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 __
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user