[TypeFeedbackVector] DeclareGlobals needs a literals array

[RELAND with one change: until literal arrays are rooted in the outer
feedback vector (coming in the next days), the runtime-scope.cc change
is held off.]

When a function is declared in global scope, the closure is created
by the DeclareGlobals runtime service. It needs a pointer to the
literals array, already allocated in the feedback vector. This
fixes a bug where it's behavior wasn't in sync with CreateClosure,
which accepts the literals from the vector.

This enables a follow-on performance improvement in the CompileLazy
builtin.

BUG=680637

Review-Url: https://codereview.chromium.org/2634283003
Cr-Commit-Position: refs/heads/master@{#42620}
This commit is contained in:
mvstanton 2017-01-24 00:46:40 -08:00 committed by Commit bot
parent 09163d71bd
commit d287c81969
10 changed files with 80 additions and 7 deletions

View File

@ -933,6 +933,7 @@ void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
DCHECK(!slot.IsInvalid());
globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
globals()->push_back(isolate()->factory()->undefined_value());
globals()->push_back(isolate()->factory()->undefined_value());
break;
}
case VariableLocation::PARAMETER:
@ -968,6 +969,12 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
// We need the slot where the literals array lives, too.
slot = decl->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
globals()->push_back(function);
break;
}

View File

@ -11848,6 +11848,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_.Add(isolate()->factory()->undefined_value(), zone());
globals_.Add(isolate()->factory()->undefined_value(), zone());
return;
}
case VariableLocation::PARAMETER:
@ -11886,6 +11887,12 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
declaration->fun(), current_info()->script(), top_info());
// Check for stack-overflow exception.

View File

@ -761,6 +761,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -800,6 +801,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.

View File

@ -756,6 +756,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -795,6 +796,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack overflow exception.

View File

@ -709,6 +709,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -748,6 +749,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.

View File

@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -799,6 +800,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.

View File

@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -799,6 +800,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.

View File

@ -723,6 +723,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break;
}
case VariableLocation::PARAMETER:
@ -762,6 +763,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
// We need the slot where the literals array lives, too.
slot = declaration->fun()->LiteralFeedbackSlot();
DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception.

View File

@ -498,9 +498,10 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
has_constant_pool_entry_(false) {}
void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot,
FeedbackVectorSlot literal_slot,
FunctionLiteral* func) {
DCHECK(!slot.IsInvalid());
declarations_.push_back(Declaration(name, slot, func));
declarations_.push_back(Declaration(name, slot, literal_slot, func));
}
void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) {
@ -512,7 +513,7 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
DCHECK(has_constant_pool_entry_);
int array_index = 0;
Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray(
static_cast<int>(declarations_.size() * 3), TENURED);
static_cast<int>(declarations_.size() * 4), TENURED);
for (const Declaration& declaration : declarations_) {
FunctionLiteral* func = declaration.func;
Handle<Object> initial_value;
@ -529,6 +530,14 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
data->set(array_index++, *declaration.name);
data->set(array_index++, Smi::FromInt(declaration.slot.ToInt()));
Object* undefined_or_literal_slot;
if (declaration.literal_slot.IsInvalid()) {
undefined_or_literal_slot = info->isolate()->heap()->undefined_value();
} else {
undefined_or_literal_slot =
Smi::FromInt(declaration.literal_slot.ToInt());
}
data->set(array_index++, undefined_or_literal_slot);
data->set(array_index++, *initial_value);
}
return data;
@ -551,12 +560,19 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
private:
struct Declaration {
Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {}
Declaration(Handle<String> name, FeedbackVectorSlot slot,
FeedbackVectorSlot literal_slot, FunctionLiteral* func)
: name(name), slot(slot), literal_slot(literal_slot), func(func) {}
Declaration(Handle<String> name, FeedbackVectorSlot slot,
FunctionLiteral* func)
: name(name), slot(slot), func(func) {}
: name(name),
slot(slot),
literal_slot(FeedbackVectorSlot::Invalid()),
func(func) {}
Handle<String> name;
FeedbackVectorSlot slot;
FeedbackVectorSlot literal_slot;
FunctionLiteral* func;
};
ZoneVector<Declaration> declarations_;
@ -889,8 +905,9 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
switch (variable->location()) {
case VariableLocation::UNALLOCATED: {
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
globals_builder()->AddFunctionDeclaration(variable->name(), slot,
decl->fun());
globals_builder()->AddFunctionDeclaration(
variable->name(), slot, decl->fun()->LiteralFeedbackSlot(),
decl->fun());
break;
}
case VariableLocation::PARAMETER:

View File

@ -137,10 +137,10 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
// Traverse the name/value pairs and set the properties.
int length = declarations->length();
FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 3, {
FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 4, {
Handle<String> name(String::cast(declarations->get(i)), isolate);
FeedbackVectorSlot slot(Smi::cast(declarations->get(i + 1))->value());
Handle<Object> initial_value(declarations->get(i + 2), isolate);
Handle<Object> initial_value(declarations->get(i + 3), isolate);
bool is_var = initial_value->IsUndefined(isolate);
bool is_function = initial_value->IsSharedFunctionInfo();