[turbofan] Revive the VectorSlotPair and also put feedback on JSCallFunction.

We resurrect the VectorSlotPair in order to be able to separate the
feedback input for the compiler from the actual type feedback vector
that is required to meet the IC requirements at runtime. This will allow
us to for example use feedback from a different context or divide the
type feedback vector into two separate vectors, without having to touch
the compiler. It'll allow use to load the vector from the shared
function info at runtime, while still consuming feedback in the
compiler (i.e. we don't rely on the feedback vector node to be a heap
constant).

R=mvstanton@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#29185}
This commit is contained in:
bmeurer 2015-06-22 05:08:05 -07:00 committed by Commit bot
parent 42f30f4ded
commit d4f70f8ce8
9 changed files with 256 additions and 228 deletions

View File

@ -1365,9 +1365,10 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
test_value.Else();
{
// Bind value and do loop body.
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(stmt->EachFeedbackSlot());
VisitForInAssignment(stmt->each(), value, slot, stmt->AssignmentId());
VectorSlotPair feedback =
CreateVectorSlotPair(stmt->EachFeedbackSlot());
VisitForInAssignment(stmt->each(), value, feedback,
stmt->AssignmentId());
VisitIterationBody(stmt, &for_loop);
}
test_value.End();
@ -1611,9 +1612,9 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
Node* value = environment()->Pop();
Node* key = environment()->Pop();
Node* receiver = environment()->Pop();
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(
VectorSlotPair feedback = CreateVectorSlotPair(
expr->SlotForHomeObject(property->value(), &store_slot_index));
BuildSetHomeObject(value, receiver, property->value(), slot);
BuildSetHomeObject(value, receiver, property->value(), feedback);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
@ -1653,10 +1654,10 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
DCHECK_NOT_NULL(expr->class_variable_proxy());
Variable* var = expr->class_variable_proxy()->var();
FrameStateBeforeAndAfter states(this, BailoutId::None());
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(
VectorSlotPair feedback = CreateVectorSlotPair(
FLAG_vector_stores ? expr->GetNthSlot(store_slot_index++)
: FeedbackVectorICSlot::Invalid());
BuildVariableAssignment(var, literal, Token::INIT_CONST, slot,
BuildVariableAssignment(var, literal, Token::INIT_CONST, feedback,
BailoutId::None(), states);
}
@ -1684,9 +1685,9 @@ void AstGraphBuilder::VisitConditional(Conditional* expr) {
void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->VariableFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
FrameStateBeforeAndAfter states(this, BeforeId(expr));
Node* value = BuildVariableLoad(expr->var(), expr->id(), states, slot,
Node* value = BuildVariableLoad(expr->var(), expr->id(), states, pair,
ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
@ -1758,17 +1759,18 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
FrameStateBeforeAndAfter states(this, property->value()->id());
Node* value = environment()->Pop();
Handle<Name> name = key->AsPropertyName();
ResolvedFeedbackSlot slot =
VectorSlotPair feedback =
FLAG_vector_stores
? ResolveFeedbackSlot(expr->GetNthSlot(store_slot_index++))
: ResolvedFeedbackSlot();
Node* store = BuildNamedStore(literal, name, value, slot,
? CreateVectorSlotPair(expr->GetNthSlot(store_slot_index++))
: VectorSlotPair();
Node* store = BuildNamedStore(literal, name, value, feedback,
TypeFeedbackId::None());
states.AddToNode(store, key->id(),
OutputFrameStateCombine::Ignore());
ResolvedFeedbackSlot home_slot = ResolveFeedbackSlot(
VectorSlotPair home_feedback = CreateVectorSlotPair(
expr->SlotForHomeObject(property->value(), &store_slot_index));
BuildSetHomeObject(value, literal, property->value(), home_slot);
BuildSetHomeObject(value, literal, property->value(),
home_feedback);
} else {
VisitForEffect(property->value());
}
@ -1787,9 +1789,9 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
Node* set_property = NewNode(op, receiver, key, value, language);
// SetProperty should not lazy deopt on an object literal.
PrepareFrameState(set_property, BailoutId::None());
ResolvedFeedbackSlot home_slot = ResolveFeedbackSlot(
VectorSlotPair home_feedback = CreateVectorSlotPair(
expr->SlotForHomeObject(property->value(), &store_slot_index));
BuildSetHomeObject(value, receiver, property->value(), home_slot);
BuildSetHomeObject(value, receiver, property->value(), home_feedback);
}
break;
}
@ -1825,15 +1827,15 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
it != accessor_table.end(); ++it) {
VisitForValue(it->first);
VisitForValueOrNull(it->second->getter);
ResolvedFeedbackSlot slot_getter = ResolveFeedbackSlot(
VectorSlotPair feedback_getter = CreateVectorSlotPair(
expr->SlotForHomeObject(it->second->getter, &store_slot_index));
BuildSetHomeObject(environment()->Top(), literal, it->second->getter,
slot_getter);
feedback_getter);
VisitForValueOrNull(it->second->setter);
ResolvedFeedbackSlot slot_setter = ResolveFeedbackSlot(
VectorSlotPair feedback_setter = CreateVectorSlotPair(
expr->SlotForHomeObject(it->second->getter, &store_slot_index));
BuildSetHomeObject(environment()->Top(), literal, it->second->setter,
slot_setter);
feedback_setter);
Node* setter = environment()->Pop();
Node* getter = environment()->Pop();
Node* name = environment()->Pop();
@ -1878,9 +1880,9 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
Node* value = environment()->Pop();
Node* key = environment()->Pop();
Node* receiver = environment()->Pop();
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(
VectorSlotPair feedback = CreateVectorSlotPair(
expr->SlotForHomeObject(property->value(), &store_slot_index));
BuildSetHomeObject(value, receiver, property->value(), slot);
BuildSetHomeObject(value, receiver, property->value(), feedback);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
case ObjectLiteral::Property::COMPUTED:
@ -1962,9 +1964,8 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
FrameStateBeforeAndAfter states(this, subexpr->id());
Node* value = environment()->Pop();
Node* index = jsgraph()->Constant(array_index);
Node* store =
BuildKeyedStore(literal, index, value, ResolvedFeedbackSlot(),
TypeFeedbackId::None());
Node* store = BuildKeyedStore(literal, index, value, VectorSlotPair(),
TypeFeedbackId::None());
states.AddToNode(store, expr->GetIdForElement(array_index),
OutputFrameStateCombine::Ignore());
}
@ -2008,7 +2009,7 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
const ResolvedFeedbackSlot& slot,
const VectorSlotPair& feedback,
BailoutId bailout_id) {
DCHECK(expr->IsValidReferenceExpression());
@ -2021,7 +2022,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
case VARIABLE: {
Variable* var = expr->AsVariableProxy()->var();
FrameStateBeforeAndAfter states(this, BailoutId::None());
BuildVariableAssignment(var, value, Token::ASSIGN, slot, bailout_id,
BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id,
states);
break;
}
@ -2032,8 +2033,8 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
Node* object = environment()->Pop();
value = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store =
BuildNamedStore(object, name, value, slot, TypeFeedbackId::None());
Node* store = BuildNamedStore(object, name, value, feedback,
TypeFeedbackId::None());
states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
break;
}
@ -2046,7 +2047,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
Node* object = environment()->Pop();
value = environment()->Pop();
Node* store =
BuildKeyedStore(object, key, value, slot, TypeFeedbackId::None());
BuildKeyedStore(object, key, value, feedback, TypeFeedbackId::None());
states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
break;
}
@ -2128,21 +2129,21 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
switch (assign_type) {
case VARIABLE: {
VariableProxy* proxy = expr->target()->AsVariableProxy();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(proxy->VariableFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(proxy->VariableFeedbackSlot());
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
old_value =
BuildVariableLoad(proxy->var(), expr->target()->id(), states, slot,
BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair,
OutputFrameStateCombine::Push());
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Top();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
FrameStateBeforeAndAfter states(this, property->obj()->id());
old_value = BuildNamedLoad(object, name, slot);
old_value = BuildNamedLoad(object, name, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -2150,10 +2151,10 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
case KEYED_PROPERTY: {
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
FrameStateBeforeAndAfter states(this, property->key()->id());
old_value = BuildKeyedLoad(object, key, slot);
old_value = BuildKeyedLoad(object, key, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -2162,10 +2163,10 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* home_object = environment()->Top();
Node* receiver = environment()->Peek(1);
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
FrameStateBeforeAndAfter states(this, property->obj()->id());
old_value = BuildNamedSuperLoad(receiver, home_object, name, slot);
old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -2174,10 +2175,10 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* key = environment()->Top();
Node* home_object = environment()->Peek(1);
Node* receiver = environment()->Peek(2);
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
FrameStateBeforeAndAfter states(this, property->key()->id());
old_value = BuildKeyedSuperLoad(receiver, home_object, key, slot);
old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
break;
@ -2208,18 +2209,18 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
FrameStateBeforeAndAfter store_states(this, before_store_id);
// Store the value.
Node* value = environment()->Pop();
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->AssignmentSlot());
VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot());
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->target()->AsVariableProxy()->var();
BuildVariableAssignment(variable, value, expr->op(), slot, expr->id(),
BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(),
store_states, ast_context()->GetStateCombine());
break;
}
case NAMED_PROPERTY: {
Node* object = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, slot,
Node* store = BuildNamedStore(object, name, value, feedback,
expr->AssignmentFeedbackId());
store_states.AddToNode(store, expr->id(),
ast_context()->GetStateCombine());
@ -2228,7 +2229,7 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
case KEYED_PROPERTY: {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, slot,
Node* store = BuildKeyedStore(object, key, value, feedback,
expr->AssignmentFeedbackId());
store_states.AddToNode(store, expr->id(),
ast_context()->GetStateCombine());
@ -2278,7 +2279,7 @@ void AstGraphBuilder::VisitThrow(Throw* expr) {
void AstGraphBuilder::VisitProperty(Property* expr) {
Node* value = nullptr;
LhsKind property_kind = Property::GetAssignType(expr);
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->PropertyFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
switch (property_kind) {
case VARIABLE:
UNREACHABLE();
@ -2288,7 +2289,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
FrameStateBeforeAndAfter states(this, expr->obj()->id());
Node* object = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedLoad(object, name, slot);
value = BuildNamedLoad(object, name, pair);
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
break;
}
@ -2298,7 +2299,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
FrameStateBeforeAndAfter states(this, expr->key()->id());
Node* key = environment()->Pop();
Node* object = environment()->Pop();
value = BuildKeyedLoad(object, key, slot);
value = BuildKeyedLoad(object, key, pair);
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
break;
}
@ -2309,7 +2310,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
value = BuildNamedSuperLoad(receiver, home_object, name, slot);
value = BuildNamedSuperLoad(receiver, home_object, name, pair);
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
break;
}
@ -2321,7 +2322,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
Node* key = environment()->Pop();
Node* home_object = environment()->Pop();
Node* receiver = environment()->Pop();
value = BuildKeyedSuperLoad(receiver, home_object, key, slot);
value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
break;
}
@ -2343,12 +2344,11 @@ void AstGraphBuilder::VisitCall(Call* expr) {
switch (call_type) {
case Call::GLOBAL_CALL: {
VariableProxy* proxy = callee->AsVariableProxy();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(proxy->VariableFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
callee_value =
BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
slot, OutputFrameStateCombine::Push());
pair, OutputFrameStateCombine::Push());
receiver_value = jsgraph()->UndefinedConstant();
break;
}
@ -2368,8 +2368,8 @@ void AstGraphBuilder::VisitCall(Call* expr) {
}
case Call::PROPERTY_CALL: {
Property* property = callee->AsProperty();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
if (!property->IsSuperAccess()) {
VisitForValue(property->obj());
Node* object = environment()->Top();
@ -2377,14 +2377,14 @@ void AstGraphBuilder::VisitCall(Call* expr) {
if (property->key()->IsPropertyName()) {
FrameStateBeforeAndAfter states(this, property->obj()->id());
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
callee_value = BuildNamedLoad(object, name, slot);
callee_value = BuildNamedLoad(object, name, pair);
states.AddToNode(callee_value, property->LoadId(),
OutputFrameStateCombine::Push());
} else {
VisitForValue(property->key());
FrameStateBeforeAndAfter states(this, property->key()->id());
Node* key = environment()->Pop();
callee_value = BuildKeyedLoad(object, key, slot);
callee_value = BuildKeyedLoad(object, key, pair);
states.AddToNode(callee_value, property->LoadId(),
OutputFrameStateCombine::Push());
}
@ -2405,7 +2405,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
FrameStateBeforeAndAfter states(this, property->obj()->id());
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
callee_value =
BuildNamedSuperLoad(receiver_value, home_object, name, slot);
BuildNamedSuperLoad(receiver_value, home_object, name, pair);
states.AddToNode(callee_value, property->LoadId(),
OutputFrameStateCombine::Push());
@ -2414,7 +2414,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
FrameStateBeforeAndAfter states(this, property->key()->id());
Node* key = environment()->Pop();
callee_value =
BuildKeyedSuperLoad(receiver_value, home_object, key, slot);
BuildKeyedSuperLoad(receiver_value, home_object, key, pair);
states.AddToNode(callee_value, property->LoadId(),
OutputFrameStateCombine::Push());
}
@ -2473,8 +2473,9 @@ void AstGraphBuilder::VisitCall(Call* expr) {
}
// Create node to perform the function call.
const Operator* call =
javascript()->CallFunction(args->length() + 2, flags, language_mode());
VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
const Operator* call = javascript()->CallFunction(args->length() + 2, flags,
language_mode(), feedback);
Node* value = ProcessArguments(call, args->length() + 2);
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
@ -2503,11 +2504,10 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
// before arguments are being evaluated.
CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
Node* receiver_value = BuildLoadBuiltinsObject();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(expr->CallRuntimeFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
// TODO(jarin): bailout ids for runtime calls.
FrameStateBeforeAndAfter states(this, BailoutId::None());
Node* callee_value = BuildNamedLoad(receiver_value, name, slot);
Node* callee_value = BuildNamedLoad(receiver_value, name, pair);
states.AddToNode(callee_value, BailoutId::None(),
OutputFrameStateCombine::Push());
environment()->Push(callee_value);
@ -2585,12 +2585,11 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
switch (assign_type) {
case VARIABLE: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(proxy->VariableFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
old_value =
BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
slot, OutputFrameStateCombine::Push());
pair, OutputFrameStateCombine::Push());
stack_depth = 0;
break;
}
@ -2599,9 +2598,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
FrameStateBeforeAndAfter states(this, property->obj()->id());
Node* object = environment()->Top();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
old_value = BuildNamedLoad(object, name, slot);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildNamedLoad(object, name, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 1;
@ -2613,9 +2612,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
FrameStateBeforeAndAfter states(this, property->key()->id());
Node* key = environment()->Top();
Node* object = environment()->Peek(1);
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
old_value = BuildKeyedLoad(object, key, slot);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildKeyedLoad(object, key, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 2;
@ -2628,9 +2627,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* home_object = environment()->Top();
Node* receiver = environment()->Peek(1);
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
old_value = BuildNamedSuperLoad(receiver, home_object, name, slot);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 2;
@ -2644,9 +2643,9 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* key = environment()->Top();
Node* home_object = environment()->Peek(1);
Node* receiver = environment()->Peek(2);
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(property->PropertyFeedbackSlot());
old_value = BuildKeyedSuperLoad(receiver, home_object, key, slot);
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
states.AddToNode(old_value, property->LoadId(),
OutputFrameStateCombine::Push());
stack_depth = 3;
@ -2680,12 +2679,12 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
}
// Store the value.
ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->CountSlot());
VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
switch (assign_type) {
case VARIABLE: {
Variable* variable = expr->expression()->AsVariableProxy()->var();
environment()->Push(value);
BuildVariableAssignment(variable, value, expr->op(), slot,
BuildVariableAssignment(variable, value, expr->op(), feedback,
expr->AssignmentId(), store_states);
environment()->Pop();
break;
@ -2693,7 +2692,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
case NAMED_PROPERTY: {
Node* object = environment()->Pop();
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store = BuildNamedStore(object, name, value, slot,
Node* store = BuildNamedStore(object, name, value, feedback,
expr->CountStoreFeedbackId());
environment()->Push(value);
store_states.AddToNode(store, expr->AssignmentId(),
@ -2704,7 +2703,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
case KEYED_PROPERTY: {
Node* key = environment()->Pop();
Node* object = environment()->Pop();
Node* store = BuildKeyedStore(object, key, value, slot,
Node* store = BuildKeyedStore(object, key, value, feedback,
expr->CountStoreFeedbackId());
environment()->Push(value);
store_states.AddToNode(store, expr->AssignmentId(),
@ -2927,11 +2926,10 @@ void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
// Typeof does not throw a reference error on global variables, hence we
// perform a non-contextual load in case the operand is a variable proxy.
VariableProxy* proxy = expr->expression()->AsVariableProxy();
ResolvedFeedbackSlot slot =
ResolveFeedbackSlot(proxy->VariableFeedbackSlot());
VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
operand =
BuildVariableLoad(proxy->var(), expr->expression()->id(), states, slot,
BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair,
OutputFrameStateCombine::Push(), NOT_CONTEXTUAL);
} else {
VisitForValue(expr->expression());
@ -2992,10 +2990,9 @@ LanguageMode AstGraphBuilder::language_mode() const {
}
ResolvedFeedbackSlot AstGraphBuilder::ResolveFeedbackSlot(
VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
FeedbackVectorICSlot slot) const {
return ResolvedFeedbackSlot(handle(info()->shared_info()->feedback_vector()),
slot);
return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
}
@ -3146,8 +3143,8 @@ Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
// This should never lazy deopt, so it is fine to send invalid bailout id.
FrameStateBeforeAndAfter states(this, BailoutId::None());
ResolvedFeedbackSlot slot;
BuildVariableAssignment(arguments, object, Token::ASSIGN, slot,
VectorSlotPair feedback;
BuildVariableAssignment(arguments, object, Token::ASSIGN, feedback,
BailoutId::None(), states);
return object;
@ -3166,9 +3163,9 @@ Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) {
DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
// This should never lazy deopt, so it is fine to send invalid bailout id.
FrameStateBeforeAndAfter states(this, BailoutId::None());
ResolvedFeedbackSlot slot;
BuildVariableAssignment(rest, object, Token::ASSIGN, slot, BailoutId::None(),
states);
VectorSlotPair feedback;
BuildVariableAssignment(rest, object, Token::ASSIGN, feedback,
BailoutId::None(), states);
return object;
}
@ -3179,9 +3176,9 @@ Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) {
Node* this_function = GetFunctionClosure();
FrameStateBeforeAndAfter states(this, BailoutId::None());
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST,
slot, BailoutId::None(), states);
feedback, BailoutId::None(), states);
return this_function;
}
@ -3232,7 +3229,7 @@ Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
BailoutId bailout_id,
FrameStateBeforeAndAfter& states,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
OutputFrameStateCombine combine,
ContextualMode contextual_mode) {
Node* the_hole = jsgraph()->TheHoleConstant();
@ -3367,7 +3364,7 @@ Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
Node* AstGraphBuilder::BuildVariableAssignment(
Variable* variable, Node* value, Token::Value op,
const ResolvedFeedbackSlot& slot, BailoutId bailout_id,
const VectorSlotPair& feedback, BailoutId bailout_id,
FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
@ -3376,8 +3373,8 @@ Node* AstGraphBuilder::BuildVariableAssignment(
// Global var, const, or let variable.
Node* global = BuildLoadGlobalObject();
Handle<Name> name = variable->name();
Node* store =
BuildNamedStore(global, name, value, slot, TypeFeedbackId::None());
Node* store = BuildNamedStore(global, name, value, feedback,
TypeFeedbackId::None());
states.AddToNode(store, bailout_id, combine);
return store;
}
@ -3492,7 +3489,7 @@ static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node,
Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
const ResolvedFeedbackSlot& feedback) {
const VectorSlotPair& feedback) {
const Operator* op = javascript()->LoadProperty(feedback);
return Record(js_type_feedback_,
NewNode(op, object, key, GetFeedbackVector()), feedback.slot());
@ -3500,7 +3497,7 @@ Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode) {
const Operator* op =
javascript()->LoadNamed(MakeUnique(name), feedback, mode);
@ -3510,7 +3507,7 @@ Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
TypeFeedbackId id) {
const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
return Record(js_type_feedback_, NewNode(op, object, key, value), id);
@ -3519,7 +3516,7 @@ Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
Node* value,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
TypeFeedbackId id) {
const Operator* op =
javascript()->StoreNamed(language_mode(), MakeUnique(name), feedback);
@ -3527,9 +3524,9 @@ Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
}
Node* AstGraphBuilder::BuildNamedSuperLoad(
Node* receiver, Node* home_object, Handle<Name> name,
const ResolvedFeedbackSlot& feedback) {
Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
Handle<Name> name,
const VectorSlotPair& feedback) {
Node* name_node = jsgraph()->Constant(name);
const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, name_node);
@ -3537,9 +3534,9 @@ Node* AstGraphBuilder::BuildNamedSuperLoad(
}
Node* AstGraphBuilder::BuildKeyedSuperLoad(
Node* receiver, Node* home_object, Node* key,
const ResolvedFeedbackSlot& feedback) {
Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
Node* key,
const VectorSlotPair& feedback) {
const Operator* op =
javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
Node* value = NewNode(op, receiver, home_object, key);
@ -3668,12 +3665,12 @@ Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) {
Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
Expression* expr,
const ResolvedFeedbackSlot& slot) {
const VectorSlotPair& feedback) {
if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
Handle<Name> name = isolate()->factory()->home_object_symbol();
FrameStateBeforeAndAfter states(this, BailoutId::None());
Node* store =
BuildNamedStore(value, name, home_object, slot, TypeFeedbackId::None());
Node* store = BuildNamedStore(value, name, home_object, feedback,
TypeFeedbackId::None());
states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
return store;
}

View File

@ -236,9 +236,8 @@ class AstGraphBuilder : public AstVisitor {
Node** EnsureInputBufferSize(int size);
// Named and keyed loads require a ResolvedFeedbackSlot for successful
// lowering.
ResolvedFeedbackSlot ResolveFeedbackSlot(FeedbackVectorICSlot slot) const;
// Named and keyed loads require a VectorSlotPair for successful lowering.
VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const;
// Determine which contexts need to be checked for extension objects that
// might shadow the optimistic declaration of dynamic lookup variables.
@ -269,8 +268,7 @@ class AstGraphBuilder : public AstVisitor {
// Builders for variable load and assignment.
Node* BuildVariableAssignment(Variable* variable, Node* value,
Token::Value op,
const ResolvedFeedbackSlot& slot,
Token::Value op, const VectorSlotPair& slot,
BailoutId bailout_id,
FrameStateBeforeAndAfter& states,
OutputFrameStateCombine framestate_combine =
@ -279,22 +277,20 @@ class AstGraphBuilder : public AstVisitor {
OutputFrameStateCombine framestate_combine);
Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id,
FrameStateBeforeAndAfter& states,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
OutputFrameStateCombine framestate_combine,
ContextualMode mode = CONTEXTUAL);
// Builders for property loads and stores.
Node* BuildKeyedLoad(Node* receiver, Node* key,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode = NOT_CONTEXTUAL);
Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
const ResolvedFeedbackSlot& feedback,
TypeFeedbackId id);
const VectorSlotPair& feedback, TypeFeedbackId id);
Node* BuildNamedStore(Node* receiver, Handle<Name>, Node* value,
const ResolvedFeedbackSlot& feedback,
TypeFeedbackId id);
const VectorSlotPair& feedback, TypeFeedbackId id);
// Builders for super property loads and stores.
Node* BuildKeyedSuperStore(Node* receiver, Node* home_object, Node* key,
@ -302,10 +298,9 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildNamedSuperStore(Node* receiver, Node* home_object,
Handle<Name> name, Node* value, TypeFeedbackId id);
Node* BuildNamedSuperLoad(Node* receiver, Node* home_object,
Handle<Name> name,
const ResolvedFeedbackSlot& feedback);
Handle<Name> name, const VectorSlotPair& feedback);
Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
// Builders for accessing the function context.
Node* BuildLoadBuiltinsObject();
@ -326,7 +321,7 @@ class AstGraphBuilder : public AstVisitor {
// Builder for adding the [[HomeObject]] to a value if the value came from a
// function literal and needs a home object. Do nothing otherwise.
Node* BuildSetHomeObject(Node* value, Node* home_object, Expression* expr,
const ResolvedFeedbackSlot& slot);
const VectorSlotPair& feedback);
// Builders for error reporting at runtime.
Node* BuildThrowError(Node* exception, BailoutId bailout_id);
@ -392,7 +387,7 @@ class AstGraphBuilder : public AstVisitor {
// Dispatched from VisitForInStatement.
void VisitForInAssignment(Expression* expr, Node* value,
const ResolvedFeedbackSlot& slot,
const VectorSlotPair& feedback,
BailoutId bailout_id);
// Dispatched from VisitClassLiteral.

View File

@ -14,6 +14,21 @@ namespace v8 {
namespace internal {
namespace compiler {
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
return lhs.slot() == rhs.slot() && lhs.vector() == rhs.vector();
}
bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(VectorSlotPair const& p) {
return base::hash_combine(p.slot(), p.vector());
}
std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
return os << p.arity() << ", " << p.flags() << ", " << p.language_mode();
}
@ -93,7 +108,7 @@ ContextAccess const& ContextAccessOf(Operator const* op) {
DynamicGlobalAccess::DynamicGlobalAccess(const Handle<String>& name,
uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode)
: name_(name),
check_bitset_(check_bitset),
@ -175,18 +190,6 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const* op) {
}
bool operator==(ResolvedFeedbackSlot const& lhs,
ResolvedFeedbackSlot const& rhs) {
return lhs.slot().ToInt() == rhs.slot().ToInt();
}
size_t hash_value(ResolvedFeedbackSlot const& p) {
base::hash<int> h;
return h(p.slot().ToInt());
}
bool operator==(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
@ -452,10 +455,10 @@ CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
#undef CACHED_WITH_LANGUAGE_MODE
const Operator* JSOperatorBuilder::CallFunction(size_t arity,
CallFunctionFlags flags,
LanguageMode language_mode) {
CallFunctionParameters parameters(arity, flags, language_mode);
const Operator* JSOperatorBuilder::CallFunction(
size_t arity, CallFunctionFlags flags, LanguageMode language_mode,
VectorSlotPair const& feedback) {
CallFunctionParameters parameters(arity, flags, language_mode, feedback);
return new (zone()) Operator1<CallFunctionParameters>( // --
IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode
"JSCallFunction", // name
@ -486,9 +489,9 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
}
const Operator* JSOperatorBuilder::LoadNamed(
const Unique<Name>& name, const ResolvedFeedbackSlot& feedback,
ContextualMode contextual_mode) {
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
@ -499,7 +502,7 @@ const Operator* JSOperatorBuilder::LoadNamed(
const Operator* JSOperatorBuilder::LoadProperty(
const ResolvedFeedbackSlot& feedback) {
const VectorSlotPair& feedback) {
LoadPropertyParameters parameters(feedback);
return new (zone()) Operator1<LoadPropertyParameters>( // --
IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
@ -509,9 +512,9 @@ const Operator* JSOperatorBuilder::LoadProperty(
}
const Operator* JSOperatorBuilder::StoreNamed(
LanguageMode language_mode, const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback) {
const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
const Unique<Name>& name,
const VectorSlotPair& feedback) {
StoreNamedParameters parameters(language_mode, feedback, name);
return new (zone()) Operator1<StoreNamedParameters>( // --
IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
@ -522,7 +525,7 @@ const Operator* JSOperatorBuilder::StoreNamed(
const Operator* JSOperatorBuilder::StoreProperty(
LanguageMode language_mode, const ResolvedFeedbackSlot& feedback) {
LanguageMode language_mode, const VectorSlotPair& feedback) {
StorePropertyParameters parameters(language_mode, feedback);
return new (zone()) Operator1<StorePropertyParameters>( // --
IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode
@ -566,7 +569,7 @@ const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
const Operator* JSOperatorBuilder::LoadDynamicGlobal(
const Handle<String>& name, uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback, ContextualMode mode) {
const VectorSlotPair& feedback, ContextualMode mode) {
DynamicGlobalAccess access(name, check_bitset, feedback, mode);
return new (zone()) Operator1<DynamicGlobalAccess>( // --
IrOpcode::kJSLoadDynamicGlobal, Operator::kNoProperties, // opcode

View File

@ -17,23 +17,56 @@ class Operator;
struct JSOperatorGlobalCache;
// Defines a pair of {TypeFeedbackVector} and {TypeFeedbackVectorICSlot}, which
// is used to access the type feedback for a certain {Node}.
class VectorSlotPair {
public:
VectorSlotPair() : slot_(FeedbackVectorICSlot::Invalid()) {}
VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
: vector_(vector), slot_(slot) {}
bool IsValid() const { return !vector_.is_null(); }
MaybeHandle<TypeFeedbackVector> vector() const { return vector_; }
FeedbackVectorICSlot slot() const { return slot_; }
int index() const {
Handle<TypeFeedbackVector> vector;
return vector_.ToHandle(&vector) ? vector->GetIndex(slot_) : -1;
}
private:
const MaybeHandle<TypeFeedbackVector> vector_;
const FeedbackVectorICSlot slot_;
};
bool operator==(VectorSlotPair const&, VectorSlotPair const&);
bool operator!=(VectorSlotPair const&, VectorSlotPair const&);
size_t hash_value(VectorSlotPair const&);
// Defines the arity and the call flags for a JavaScript function call. This is
// used as a parameter by JSCallFunction operators.
class CallFunctionParameters final {
public:
CallFunctionParameters(size_t arity, CallFunctionFlags flags,
LanguageMode language_mode)
LanguageMode language_mode,
VectorSlotPair const& feedback)
: bit_field_(ArityField::encode(arity) | FlagsField::encode(flags) |
LanguageModeField::encode(language_mode)) {}
LanguageModeField::encode(language_mode)),
feedback_(feedback) {}
size_t arity() const { return ArityField::decode(bit_field_); }
CallFunctionFlags flags() const { return FlagsField::decode(bit_field_); }
LanguageMode language_mode() const {
return LanguageModeField::decode(bit_field_);
}
VectorSlotPair const& feedback() const { return feedback_; }
bool operator==(CallFunctionParameters const& that) const {
return this->bit_field_ == that.bit_field_;
return this->bit_field_ == that.bit_field_ &&
this->feedback_ == that.feedback_;
}
bool operator!=(CallFunctionParameters const& that) const {
return !(*this == that);
@ -41,7 +74,7 @@ class CallFunctionParameters final {
private:
friend size_t hash_value(CallFunctionParameters const& p) {
return p.bit_field_;
return base::hash_combine(p.bit_field_, p.feedback_);
}
typedef BitField<size_t, 0, 28> ArityField;
@ -49,6 +82,7 @@ class CallFunctionParameters final {
typedef BitField<LanguageMode, 30, 2> LanguageModeField;
const uint32_t bit_field_;
const VectorSlotPair feedback_;
};
size_t hash_value(CallFunctionParameters const&);
@ -112,42 +146,17 @@ std::ostream& operator<<(std::ostream&, ContextAccess const&);
ContextAccess const& ContextAccessOf(Operator const*);
// A ResolvedFeedbackSlot needs to query the type feedback vector to get it's
// index in the vector.
class ResolvedFeedbackSlot {
public:
ResolvedFeedbackSlot(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot)
: slot_(slot),
index_(slot == FeedbackVectorICSlot::Invalid() ? -1 : vector->GetIndex(
slot)) {}
ResolvedFeedbackSlot() : slot_(FeedbackVectorICSlot::Invalid()), index_(-1) {}
FeedbackVectorICSlot slot() const { return slot_; }
int index() const { return index_; }
private:
const FeedbackVectorICSlot slot_;
const int index_;
};
bool operator==(ResolvedFeedbackSlot const& lhs,
ResolvedFeedbackSlot const& rhs);
// Defines the name for a dynamic variable lookup. The {check_bitset} allows to
// inline checks whether the lookup yields in a global variable. This is used as
// a parameter by JSLoadDynamicGlobal and JSStoreDynamicGlobal operators.
class DynamicGlobalAccess final {
public:
DynamicGlobalAccess(const Handle<String>& name, uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback,
ContextualMode mode);
const VectorSlotPair& feedback, ContextualMode mode);
const Handle<String>& name() const { return name_; }
uint32_t check_bitset() const { return check_bitset_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
const VectorSlotPair& feedback() const { return feedback_; }
ContextualMode mode() const { return mode_; }
// Indicates that an inline check is disabled.
@ -164,7 +173,7 @@ class DynamicGlobalAccess final {
private:
const Handle<String> name_;
const uint32_t check_bitset_;
const ResolvedFeedbackSlot feedback_;
const VectorSlotPair feedback_;
const ContextualMode mode_;
};
@ -221,19 +230,18 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const*);
// used as a parameter by JSLoadNamed operators.
class LoadNamedParameters final {
public:
LoadNamedParameters(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
ContextualMode contextual_mode)
: name_(name), feedback_(feedback), contextual_mode_(contextual_mode) {}
const Unique<Name>& name() const { return name_; }
ContextualMode contextual_mode() const { return contextual_mode_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const Unique<Name> name_;
const ResolvedFeedbackSlot feedback_;
const VectorSlotPair feedback_;
const ContextualMode contextual_mode_;
};
@ -251,13 +259,13 @@ const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
// used as a parameter by JSLoadProperty operators.
class LoadPropertyParameters final {
public:
explicit LoadPropertyParameters(const ResolvedFeedbackSlot& feedback)
explicit LoadPropertyParameters(const VectorSlotPair& feedback)
: feedback_(feedback) {}
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const ResolvedFeedbackSlot feedback_;
const VectorSlotPair feedback_;
};
bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
@ -275,18 +283,17 @@ const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
class StoreNamedParameters final {
public:
StoreNamedParameters(LanguageMode language_mode,
const ResolvedFeedbackSlot& feedback,
const Unique<Name>& name)
const VectorSlotPair& feedback, const Unique<Name>& name)
: language_mode_(language_mode), name_(name), feedback_(feedback) {}
LanguageMode language_mode() const { return language_mode_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
const VectorSlotPair& feedback() const { return feedback_; }
const Unique<Name>& name() const { return name_; }
private:
const LanguageMode language_mode_;
const Unique<Name> name_;
const ResolvedFeedbackSlot feedback_;
const VectorSlotPair feedback_;
};
bool operator==(StoreNamedParameters const&, StoreNamedParameters const&);
@ -304,15 +311,15 @@ const StoreNamedParameters& StoreNamedParametersOf(const Operator* op);
class StorePropertyParameters final {
public:
StorePropertyParameters(LanguageMode language_mode,
const ResolvedFeedbackSlot& feedback)
const VectorSlotPair& feedback)
: language_mode_(language_mode), feedback_(feedback) {}
LanguageMode language_mode() const { return language_mode_; }
const ResolvedFeedbackSlot& feedback() const { return feedback_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const LanguageMode language_mode_;
const ResolvedFeedbackSlot feedback_;
const VectorSlotPair feedback_;
};
bool operator==(StorePropertyParameters const&, StorePropertyParameters const&);
@ -392,22 +399,23 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* CreateLiteralArray(int literal_flags);
const Operator* CreateLiteralObject(int literal_flags);
const Operator* CallFunction(size_t arity, CallFunctionFlags flags,
LanguageMode language_mode);
const Operator* CallFunction(
size_t arity, CallFunctionFlags flags, LanguageMode language_mode,
VectorSlotPair const& feedback = VectorSlotPair());
const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
const Operator* CallConstruct(int arguments);
const Operator* LoadProperty(const ResolvedFeedbackSlot& feedback);
const Operator* LoadProperty(const VectorSlotPair& feedback);
const Operator* LoadNamed(const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode contextual_mode = NOT_CONTEXTUAL);
const Operator* StoreProperty(LanguageMode language_mode,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
const Operator* StoreNamed(LanguageMode language_mode,
const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
const Operator* DeleteProperty(LanguageMode language_mode);
@ -418,7 +426,7 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* LoadDynamicGlobal(const Handle<String>& name,
uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode);
const Operator* LoadDynamicContext(const Handle<String>& name,
uint32_t check_bitset, size_t depth,

View File

@ -9,7 +9,6 @@
namespace v8 {
namespace internal {
int HandleScope::NumberOfHandles(Isolate* isolate) {
HandleScopeImplementer* impl = isolate->handle_scope_implementer();
int n = impl->blocks()->length();

View File

@ -66,14 +66,32 @@ class MaybeHandle {
bool is_null() const { return location_ == NULL; }
template <typename S>
bool operator==(MaybeHandle<S> that) const {
return this->location_ == that.location_;
}
template <typename S>
bool operator!=(MaybeHandle<S> that) const {
return !(*this == that);
}
protected:
T** location_;
// MaybeHandles of different classes are allowed to access each
// other's location_.
template<class S> friend class MaybeHandle;
template <typename S>
friend size_t hash_value(MaybeHandle<S>);
};
template <typename S>
inline size_t hash_value(MaybeHandle<S> maybe_handle) {
return bit_cast<size_t>(maybe_handle.location_);
}
// ----------------------------------------------------------------------------
// A Handle provides a reference to an object that survives relocation by
// the garbage collector.

View File

@ -1047,17 +1047,19 @@ template <int dummy_parameter>
class VectorSlot {
public:
explicit VectorSlot(int id) : id_(id) {}
int ToInt() const { return id_; }
static VectorSlot Invalid() { return VectorSlot(kInvalidSlot); }
bool IsInvalid() const { return id_ == kInvalidSlot; }
VectorSlot next() const {
DCHECK(id_ != kInvalidSlot);
DCHECK_NE(kInvalidSlot, id_);
return VectorSlot(id_ + 1);
}
bool operator==(const VectorSlot& other) const { return id_ == other.id_; }
bool operator==(VectorSlot that) const { return this->id_ == that.id_; }
bool operator!=(VectorSlot that) const { return !(*this == that); }
private:
static const int kInvalidSlot = -1;
@ -1066,6 +1068,12 @@ class VectorSlot {
};
template <int dummy_parameter>
size_t hash_value(VectorSlot<dummy_parameter> slot) {
return slot.ToInt();
}
typedef VectorSlot<0> FeedbackVectorSlot;
typedef VectorSlot<1> FeedbackVectorICSlot;

View File

@ -77,7 +77,7 @@ class JSTypeFeedbackTest : public TypedGraphTest {
Node* ReturnLoadNamedFromGlobal(
const char* string, Node* effect, Node* control,
JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();

View File

@ -648,7 +648,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
@ -687,7 +687,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
@ -739,9 +739,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
@ -787,9 +787,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
@ -848,9 +848,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
@ -884,7 +884,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
IsNumberConstant(IsNaN()) // --
};
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
@ -914,7 +914,7 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) {
Node* const effect = graph()->start();
Node* const control = graph()->start();
Handle<String> name = factory()->object_string();
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
uint32_t bitset = 1 << i; // Only single check.
Reduction r = Reduce(graph()->NewNode(