| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 5fb120def80393b05a29466908ad279c33e77b1f..9829082d5daeeabdd07c599b0bddf538e0685d72 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -537,25 +537,44 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
| public:
|
| GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone)
|
| : isolate_(isolate),
|
| - declaration_pairs_(0, zone),
|
| + declarations_(0, zone),
|
| constant_pool_entry_(0),
|
| has_constant_pool_entry_(false) {}
|
|
|
| - void AddDeclaration(FeedbackVectorSlot slot, Handle<Object> initial_value) {
|
| + void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) {
|
| DCHECK(!slot.IsInvalid());
|
| - declaration_pairs_.push_back(handle(Smi::FromInt(slot.ToInt()), isolate_));
|
| - declaration_pairs_.push_back(initial_value);
|
| + declarations_.push_back(std::make_pair(slot, func));
|
| }
|
|
|
| - 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_);
|
| int array_index = 0;
|
| - Handle<FixedArray> data = isolate_->factory()->NewFixedArray(
|
| - static_cast<int>(declaration_pairs_.size()), TENURED);
|
| - for (Handle<Object> obj : declaration_pairs_) {
|
| - data->set(array_index++, *obj);
|
| + Handle<FixedArray> pairs = isolate_->factory()->NewFixedArray(
|
| + static_cast<int>(declarations_.size() * 2), TENURED);
|
| + for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration :
|
| + 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() {
|
| @@ -570,11 +589,11 @@ class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
|
| has_constant_pool_entry_ = true;
|
| }
|
|
|
| - bool empty() { return declaration_pairs_.empty(); }
|
| + bool empty() { return declarations_.empty(); }
|
|
|
| private:
|
| Isolate* isolate_;
|
| - ZoneVector<Handle<Object>> declaration_pairs_;
|
| + ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_;
|
| size_t constant_pool_entry_;
|
| bool has_constant_pool_entry_;
|
| };
|
| @@ -592,6 +611,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
|
| globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(),
|
| info->zone())),
|
| global_declarations_(0, info->zone()),
|
| + function_literals_(0, info->zone()),
|
| + native_function_literals_(0, info->zone()),
|
| execution_control_(nullptr),
|
| execution_context_(nullptr),
|
| execution_result_(nullptr),
|
| @@ -603,16 +624,39 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
|
|
|
| Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
|
| GenerateBytecode();
|
| + FinalizeBytecode();
|
| + return builder()->ToBytecodeArray();
|
| +}
|
|
|
| +void BytecodeGenerator::FinalizeBytecode() {
|
| // Build global declaration pair arrays.
|
| for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
|
| Handle<FixedArray> declarations =
|
| - globals_builder->AllocateDeclarationPairs();
|
| + globals_builder->AllocateDeclarationPairs(info());
|
| + if (declarations.is_null()) return SetStackOverflow();
|
| builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
|
| 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() {
|
| @@ -785,8 +829,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| case VariableLocation::UNALLOCATED: {
|
| DCHECK(!variable->binding_needs_init());
|
| FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
|
| - globals_builder()->AddDeclaration(
|
| - slot, isolate()->factory()->undefined_value());
|
| + globals_builder()->AddUndefinedDeclaration(slot);
|
| break;
|
| }
|
| case VariableLocation::LOCAL:
|
| @@ -829,12 +872,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| switch (variable->location()) {
|
| case VariableLocation::GLOBAL:
|
| 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();
|
| - globals_builder()->AddDeclaration(slot, function);
|
| + globals_builder()->AddFunctionDeclaration(slot, decl->fun());
|
| break;
|
| }
|
| case VariableLocation::PARAMETER:
|
| @@ -1348,15 +1387,11 @@ void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
| }
|
|
|
| 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(),
|
| 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();
|
| }
|
|
|
| @@ -1498,10 +1533,9 @@ void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName(
|
|
|
| void BytecodeGenerator::VisitNativeFunctionLiteral(
|
| NativeFunctionLiteral* expr) {
|
| - // Find or build a shared function info for the native function template.
|
| - Handle<SharedFunctionInfo> shared_info =
|
| - Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
|
| - builder()->CreateClosure(shared_info, NOT_TENURED);
|
| + size_t entry = builder()->AllocateConstantPoolEntry();
|
| + builder()->CreateClosure(entry, NOT_TENURED);
|
| + native_function_literals_.push_back(std::make_pair(expr, entry));
|
| execution_result()->SetResultInAccumulator();
|
| }
|
|
|
|
|