diff options
author | Michaƫl Zasso <targos@protonmail.com> | 2018-01-24 20:16:06 +0100 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2018-01-24 15:02:20 -0800 |
commit | 4c4af643e5042d615a60c6bbc05aee9d81b903e5 (patch) | |
tree | 3fb0a97988fe4439ae3ae06f26915d1dcf8cab92 /deps/v8/src/d8.cc | |
parent | fa9f31a4fda5a3782c652e56e394465805ebb50f (diff) | |
download | android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.gz android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.bz2 android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.zip |
deps: update V8 to 6.4.388.40
PR-URL: https://github.com/nodejs/node/pull/17489
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/d8.cc')
-rw-r--r-- | deps/v8/src/d8.cc | 406 |
1 files changed, 262 insertions, 144 deletions
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc index 8a7b922ebb..54a41fc00e 100644 --- a/deps/v8/src/d8.cc +++ b/deps/v8/src/d8.cc @@ -124,7 +124,7 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase { } #endif void* data = AllocateUninitialized(length); - return data == NULL ? data : memset(data, 0, length); + return data == nullptr ? data : memset(data, 0, length); } void* AllocateUninitialized(size_t length) override { #if USE_VM @@ -142,34 +142,35 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase { void Free(void* data, size_t length) override { #if USE_VM if (RoundToPageSize(&length)) { - base::OS::ReleaseRegion(data, length); + CHECK(base::OS::Free(data, length)); return; } #endif free(data); } - // If {length} is at least {VM_THRESHOLD}, round up to next page size - // and return {true}. Otherwise return {false}. + // If {length} is at least {VM_THRESHOLD}, round up to next page size and + // return {true}. Otherwise return {false}. bool RoundToPageSize(size_t* length) { - const size_t kPageSize = base::OS::CommitPageSize(); + size_t page_size = base::OS::AllocatePageSize(); if (*length >= VM_THRESHOLD && *length < TWO_GB) { - *length = ((*length + kPageSize - 1) / kPageSize) * kPageSize; + *length = RoundUp(*length, page_size); return true; } return false; } #if USE_VM void* VirtualMemoryAllocate(size_t length) { - void* data = base::OS::ReserveRegion(length, nullptr); - if (data && !base::OS::CommitRegion(data, length, false)) { - base::OS::ReleaseRegion(data, length); - return nullptr; - } + size_t page_size = base::OS::AllocatePageSize(); + size_t alloc_size = RoundUp(length, page_size); + void* address = base::OS::Allocate(nullptr, alloc_size, page_size, + base::OS::MemoryPermission::kReadWrite); + if (address != nullptr) { #if defined(LEAK_SANITIZER) - __lsan_register_root_region(data, length); + __lsan_register_root_region(address, alloc_size); #endif - MSAN_MEMORY_IS_INITIALIZED(data, length); - return data; + MSAN_MEMORY_IS_INITIALIZED(address, alloc_size); + } + return address; } #endif }; @@ -177,14 +178,14 @@ class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase { class MockArrayBufferAllocator : public ArrayBufferAllocatorBase { const size_t kAllocationLimit = 10 * MB; size_t get_actual_length(size_t length) const { - return length > kAllocationLimit ? base::OS::CommitPageSize() : length; + return length > kAllocationLimit ? base::OS::AllocatePageSize() : length; } public: void* Allocate(size_t length) override { const size_t actual_length = get_actual_length(length); void* data = AllocateUninitialized(actual_length); - return data == NULL ? data : memset(data, 0, actual_length); + return data == nullptr ? data : memset(data, 0, actual_length); } void* AllocateUninitialized(size_t length) override { return malloc(get_actual_length(length)); @@ -208,6 +209,18 @@ class PredictablePlatform : public Platform { DCHECK_NOT_NULL(platform_); } + std::shared_ptr<TaskRunner> GetForegroundTaskRunner( + v8::Isolate* isolate) override { + return platform_->GetForegroundTaskRunner(isolate); + } + + std::shared_ptr<TaskRunner> GetBackgroundTaskRunner( + v8::Isolate* isolate) override { + // Return the foreground task runner here, so that all tasks get executed + // sequentially in a predictable order. + return platform_->GetForegroundTaskRunner(isolate); + } + void CallOnBackgroundThread(Task* task, ExpectedRuntime expected_runtime) override { // It's not defined when background tasks are being executed, so we can just @@ -252,13 +265,12 @@ class PredictablePlatform : public Platform { DISALLOW_COPY_AND_ASSIGN(PredictablePlatform); }; - -v8::Platform* g_platform = NULL; +std::unique_ptr<v8::Platform> g_platform; v8::Platform* GetDefaultPlatform() { return i::FLAG_verify_predictable - ? static_cast<PredictablePlatform*>(g_platform)->platform() - : g_platform; + ? static_cast<PredictablePlatform*>(g_platform.get())->platform() + : g_platform.get(); } static Local<Value> Throw(Isolate* isolate, const char* message) { @@ -270,19 +282,26 @@ static Local<Value> Throw(Isolate* isolate, const char* message) { Worker* GetWorkerFromInternalField(Isolate* isolate, Local<Object> object) { if (object->InternalFieldCount() != 1) { Throw(isolate, "this is not a Worker"); - return NULL; + return nullptr; } Worker* worker = static_cast<Worker*>(object->GetAlignedPointerFromInternalField(0)); - if (worker == NULL) { + if (worker == nullptr) { Throw(isolate, "Worker is defunct because main thread is terminating"); - return NULL; + return nullptr; } return worker; } +base::Thread::Options GetThreadOptions(const char* name) { + // On some systems (OSX 10.6) the stack size default is 0.5Mb or less + // which is not enough to parse the big literal expressions used in tests. + // The stack size should be at least StackGuard::kLimitSize + some + // OS-specific padding for thread startup code. 2Mbytes seems to be enough. + return base::Thread::Options(name, 2 * MB); +} } // namespace @@ -401,12 +420,13 @@ static platform::tracing::TraceConfig* CreateTraceConfigFromJSON( class PerIsolateData { public: - explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) { + explicit PerIsolateData(Isolate* isolate) + : isolate_(isolate), realms_(nullptr) { isolate->SetData(0, this); } ~PerIsolateData() { - isolate_->SetData(0, NULL); // Not really needed, just to be sure... + isolate_->SetData(0, nullptr); // Not really needed, just to be sure... } inline static PerIsolateData* Get(Isolate* isolate) { @@ -473,7 +493,7 @@ class ExternalOwningOneByteStringResource }; CounterMap* Shell::counter_map_; -base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; +base::OS::MemoryMappedFile* Shell::counters_file_ = nullptr; CounterCollection Shell::local_counters_; CounterCollection* Shell::counters_ = &local_counters_; base::LazyMutex Shell::context_mutex_; @@ -498,6 +518,53 @@ bool CounterMap::Match(void* key1, void* key2) { return strcmp(name1, name2) == 0; } +// Dummy external source stream which returns the whole source in one go. +class DummySourceStream : public v8::ScriptCompiler::ExternalSourceStream { + public: + explicit DummySourceStream(Local<String> source) : done_(false) { + source_length_ = source->Utf8Length(); + source_buffer_.reset(new uint8_t[source_length_]); + source->WriteUtf8(reinterpret_cast<char*>(source_buffer_.get()), + source_length_); + } + + virtual size_t GetMoreData(const uint8_t** src) { + if (done_) { + return 0; + } + *src = source_buffer_.release(); + done_ = true; + + return source_length_; + } + + private: + int source_length_; + std::unique_ptr<uint8_t[]> source_buffer_; + bool done_; +}; + +class BackgroundCompileThread : public base::Thread { + public: + BackgroundCompileThread(Isolate* isolate, Local<String> source) + : base::Thread(GetThreadOptions("BackgroundCompileThread")), + source_(source), + streamed_source_(new DummySourceStream(source), + v8::ScriptCompiler::StreamedSource::UTF8), + task_(v8::ScriptCompiler::StartStreamingScript(isolate, + &streamed_source_)) {} + + void Run() override { task_->Run(); } + + v8::ScriptCompiler::StreamedSource* streamed_source() { + return &streamed_source_; + } + + private: + Local<String> source_; + v8::ScriptCompiler::StreamedSource streamed_source_; + std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task_; +}; ScriptCompiler::CachedData* CompileForCachedData( Local<String> source, Local<Value> name, @@ -506,7 +573,7 @@ ScriptCompiler::CachedData* CompileForCachedData( uint16_t* source_buffer = new uint16_t[source_length]; source->Write(source_buffer, 0, source_length); int name_length = 0; - uint16_t* name_buffer = NULL; + uint16_t* name_buffer = nullptr; if (name->IsString()) { Local<String> name_string = Local<String>::Cast(name); name_length = name_string->Length(); @@ -515,10 +582,14 @@ ScriptCompiler::CachedData* CompileForCachedData( } Isolate::CreateParams create_params; create_params.array_buffer_allocator = Shell::array_buffer_allocator; + i::FLAG_hash_seed ^= 1337; // Use a different hash seed. Isolate* temp_isolate = Isolate::New(create_params); + i::FLAG_hash_seed ^= 1337; // Restore old hash seed. temp_isolate->SetHostImportModuleDynamicallyCallback( Shell::HostImportModuleDynamically); - ScriptCompiler::CachedData* result = NULL; + temp_isolate->SetHostInitializeImportMetaObjectCallback( + Shell::HostInitializeImportMetaObject); + ScriptCompiler::CachedData* result = nullptr; { Isolate::Scope isolate_scope(temp_isolate); HandleScope handle_scope(temp_isolate); @@ -576,10 +647,10 @@ MaybeLocal<Script> Shell::CompileString( } else { DCHECK(false); // A new compile option? } - if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions; + if (data == nullptr) compile_options = ScriptCompiler::kNoCompileOptions; MaybeLocal<Script> result = ScriptCompiler::Compile(context, &cached_source, compile_options); - CHECK(data == NULL || !data->rejected); + CHECK(data == nullptr || !data->rejected); return result; } @@ -593,20 +664,44 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source, try_catch.SetVerbose(true); MaybeLocal<Value> maybe_result; + bool success = true; { PerIsolateData* data = PerIsolateData::Get(isolate); Local<Context> realm = Local<Context>::New(isolate, data->realms_[data->realm_current_]); Context::Scope context_scope(realm); + MaybeLocal<Script> maybe_script; + if (options.stress_background_compile) { + // Start a background thread compiling the script. + BackgroundCompileThread background_compile_thread(isolate, source); + background_compile_thread.Start(); + + // In parallel, compile on the main thread to flush out any data races. + { + TryCatch ignore_try_catch(isolate); + Shell::CompileString(isolate, source, name, options.compile_options); + } + + // Join with background thread and finalize compilation. + background_compile_thread.Join(); + ScriptOrigin origin(name); + maybe_script = v8::ScriptCompiler::Compile( + isolate->GetCurrentContext(), + background_compile_thread.streamed_source(), source, origin); + } else { + maybe_script = + Shell::CompileString(isolate, source, name, options.compile_options); + } + Local<Script> script; - if (!Shell::CompileString(isolate, source, name, options.compile_options) - .ToLocal(&script)) { + if (!maybe_script.ToLocal(&script)) { // Print errors that happened during compilation. if (report_exceptions) ReportException(isolate, &try_catch); return false; } + maybe_result = script->Run(realm); - EmptyMessageQueues(isolate); + if (!EmptyMessageQueues(isolate)) success = false; data->realm_current_ = data->realm_switch_; } Local<Value> result; @@ -632,7 +727,7 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source, printf("\n"); } } - return true; + return success; } namespace { @@ -659,7 +754,7 @@ std::string GetWorkingDirectory() { char system_buffer[MAX_PATH]; // TODO(adamk): Support Unicode paths. DWORD len = GetCurrentDirectoryA(MAX_PATH, system_buffer); - CHECK(len > 0); + CHECK_GT(len, 0); return system_buffer; #else char curdir[PATH_MAX]; @@ -712,13 +807,13 @@ class ModuleEmbedderData { public: explicit ModuleEmbedderData(Isolate* isolate) - : module_to_directory_map(10, ModuleGlobalHash(isolate)) {} + : module_to_specifier_map(10, ModuleGlobalHash(isolate)) {} // Map from normalized module specifier to Module. std::unordered_map<std::string, Global<Module>> specifier_to_module_map; - // Map from Module to the directory that Module was loaded from. + // Map from Module to its URL as defined in the ScriptOrigin std::unordered_map<Global<Module>, std::string, ModuleGlobalHash> - module_to_directory_map; + module_to_specifier_map; }; enum { @@ -746,11 +841,11 @@ MaybeLocal<Module> ResolveModuleCallback(Local<Context> context, Local<Module> referrer) { Isolate* isolate = context->GetIsolate(); ModuleEmbedderData* d = GetModuleDataFromContext(context); - auto dir_name_it = - d->module_to_directory_map.find(Global<Module>(isolate, referrer)); - CHECK(dir_name_it != d->module_to_directory_map.end()); - std::string absolute_path = - NormalizePath(ToSTLString(isolate, specifier), dir_name_it->second); + auto specifier_it = + d->module_to_specifier_map.find(Global<Module>(isolate, referrer)); + CHECK(specifier_it != d->module_to_specifier_map.end()); + std::string absolute_path = NormalizePath(ToSTLString(isolate, specifier), + DirName(specifier_it->second)); auto module_it = d->specifier_to_module_map.find(absolute_path); CHECK(module_it != d->specifier_to_module_map.end()); return module_it->second.Get(isolate); @@ -783,11 +878,11 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context, CHECK(d->specifier_to_module_map .insert(std::make_pair(file_name, Global<Module>(isolate, module))) .second); + CHECK(d->module_to_specifier_map + .insert(std::make_pair(Global<Module>(isolate, module), file_name)) + .second); std::string dir_name = DirName(file_name); - CHECK(d->module_to_directory_map - .insert(std::make_pair(Global<Module>(isolate, module), dir_name)) - .second); for (int i = 0, length = module->GetModuleRequestsLength(); i < length; ++i) { Local<String> name = module->GetModuleRequest(i); @@ -842,6 +937,26 @@ MaybeLocal<Promise> Shell::HostImportModuleDynamically( return MaybeLocal<Promise>(); } +void Shell::HostInitializeImportMetaObject(Local<Context> context, + Local<Module> module, + Local<Object> meta) { + Isolate* isolate = context->GetIsolate(); + HandleScope handle_scope(isolate); + + ModuleEmbedderData* d = GetModuleDataFromContext(context); + auto specifier_it = + d->module_to_specifier_map.find(Global<Module>(isolate, module)); + CHECK(specifier_it != d->module_to_specifier_map.end()); + + Local<String> url_key = + String::NewFromUtf8(isolate, "url", NewStringType::kNormal) + .ToLocalChecked(); + Local<String> url = String::NewFromUtf8(isolate, specifier_it->second.c_str(), + NewStringType::kNormal) + .ToLocalChecked(); + meta->CreateDataProperty(context, url_key, url).ToChecked(); +} + void Shell::DoHostImportModuleDynamically(void* import_data) { std::unique_ptr<DynamicImportData> import_data_( static_cast<DynamicImportData*>(import_data)); @@ -1059,7 +1174,7 @@ MaybeLocal<Context> Shell::CreateRealm( } Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); Local<Context> context = - Context::New(isolate, NULL, global_template, global_object); + Context::New(isolate, nullptr, global_template, global_object); DCHECK(!try_catch.HasCaught()); if (context.IsEmpty()) return MaybeLocal<Context>(); InitializeModuleEmbedderData(context); @@ -1240,7 +1355,7 @@ void Shell::Write(const v8::FunctionCallbackInfo<v8::Value>& args) { void Shell::Read(const v8::FunctionCallbackInfo<v8::Value>& args) { String::Utf8Value file(args.GetIsolate(), args[0]); - if (*file == NULL) { + if (*file == nullptr) { Throw(args.GetIsolate(), "Error loading file"); return; } @@ -1270,9 +1385,9 @@ Local<String> Shell::ReadFromStdin(Isolate* isolate) { // Continue reading if the line ends with an escape '\\' or the line has // not been fully read into the buffer yet (does not end with '\n'). // If fgets gets an error, just give up. - char* input = NULL; + char* input = nullptr; input = fgets(buffer, kBufferSize, stdin); - if (input == NULL) return Local<String>(); + if (input == nullptr) return Local<String>(); length = static_cast<int>(strlen(buffer)); if (length == 0) { return accumulator; @@ -1301,7 +1416,7 @@ void Shell::Load(const v8::FunctionCallbackInfo<v8::Value>& args) { for (int i = 0; i < args.Length(); i++) { HandleScope handle_scope(args.GetIsolate()); String::Utf8Value file(args.GetIsolate(), args[i]); - if (*file == NULL) { + if (*file == nullptr) { Throw(args.GetIsolate(), "Error loading file"); return; } @@ -1310,11 +1425,11 @@ void Shell::Load(const v8::FunctionCallbackInfo<v8::Value>& args) { Throw(args.GetIsolate(), "Error loading file"); return; } - if (!ExecuteString( - args.GetIsolate(), source, - String::NewFromUtf8(args.GetIsolate(), *file, - NewStringType::kNormal).ToLocalChecked(), - false, true)) { + if (!ExecuteString(args.GetIsolate(), source, + String::NewFromUtf8(args.GetIsolate(), *file, + NewStringType::kNormal) + .ToLocalChecked(), + false, !options.quiet_load)) { Throw(args.GetIsolate(), "Error executing file"); return; } @@ -1350,10 +1465,10 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) { return; } - // Initialize the embedder field to NULL; if we return early without + // Initialize the embedder field to nullptr; if we return early without // creating a new Worker (because the main thread is terminating) we can // early-out from the instance calls. - args.Holder()->SetAlignedPointerInInternalField(0, NULL); + args.Holder()->SetAlignedPointerInInternalField(0, nullptr); if (!allow_new_workers_) return; @@ -1545,17 +1660,17 @@ CounterCollection::CounterCollection() { Counter* CounterCollection::GetNextCounter() { - if (counters_in_use_ == kMaxCounters) return NULL; + if (counters_in_use_ == kMaxCounters) return nullptr; return &counters_[counters_in_use_++]; } void Shell::MapCounters(v8::Isolate* isolate, const char* name) { counters_file_ = base::OS::MemoryMappedFile::create( - name, nullptr, sizeof(CounterCollection), &local_counters_); - void* memory = (counters_file_ == NULL) ? - NULL : counters_file_->memory(); - if (memory == NULL) { + name, sizeof(CounterCollection), &local_counters_); + void* memory = + (counters_file_ == nullptr) ? nullptr : counters_file_->memory(); + if (memory == nullptr) { printf("Could not map counters file %s\n", name); Exit(1); } @@ -1580,9 +1695,9 @@ int CounterMap::Hash(const char* name) { Counter* Shell::GetCounter(const char* name, bool is_histogram) { Counter* counter = counter_map_->Lookup(name); - if (counter == NULL) { + if (counter == nullptr) { counter = counters_->GetNextCounter(); - if (counter != NULL) { + if (counter != nullptr) { counter_map_->Set(name, counter); counter->Bind(name, is_histogram); } @@ -1596,10 +1711,10 @@ Counter* Shell::GetCounter(const char* name, bool is_histogram) { int* Shell::LookupCounter(const char* name) { Counter* counter = GetCounter(name, false); - if (counter != NULL) { + if (counter != nullptr) { return counter->ptr(); } else { - return NULL; + return nullptr; } } @@ -1871,7 +1986,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { // Initialize the global objects Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); EscapableHandleScope handle_scope(isolate); - Local<Context> context = Context::New(isolate, NULL, global_template); + Local<Context> context = Context::New(isolate, nullptr, global_template); DCHECK(!context.IsEmpty()); InitializeModuleEmbedderData(context); Context::Scope scope(context); @@ -2082,17 +2197,17 @@ static FILE* FOpen(const char* path, const char* mode) { if (fopen_s(&result, path, mode) == 0) { return result; } else { - return NULL; + return nullptr; } #else FILE* file = fopen(path, mode); - if (file == NULL) return NULL; + if (file == nullptr) return nullptr; struct stat file_stat; - if (fstat(fileno(file), &file_stat) != 0) return NULL; + if (fstat(fileno(file), &file_stat) != 0) return nullptr; bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0); if (is_regular_file) return file; fclose(file); - return NULL; + return nullptr; #endif } @@ -2102,7 +2217,7 @@ static char* ReadChars(const char* name, int* size_out) { } FILE* file = FOpen(name, "rb"); - if (file == NULL) return NULL; + if (file == nullptr) return nullptr; fseek(file, 0, SEEK_END); size_t size = ftell(file); @@ -2144,18 +2259,19 @@ static void ReadBufferWeakCallback( void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) { - DCHECK(sizeof(char) == sizeof(uint8_t)); // NOLINT + static_assert(sizeof(char) == sizeof(uint8_t), + "char and uint8_t should both have 1 byte"); Isolate* isolate = args.GetIsolate(); String::Utf8Value filename(isolate, args[0]); int length; - if (*filename == NULL) { + if (*filename == nullptr) { Throw(isolate, "Error loading file"); return; } DataAndPersistent* data = new DataAndPersistent; data->data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length)); - if (data->data == NULL) { + if (data->data == nullptr) { delete data; Throw(isolate, "Error reading file"); return; @@ -2165,7 +2281,6 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) { data->handle.Reset(isolate, buffer); data->handle.SetWeak(data, ReadBufferWeakCallback, v8::WeakCallbackType::kParameter); - data->handle.MarkIndependent(); isolate->AdjustAmountOfExternalAllocatedMemory(length); args.GetReturnValue().Set(buffer); @@ -2175,7 +2290,7 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) { Local<String> Shell::ReadFile(Isolate* isolate, const char* name) { int size = 0; char* chars = ReadChars(name, &size); - if (chars == NULL) return Local<String>(); + if (chars == nullptr) return Local<String>(); Local<String> result; if (i::FLAG_use_external_strings && internal::String::IsAscii(chars, size)) { String::ExternalOneByteStringResource* resource = @@ -2237,7 +2352,7 @@ class InspectorFrontend final : public v8_inspector::V8Inspector::Channel { void Send(const v8_inspector::StringView& string) { v8::Isolate::AllowJavascriptExecutionScope allow_script(isolate_); int length = static_cast<int>(string.length()); - DCHECK(length < v8::String::kMaxLength); + DCHECK_LT(length, v8::String::kMaxLength); Local<String> message = (string.is8Bit() ? v8::String::NewFromOneByte( @@ -2350,7 +2465,7 @@ class InspectorClient : public v8_inspector::V8InspectorClient { SourceGroup::~SourceGroup() { delete thread_; - thread_ = NULL; + thread_ = nullptr; } @@ -2413,14 +2528,8 @@ Local<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) { return Shell::ReadFile(isolate, name); } - -base::Thread::Options SourceGroup::GetThreadOptions() { - // On some systems (OSX 10.6) the stack size default is 0.5Mb or less - // which is not enough to parse the big literal expressions used in tests. - // The stack size should be at least StackGuard::kLimitSize + some - // OS-specific padding for thread startup code. 2Mbytes seems to be enough. - return base::Thread::Options("IsolateThread", 2 * MB); -} +SourceGroup::IsolateThread::IsolateThread(SourceGroup* group) + : base::Thread(GetThreadOptions("IsolateThread")), group_(group) {} void SourceGroup::ExecuteInThread() { Isolate::CreateParams create_params; @@ -2428,6 +2537,8 @@ void SourceGroup::ExecuteInThread() { Isolate* isolate = Isolate::New(create_params); isolate->SetHostImportModuleDynamicallyCallback( Shell::HostImportModuleDynamically); + isolate->SetHostInitializeImportMetaObjectCallback( + Shell::HostInitializeImportMetaObject); Shell::EnsureEventLoopInitialized(isolate); D8Console console(isolate); @@ -2460,7 +2571,7 @@ void SourceGroup::ExecuteInThread() { void SourceGroup::StartExecuteInThread() { - if (thread_ == NULL) { + if (thread_ == nullptr) { thread_ = new IsolateThread(this); thread_->Start(); } @@ -2469,13 +2580,13 @@ void SourceGroup::StartExecuteInThread() { void SourceGroup::WaitForThread() { - if (thread_ == NULL) return; + if (thread_ == nullptr) return; done_semaphore_.Wait(); } void SourceGroup::JoinThread() { - if (thread_ == NULL) return; + if (thread_ == nullptr) return; thread_->Join(); } @@ -2510,20 +2621,18 @@ void SerializationDataQueue::Clear() { data_.clear(); } - Worker::Worker() : in_semaphore_(0), out_semaphore_(0), - thread_(NULL), - script_(NULL), + thread_(nullptr), + script_(nullptr), running_(false) {} - Worker::~Worker() { delete thread_; - thread_ = NULL; + thread_ = nullptr; delete[] script_; - script_ = NULL; + script_ = nullptr; in_queue_.Clear(); out_queue_.Clear(); } @@ -2555,9 +2664,9 @@ std::unique_ptr<SerializationData> Worker::GetMessage() { void Worker::Terminate() { base::Relaxed_Store(&running_, false); - // Post NULL to wake the Worker thread message loop, and tell it to stop + // Post nullptr to wake the Worker thread message loop, and tell it to stop // running. - PostMessage(NULL); + PostMessage(nullptr); } @@ -2573,6 +2682,8 @@ void Worker::ExecuteInThread() { Isolate* isolate = Isolate::New(create_params); isolate->SetHostImportModuleDynamicallyCallback( Shell::HostImportModuleDynamically); + isolate->SetHostInitializeImportMetaObjectCallback( + Shell::HostInitializeImportMetaObject); D8Console console(isolate); debug::SetConsoleDelegate(isolate, &console); { @@ -2642,8 +2753,8 @@ void Worker::ExecuteInThread() { } isolate->Dispose(); - // Post NULL to wake the thread waiting on GetMessage() if there is one. - out_queue_.Enqueue(NULL); + // Post nullptr to wake the thread waiting on GetMessage() if there is one. + out_queue_.Enqueue(nullptr); out_semaphore_.Signal(); } @@ -2681,17 +2792,24 @@ bool Shell::SetOptions(int argc, char* argv[]) { for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--stress-opt") == 0) { options.stress_opt = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--nostress-opt") == 0 || strcmp(argv[i], "--no-stress-opt") == 0) { options.stress_opt = false; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--stress-deopt") == 0) { options.stress_deopt = true; - argv[i] = NULL; + argv[i] = nullptr; + } else if (strcmp(argv[i], "--stress-background-compile") == 0) { + options.stress_background_compile = true; + argv[i] = nullptr; + } else if (strcmp(argv[i], "--nostress-background-compile") == 0 || + strcmp(argv[i], "--no-stress-background-compile") == 0) { + options.stress_background_compile = false; + argv[i] = nullptr; } else if (strcmp(argv[i], "--mock-arraybuffer-allocator") == 0) { options.mock_arraybuffer_allocator = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--noalways-opt") == 0 || strcmp(argv[i], "--no-always-opt") == 0) { // No support for stressing if we can't use --always-opt. @@ -2699,28 +2817,28 @@ bool Shell::SetOptions(int argc, char* argv[]) { options.stress_deopt = false; } else if (strcmp(argv[i], "--logfile-per-isolate") == 0) { logfile_per_isolate = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--shell") == 0) { options.interactive_shell = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--test") == 0) { options.test_shell = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--notest") == 0 || strcmp(argv[i], "--no-test") == 0) { options.test_shell = false; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--send-idle-notification") == 0) { options.send_idle_notification = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--invoke-weak-callbacks") == 0) { options.invoke_weak_callbacks = true; // TODO(jochen) See issue 3351 options.send_idle_notification = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--omit-quit") == 0) { options.omit_quit = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "-f") == 0) { // Ignore any -f flags for compatibility with other stand-alone // JavaScript engines. @@ -2729,17 +2847,17 @@ bool Shell::SetOptions(int argc, char* argv[]) { options.num_isolates++; } else if (strcmp(argv[i], "--throws") == 0) { options.expected_to_throw = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strncmp(argv[i], "--icu-data-file=", 16) == 0) { options.icu_data_file = argv[i] + 16; - argv[i] = NULL; + argv[i] = nullptr; #ifdef V8_USE_EXTERNAL_STARTUP_DATA } else if (strncmp(argv[i], "--natives_blob=", 15) == 0) { options.natives_blob = argv[i] + 15; - argv[i] = NULL; + argv[i] = nullptr; } else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) { options.snapshot_blob = argv[i] + 16; - argv[i] = NULL; + argv[i] = nullptr; #endif // V8_USE_EXTERNAL_STARTUP_DATA } else if (strcmp(argv[i], "--cache") == 0 || strncmp(argv[i], "--cache=", 8) == 0) { @@ -2754,39 +2872,36 @@ bool Shell::SetOptions(int argc, char* argv[]) { printf("Unknown option to --cache.\n"); return false; } - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--enable-tracing") == 0) { options.trace_enabled = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strncmp(argv[i], "--trace-config=", 15) == 0) { options.trace_config = argv[i] + 15; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--enable-inspector") == 0) { options.enable_inspector = true; - argv[i] = NULL; + argv[i] = nullptr; } else if (strncmp(argv[i], "--lcov=", 7) == 0) { options.lcov_file = argv[i] + 7; - argv[i] = NULL; + argv[i] = nullptr; } else if (strcmp(argv[i], "--disable-in-process-stack-traces") == 0) { options.disable_in_process_stack_traces = true; - argv[i] = NULL; + argv[i] = nullptr; #ifdef V8_OS_POSIX } else if (strncmp(argv[i], "--read-from-tcp-port=", 21) == 0) { options.read_from_tcp_port = atoi(argv[i] + 21); - argv[i] = NULL; + argv[i] = nullptr; #endif // V8_OS_POSIX } else if (strcmp(argv[i], "--enable-os-system") == 0) { options.enable_os_system = true; - argv[i] = NULL; + argv[i] = nullptr; + } else if (strcmp(argv[i], "--quiet-load") == 0) { + options.quiet_load = true; + argv[i] = nullptr; } } -// On x64 Linux we want to enable the Wasm trap handler by default. Setting -// the flag here allows the command line argument to still override it. -#if V8_OS_LINUX && V8_TARGET_ARCH_X64 - SetFlagsFromString("--wasm-trap-handler"); -#endif - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); // Set up isolated source groups. @@ -2891,7 +3006,7 @@ void Shell::SetWaitUntilDone(Isolate* isolate, bool value) { } namespace { -void ProcessMessages(Isolate* isolate, +bool ProcessMessages(Isolate* isolate, std::function<platform::MessageLoopBehavior()> behavior) { Platform* platform = GetDefaultPlatform(); while (true) { @@ -2913,9 +3028,10 @@ void ProcessMessages(Isolate* isolate, Context::Scope context_scope(context); if (callback->Call(context, Undefined(isolate), 0, nullptr).IsEmpty()) { Shell::ReportException(isolate, &try_catch); - return; + return false; } } + return true; } } // anonymous namespace @@ -2929,9 +3045,9 @@ void Shell::CompleteMessageLoop(Isolate* isolate) { }); } -void Shell::EmptyMessageQueues(Isolate* isolate) { - ProcessMessages(isolate, - []() { return platform::MessageLoopBehavior::kDoNotWait; }); +bool Shell::EmptyMessageQueues(Isolate* isolate) { + return ProcessMessages( + isolate, []() { return platform::MessageLoopBehavior::kDoNotWait; }); } class Serializer : public ValueSerializer::Delegate { @@ -2976,7 +3092,7 @@ class Serializer : public ValueSerializer::Delegate { Maybe<uint32_t> GetSharedArrayBufferId( Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer) override { - DCHECK(data_ != nullptr); + DCHECK_NOT_NULL(data_); for (size_t index = 0; index < shared_array_buffers_.size(); ++index) { if (shared_array_buffers_[index] == shared_array_buffer) { return Just<uint32_t>(static_cast<uint32_t>(index)); @@ -3187,25 +3303,26 @@ int Shell::Main(int argc, char* argv[]) { ? v8::platform::InProcessStackDumping::kDisabled : v8::platform::InProcessStackDumping::kEnabled; - platform::tracing::TracingController* tracing_controller = nullptr; + std::unique_ptr<platform::tracing::TracingController> tracing; if (options.trace_enabled && !i::FLAG_verify_predictable) { + tracing = base::make_unique<platform::tracing::TracingController>(); trace_file.open("v8_trace.json"); - tracing_controller = new platform::tracing::TracingController(); platform::tracing::TraceBuffer* trace_buffer = platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer( platform::tracing::TraceBuffer::kRingBufferChunks, platform::tracing::TraceWriter::CreateJSONTraceWriter(trace_file)); - tracing_controller->Initialize(trace_buffer); + tracing->Initialize(trace_buffer); } - g_platform = v8::platform::CreateDefaultPlatform( + platform::tracing::TracingController* tracing_controller = tracing.get(); + g_platform = v8::platform::NewDefaultPlatform( 0, v8::platform::IdleTaskSupport::kEnabled, in_process_stack_dumping, - tracing_controller); + std::move(tracing)); if (i::FLAG_verify_predictable) { - g_platform = new PredictablePlatform(std::unique_ptr<Platform>(g_platform)); + g_platform.reset(new PredictablePlatform(std::move(g_platform))); } - v8::V8::InitializePlatform(g_platform); + v8::V8::InitializePlatform(g_platform.get()); v8::V8::Initialize(); if (options.natives_blob || options.snapshot_blob) { v8::V8::InitializeExternalStartupData(options.natives_blob, @@ -3249,6 +3366,8 @@ int Shell::Main(int argc, char* argv[]) { Isolate* isolate = Isolate::New(create_params); isolate->SetHostImportModuleDynamicallyCallback( Shell::HostImportModuleDynamically); + isolate->SetHostInitializeImportMetaObjectCallback( + Shell::HostInitializeImportMetaObject); D8Console console(isolate); { @@ -3318,7 +3437,6 @@ int Shell::Main(int argc, char* argv[]) { OnExit(isolate); V8::Dispose(); V8::ShutdownPlatform(); - delete g_platform; return result; } |