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

Side by Side Diff: src/d8.cc

Issue 2406973003: Revert of [modules] Store Module metadata in per-Context EmbedderData (Closed)
Patch Set: Created 4 years, 2 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
« no previous file with comments | « src/d8.h ('k') | src/factory.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 // 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 <errno.h> 5 #include <errno.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <fstream> 11 #include <fstream>
12 #include <unordered_map> 12 #include <map>
13 #include <utility> 13 #include <utility>
14 #include <vector> 14 #include <vector>
15 15
16 #ifdef ENABLE_VTUNE_JIT_INTERFACE 16 #ifdef ENABLE_VTUNE_JIT_INTERFACE
17 #include "src/third_party/vtune/v8-vtune.h" 17 #include "src/third_party/vtune/v8-vtune.h"
18 #endif 18 #endif
19 19
20 #include "src/d8.h" 20 #include "src/d8.h"
21 #include "src/ostreams.h" 21 #include "src/ostreams.h"
22 22
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 result = dir_name + '/' + path; 565 result = dir_name + '/' + path;
566 } 566 }
567 std::replace(result.begin(), result.end(), '\\', '/'); 567 std::replace(result.begin(), result.end(), '\\', '/');
568 size_t i; 568 size_t i;
569 while ((i = result.find("/./")) != std::string::npos) { 569 while ((i = result.find("/./")) != std::string::npos) {
570 result.erase(i, 2); 570 result.erase(i, 2);
571 } 571 }
572 return result; 572 return result;
573 } 573 }
574 574
575 // Per-context Module data, allowing sharing of module maps
576 // across top-level module loads.
577 class ModuleEmbedderData {
578 private:
579 class ModuleGlobalHash {
580 public:
581 explicit ModuleGlobalHash(Isolate* isolate) : isolate_(isolate) {}
582 size_t operator()(const Global<Module>& module) const {
583 return module.Get(isolate_)->GetIdentityHash();
584 }
585
586 private:
587 Isolate* isolate_;
588 };
589
590 public:
591 explicit ModuleEmbedderData(Isolate* isolate)
592 : module_to_directory_map(10, ModuleGlobalHash(isolate)) {}
593
594 // Map from normalized module specifier to Module.
595 std::unordered_map<std::string, Global<Module>> specifier_to_module_map;
596 // Map from Module to the directory that Module was loaded from.
597 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash>
598 module_to_directory_map;
599 };
600
601 enum {
602 // The debugger reserves the first slot in the Context embedder data.
603 kDebugIdIndex = Context::kDebugIdIndex,
604 kModuleEmbedderDataIndex
605 };
606
607 void InitializeModuleEmbedderData(Local<Context> context) {
608 context->SetAlignedPointerInEmbedderData(
609 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate()));
610 }
611
612 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) {
613 return static_cast<ModuleEmbedderData*>(
614 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex));
615 }
616
617 void DisposeModuleEmbedderData(Local<Context> context) {
618 delete GetModuleDataFromContext(context);
619 context->SetAlignedPointerInEmbedderData(kModuleEmbedderDataIndex, nullptr);
620 }
621
622 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, 575 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
623 Local<String> specifier, 576 Local<String> specifier,
624 Local<Module> referrer) { 577 Local<Module> referrer,
578 Local<Value> data) {
625 Isolate* isolate = context->GetIsolate(); 579 Isolate* isolate = context->GetIsolate();
626 ModuleEmbedderData* d = GetModuleDataFromContext(context); 580 auto module_map = static_cast<std::map<std::string, Global<Module>>*>(
627 auto dir_name_it = 581 External::Cast(*data)->Value());
628 d->module_to_directory_map.find(Global<Module>(isolate, referrer)); 582 Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData());
629 CHECK(dir_name_it != d->module_to_directory_map.end());
630 std::string absolute_path = 583 std::string absolute_path =
631 NormalizePath(ToSTLString(specifier), dir_name_it->second); 584 NormalizePath(ToSTLString(specifier), ToSTLString(dir_name));
632 auto module_it = d->specifier_to_module_map.find(absolute_path); 585 auto it = module_map->find(absolute_path);
633 CHECK(module_it != d->specifier_to_module_map.end()); 586 if (it != module_map->end()) {
634 return module_it->second.Get(isolate); 587 return it->second.Get(isolate);
588 }
589 return MaybeLocal<Module>();
635 } 590 }
636 591
637 } // anonymous namespace 592 } // anonymous namespace
638 593
639 MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, 594 MaybeLocal<Module> Shell::FetchModuleTree(
640 const std::string& file_name) { 595 Isolate* isolate, const std::string& file_name,
596 std::map<std::string, Global<Module>>* module_map) {
641 DCHECK(IsAbsolutePath(file_name)); 597 DCHECK(IsAbsolutePath(file_name));
642 Isolate* isolate = context->GetIsolate();
643 TryCatch try_catch(isolate); 598 TryCatch try_catch(isolate);
644 try_catch.SetVerbose(true); 599 try_catch.SetVerbose(true);
645 Local<String> source_text = ReadFile(isolate, file_name.c_str()); 600 Local<String> source_text = ReadFile(isolate, file_name.c_str());
646 if (source_text.IsEmpty()) { 601 if (source_text.IsEmpty()) {
647 printf("Error reading '%s'\n", file_name.c_str()); 602 printf("Error reading '%s'\n", file_name.c_str());
648 Shell::Exit(1); 603 Shell::Exit(1);
649 } 604 }
650 ScriptOrigin origin( 605 ScriptOrigin origin(
651 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) 606 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal)
652 .ToLocalChecked()); 607 .ToLocalChecked());
653 ScriptCompiler::Source source(source_text, origin); 608 ScriptCompiler::Source source(source_text, origin);
654 Local<Module> module; 609 Local<Module> module;
655 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { 610 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
656 ReportException(isolate, &try_catch); 611 ReportException(isolate, &try_catch);
657 return MaybeLocal<Module>(); 612 return MaybeLocal<Module>();
658 } 613 }
659 614 module_map->insert(
660 ModuleEmbedderData* d = GetModuleDataFromContext(context); 615 std::make_pair(file_name, Global<Module>(isolate, module)));
661 CHECK(d->specifier_to_module_map
662 .insert(std::make_pair(file_name, Global<Module>(isolate, module)))
663 .second);
664 616
665 std::string dir_name = DirName(file_name); 617 std::string dir_name = DirName(file_name);
666 CHECK(d->module_to_directory_map 618 module->SetEmbedderData(
667 .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) 619 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal)
668 .second); 620 .ToLocalChecked());
669 621
670 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { 622 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) {
671 Local<String> name = module->GetModuleRequest(i); 623 Local<String> name = module->GetModuleRequest(i);
672 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name); 624 std::string absolute_path = NormalizePath(ToSTLString(name), dir_name);
673 if (!d->specifier_to_module_map.count(absolute_path)) { 625 if (!module_map->count(absolute_path)) {
674 if (FetchModuleTree(context, absolute_path).IsEmpty()) { 626 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) {
675 return MaybeLocal<Module>(); 627 return MaybeLocal<Module>();
676 } 628 }
677 } 629 }
678 } 630 }
679 631
680 return module; 632 return module;
681 } 633 }
682 634
683 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { 635 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
684 HandleScope handle_scope(isolate); 636 HandleScope handle_scope(isolate);
685 637
686 PerIsolateData* data = PerIsolateData::Get(isolate);
687 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
688 Context::Scope context_scope(realm);
689
690 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory()); 638 std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
691 639
692 Local<Module> root_module; 640 Local<Module> root_module;
693 if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { 641 std::map<std::string, Global<Module>> module_map;
642 if (!FetchModuleTree(isolate, absolute_path, &module_map)
643 .ToLocal(&root_module)) {
694 return false; 644 return false;
695 } 645 }
696 646
697 TryCatch try_catch(isolate); 647 TryCatch try_catch(isolate);
698 try_catch.SetVerbose(true); 648 try_catch.SetVerbose(true);
699 649
700 MaybeLocal<Value> maybe_result; 650 MaybeLocal<Value> maybe_result;
701 if (root_module->Instantiate(realm, ResolveModuleCallback)) { 651 {
702 maybe_result = root_module->Evaluate(realm); 652 PerIsolateData* data = PerIsolateData::Get(isolate);
703 EmptyMessageQueues(isolate); 653 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
654 Context::Scope context_scope(realm);
655
656 if (root_module->Instantiate(realm, ResolveModuleCallback,
657 External::New(isolate, &module_map))) {
658 maybe_result = root_module->Evaluate(realm);
659 EmptyMessageQueues(isolate);
660 }
704 } 661 }
705 Local<Value> result; 662 Local<Value> result;
706 if (!maybe_result.ToLocal(&result)) { 663 if (!maybe_result.ToLocal(&result)) {
707 DCHECK(try_catch.HasCaught()); 664 DCHECK(try_catch.HasCaught());
708 // Print errors that happened during execution. 665 // Print errors that happened during execution.
709 ReportException(isolate, &try_catch); 666 ReportException(isolate, &try_catch);
710 return false; 667 return false;
711 } 668 }
712 DCHECK(!try_catch.HasCaught()); 669 DCHECK(!try_catch.HasCaught());
713 return true; 670 return true;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 old_realms[i].Reset(); 780 old_realms[i].Reset();
824 } 781 }
825 delete[] old_realms; 782 delete[] old_realms;
826 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); 783 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
827 Local<Context> context = Context::New(isolate, NULL, global_template); 784 Local<Context> context = Context::New(isolate, NULL, global_template);
828 if (context.IsEmpty()) { 785 if (context.IsEmpty()) {
829 DCHECK(try_catch.HasCaught()); 786 DCHECK(try_catch.HasCaught());
830 try_catch.ReThrow(); 787 try_catch.ReThrow();
831 return MaybeLocal<Context>(); 788 return MaybeLocal<Context>();
832 } 789 }
833 InitializeModuleEmbedderData(context);
834 data->realms_[index].Reset(isolate, context); 790 data->realms_[index].Reset(isolate, context);
835 args.GetReturnValue().Set(index); 791 args.GetReturnValue().Set(index);
836 return context; 792 return context;
837 } 793 }
838 794
839 // Realm.create() creates a new realm with a distinct security token 795 // Realm.create() creates a new realm with a distinct security token
840 // and returns its index. 796 // and returns its index.
841 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) { 797 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) {
842 CreateRealm(args); 798 CreateRealm(args);
843 } 799 }
(...skipping 13 matching lines...) Expand all
857 void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) { 813 void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) {
858 Isolate* isolate = args.GetIsolate(); 814 Isolate* isolate = args.GetIsolate();
859 PerIsolateData* data = PerIsolateData::Get(isolate); 815 PerIsolateData* data = PerIsolateData::Get(isolate);
860 int index = data->RealmIndexOrThrow(args, 0); 816 int index = data->RealmIndexOrThrow(args, 0);
861 if (index == -1) return; 817 if (index == -1) return;
862 if (index == 0 || 818 if (index == 0 ||
863 index == data->realm_current_ || index == data->realm_switch_) { 819 index == data->realm_current_ || index == data->realm_switch_) {
864 Throw(args.GetIsolate(), "Invalid realm index"); 820 Throw(args.GetIsolate(), "Invalid realm index");
865 return; 821 return;
866 } 822 }
867 DisposeModuleEmbedderData(data->realms_[index].Get(isolate));
868 data->realms_[index].Reset(); 823 data->realms_[index].Reset();
869 isolate->ContextDisposedNotification(); 824 isolate->ContextDisposedNotification();
870 isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime()); 825 isolate->IdleNotificationDeadline(g_platform->MonotonicallyIncreasingTime());
871 } 826 }
872 827
873 828
874 // Realm.switch(i) switches to the realm i for consecutive interactive inputs. 829 // Realm.switch(i) switches to the realm i for consecutive interactive inputs.
875 void Shell::RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) { 830 void Shell::RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) {
876 Isolate* isolate = args.GetIsolate(); 831 Isolate* isolate = args.GetIsolate();
877 PerIsolateData* data = PerIsolateData::Get(isolate); 832 PerIsolateData* data = PerIsolateData::Get(isolate);
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 1481
1527 1482
1528 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { 1483 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
1529 // This needs to be a critical section since this is not thread-safe 1484 // This needs to be a critical section since this is not thread-safe
1530 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer()); 1485 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer());
1531 // Initialize the global objects 1486 // Initialize the global objects
1532 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); 1487 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
1533 EscapableHandleScope handle_scope(isolate); 1488 EscapableHandleScope handle_scope(isolate);
1534 Local<Context> context = Context::New(isolate, NULL, global_template); 1489 Local<Context> context = Context::New(isolate, NULL, global_template);
1535 DCHECK(!context.IsEmpty()); 1490 DCHECK(!context.IsEmpty());
1536 InitializeModuleEmbedderData(context);
1537 Context::Scope scope(context); 1491 Context::Scope scope(context);
1538 1492
1539 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory(); 1493 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
1540 i::JSArguments js_args = i::FLAG_js_arguments; 1494 i::JSArguments js_args = i::FLAG_js_arguments;
1541 i::Handle<i::FixedArray> arguments_array = 1495 i::Handle<i::FixedArray> arguments_array =
1542 factory->NewFixedArray(js_args.argc); 1496 factory->NewFixedArray(js_args.argc);
1543 for (int j = 0; j < js_args.argc; j++) { 1497 for (int j = 0; j < js_args.argc; j++) {
1544 i::Handle<i::String> arg = 1498 i::Handle<i::String> arg =
1545 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked(); 1499 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked();
1546 arguments_array->set(j, *arg); 1500 arguments_array->set(j, *arg);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 Isolate::Scope iscope(isolate); 1806 Isolate::Scope iscope(isolate);
1853 { 1807 {
1854 HandleScope scope(isolate); 1808 HandleScope scope(isolate);
1855 PerIsolateData data(isolate); 1809 PerIsolateData data(isolate);
1856 Local<Context> context = Shell::CreateEvaluationContext(isolate); 1810 Local<Context> context = Shell::CreateEvaluationContext(isolate);
1857 { 1811 {
1858 Context::Scope cscope(context); 1812 Context::Scope cscope(context);
1859 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); 1813 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
1860 Execute(isolate); 1814 Execute(isolate);
1861 } 1815 }
1862 DisposeModuleEmbedderData(context);
1863 } 1816 }
1864 Shell::CollectGarbage(isolate); 1817 Shell::CollectGarbage(isolate);
1865 } 1818 }
1866 done_semaphore_.Signal(); 1819 done_semaphore_.Signal();
1867 } 1820 }
1868 1821
1869 isolate->Dispose(); 1822 isolate->Dispose();
1870 } 1823 }
1871 1824
1872 1825
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 if (Shell::DeserializeValue(isolate, *data, &offset) 2065 if (Shell::DeserializeValue(isolate, *data, &offset)
2113 .ToLocal(&data_value)) { 2066 .ToLocal(&data_value)) {
2114 Local<Value> argv[] = {data_value}; 2067 Local<Value> argv[] = {data_value};
2115 (void)onmessage_fun->Call(context, global, 1, argv); 2068 (void)onmessage_fun->Call(context, global, 1, argv);
2116 } 2069 }
2117 delete data; 2070 delete data;
2118 } 2071 }
2119 } 2072 }
2120 } 2073 }
2121 } 2074 }
2122 DisposeModuleEmbedderData(context);
2123 } 2075 }
2124 Shell::CollectGarbage(isolate); 2076 Shell::CollectGarbage(isolate);
2125 } 2077 }
2126 isolate->Dispose(); 2078 isolate->Dispose();
2127 2079
2128 // Post NULL to wake the thread waiting on GetMessage() if there is one. 2080 // Post NULL to wake the thread waiting on GetMessage() if there is one.
2129 out_queue_.Enqueue(NULL); 2081 out_queue_.Enqueue(NULL);
2130 out_semaphore_.Signal(); 2082 out_semaphore_.Signal();
2131 } 2083 }
2132 2084
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 Local<Context> context = CreateEvaluationContext(isolate); 2248 Local<Context> context = CreateEvaluationContext(isolate);
2297 if (last_run && options.use_interactive_shell()) { 2249 if (last_run && options.use_interactive_shell()) {
2298 // Keep using the same context in the interactive shell. 2250 // Keep using the same context in the interactive shell.
2299 evaluation_context_.Reset(isolate, context); 2251 evaluation_context_.Reset(isolate, context);
2300 } 2252 }
2301 { 2253 {
2302 Context::Scope cscope(context); 2254 Context::Scope cscope(context);
2303 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate)); 2255 PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
2304 options.isolate_sources[0].Execute(isolate); 2256 options.isolate_sources[0].Execute(isolate);
2305 } 2257 }
2306 DisposeModuleEmbedderData(context);
2307 } 2258 }
2308 CollectGarbage(isolate); 2259 CollectGarbage(isolate);
2309 for (int i = 1; i < options.num_isolates; ++i) { 2260 for (int i = 1; i < options.num_isolates; ++i) {
2310 if (last_run) { 2261 if (last_run) {
2311 options.isolate_sources[i].JoinThread(); 2262 options.isolate_sources[i].JoinThread();
2312 } else { 2263 } else {
2313 options.isolate_sources[i].WaitForThread(); 2264 options.isolate_sources[i].WaitForThread();
2314 } 2265 }
2315 } 2266 }
2316 CleanupWorkers(); 2267 CleanupWorkers();
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
2813 } 2764 }
2814 2765
2815 } // namespace v8 2766 } // namespace v8
2816 2767
2817 2768
2818 #ifndef GOOGLE3 2769 #ifndef GOOGLE3
2819 int main(int argc, char* argv[]) { 2770 int main(int argc, char* argv[]) {
2820 return v8::Shell::Main(argc, argv); 2771 return v8::Shell::Main(argc, argv);
2821 } 2772 }
2822 #endif 2773 #endif
OLDNEW
« no previous file with comments | « src/d8.h ('k') | src/factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698