Commit 437cf794 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Move SharedFunctionInfo creation to finalization step.

Moves the creation of SharedFunctionInfo for function literals to the
finalization step. This is required for bytecode generation to be
performed off-thread.

BUG=v8:5203

Review-Url: https://codereview.chromium.org/2179303005
Cr-Commit-Position: refs/heads/master@{#38309}
parent b947fff8
...@@ -329,9 +329,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( ...@@ -329,9 +329,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
return *this; return *this;
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry,
Handle<SharedFunctionInfo> shared_info, int flags) { int flags) {
size_t entry = GetConstantPoolEntry(shared_info);
Output(Bytecode::kCreateClosure, UnsignedOperand(entry), Output(Bytecode::kCreateClosure, UnsignedOperand(entry),
UnsignedOperand(flags)); UnsignedOperand(flags));
return *this; return *this;
......
...@@ -131,9 +131,9 @@ class BytecodeArrayBuilder final : public ZoneObject { ...@@ -131,9 +131,9 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& StoreLookupSlot(const Handle<String> name, BytecodeArrayBuilder& StoreLookupSlot(const Handle<String> name,
LanguageMode language_mode); LanguageMode language_mode);
// Create a new closure for the SharedFunctionInfo. // Create a new closure for a SharedFunctionInfo which will be inserted at
BytecodeArrayBuilder& CreateClosure(Handle<SharedFunctionInfo> shared_info, // constant pool index |entry|.
int flags); BytecodeArrayBuilder& CreateClosure(size_t entry, int flags);
// Create a new context with size |slots|. // Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots); BytecodeArrayBuilder& CreateFunctionContext(int slots);
......
...@@ -540,25 +540,44 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -540,25 +540,44 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
public: public:
GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone) GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone)
: isolate_(isolate), : isolate_(isolate),
declaration_pairs_(0, zone), declarations_(0, zone),
constant_pool_entry_(0), constant_pool_entry_(0),
has_constant_pool_entry_(false) {} has_constant_pool_entry_(false) {}
void AddDeclaration(FeedbackVectorSlot slot, Handle<Object> initial_value) { void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) {
DCHECK(!slot.IsInvalid()); DCHECK(!slot.IsInvalid());
declaration_pairs_.push_back(handle(Smi::FromInt(slot.ToInt()), isolate_)); declarations_.push_back(std::make_pair(slot, func));
declaration_pairs_.push_back(initial_value);
} }
Handle<FixedArray> AllocateDeclarationPairs() { void AddUndefinedDeclaration(FeedbackVectorSlot slot) {
DCHECK(!slot.IsInvalid());
declarations_.push_back(std::make_pair(slot, nullptr));
}
Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) {
DCHECK(has_constant_pool_entry_); DCHECK(has_constant_pool_entry_);
int array_index = 0; int array_index = 0;
Handle<FixedArray> data = isolate_->factory()->NewFixedArray( Handle<FixedArray> pairs = isolate_->factory()->NewFixedArray(
static_cast<int>(declaration_pairs_.size()), TENURED); static_cast<int>(declarations_.size() * 2), TENURED);
for (Handle<Object> obj : declaration_pairs_) { for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration :
data->set(array_index++, *obj); declarations_) {
FunctionLiteral* func = declaration.second;
Handle<Object> initial_value;
if (func == nullptr) {
initial_value = isolate_->factory()->undefined_value();
} else {
initial_value =
Compiler::GetSharedFunctionInfo(func, info->script(), info);
}
// Return a null handle if any initial values can't be created. Caller
// will set stack overflow.
if (initial_value.is_null()) return Handle<FixedArray>();
pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt()));
pairs->set(array_index++, *initial_value);
} }
return data; return pairs;
} }
size_t constant_pool_entry() { size_t constant_pool_entry() {
...@@ -573,11 +592,11 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { ...@@ -573,11 +592,11 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
has_constant_pool_entry_ = true; has_constant_pool_entry_ = true;
} }
bool empty() { return declaration_pairs_.empty(); } bool empty() { return declarations_.empty(); }
private: private:
Isolate* isolate_; Isolate* isolate_;
ZoneVector<Handle<Object>> declaration_pairs_; ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_;
size_t constant_pool_entry_; size_t constant_pool_entry_;
bool has_constant_pool_entry_; bool has_constant_pool_entry_;
}; };
...@@ -595,6 +614,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) ...@@ -595,6 +614,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(), globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(),
info->zone())), info->zone())),
global_declarations_(0, info->zone()), global_declarations_(0, info->zone()),
function_literals_(0, info->zone()),
native_function_literals_(0, info->zone()),
execution_control_(nullptr), execution_control_(nullptr),
execution_context_(nullptr), execution_context_(nullptr),
execution_result_(nullptr), execution_result_(nullptr),
...@@ -607,16 +628,39 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) ...@@ -607,16 +628,39 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
GenerateBytecode(); GenerateBytecode();
FinalizeBytecode();
return builder()->ToBytecodeArray();
}
void BytecodeGenerator::FinalizeBytecode() {
// Build global declaration pair arrays. // Build global declaration pair arrays.
for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
Handle<FixedArray> declarations = Handle<FixedArray> declarations =
globals_builder->AllocateDeclarationPairs(); globals_builder->AllocateDeclarationPairs(info());
if (declarations.is_null()) return SetStackOverflow();
builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
declarations); declarations);
} }
return builder()->ToBytecodeArray(); // Find or build shared function infos.
for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
FunctionLiteral* expr = literal.first;
Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
if (shared_info.is_null()) return SetStackOverflow();
builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
}
// Find or build shared function infos for the native function templates.
for (std::pair<NativeFunctionLiteral*, size_t> literal :
native_function_literals_) {
NativeFunctionLiteral* expr = literal.first;
Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfoForNative(expr->extension(),
expr->name());
if (shared_info.is_null()) return SetStackOverflow();
builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
}
} }
void BytecodeGenerator::GenerateBytecode() { void BytecodeGenerator::GenerateBytecode() {
...@@ -797,8 +841,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { ...@@ -797,8 +841,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
case VariableLocation::UNALLOCATED: { case VariableLocation::UNALLOCATED: {
DCHECK(!variable->binding_needs_init()); DCHECK(!variable->binding_needs_init());
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
globals_builder()->AddDeclaration( globals_builder()->AddUndefinedDeclaration(slot);
slot, isolate()->factory()->undefined_value());
break; break;
} }
case VariableLocation::LOCAL: case VariableLocation::LOCAL:
...@@ -841,12 +884,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { ...@@ -841,12 +884,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
switch (variable->location()) { switch (variable->location()) {
case VariableLocation::GLOBAL: case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: { case VariableLocation::UNALLOCATED: {
Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
decl->fun(), info()->script(), info());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
globals_builder()->AddDeclaration(slot, function); globals_builder()->AddFunctionDeclaration(slot, decl->fun());
break; break;
} }
case VariableLocation::PARAMETER: case VariableLocation::PARAMETER:
...@@ -1359,15 +1398,11 @@ void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { ...@@ -1359,15 +1398,11 @@ void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
} }
void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
// Find or build a shared function info.
Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
if (shared_info.is_null()) {
return SetStackOverflow();
}
uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(), uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(),
scope()->is_function_scope()); scope()->is_function_scope());
builder()->CreateClosure(shared_info, flags); size_t entry = builder()->AllocateConstantPoolEntry();
builder()->CreateClosure(entry, flags);
function_literals_.push_back(std::make_pair(expr, entry));
execution_result()->SetResultInAccumulator(); execution_result()->SetResultInAccumulator();
} }
...@@ -1509,10 +1544,9 @@ void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( ...@@ -1509,10 +1544,9 @@ void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName(
void BytecodeGenerator::VisitNativeFunctionLiteral( void BytecodeGenerator::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) { NativeFunctionLiteral* expr) {
// Find or build a shared function info for the native function template. size_t entry = builder()->AllocateConstantPoolEntry();
Handle<SharedFunctionInfo> shared_info = builder()->CreateClosure(entry, NOT_TENURED);
Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); native_function_literals_.push_back(std::make_pair(expr, entry));
builder()->CreateClosure(shared_info, NOT_TENURED);
execution_result()->SetResultInAccumulator(); execution_result()->SetResultInAccumulator();
} }
......
...@@ -51,6 +51,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -51,6 +51,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void GenerateBytecode(); void GenerateBytecode();
void GenerateBytecodeBody(); void GenerateBytecodeBody();
void FinalizeBytecode();
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
...@@ -208,6 +209,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -208,6 +209,9 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
Scope* scope_; Scope* scope_;
GlobalDeclarationsBuilder* globals_builder_; GlobalDeclarationsBuilder* globals_builder_;
ZoneVector<GlobalDeclarationsBuilder*> global_declarations_; ZoneVector<GlobalDeclarationsBuilder*> global_declarations_;
ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
native_function_literals_;
ControlScope* execution_control_; ControlScope* execution_control_;
ContextScope* execution_context_; ContextScope* execution_context_;
ExpressionResultScope* execution_result_; ExpressionResultScope* execution_result_;
......
...@@ -99,10 +99,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -99,10 +99,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreLookupSlot(name, LanguageMode::STRICT); .StoreLookupSlot(name, LanguageMode::STRICT);
// Emit closure operations. // Emit closure operations.
Handle<SharedFunctionInfo> shared_info = factory->NewSharedFunctionInfo( builder.CreateClosure(0, NOT_TENURED);
factory->NewStringFromStaticChars("function_a"), MaybeHandle<Code>(),
false);
builder.CreateClosure(shared_info, NOT_TENURED);
// Emit create context operation. // Emit create context operation.
builder.CreateFunctionContext(1); builder.CreateFunctionContext(1);
...@@ -328,10 +325,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -328,10 +325,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreAccumulatorInRegister(reg); .StoreAccumulatorInRegister(reg);
// CreateClosureWide // CreateClosureWide
Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo( builder.CreateClosure(1000, NOT_TENURED);
factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(),
false);
builder.CreateClosure(shared_info2, NOT_TENURED);
// Emit wide variant of literal creation operations. // Emit wide variant of literal creation operations.
builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"), builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
......
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