Commit b83c3d29 authored by mvstanton's avatar mvstanton Committed by Commit bot

[TypeFeedbackVector] DeclareGlobals needs a literals array

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@{#42408}
parent c5948b98
...@@ -933,6 +933,7 @@ void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { ...@@ -933,6 +933,7 @@ void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate()));
globals()->push_back(isolate()->factory()->undefined_value()); globals()->push_back(isolate()->factory()->undefined_value());
globals()->push_back(isolate()->factory()->undefined_value());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -958,6 +959,12 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { ...@@ -958,6 +959,12 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); 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); globals()->push_back(function);
break; break;
} }
......
...@@ -11789,6 +11789,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration( ...@@ -11789,6 +11789,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_.Add(isolate()->factory()->undefined_value(), zone()); globals_.Add(isolate()->factory()->undefined_value(), zone());
globals_.Add(isolate()->factory()->undefined_value(), zone());
return; return;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -11813,6 +11814,12 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration( ...@@ -11813,6 +11814,12 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_.Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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( Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
declaration->fun(), current_info()->script(), top_info()); declaration->fun(), current_info()->script(), top_info());
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -761,6 +761,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -761,6 +761,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -785,6 +786,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -785,6 +786,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -756,6 +756,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -756,6 +756,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -780,6 +781,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -780,6 +781,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack overflow exception. // Check for stack overflow exception.
......
...@@ -709,6 +709,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -709,6 +709,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -733,6 +734,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -733,6 +734,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -784,6 +785,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -784,6 +785,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -760,6 +760,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -784,6 +785,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -784,6 +785,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -723,6 +723,7 @@ void FullCodeGenerator::VisitVariableDeclaration( ...@@ -723,6 +723,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone()); globals_->Add(isolate()->factory()->undefined_value(), zone());
globals_->Add(isolate()->factory()->undefined_value(), zone());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -747,6 +748,12 @@ void FullCodeGenerator::VisitFunctionDeclaration( ...@@ -747,6 +748,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 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 = Handle<SharedFunctionInfo> function =
Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
// Check for stack-overflow exception. // Check for stack-overflow exception.
......
...@@ -498,9 +498,10 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -498,9 +498,10 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
has_constant_pool_entry_(false) {} has_constant_pool_entry_(false) {}
void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot,
FeedbackVectorSlot literal_slot,
FunctionLiteral* func) { FunctionLiteral* func) {
DCHECK(!slot.IsInvalid()); 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) { void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) {
...@@ -512,7 +513,7 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -512,7 +513,7 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
DCHECK(has_constant_pool_entry_); DCHECK(has_constant_pool_entry_);
int array_index = 0; int array_index = 0;
Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( 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_) { for (const Declaration& declaration : declarations_) {
FunctionLiteral* func = declaration.func; FunctionLiteral* func = declaration.func;
Handle<Object> initial_value; Handle<Object> initial_value;
...@@ -529,6 +530,14 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -529,6 +530,14 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
data->set(array_index++, *declaration.name); data->set(array_index++, *declaration.name);
data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); 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); data->set(array_index++, *initial_value);
} }
return data; return data;
...@@ -551,12 +560,19 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -551,12 +560,19 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
private: private:
struct Declaration { struct Declaration {
Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} 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, Declaration(Handle<String> name, FeedbackVectorSlot slot,
FunctionLiteral* func) FunctionLiteral* func)
: name(name), slot(slot), func(func) {} : name(name),
slot(slot),
literal_slot(FeedbackVectorSlot::Invalid()),
func(func) {}
Handle<String> name; Handle<String> name;
FeedbackVectorSlot slot; FeedbackVectorSlot slot;
FeedbackVectorSlot literal_slot;
FunctionLiteral* func; FunctionLiteral* func;
}; };
ZoneVector<Declaration> declarations_; ZoneVector<Declaration> declarations_;
...@@ -889,8 +905,9 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { ...@@ -889,8 +905,9 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
switch (variable->location()) { switch (variable->location()) {
case VariableLocation::UNALLOCATED: { case VariableLocation::UNALLOCATED: {
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
globals_builder()->AddFunctionDeclaration(variable->name(), slot, globals_builder()->AddFunctionDeclaration(
decl->fun()); variable->name(), slot, decl->fun()->LiteralFeedbackSlot(),
decl->fun());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
......
...@@ -137,10 +137,11 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, ...@@ -137,10 +137,11 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
// Traverse the name/value pairs and set the properties. // Traverse the name/value pairs and set the properties.
int length = declarations->length(); 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); Handle<String> name(String::cast(declarations->get(i)), isolate);
FeedbackVectorSlot slot(Smi::cast(declarations->get(i + 1))->value()); FeedbackVectorSlot slot(Smi::cast(declarations->get(i + 1))->value());
Handle<Object> initial_value(declarations->get(i + 2), isolate); Handle<Object> possibly_literal_slot(declarations->get(i + 2), isolate);
Handle<Object> initial_value(declarations->get(i + 3), isolate);
bool is_var = initial_value->IsUndefined(isolate); bool is_var = initial_value->IsUndefined(isolate);
bool is_function = initial_value->IsSharedFunctionInfo(); bool is_function = initial_value->IsSharedFunctionInfo();
...@@ -148,12 +149,17 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, ...@@ -148,12 +149,17 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
Handle<Object> value; Handle<Object> value;
if (is_function) { if (is_function) {
DCHECK(possibly_literal_slot->IsSmi());
// Copy the function and update its context. Use it as value. // Copy the function and update its context. Use it as value.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>::cast(initial_value); Handle<SharedFunctionInfo>::cast(initial_value);
FeedbackVectorSlot literals_slot(
Smi::cast(*possibly_literal_slot)->value());
Handle<LiteralsArray> literals(
LiteralsArray::cast(feedback_vector->Get(literals_slot)), isolate);
Handle<JSFunction> function = Handle<JSFunction> function =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, isolate->factory()->NewFunctionFromSharedFunctionInfo(
TENURED); shared, context, literals, TENURED);
value = function; value = function;
} else { } else {
value = isolate->factory()->undefined_value(); value = isolate->factory()->undefined_value();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment