From 78e6a4251dac13a40f86ef0feadf7464caf9bd2c Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 20 Apr 2020 06:16:58 +0800 Subject: [PATCH] src: split the main context initialization from Environemnt ctor So that it's possible to create an Environment not yet attached to any V8 context. We'll use this to deserialize the V8 context before attaching an Environment to it. PR-URL: https://github.com/nodejs/node/pull/32984 Reviewed-By: Anna Henningsen Reviewed-By: Daniel Bevenius --- src/api/environment.cc | 5 +---- src/env.cc | 51 +++++++++++++++++++++++++++++++----------- src/env.h | 10 +++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/api/environment.cc b/src/api/environment.cc index 997c9530fc2771..1104d758f63e36 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -356,10 +356,7 @@ Environment* CreateEnvironment( exec_args, flags, thread_id); - if (flags & EnvironmentFlags::kOwnsProcessState) { - env->set_abort_on_uncaught_exception(false); - } - + env->InitializeMainContext(context); #if HAVE_INSPECTOR if (inspector_parent_handle) { env->InitializeInspector( diff --git a/src/env.cc b/src/env.cc index bcaa50bd0129b0..494c1877f4483b 100644 --- a/src/env.cc +++ b/src/env.cc @@ -306,15 +306,15 @@ std::string GetExecPath(const std::vector& argv) { } Environment::Environment(IsolateData* isolate_data, - Local context, + Isolate* isolate, const std::vector& args, const std::vector& exec_args, EnvironmentFlags::Flags flags, ThreadId thread_id) - : isolate_(context->GetIsolate()), + : isolate_(isolate), isolate_data_(isolate_data), - immediate_info_(context->GetIsolate()), - tick_info_(context->GetIsolate()), + immediate_info_(isolate), + tick_info_(isolate), timer_base_(uv_now(isolate_data->event_loop())), exec_argv_(exec_args), argv_(args), @@ -322,12 +322,11 @@ Environment::Environment(IsolateData* isolate_data, should_abort_on_uncaught_toggle_(isolate_, 1), stream_base_state_(isolate_, StreamBase::kNumStreamBaseStateFields), flags_(flags), - thread_id_(thread_id.id == static_cast(-1) ? - AllocateEnvironmentThreadId().id : thread_id.id), - context_(context->GetIsolate(), context) { + thread_id_(thread_id.id == static_cast(-1) + ? AllocateEnvironmentThreadId().id + : thread_id.id) { // We'll be creating new objects so make sure we've entered the context. - HandleScope handle_scope(isolate()); - Context::Scope context_scope(context); + HandleScope handle_scope(isolate); // Set some flags if only kDefaultFlags was passed. This can make API version // transitions easier for embedders. @@ -338,6 +337,8 @@ Environment::Environment(IsolateData* isolate_data, } set_env_vars(per_process::system_environment); + // TODO(joyeecheung): pass Isolate* and env_vars to it instead of the entire + // env enabled_debug_list_.Parse(this); // We create new copies of the per-Environment option sets, so that it is @@ -348,13 +349,15 @@ Environment::Environment(IsolateData* isolate_data, inspector_host_port_.reset( new ExclusiveAccess(options_->debug_options().host_port)); + if (flags & EnvironmentFlags::kOwnsProcessState) { + set_abort_on_uncaught_exception(false); + } + #if HAVE_INSPECTOR // We can only create the inspector agent after having cloned the options. inspector_agent_ = std::make_unique(this); #endif - AssignToContext(context, ContextInfo("")); - static uv_once_t init_once = UV_ONCE_INIT; uv_once(&init_once, InitThreadLocalOnce); uv_key_set(&thread_local_env, this); @@ -367,8 +370,7 @@ Environment::Environment(IsolateData* isolate_data, destroy_async_id_list_.reserve(512); - performance_state_ = - std::make_unique(isolate()); + performance_state_ = std::make_unique(isolate); performance_state_->Mark( performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT); performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_NODE_START, @@ -400,6 +402,29 @@ Environment::Environment(IsolateData* isolate_data, async_hooks_.no_force_checks(); } + // This adjusts the return value of base_object_count() so that tests that + // check the count do not have to account for internally created BaseObjects. + initial_base_object_count_ = base_object_count(); +} + +Environment::Environment(IsolateData* isolate_data, + Local context, + const std::vector& args, + const std::vector& exec_args, + EnvironmentFlags::Flags flags, + ThreadId thread_id) + : Environment(isolate_data, + context->GetIsolate(), + args, + exec_args, + flags, + thread_id) { + InitializeMainContext(context); +} + +void Environment::InitializeMainContext(Local context) { + context_.Reset(context->GetIsolate(), context); + AssignToContext(context, ContextInfo("")); // TODO(joyeecheung): deserialize when the snapshot covers the environment // properties. CreateProperties(); diff --git a/src/env.h b/src/env.h index 39bcee9c4895c9..8c1bf71ddfaee4 100644 --- a/src/env.h +++ b/src/env.h @@ -919,6 +919,16 @@ class Environment : public MemoryRetainer { static uv_key_t thread_local_env; static inline Environment* GetThreadLocalEnv(); + // Create an Environment without initializing a main Context. Use + // InitializeMainContext() to initialize a main context for it. + Environment(IsolateData* isolate_data, + v8::Isolate* isolate, + const std::vector& args, + const std::vector& exec_args, + EnvironmentFlags::Flags flags, + ThreadId thread_id); + void InitializeMainContext(v8::Local context); + // Create an Environment and initialize the provided main context for it. Environment(IsolateData* isolate_data, v8::Local context, const std::vector& args,