Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2179303005: [Interpreter] Move SharedFunctionInfo creation to finalization step. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/bytecode-flags.h" 10 #include "src/interpreter/bytecode-flags.h"
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 530
531 private: 531 private:
532 Register result_register_; 532 Register result_register_;
533 }; 533 };
534 534
535 // Used to build a list of global declaration initial value pairs. 535 // Used to build a list of global declaration initial value pairs.
536 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { 536 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
537 public: 537 public:
538 GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone) 538 GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone)
539 : isolate_(isolate), 539 : isolate_(isolate),
540 declaration_pairs_(0, zone), 540 declarations_(0, zone),
541 constant_pool_entry_(0), 541 constant_pool_entry_(0),
542 has_constant_pool_entry_(false) {} 542 has_constant_pool_entry_(false) {}
543 543
544 void AddDeclaration(FeedbackVectorSlot slot, Handle<Object> initial_value) { 544 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) {
545 DCHECK(!slot.IsInvalid()); 545 DCHECK(!slot.IsInvalid());
546 declaration_pairs_.push_back(handle(Smi::FromInt(slot.ToInt()), isolate_)); 546 declarations_.push_back(std::make_pair(slot, func));
547 declaration_pairs_.push_back(initial_value);
548 } 547 }
549 548
550 Handle<FixedArray> AllocateDeclarationPairs() { 549 void AddUndefinedDeclaration(FeedbackVectorSlot slot) {
550 DCHECK(!slot.IsInvalid());
551 declarations_.push_back(std::make_pair(slot, nullptr));
552 }
553
554 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) {
551 DCHECK(has_constant_pool_entry_); 555 DCHECK(has_constant_pool_entry_);
552 int array_index = 0; 556 int array_index = 0;
553 Handle<FixedArray> data = isolate_->factory()->NewFixedArray( 557 Handle<FixedArray> pairs = isolate_->factory()->NewFixedArray(
554 static_cast<int>(declaration_pairs_.size()), TENURED); 558 static_cast<int>(declarations_.size() * 2), TENURED);
555 for (Handle<Object> obj : declaration_pairs_) { 559 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration :
556 data->set(array_index++, *obj); 560 declarations_) {
561 FunctionLiteral* func = declaration.second;
562 Handle<Object> initial_value;
563 if (func == nullptr) {
564 initial_value = isolate_->factory()->undefined_value();
565 } else {
566 initial_value =
567 Compiler::GetSharedFunctionInfo(func, info->script(), info);
568 }
569
570 // Return a null handle if any initial values can't be created. Caller
571 // will set stack overflow.
572 if (initial_value.is_null()) return Handle<FixedArray>();
573
574 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt()));
575 pairs->set(array_index++, *initial_value);
557 } 576 }
558 return data; 577 return pairs;
559 } 578 }
560 579
561 size_t constant_pool_entry() { 580 size_t constant_pool_entry() {
562 DCHECK(has_constant_pool_entry_); 581 DCHECK(has_constant_pool_entry_);
563 return constant_pool_entry_; 582 return constant_pool_entry_;
564 } 583 }
565 584
566 void set_constant_pool_entry(size_t constant_pool_entry) { 585 void set_constant_pool_entry(size_t constant_pool_entry) {
567 DCHECK(!empty()); 586 DCHECK(!empty());
568 DCHECK(!has_constant_pool_entry_); 587 DCHECK(!has_constant_pool_entry_);
569 constant_pool_entry_ = constant_pool_entry; 588 constant_pool_entry_ = constant_pool_entry;
570 has_constant_pool_entry_ = true; 589 has_constant_pool_entry_ = true;
571 } 590 }
572 591
573 bool empty() { return declaration_pairs_.empty(); } 592 bool empty() { return declarations_.empty(); }
574 593
575 private: 594 private:
576 Isolate* isolate_; 595 Isolate* isolate_;
577 ZoneVector<Handle<Object>> declaration_pairs_; 596 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_;
578 size_t constant_pool_entry_; 597 size_t constant_pool_entry_;
579 bool has_constant_pool_entry_; 598 bool has_constant_pool_entry_;
580 }; 599 };
581 600
582 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) 601 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
583 : isolate_(info->isolate()), 602 : isolate_(info->isolate()),
584 zone_(info->zone()), 603 zone_(info->zone()),
585 builder_(new (zone()) BytecodeArrayBuilder( 604 builder_(new (zone()) BytecodeArrayBuilder(
586 info->isolate(), info->zone(), info->num_parameters_including_this(), 605 info->isolate(), info->zone(), info->num_parameters_including_this(),
587 info->scope()->MaxNestedContextChainLength(), 606 info->scope()->MaxNestedContextChainLength(),
588 info->scope()->num_stack_slots(), info->literal(), 607 info->scope()->num_stack_slots(), info->literal(),
589 info->SourcePositionRecordingMode())), 608 info->SourcePositionRecordingMode())),
590 info_(info), 609 info_(info),
591 scope_(info->scope()), 610 scope_(info->scope()),
592 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(), 611 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(),
593 info->zone())), 612 info->zone())),
594 global_declarations_(0, info->zone()), 613 global_declarations_(0, info->zone()),
614 function_literals_(0, info->zone()),
615 native_function_literals_(0, info->zone()),
595 execution_control_(nullptr), 616 execution_control_(nullptr),
596 execution_context_(nullptr), 617 execution_context_(nullptr),
597 execution_result_(nullptr), 618 execution_result_(nullptr),
598 register_allocator_(nullptr), 619 register_allocator_(nullptr),
599 generator_resume_points_(info->literal()->yield_count(), info->zone()), 620 generator_resume_points_(info->literal()->yield_count(), info->zone()),
600 generator_state_() { 621 generator_state_() {
601 InitializeAstVisitor(isolate()->stack_guard()->real_climit()); 622 InitializeAstVisitor(isolate()->stack_guard()->real_climit());
602 } 623 }
603 624
604 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { 625 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
605 GenerateBytecode(); 626 GenerateBytecode();
627 FinalizeBytecode();
628 return builder()->ToBytecodeArray();
629 }
606 630
631 void BytecodeGenerator::FinalizeBytecode() {
607 // Build global declaration pair arrays. 632 // Build global declaration pair arrays.
608 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { 633 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
609 Handle<FixedArray> declarations = 634 Handle<FixedArray> declarations =
610 globals_builder->AllocateDeclarationPairs(); 635 globals_builder->AllocateDeclarationPairs(info());
636 if (declarations.is_null()) return SetStackOverflow();
611 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), 637 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
612 declarations); 638 declarations);
613 } 639 }
614 640
615 return builder()->ToBytecodeArray(); 641 // Find or build shared function infos.
642 for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
643 FunctionLiteral* expr = literal.first;
644 Handle<SharedFunctionInfo> shared_info =
645 Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
646 if (shared_info.is_null()) return SetStackOverflow();
647 builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
648 }
649
650 // Find or build shared function infos for the native function templates.
651 for (std::pair<NativeFunctionLiteral*, size_t> literal :
652 native_function_literals_) {
653 NativeFunctionLiteral* expr = literal.first;
654 Handle<SharedFunctionInfo> shared_info =
655 Compiler::GetSharedFunctionInfoForNative(expr->extension(),
656 expr->name());
657 if (shared_info.is_null()) return SetStackOverflow();
658 builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
659 }
616 } 660 }
617 661
618 void BytecodeGenerator::GenerateBytecode() { 662 void BytecodeGenerator::GenerateBytecode() {
619 // Initialize the incoming context. 663 // Initialize the incoming context.
620 ContextScope incoming_context(this, scope(), false); 664 ContextScope incoming_context(this, scope(), false);
621 665
622 // Initialize control scope. 666 // Initialize control scope.
623 ControlScopeForTopLevel control(this); 667 ControlScopeForTopLevel control(this);
624 668
625 RegisterAllocationScope register_scope(this); 669 RegisterAllocationScope register_scope(this);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 Variable* variable = decl->proxy()->var(); 822 Variable* variable = decl->proxy()->var();
779 VariableMode mode = decl->mode(); 823 VariableMode mode = decl->mode();
780 // Const and let variables are initialized with the hole so that we can 824 // Const and let variables are initialized with the hole so that we can
781 // check that they are only assigned once. 825 // check that they are only assigned once.
782 bool hole_init = mode == CONST || mode == LET; 826 bool hole_init = mode == CONST || mode == LET;
783 switch (variable->location()) { 827 switch (variable->location()) {
784 case VariableLocation::GLOBAL: 828 case VariableLocation::GLOBAL:
785 case VariableLocation::UNALLOCATED: { 829 case VariableLocation::UNALLOCATED: {
786 DCHECK(!variable->binding_needs_init()); 830 DCHECK(!variable->binding_needs_init());
787 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); 831 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
788 globals_builder()->AddDeclaration( 832 globals_builder()->AddUndefinedDeclaration(slot);
789 slot, isolate()->factory()->undefined_value());
790 break; 833 break;
791 } 834 }
792 case VariableLocation::LOCAL: 835 case VariableLocation::LOCAL:
793 if (hole_init) { 836 if (hole_init) {
794 Register destination(variable->index()); 837 Register destination(variable->index());
795 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); 838 builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
796 } 839 }
797 break; 840 break;
798 case VariableLocation::PARAMETER: 841 case VariableLocation::PARAMETER:
799 if (hole_init) { 842 if (hole_init) {
(...skipping 22 matching lines...) Expand all
822 break; 865 break;
823 } 866 }
824 } 867 }
825 } 868 }
826 869
827 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 870 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
828 Variable* variable = decl->proxy()->var(); 871 Variable* variable = decl->proxy()->var();
829 switch (variable->location()) { 872 switch (variable->location()) {
830 case VariableLocation::GLOBAL: 873 case VariableLocation::GLOBAL:
831 case VariableLocation::UNALLOCATED: { 874 case VariableLocation::UNALLOCATED: {
832 Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
833 decl->fun(), info()->script(), info());
834 // Check for stack-overflow exception.
835 if (function.is_null()) return SetStackOverflow();
836 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); 875 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
837 globals_builder()->AddDeclaration(slot, function); 876 globals_builder()->AddFunctionDeclaration(slot, decl->fun());
838 break; 877 break;
839 } 878 }
840 case VariableLocation::PARAMETER: 879 case VariableLocation::PARAMETER:
841 case VariableLocation::LOCAL: { 880 case VariableLocation::LOCAL: {
842 VisitForAccumulatorValue(decl->fun()); 881 VisitForAccumulatorValue(decl->fun());
843 DCHECK(variable->mode() == LET || variable->mode() == VAR || 882 DCHECK(variable->mode() == LET || variable->mode() == VAR ||
844 variable->mode() == CONST); 883 variable->mode() == CONST);
845 VisitVariableAssignment(variable, Token::INIT, 884 VisitVariableAssignment(variable, Token::INIT,
846 FeedbackVectorSlot::Invalid()); 885 FeedbackVectorSlot::Invalid());
847 break; 886 break;
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 // Dynamic dispatch after the finally-block. 1380 // Dynamic dispatch after the finally-block.
1342 commands.ApplyDeferredCommands(); 1381 commands.ApplyDeferredCommands();
1343 } 1382 }
1344 1383
1345 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1384 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1346 builder()->SetStatementPosition(stmt); 1385 builder()->SetStatementPosition(stmt);
1347 builder()->Debugger(); 1386 builder()->Debugger();
1348 } 1387 }
1349 1388
1350 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1389 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1351 // Find or build a shared function info.
1352 Handle<SharedFunctionInfo> shared_info =
1353 Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
1354 if (shared_info.is_null()) {
1355 return SetStackOverflow();
1356 }
1357 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(), 1390 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(),
1358 scope()->is_function_scope()); 1391 scope()->is_function_scope());
1359 builder()->CreateClosure(shared_info, flags); 1392 size_t entry = builder()->AllocateConstantPoolEntry();
1393 builder()->CreateClosure(entry, flags);
1394 function_literals_.push_back(std::make_pair(expr, entry));
1360 execution_result()->SetResultInAccumulator(); 1395 execution_result()->SetResultInAccumulator();
1361 } 1396 }
1362 1397
1363 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { 1398 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
1364 VisitClassLiteralForRuntimeDefinition(expr); 1399 VisitClassLiteralForRuntimeDefinition(expr);
1365 1400
1366 // Load the "prototype" from the constructor. 1401 // Load the "prototype" from the constructor.
1367 register_allocator()->PrepareForConsecutiveAllocations(2); 1402 register_allocator()->PrepareForConsecutiveAllocations(2);
1368 Register literal = register_allocator()->NextConsecutiveRegister(); 1403 Register literal = register_allocator()->NextConsecutiveRegister();
1369 Register prototype = register_allocator()->NextConsecutiveRegister(); 1404 Register prototype = register_allocator()->NextConsecutiveRegister();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 builder() 1526 builder()
1492 ->LoadLiteral(isolate()->factory()->prototype_string()) 1527 ->LoadLiteral(isolate()->factory()->prototype_string())
1493 .CompareOperation(Token::Value::EQ_STRICT, key) 1528 .CompareOperation(Token::Value::EQ_STRICT, key)
1494 .JumpIfFalse(&done) 1529 .JumpIfFalse(&done)
1495 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) 1530 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0)
1496 .Bind(&done); 1531 .Bind(&done);
1497 } 1532 }
1498 1533
1499 void BytecodeGenerator::VisitNativeFunctionLiteral( 1534 void BytecodeGenerator::VisitNativeFunctionLiteral(
1500 NativeFunctionLiteral* expr) { 1535 NativeFunctionLiteral* expr) {
1501 // Find or build a shared function info for the native function template. 1536 size_t entry = builder()->AllocateConstantPoolEntry();
1502 Handle<SharedFunctionInfo> shared_info = 1537 builder()->CreateClosure(entry, NOT_TENURED);
1503 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); 1538 native_function_literals_.push_back(std::make_pair(expr, entry));
1504 builder()->CreateClosure(shared_info, NOT_TENURED);
1505 execution_result()->SetResultInAccumulator(); 1539 execution_result()->SetResultInAccumulator();
1506 } 1540 }
1507 1541
1508 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { 1542 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
1509 VisitBlock(expr->block()); 1543 VisitBlock(expr->block());
1510 VisitVariableProxy(expr->result()); 1544 VisitVariableProxy(expr->result());
1511 } 1545 }
1512 1546
1513 void BytecodeGenerator::VisitConditional(Conditional* expr) { 1547 void BytecodeGenerator::VisitConditional(Conditional* expr) {
1514 // TODO(rmcilroy): Spot easy cases where there code would not need to 1548 // TODO(rmcilroy): Spot easy cases where there code would not need to
(...skipping 1712 matching lines...) Expand 10 before | Expand all | Expand 10 after
3227 return execution_context()->scope()->language_mode(); 3261 return execution_context()->scope()->language_mode();
3228 } 3262 }
3229 3263
3230 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3264 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3231 return TypeFeedbackVector::GetIndex(slot); 3265 return TypeFeedbackVector::GetIndex(slot);
3232 } 3266 }
3233 3267
3234 } // namespace interpreter 3268 } // namespace interpreter
3235 } // namespace internal 3269 } // namespace internal
3236 } // namespace v8 3270 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | test/unittests/interpreter/bytecode-array-builder-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698