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

Side by Side Diff: src/d8.cc

Issue 2393303002: [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 <map> 12 #include <unordered_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 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 size_t last_slash = path.find_last_of('/'); 551 size_t last_slash = path.find_last_of('/');
552 DCHECK(last_slash != std::string::npos); 552 DCHECK(last_slash != std::string::npos);
553 return path.substr(0, last_slash); 553 return path.substr(0, last_slash);
554 } 554 }
555 555
556 std::string EnsureAbsolutePath(const std::string& path, 556 std::string EnsureAbsolutePath(const std::string& path,
557 const std::string& dir_name) { 557 const std::string& dir_name) {
558 return IsAbsolutePath(path) ? path : dir_name + '/' + path; 558 return IsAbsolutePath(path) ? path : dir_name + '/' + path;
559 } 559 }
560 560
561 // Per-context Module data, allowing sharing of module maps
562 // across top-level module loads.
563 class ModuleEmbedderData {
564 private:
565 class ModuleGlobalHash {
566 public:
567 explicit ModuleGlobalHash(Isolate* isolate) : isolate_(isolate) {}
568 size_t operator()(const Global<Module>& module) const {
569 return module.Get(isolate_)->GetIdentityHash();
570 }
571
572 private:
573 Isolate* isolate_;
574 };
575
576 public:
577 explicit ModuleEmbedderData(Isolate* isolate)
578 : module_to_directory_map(10, ModuleGlobalHash(isolate)) {}
579
580 // Map from normalized module specifiers to Modules.
581 std::unordered_map<std::string, Global<Module>> specifier_to_module_map;
582 // Map from Module to the directory that Module was loaded from.
neis 2016/10/06 09:44:46 Nit: keep the comments both in singular or both in
adamk 2016/10/06 20:47:01 Thanks for keeping me honest. Went with singular.
583 std::unordered_map<Global<Module>, std::string, ModuleGlobalHash>
584 module_to_directory_map;
585 };
586
587 enum D8EmbedderDataFields {
588 kDebugIdIndex = Context::kDebugIdIndex,
neis 2016/10/06 09:44:46 What is this for?
adamk 2016/10/06 20:47:01 Added a comment (and removed the type name). Basic
589 kModuleEmbedderDataIndex
590 };
591
592 void InitializeModuleEmbedderData(Local<Context> context) {
593 context->SetAlignedPointerInEmbedderData(
594 kModuleEmbedderDataIndex, new ModuleEmbedderData(context->GetIsolate()));
595 }
596
597 ModuleEmbedderData* GetModuleDataFromContext(Local<Context> context) {
598 return static_cast<ModuleEmbedderData*>(
599 context->GetAlignedPointerFromEmbedderData(kModuleEmbedderDataIndex));
600 }
601
561 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, 602 MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
562 Local<String> specifier, 603 Local<String> specifier,
563 Local<Module> referrer, 604 Local<Module> referrer) {
564 Local<Value> data) {
565 Isolate* isolate = context->GetIsolate(); 605 Isolate* isolate = context->GetIsolate();
566 auto module_map = static_cast<std::map<std::string, Global<Module>>*>( 606 ModuleEmbedderData* d = GetModuleDataFromContext(context);
567 External::Cast(*data)->Value()); 607 auto dir_name_it =
568 Local<String> dir_name = Local<String>::Cast(referrer->GetEmbedderData()); 608 d->module_to_directory_map.find(Global<Module>(isolate, referrer));
609 CHECK(dir_name_it != d->module_to_directory_map.end());
569 std::string absolute_path = 610 std::string absolute_path =
570 EnsureAbsolutePath(ToSTLString(specifier), ToSTLString(dir_name)); 611 EnsureAbsolutePath(ToSTLString(specifier), dir_name_it->second);
571 auto it = module_map->find(absolute_path); 612 auto module_it = d->specifier_to_module_map.find(absolute_path);
572 if (it != module_map->end()) { 613 CHECK(module_it != d->specifier_to_module_map.end());
573 return it->second.Get(isolate); 614 return module_it->second.Get(isolate);
574 }
575 return MaybeLocal<Module>();
576 } 615 }
577 616
578 } // anonymous namespace 617 } // anonymous namespace
579 618
580 MaybeLocal<Module> Shell::FetchModuleTree( 619 MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
581 Isolate* isolate, const std::string& file_name, 620 const std::string& file_name) {
582 std::map<std::string, Global<Module>>* module_map) {
583 DCHECK(IsAbsolutePath(file_name)); 621 DCHECK(IsAbsolutePath(file_name));
622 Isolate* isolate = context->GetIsolate();
584 TryCatch try_catch(isolate); 623 TryCatch try_catch(isolate);
585 try_catch.SetVerbose(true); 624 try_catch.SetVerbose(true);
586 Local<String> source_text = ReadFile(isolate, file_name.c_str()); 625 Local<String> source_text = ReadFile(isolate, file_name.c_str());
587 if (source_text.IsEmpty()) { 626 if (source_text.IsEmpty()) {
588 printf("Error reading '%s'\n", file_name.c_str()); 627 printf("Error reading '%s'\n", file_name.c_str());
589 Shell::Exit(1); 628 Shell::Exit(1);
590 } 629 }
591 ScriptOrigin origin( 630 ScriptOrigin origin(
592 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal) 631 String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal)
593 .ToLocalChecked()); 632 .ToLocalChecked());
594 ScriptCompiler::Source source(source_text, origin); 633 ScriptCompiler::Source source(source_text, origin);
595 Local<Module> module; 634 Local<Module> module;
596 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) { 635 if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
597 ReportException(isolate, &try_catch); 636 ReportException(isolate, &try_catch);
598 return MaybeLocal<Module>(); 637 return MaybeLocal<Module>();
599 } 638 }
600 module_map->insert( 639
640 ModuleEmbedderData* d = GetModuleDataFromContext(context);
641 d->specifier_to_module_map.insert(
601 std::make_pair(file_name, Global<Module>(isolate, module))); 642 std::make_pair(file_name, Global<Module>(isolate, module)));
602 643
603 std::string dir_name = DirName(file_name); 644 std::string dir_name = DirName(file_name);
604 module->SetEmbedderData( 645 d->module_to_directory_map.insert(
605 String::NewFromUtf8(isolate, dir_name.c_str(), NewStringType::kNormal) 646 std::make_pair(Global<Module>(isolate, module), dir_name));
neis 2016/10/06 09:44:46 Can you add checks here that these insertions succ
adamk 2016/10/06 20:47:01 Done.
606 .ToLocalChecked());
607 647
608 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { 648 for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) {
609 Local<String> name = module->GetModuleRequest(i); 649 Local<String> name = module->GetModuleRequest(i);
610 std::string absolute_path = EnsureAbsolutePath(ToSTLString(name), dir_name); 650 std::string absolute_path = EnsureAbsolutePath(ToSTLString(name), dir_name);
611 if (!module_map->count(absolute_path)) { 651 if (!d->specifier_to_module_map.count(absolute_path)) {
612 if (FetchModuleTree(isolate, absolute_path, module_map).IsEmpty()) { 652 if (FetchModuleTree(context, absolute_path).IsEmpty()) {
613 return MaybeLocal<Module>(); 653 return MaybeLocal<Module>();
614 } 654 }
615 } 655 }
616 } 656 }
617 657
618 return module; 658 return module;
619 } 659 }
620 660
621 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { 661 bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
622 HandleScope handle_scope(isolate); 662 HandleScope handle_scope(isolate);
623 663
664 PerIsolateData* data = PerIsolateData::Get(isolate);
665 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
666 Context::Scope context_scope(realm);
667
624 std::string absolute_path = 668 std::string absolute_path =
625 EnsureAbsolutePath(file_name, GetWorkingDirectory()); 669 EnsureAbsolutePath(file_name, GetWorkingDirectory());
626 std::replace(absolute_path.begin(), absolute_path.end(), '\\', '/'); 670 std::replace(absolute_path.begin(), absolute_path.end(), '\\', '/');
627 671
628 Local<Module> root_module; 672 Local<Module> root_module;
629 std::map<std::string, Global<Module>> module_map; 673 if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) {
630 if (!FetchModuleTree(isolate, absolute_path, &module_map)
631 .ToLocal(&root_module)) {
632 return false; 674 return false;
633 } 675 }
634 676
635 TryCatch try_catch(isolate); 677 TryCatch try_catch(isolate);
636 try_catch.SetVerbose(true); 678 try_catch.SetVerbose(true);
637 679
638 MaybeLocal<Value> maybe_result; 680 MaybeLocal<Value> maybe_result;
639 { 681 if (root_module->Instantiate(realm, ResolveModuleCallback)) {
640 PerIsolateData* data = PerIsolateData::Get(isolate); 682 maybe_result = root_module->Evaluate(realm);
641 Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); 683 EmptyMessageQueues(isolate);
642 Context::Scope context_scope(realm);
643
644 if (root_module->Instantiate(realm, ResolveModuleCallback,
645 External::New(isolate, &module_map))) {
646 maybe_result = root_module->Evaluate(realm);
647 EmptyMessageQueues(isolate);
648 }
649 } 684 }
650 Local<Value> result; 685 Local<Value> result;
651 if (!maybe_result.ToLocal(&result)) { 686 if (!maybe_result.ToLocal(&result)) {
652 DCHECK(try_catch.HasCaught()); 687 DCHECK(try_catch.HasCaught());
653 // Print errors that happened during execution. 688 // Print errors that happened during execution.
654 ReportException(isolate, &try_catch); 689 ReportException(isolate, &try_catch);
655 return false; 690 return false;
656 } 691 }
657 DCHECK(!try_catch.HasCaught()); 692 DCHECK(!try_catch.HasCaught());
658 return true; 693 return true;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 old_realms[i].Reset(); 803 old_realms[i].Reset();
769 } 804 }
770 delete[] old_realms; 805 delete[] old_realms;
771 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); 806 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
772 Local<Context> context = Context::New(isolate, NULL, global_template); 807 Local<Context> context = Context::New(isolate, NULL, global_template);
773 if (context.IsEmpty()) { 808 if (context.IsEmpty()) {
774 DCHECK(try_catch.HasCaught()); 809 DCHECK(try_catch.HasCaught());
775 try_catch.ReThrow(); 810 try_catch.ReThrow();
776 return MaybeLocal<Context>(); 811 return MaybeLocal<Context>();
777 } 812 }
813 InitializeModuleEmbedderData(context);
778 data->realms_[index].Reset(isolate, context); 814 data->realms_[index].Reset(isolate, context);
779 args.GetReturnValue().Set(index); 815 args.GetReturnValue().Set(index);
780 return context; 816 return context;
781 } 817 }
782 818
783 // Realm.create() creates a new realm with a distinct security token 819 // Realm.create() creates a new realm with a distinct security token
784 // and returns its index. 820 // and returns its index.
785 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) { 821 void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) {
786 CreateRealm(args); 822 CreateRealm(args);
787 } 823 }
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 1505
1470 1506
1471 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { 1507 Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
1472 // This needs to be a critical section since this is not thread-safe 1508 // This needs to be a critical section since this is not thread-safe
1473 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer()); 1509 base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer());
1474 // Initialize the global objects 1510 // Initialize the global objects
1475 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); 1511 Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
1476 EscapableHandleScope handle_scope(isolate); 1512 EscapableHandleScope handle_scope(isolate);
1477 Local<Context> context = Context::New(isolate, NULL, global_template); 1513 Local<Context> context = Context::New(isolate, NULL, global_template);
1478 DCHECK(!context.IsEmpty()); 1514 DCHECK(!context.IsEmpty());
1515 InitializeModuleEmbedderData(context);
1479 Context::Scope scope(context); 1516 Context::Scope scope(context);
1480 1517
1481 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory(); 1518 i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
1482 i::JSArguments js_args = i::FLAG_js_arguments; 1519 i::JSArguments js_args = i::FLAG_js_arguments;
1483 i::Handle<i::FixedArray> arguments_array = 1520 i::Handle<i::FixedArray> arguments_array =
1484 factory->NewFixedArray(js_args.argc); 1521 factory->NewFixedArray(js_args.argc);
1485 for (int j = 0; j < js_args.argc; j++) { 1522 for (int j = 0; j < js_args.argc; j++) {
1486 i::Handle<i::String> arg = 1523 i::Handle<i::String> arg =
1487 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked(); 1524 factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked();
1488 arguments_array->set(j, *arg); 1525 arguments_array->set(j, *arg);
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 } 2789 }
2753 2790
2754 } // namespace v8 2791 } // namespace v8
2755 2792
2756 2793
2757 #ifndef GOOGLE3 2794 #ifndef GOOGLE3
2758 int main(int argc, char* argv[]) { 2795 int main(int argc, char* argv[]) {
2759 return v8::Shell::Main(argc, argv); 2796 return v8::Shell::Main(argc, argv);
2760 } 2797 }
2761 #endif 2798 #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