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

Side by Side Diff: src/full-codegen.cc

Issue 11093074: Get rid of static module allocation, do it in code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed last comments; added other back-ends Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « src/full-codegen.h ('k') | src/heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) { 79 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
80 } 80 }
81 81
82 void BreakableStatementChecker::VisitModulePath(ModulePath* module) { 82 void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
83 } 83 }
84 84
85 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { 85 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) {
86 } 86 }
87 87
88 88
89 void BreakableStatementChecker::VisitModuleStatement(ModuleStatement* stmt) {
90 }
91
92
89 void BreakableStatementChecker::VisitBlock(Block* stmt) { 93 void BreakableStatementChecker::VisitBlock(Block* stmt) {
90 } 94 }
91 95
92 96
93 void BreakableStatementChecker::VisitExpressionStatement( 97 void BreakableStatementChecker::VisitExpressionStatement(
94 ExpressionStatement* stmt) { 98 ExpressionStatement* stmt) {
95 // Check if expression is breakable. 99 // Check if expression is breakable.
96 Visit(stmt->expression()); 100 Visit(stmt->expression());
97 } 101 }
98 102
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 579
576 580
577 void FullCodeGenerator::DoTest(const TestContext* context) { 581 void FullCodeGenerator::DoTest(const TestContext* context) {
578 DoTest(context->condition(), 582 DoTest(context->condition(),
579 context->true_label(), 583 context->true_label(),
580 context->false_label(), 584 context->false_label(),
581 context->fall_through()); 585 context->fall_through());
582 } 586 }
583 587
584 588
589 void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) {
590 ASSERT(scope_->is_global_scope());
591
592 for (int i = 0; i < declarations->length(); i++) {
593 ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration();
594 if (declaration != NULL) {
595 ModuleLiteral* module = declaration->module()->AsModuleLiteral();
596 if (module != NULL) {
597 Comment cmnt(masm_, "[ Link nested modules");
598 Scope* scope = module->body()->scope();
599 Interface* interface = scope->interface();
600 ASSERT(interface->IsModule() && interface->IsFrozen());
601
602 interface->Allocate(scope->module_var()->index());
603
604 // Set up module context.
605 ASSERT(scope->interface()->Index() >= 0);
606 __ Push(Smi::FromInt(scope->interface()->Index()));
607 __ Push(scope->GetScopeInfo());
608 __ CallRuntime(Runtime::kPushModuleContext, 2);
609 StoreToFrameField(StandardFrameConstants::kContextOffset,
610 context_register());
611
612 AllocateModules(scope->declarations());
613
614 // Pop module context.
615 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
616 // Update local stack frame context field.
617 StoreToFrameField(StandardFrameConstants::kContextOffset,
618 context_register());
619 }
620 }
621 }
622 }
623
624
625 // Modules have their own local scope, represented by their own context.
626 // Module instance objects have an accessor for every export that forwards
627 // access to the respective slot from the module's context. (Exports that are
628 // modules themselves, however, are simple data properties.)
629 //
630 // All modules have a _hosting_ scope/context, which (currently) is the
631 // (innermost) enclosing global scope. To deal with recursion, nested modules
632 // are hosted by the same scope as global ones.
633 //
634 // For every (global or nested) module literal, the hosting context has an
635 // internal slot that points directly to the respective module context. This
636 // enables quick access to (statically resolved) module members by 2-dimensional
637 // access through the hosting context. For example,
638 //
639 // module A {
640 // let x;
641 // module B { let y; }
642 // }
643 // module C { let z; }
644 //
645 // allocates contexts as follows:
646 //
647 // [header| .A | .B | .C | A | C ] (global)
648 // | | |
649 // | | +-- [header| z ] (module)
650 // | |
651 // | +------- [header| y ] (module)
652 // |
653 // +------------ [header| x | B ] (module)
654 //
655 // Here, .A, .B, .C are the internal slots pointing to the hosted module
656 // contexts, whereas A, B, C hold the actual instance objects (note that every
657 // module context also points to the respective instance object through its
658 // extension slot in the header).
659 //
660 // To deal with arbitrary recursion and aliases between modules,
661 // they are created and initialized in several stages. Each stage applies to
662 // all modules in the hosting global scope, including nested ones.
663 //
664 // 1. Allocate: for each module _literal_, allocate the module contexts and
665 // respective instance object and wire them up. This happens in the
666 // PushModuleContext runtime function, as generated by AllocateModules
667 // (invoked by VisitDeclarations in the hosting scope).
668 //
669 // 2. Bind: for each module _declaration_ (i.e. literals as well as aliases),
670 // assign the respective instance object to respective local variables. This
671 // happens in VisitModuleDeclaration, and uses the instance objects created
672 // in the previous stage.
673 // For each module _literal_, this phase also constructs a module descriptor
674 // for the next stage. This happens in VisitModuleLiteral.
675 //
676 // 3. Populate: invoke the DeclareModules runtime function to populate each
677 // _instance_ object with accessors for it exports. This is generated by
678 // DeclareModules (invoked by VisitDeclarations in the hosting scope again),
679 // and uses the descriptors generated in the previous stage.
680 //
681 // 4. Initialize: execute the module bodies (and other code) in sequence. This
682 // happens by the separate statements generated for module bodies. To reenter
683 // the module scopes properly, the parser inserted ModuleStatements.
684
585 void FullCodeGenerator::VisitDeclarations( 685 void FullCodeGenerator::VisitDeclarations(
586 ZoneList<Declaration*>* declarations) { 686 ZoneList<Declaration*>* declarations) {
687 Handle<FixedArray> saved_modules = modules_;
688 int saved_module_index = module_index_;
587 ZoneList<Handle<Object> >* saved_globals = globals_; 689 ZoneList<Handle<Object> >* saved_globals = globals_;
588 ZoneList<Handle<Object> > inner_globals(10, zone()); 690 ZoneList<Handle<Object> > inner_globals(10, zone());
589 globals_ = &inner_globals; 691 globals_ = &inner_globals;
590 692
693 if (scope_->num_modules() != 0) {
694 // This is a scope hosting modules. Allocate a descriptor array to pass
695 // to the runtime for initialization.
696 Comment cmnt(masm_, "[ Allocate modules");
697 ASSERT(scope_->is_global_scope());
698 modules_ =
699 isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED);
700 module_index_ = 0;
701
702 // Generate code for allocating all modules, including nested ones.
703 // The allocated contexts are stored in internal variables in this scope.
704 AllocateModules(declarations);
705 }
706
591 AstVisitor::VisitDeclarations(declarations); 707 AstVisitor::VisitDeclarations(declarations);
708
709 if (scope_->num_modules() != 0) {
710 // Initialize modules from descriptor array.
711 ASSERT(module_index_ == modules_->length());
712 DeclareModules(modules_);
713 modules_ = saved_modules;
714 module_index_ = saved_module_index;
715 }
716
592 if (!globals_->is_empty()) { 717 if (!globals_->is_empty()) {
593 // Invoke the platform-dependent code generator to do the actual 718 // Invoke the platform-dependent code generator to do the actual
594 // declaration the global functions and variables. 719 // declaration of the global functions and variables.
595 Handle<FixedArray> array = 720 Handle<FixedArray> array =
596 isolate()->factory()->NewFixedArray(globals_->length(), TENURED); 721 isolate()->factory()->NewFixedArray(globals_->length(), TENURED);
597 for (int i = 0; i < globals_->length(); ++i) 722 for (int i = 0; i < globals_->length(); ++i)
598 array->set(i, *globals_->at(i)); 723 array->set(i, *globals_->at(i));
599 DeclareGlobals(array); 724 DeclareGlobals(array);
600 } 725 }
601 726
602 globals_ = saved_globals; 727 globals_ = saved_globals;
603 } 728 }
604 729
605 730
606 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { 731 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
607 // Allocate a module context statically.
608 Block* block = module->body(); 732 Block* block = module->body();
609 Scope* saved_scope = scope(); 733 Scope* saved_scope = scope();
610 scope_ = block->scope(); 734 scope_ = block->scope();
611 Interface* interface = module->interface(); 735 Interface* interface = scope_->interface();
612 Handle<JSModule> instance = interface->Instance();
613 736
614 Comment cmnt(masm_, "[ ModuleLiteral"); 737 Comment cmnt(masm_, "[ ModuleLiteral");
615 SetStatementPosition(block); 738 SetStatementPosition(block);
616 739
740 ASSERT(!modules_.is_null());
741 ASSERT(module_index_ < modules_->length());
742 int index = module_index_++;
743
617 // Set up module context. 744 // Set up module context.
618 __ Push(instance); 745 ASSERT(interface->Index() >= 0);
619 __ CallRuntime(Runtime::kPushModuleContext, 1); 746 __ Push(Smi::FromInt(interface->Index()));
747 __ Push(Smi::FromInt(0));
748 __ CallRuntime(Runtime::kPushModuleContext, 2);
620 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 749 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
621 750
622 { 751 {
623 Comment cmnt(masm_, "[ Declarations"); 752 Comment cmnt(masm_, "[ Declarations");
624 VisitDeclarations(scope_->declarations()); 753 VisitDeclarations(scope_->declarations());
625 } 754 }
626 755
756 // Populate the module description.
757 Handle<ModuleInfo> description =
758 ModuleInfo::Create(isolate(), interface, scope_);
759 modules_->set(index, *description);
760
627 scope_ = saved_scope; 761 scope_ = saved_scope;
628 // Pop module context. 762 // Pop module context.
629 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 763 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
630 // Update local stack frame context field. 764 // Update local stack frame context field.
631 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 765 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
632 } 766 }
633 767
634 768
635 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { 769 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
636 // Nothing to do. 770 // Nothing to do.
637 // The instance object is resolved statically through the module's interface. 771 // The instance object is resolved statically through the module's interface.
638 } 772 }
639 773
640 774
641 void FullCodeGenerator::VisitModulePath(ModulePath* module) { 775 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
642 // Nothing to do. 776 // Nothing to do.
643 // The instance object is resolved statically through the module's interface. 777 // The instance object is resolved statically through the module's interface.
644 } 778 }
645 779
646 780
647 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) { 781 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) {
648 // TODO(rossberg) 782 // TODO(rossberg): dummy allocation for now.
783 Scope* scope = module->body()->scope();
784 Interface* interface = scope_->interface();
785
786 ASSERT(interface->IsModule() && interface->IsFrozen());
787 ASSERT(!modules_.is_null());
788 ASSERT(module_index_ < modules_->length());
789 interface->Allocate(scope->module_var()->index());
790 int index = module_index_++;
791
792 Handle<ModuleInfo> description =
793 ModuleInfo::Create(isolate(), interface, scope_);
794 modules_->set(index, *description);
649 } 795 }
650 796
651 797
652 int FullCodeGenerator::DeclareGlobalsFlags() { 798 int FullCodeGenerator::DeclareGlobalsFlags() {
653 ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode())); 799 ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode()));
654 return DeclareGlobalsEvalFlag::encode(is_eval()) | 800 return DeclareGlobalsEvalFlag::encode(is_eval()) |
655 DeclareGlobalsNativeFlag::encode(is_native()) | 801 DeclareGlobalsNativeFlag::encode(is_native()) |
656 DeclareGlobalsLanguageMode::encode(language_mode()); 802 DeclareGlobalsLanguageMode::encode(language_mode());
657 } 803 }
658 804
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 1043
898 void FullCodeGenerator::VisitBlock(Block* stmt) { 1044 void FullCodeGenerator::VisitBlock(Block* stmt) {
899 Comment cmnt(masm_, "[ Block"); 1045 Comment cmnt(masm_, "[ Block");
900 NestedBlock nested_block(this, stmt); 1046 NestedBlock nested_block(this, stmt);
901 SetStatementPosition(stmt); 1047 SetStatementPosition(stmt);
902 1048
903 Scope* saved_scope = scope(); 1049 Scope* saved_scope = scope();
904 // Push a block context when entering a block with block scoped variables. 1050 // Push a block context when entering a block with block scoped variables.
905 if (stmt->scope() != NULL) { 1051 if (stmt->scope() != NULL) {
906 scope_ = stmt->scope(); 1052 scope_ = stmt->scope();
907 if (scope_->is_module_scope()) { 1053 ASSERT(!scope_->is_module_scope());
908 // If this block is a module body, then we have already allocated and 1054 { Comment cmnt(masm_, "[ Extend block context");
909 // initialized the declarations earlier. Just push the context. 1055 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
910 ASSERT(!scope_->interface()->Instance().is_null()); 1056 int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
911 __ Push(scope_->interface()->Instance()); 1057 __ Push(scope_info);
912 __ CallRuntime(Runtime::kPushModuleContext, 1); 1058 PushFunctionArgumentForContextAllocation();
913 StoreToFrameField( 1059 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
914 StandardFrameConstants::kContextOffset, context_register()); 1060 FastNewBlockContextStub stub(heap_slots);
915 } else { 1061 __ CallStub(&stub);
916 { Comment cmnt(masm_, "[ Extend block context"); 1062 } else {
917 Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); 1063 __ CallRuntime(Runtime::kPushBlockContext, 2);
918 int heap_slots = 1064 }
919 scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
920 __ Push(scope_info);
921 PushFunctionArgumentForContextAllocation();
922 if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
923 FastNewBlockContextStub stub(heap_slots);
924 __ CallStub(&stub);
925 } else {
926 __ CallRuntime(Runtime::kPushBlockContext, 2);
927 }
928 1065
929 // Replace the context stored in the frame. 1066 // Replace the context stored in the frame.
930 StoreToFrameField(StandardFrameConstants::kContextOffset, 1067 StoreToFrameField(StandardFrameConstants::kContextOffset,
931 context_register()); 1068 context_register());
932 } 1069 }
933 { Comment cmnt(masm_, "[ Declarations"); 1070 { Comment cmnt(masm_, "[ Declarations");
934 VisitDeclarations(scope_->declarations()); 1071 VisitDeclarations(scope_->declarations());
935 }
936 } 1072 }
937 } 1073 }
1074
938 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1075 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
939 VisitStatements(stmt->statements()); 1076 VisitStatements(stmt->statements());
940 scope_ = saved_scope; 1077 scope_ = saved_scope;
941 __ bind(nested_block.break_label()); 1078 __ bind(nested_block.break_label());
942 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1079 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
943 1080
944 // Pop block context if necessary. 1081 // Pop block context if necessary.
945 if (stmt->scope() != NULL) { 1082 if (stmt->scope() != NULL) {
946 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1083 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
947 // Update local stack frame context field. 1084 // Update local stack frame context field.
948 StoreToFrameField(StandardFrameConstants::kContextOffset, 1085 StoreToFrameField(StandardFrameConstants::kContextOffset,
949 context_register()); 1086 context_register());
950 } 1087 }
951 } 1088 }
952 1089
953 1090
1091 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) {
1092 Comment cmnt(masm_, "[ Module context");
1093
1094 __ Push(Smi::FromInt(stmt->proxy()->interface()->Index()));
1095 __ Push(Smi::FromInt(0));
1096 __ CallRuntime(Runtime::kPushModuleContext, 2);
1097 StoreToFrameField(
1098 StandardFrameConstants::kContextOffset, context_register());
1099
1100 Scope* saved_scope = scope_;
1101 scope_ = stmt->body()->scope();
1102 VisitStatements(stmt->body()->statements());
1103 scope_ = saved_scope;
1104 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1105 // Update local stack frame context field.
1106 StoreToFrameField(StandardFrameConstants::kContextOffset,
1107 context_register());
1108 }
1109
1110
954 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 1111 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
955 Comment cmnt(masm_, "[ ExpressionStatement"); 1112 Comment cmnt(masm_, "[ ExpressionStatement");
956 SetStatementPosition(stmt); 1113 SetStatementPosition(stmt);
957 VisitForEffect(stmt->expression()); 1114 VisitForEffect(stmt->expression());
958 } 1115 }
959 1116
960 1117
961 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 1118 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
962 Comment cmnt(masm_, "[ EmptyStatement"); 1119 Comment cmnt(masm_, "[ EmptyStatement");
963 SetStatementPosition(stmt); 1120 SetStatementPosition(stmt);
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 } 1578 }
1422 1579
1423 return false; 1580 return false;
1424 } 1581 }
1425 1582
1426 1583
1427 #undef __ 1584 #undef __
1428 1585
1429 1586
1430 } } // namespace v8::internal 1587 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698