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) {
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:
......@@ -958,6 +959,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;
}
......
......@@ -11789,6 +11789,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:
......@@ -11813,6 +11814,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.
......
......@@ -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:
......@@ -785,6 +786,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.
......
......@@ -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:
......@@ -780,6 +781,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.
......
......@@ -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:
......@@ -733,6 +734,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.
......
......@@ -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:
......@@ -784,6 +785,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.
......
......@@ -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:
......@@ -784,6 +785,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.
......
......@@ -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:
......@@ -747,6 +748,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.
......
......@@ -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:
......
......@@ -137,10 +137,11 @@ 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> 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_function = initial_value->IsSharedFunctionInfo();
......@@ -148,12 +149,17 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
Handle<Object> value;
if (is_function) {
DCHECK(possibly_literal_slot->IsSmi());
// Copy the function and update its context. Use it as value.
Handle<SharedFunctionInfo> shared =
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 =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
TENURED);
isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared, context, literals, TENURED);
value = function;
} else {
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