diff --git a/src/env.cc b/src/env.cc index 3d06ebe2082b08..58d7cea841bc30 100644 --- a/src/env.cc +++ b/src/env.cc @@ -79,7 +79,8 @@ IsolateData::IsolateData(Isolate* isolate, if (platform_ != nullptr) platform_->RegisterIsolate(isolate_, event_loop); - options_.reset(new PerIsolateOptions(*per_process_opts->per_isolate)); + options_.reset( + new PerIsolateOptions(*(per_process::cli_options->per_isolate))); // Create string and private symbol properties as internalized one byte // strings after the platform is properly initialized. diff --git a/src/node.cc b/src/node.cc index 0b496da4a273bc..01c9c072da7466 100644 --- a/src/node.cc +++ b/src/node.cc @@ -139,21 +139,31 @@ using v8::Undefined; using v8::V8; using v8::Value; +namespace per_process { +// Tells whether --prof is passed. +// TODO(joyeecheung): move env->options()->prof_process to +// per_process::cli_options.prof_process and use that instead. static bool v8_is_profiling = false; -// Bit flag used to track security reverts (see node_revert.h) -unsigned int reverted = 0; +// TODO(joyeecheung): these are no longer necessary. Remove them. +// See: https://github.com/nodejs/node/pull/25302#discussion_r244924196 +// Isolate on the main thread +static Mutex main_isolate_mutex; +static Isolate* main_isolate; +// node_revert.h +// Bit flag used to track security reverts. +unsigned int reverted_cve = 0; + +// util.h +// Tells whether the per-process V8::Initialize() is called and +// if it is safe to call v8::Isolate::GetCurrent(). bool v8_initialized = false; +// node_internals.h // process-relative uptime base, initialized at start-up double prog_start_time; - -Mutex per_process_opts_mutex; -std::shared_ptr per_process_opts { - new PerProcessOptions() }; -static Mutex node_isolate_mutex; -static Isolate* node_isolate; +} // namespace per_process // Ensures that __metadata trace events are only emitted // when tracing is enabled. @@ -269,14 +279,15 @@ static struct { #endif // HAVE_INSPECTOR void StartTracingAgent() { - if (per_process_opts->trace_event_categories.empty()) { + if (per_process::cli_options->trace_event_categories.empty()) { tracing_file_writer_ = tracing_agent_->DefaultHandle(); } else { tracing_file_writer_ = tracing_agent_->AddClient( - ParseCommaSeparatedSet(per_process_opts->trace_event_categories), + ParseCommaSeparatedSet( + per_process::cli_options->trace_event_categories), std::unique_ptr( new tracing::NodeTraceWriter( - per_process_opts->trace_event_file_pattern)), + per_process::cli_options->trace_event_file_pattern)), tracing::Agent::kUseDefaultCategories); } } @@ -500,7 +511,7 @@ const char* signo_string(int signo) { } void* ArrayBufferAllocator::Allocate(size_t size) { - if (zero_fill_field_ || per_process_opts->zero_fill_all_buffers) + if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) return UncheckedCalloc(size); else return UncheckedMalloc(size); @@ -1276,12 +1287,12 @@ void ProcessArgv(std::vector* args, { // TODO(addaleax): The mutex here should ideally be held during the // entire function, but that doesn't play well with the exit() calls below. - Mutex::ScopedLock lock(per_process_opts_mutex); + Mutex::ScopedLock lock(per_process::cli_options_mutex); options_parser::PerProcessOptionsParser::instance.Parse( args, exec_args, &v8_args, - per_process_opts.get(), + per_process::cli_options.get(), is_env ? kAllowedInEnvironment : kDisallowedInEnvironment, &errors); } @@ -1293,20 +1304,20 @@ void ProcessArgv(std::vector* args, exit(9); } - if (per_process_opts->print_version) { + if (per_process::cli_options->print_version) { printf("%s\n", NODE_VERSION); exit(0); } - if (per_process_opts->print_v8_help) { + if (per_process::cli_options->print_v8_help) { V8::SetFlagsFromString("--help", 6); exit(0); } - for (const std::string& cve : per_process_opts->security_reverts) + for (const std::string& cve : per_process::cli_options->security_reverts) Revert(cve.c_str()); - auto env_opts = per_process_opts->per_isolate->per_env; + auto env_opts = per_process::cli_options->per_isolate->per_env; if (std::find(v8_args.begin(), v8_args.end(), "--abort-on-uncaught-exception") != v8_args.end() || std::find(v8_args.begin(), v8_args.end(), @@ -1319,14 +1330,14 @@ void ProcessArgv(std::vector* args, // behavior but it could also interfere with the user's intentions in ways // we fail to anticipate. Dillema. if (std::find(v8_args.begin(), v8_args.end(), "--prof") != v8_args.end()) { - v8_is_profiling = true; + per_process::v8_is_profiling = true; } #ifdef __POSIX__ // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the // performance penalty of frequent EINTR wakeups when the profiler is running. // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users. - if (v8_is_profiling) { + if (per_process::v8_is_profiling) { uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF); } #endif @@ -1355,7 +1366,7 @@ void ProcessArgv(std::vector* args, void Init(std::vector* argv, std::vector* exec_argv) { // Initialize prog_start_time to get relative uptime. - prog_start_time = static_cast(uv_now(uv_default_loop())); + per_process::prog_start_time = static_cast(uv_now(uv_default_loop())); // Register built-in modules binding::RegisterBuiltinModules(); @@ -1371,7 +1382,7 @@ void Init(std::vector* argv, #endif std::shared_ptr default_env_options = - per_process_opts->per_isolate->per_env; + per_process::cli_options->per_isolate->per_env; { std::string text; default_env_options->pending_deprecation = @@ -1400,7 +1411,7 @@ void Init(std::vector* argv, } #if HAVE_OPENSSL - std::string* openssl_config = &per_process_opts->openssl_config; + std::string* openssl_config = &per_process::cli_options->openssl_config; if (openssl_config->empty()) { credentials::SafeGetenv("OPENSSL_CONF", openssl_config); } @@ -1434,16 +1445,17 @@ void Init(std::vector* argv, ProcessArgv(argv, exec_argv, false); // Set the process.title immediately after processing argv if --title is set. - if (!per_process_opts->title.empty()) - uv_set_process_title(per_process_opts->title.c_str()); + if (!per_process::cli_options->title.empty()) + uv_set_process_title(per_process::cli_options->title.c_str()); #if defined(NODE_HAVE_I18N_SUPPORT) // If the parameter isn't given, use the env variable. - if (per_process_opts->icu_data_dir.empty()) - credentials::SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir); + if (per_process::cli_options->icu_data_dir.empty()) + credentials::SafeGetenv("NODE_ICU_DATA", + &per_process::cli_options->icu_data_dir); // Initialize ICU. // If icu_data_dir is empty here, it will load the 'minimal' data. - if (!i18n::InitializeICUDirectory(per_process_opts->icu_data_dir)) { + if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) { fprintf(stderr, "%s: could not initialize ICU " "(check NODE_ICU_DATA or --icu-data-dir parameters)\n", @@ -1604,7 +1616,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data, std::vector args(argv, argv + argc); std::vector exec_args(exec_argv, exec_argv + exec_argc); Environment* env = new Environment(isolate_data, context); - env->Start(args, exec_args, v8_is_profiling); + env->Start(args, exec_args, per_process::v8_is_profiling); return env; } @@ -1678,7 +1690,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, Local context = NewContext(isolate); Context::Scope context_scope(context); Environment env(isolate_data, context); - env.Start(args, exec_args, v8_is_profiling); + env.Start(args, exec_args, per_process::v8_is_profiling); const char* path = args.size() > 1 ? args[1].c_str() : nullptr; StartInspector(&env, path); @@ -1785,9 +1797,9 @@ inline int Start(uv_loop_t* event_loop, return 12; // Signal internal error. { - Mutex::ScopedLock scoped_lock(node_isolate_mutex); - CHECK_NULL(node_isolate); - node_isolate = isolate; + Mutex::ScopedLock scoped_lock(per_process::main_isolate_mutex); + CHECK_NULL(per_process::main_isolate); + per_process::main_isolate = isolate; } int exit_code; @@ -1812,9 +1824,9 @@ inline int Start(uv_loop_t* event_loop, } { - Mutex::ScopedLock scoped_lock(node_isolate_mutex); - CHECK_EQ(node_isolate, isolate); - node_isolate = nullptr; + Mutex::ScopedLock scoped_lock(per_process::main_isolate_mutex); + CHECK_EQ(per_process::main_isolate, isolate); + per_process::main_isolate = nullptr; } isolate->Dispose(); @@ -1862,14 +1874,14 @@ int Start(int argc, char** argv) { V8::SetEntropySource(crypto::EntropySource); #endif // HAVE_OPENSSL - InitializeV8Platform(per_process_opts->v8_thread_pool_size); + InitializeV8Platform(per_process::cli_options->v8_thread_pool_size); V8::Initialize(); performance::performance_v8_start = PERFORMANCE_NOW(); - v8_initialized = true; + per_process::v8_initialized = true; const int exit_code = Start(uv_default_loop(), args, exec_args); v8_platform.StopTracingAgent(); - v8_initialized = false; + per_process::v8_initialized = false; V8::Dispose(); // uv_run cannot be called from the time before the beforeExit callback diff --git a/src/node_buffer.cc b/src/node_buffer.cc index b46b458831dd5b..ae2d1a06a78ebb 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -59,9 +59,9 @@ namespace node { namespace { inline void* BufferMalloc(size_t length) { - return per_process_opts->zero_fill_all_buffers ? - node::UncheckedCalloc(length) : - node::UncheckedMalloc(length); + return per_process::cli_options->zero_fill_all_buffers ? + node::UncheckedCalloc(length) : + node::UncheckedMalloc(length); } } // namespace diff --git a/src/node_config.cc b/src/node_config.cc index 8756969cda2986..4fd4b1a53b98ca 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -41,7 +41,7 @@ static void Initialize(Local target, #ifdef NODE_FIPS_MODE READONLY_TRUE_PROPERTY(target, "fipsMode"); // TODO(addaleax): Use options parser variable instead. - if (per_process_opts->force_fips_crypto) + if (per_process::cli_options->force_fips_crypto) READONLY_TRUE_PROPERTY(target, "fipsForced"); #endif diff --git a/src/node_constants.cc b/src/node_constants.cc index 7530d6d0a34780..debcf0e10045a1 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -1234,9 +1234,10 @@ void DefineCryptoConstants(Local target) { NODE_DEFINE_STRING_CONSTANT(target, "defaultCoreCipherList", DEFAULT_CIPHER_LIST_CORE); - NODE_DEFINE_STRING_CONSTANT(target, - "defaultCipherList", - per_process_opts->tls_cipher_list.c_str()); + NODE_DEFINE_STRING_CONSTANT( + target, + "defaultCipherList", + per_process::cli_options->tls_cipher_list.c_str()); NODE_DEFINE_CONSTANT(target, TLS1_VERSION); NODE_DEFINE_CONSTANT(target, TLS1_1_VERSION); diff --git a/src/node_credentials.cc b/src/node_credentials.cc index 82f6ef0dd8c0f3..1fea2659f79bb9 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -38,7 +38,7 @@ bool SafeGetenv(const char* key, std::string* text) { #endif { - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); if (const char* value = getenv(key)) { *text = value; return true; diff --git a/src/node_crypto.cc b/src/node_crypto.cc index ff3713eeecb133..c92ace2497942b 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -787,7 +787,7 @@ static X509_STORE* NewRootCertStore() { if (*system_cert_path != '\0') { X509_STORE_load_locations(store, system_cert_path, nullptr); } - if (per_process_opts->ssl_openssl_cert_store) { + if (per_process::cli_options->ssl_openssl_cert_store) { X509_STORE_set_default_paths(store); } else { for (X509* cert : root_certs_vector) { @@ -6183,16 +6183,15 @@ void InitCryptoOnce() { OPENSSL_no_config(); // --openssl-config=... - if (!per_process_opts->openssl_config.empty()) { + if (!per_process::cli_options->openssl_config.empty()) { OPENSSL_load_builtin_modules(); #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); #endif ERR_clear_error(); - CONF_modules_load_file( - per_process_opts->openssl_config.c_str(), - nullptr, - CONF_MFLAGS_DEFAULT_SECTION); + CONF_modules_load_file(per_process::cli_options->openssl_config.c_str(), + nullptr, + CONF_MFLAGS_DEFAULT_SECTION); int err = ERR_get_error(); if (0 != err) { fprintf(stderr, @@ -6208,8 +6207,8 @@ void InitCryptoOnce() { #ifdef NODE_FIPS_MODE /* Override FIPS settings in cnf file, if needed. */ unsigned long err = 0; // NOLINT(runtime/int) - if (per_process_opts->enable_fips_crypto || - per_process_opts->force_fips_crypto) { + if (per_process::cli_options->enable_fips_crypto || + per_process::cli_options->force_fips_crypto) { if (0 == FIPS_mode() && !FIPS_mode_set(1)) { err = ERR_get_error(); } @@ -6272,7 +6271,7 @@ void GetFipsCrypto(const FunctionCallbackInfo& args) { } void SetFipsCrypto(const FunctionCallbackInfo& args) { - CHECK(!per_process_opts->force_fips_crypto); + CHECK(!per_process::cli_options->force_fips_crypto); Environment* env = Environment::GetCurrent(args); const bool enabled = FIPS_mode(); bool enable = args[0]->BooleanValue(env->isolate()); diff --git a/src/node_env_var.cc b/src/node_env_var.cc index de0991bcab22f1..8cbfa22973c65d 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -25,13 +25,17 @@ using v8::PropertyCallbackInfo; using v8::String; using v8::Value; +namespace per_process { +Mutex env_var_mutex; +} // namespace per_process + static void EnvGetter(Local property, const PropertyCallbackInfo& info) { Isolate* isolate = info.GetIsolate(); if (property->IsSymbol()) { return info.GetReturnValue().SetUndefined(); } - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); #ifdef __POSIX__ node::Utf8Value key(isolate, property); const char* val = getenv(*key); @@ -80,7 +84,7 @@ static void EnvSetter(Local property, return; } - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); #ifdef __POSIX__ node::Utf8Value key(info.GetIsolate(), property); node::Utf8Value val(info.GetIsolate(), value); @@ -100,7 +104,7 @@ static void EnvSetter(Local property, static void EnvQuery(Local property, const PropertyCallbackInfo& info) { - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); int32_t rc = -1; // Not found unless proven otherwise. if (property->IsString()) { #ifdef __POSIX__ @@ -127,7 +131,7 @@ static void EnvQuery(Local property, static void EnvDeleter(Local property, const PropertyCallbackInfo& info) { - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); if (property->IsString()) { #ifdef __POSIX__ node::Utf8Value key(info.GetIsolate(), property); @@ -148,7 +152,7 @@ static void EnvEnumerator(const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); Isolate* isolate = env->isolate(); - Mutex::ScopedLock lock(environ_mutex); + Mutex::ScopedLock lock(per_process::env_var_mutex); Local envarr; int env_size = 0; #ifdef __POSIX__ diff --git a/src/node_errors.cc b/src/node_errors.cc index 7775e36b69bc82..9ffd8d88f1e473 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -35,6 +35,10 @@ bool IsExceptionDecorated(Environment* env, Local er) { return false; } +namespace per_process { +static Mutex tty_mutex; +} // namespace per_process + void AppendExceptionLine(Environment* env, Local er, Local message, @@ -137,7 +141,7 @@ void AppendExceptionLine(Environment* env, // by the caller. if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) { if (env->printed_error()) return; - Mutex::ScopedLock lock(process_mutex); + Mutex::ScopedLock lock(per_process::tty_mutex); env->set_printed_error(true); uv_tty_reset_mode(); diff --git a/src/node_http_parser_impl.h b/src/node_http_parser_impl.h index 9274f9dae0b7f9..48d669a7593e6c 100644 --- a/src/node_http_parser_impl.h +++ b/src/node_http_parser_impl.h @@ -830,7 +830,7 @@ class Parser : public AsyncWrap, public StreamListener { int TrackHeader(size_t len) { #ifdef NODE_EXPERIMENTAL_HTTP header_nread_ += len; - if (header_nread_ >= per_process_opts->max_http_header_size) { + if (header_nread_ >= per_process::cli_options->max_http_header_size) { llhttp_set_error_reason(&parser_, "HPE_HEADER_OVERFLOW:Header overflow"); return HPE_USER; } @@ -915,7 +915,8 @@ const parser_settings_t Parser::settings = { #ifndef NODE_EXPERIMENTAL_HTTP void InitMaxHttpHeaderSizeOnce() { - const uint32_t max_http_header_size = per_process_opts->max_http_header_size; + const uint32_t max_http_header_size = + per_process::cli_options->max_http_header_size; http_parser_set_max_header_size(max_http_header_size); } #endif /* NODE_EXPERIMENTAL_HTTP */ diff --git a/src/node_internals.h b/src/node_internals.h index 4ed75385f9aa48..f9ef31eea5aa85 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -83,14 +83,10 @@ namespace native_module { class NativeModuleLoader; } -extern Mutex process_mutex; -extern Mutex environ_mutex; - -// Tells whether it is safe to call v8::Isolate::GetCurrent(). -extern bool v8_initialized; - -extern Mutex per_process_opts_mutex; -extern std::shared_ptr per_process_opts; +namespace per_process { +extern Mutex env_var_mutex; +extern double prog_start_time; +} // namespace per_process // Forward declaration class Environment; @@ -699,8 +695,6 @@ static inline const char* errno_string(int errorno) { // Functions defined in node.cc that are exposed via the bootstrapper object -extern double prog_start_time; - void RawDebug(const v8::FunctionCallbackInfo& args); void DebugPortGetter(v8::Local property, diff --git a/src/node_options.cc b/src/node_options.cc index 117bff4a944b39..aa82d57f0a4168 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -17,6 +17,11 @@ using v8::Value; namespace node { +namespace per_process { +Mutex cli_options_mutex; +std::shared_ptr cli_options{new PerProcessOptions()}; +} // namespace per_process + void PerProcessOptions::CheckOptions(std::vector* errors) { #if HAVE_OPENSSL if (use_openssl_ca && use_bundled_ca) { @@ -397,7 +402,7 @@ HostPort SplitHostPort(const std::string& arg, // Return a map containing all the options and their metadata as well // as the aliases void GetOptions(const FunctionCallbackInfo& args) { - Mutex::ScopedLock lock(per_process_opts_mutex); + Mutex::ScopedLock lock(per_process::cli_options_mutex); Environment* env = Environment::GetCurrent(args); Isolate* isolate = env->isolate(); Local context = env->context(); @@ -405,13 +410,13 @@ void GetOptions(const FunctionCallbackInfo& args) { // Temporarily act as if the current Environment's/IsolateData's options were // the default options, i.e. like they are the ones we'd access for global // options parsing, so that all options are available from the main parser. - auto original_per_isolate = per_process_opts->per_isolate; - per_process_opts->per_isolate = env->isolate_data()->options(); - auto original_per_env = per_process_opts->per_isolate->per_env; - per_process_opts->per_isolate->per_env = env->options(); + auto original_per_isolate = per_process::cli_options->per_isolate; + per_process::cli_options->per_isolate = env->isolate_data()->options(); + auto original_per_env = per_process::cli_options->per_isolate->per_env; + per_process::cli_options->per_isolate->per_env = env->options(); OnScopeLeave on_scope_leave([&]() { - per_process_opts->per_isolate->per_env = original_per_env; - per_process_opts->per_isolate = original_per_isolate; + per_process::cli_options->per_isolate->per_env = original_per_env; + per_process::cli_options->per_isolate = original_per_isolate; }); const auto& parser = PerProcessOptionsParser::instance; @@ -421,7 +426,7 @@ void GetOptions(const FunctionCallbackInfo& args) { Local value; const auto& option_info = item.second; auto field = option_info.field; - PerProcessOptions* opts = per_process_opts.get(); + PerProcessOptions* opts = per_process::cli_options.get(); switch (option_info.type) { case kNoOp: case kV8Option: diff --git a/src/node_options.h b/src/node_options.h index ae7d7a4be5f065..5668df421aa0a7 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -8,6 +8,7 @@ #include #include #include "node_constants.h" +#include "node_mutex.h" #include "util.h" namespace node { @@ -422,6 +423,13 @@ class PerProcessOptionsParser : public OptionsParser { }; } // namespace options_parser + +namespace per_process { + +extern Mutex cli_options_mutex; +extern std::shared_ptr cli_options; + +} // namespace per_process } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/node_process.cc b/src/node_process.cc index 867d08916a258b..69f08a219b67e6 100644 --- a/src/node_process.cc +++ b/src/node_process.cc @@ -50,9 +50,6 @@ using v8::Uint32; using v8::Uint32Array; using v8::Value; -Mutex process_mutex; -Mutex environ_mutex; - // Microseconds in a second, as a float, used in CPUUsage() below #define MICROS_PER_SEC 1e6 // used in Hrtime() below @@ -244,7 +241,7 @@ static void Uptime(const FunctionCallbackInfo& args) { double uptime; uv_update_time(env->event_loop()); - uptime = uv_now(env->event_loop()) - prog_start_time; + uptime = uv_now(env->event_loop()) - per_process::prog_start_time; args.GetReturnValue().Set(uptime / 1000); } diff --git a/src/node_revert.h b/src/node_revert.h index c5963afeafd027..4c0ebcd9fd66b0 100644 --- a/src/node_revert.h +++ b/src/node_revert.h @@ -24,7 +24,9 @@ enum reversion { #undef V }; -extern unsigned int reverted; +namespace per_process { +extern unsigned int reverted_cve; +} inline const char* RevertMessage(const reversion cve) { #define V(code, label, msg) case SECURITY_REVERT_##code: return label ": " msg; @@ -37,7 +39,7 @@ inline const char* RevertMessage(const reversion cve) { } inline void Revert(const reversion cve) { - reverted |= 1 << cve; + per_process::reverted_cve |= 1 << cve; printf("SECURITY WARNING: Reverting %s\n", RevertMessage(cve)); } @@ -51,7 +53,7 @@ inline void Revert(const char* cve) { } inline bool IsReverted(const reversion cve) { - return reverted & (1 << cve); + return per_process::reverted_cve & (1 << cve); } inline bool IsReverted(const char* cve) { diff --git a/src/util.cc b/src/util.cc index ba30b23770b52e..e88b39f47b8ddc 100644 --- a/src/util.cc +++ b/src/util.cc @@ -101,7 +101,7 @@ BufferValue::BufferValue(Isolate* isolate, Local value) { } void LowMemoryNotification() { - if (v8_initialized) { + if (per_process::v8_initialized) { auto isolate = Isolate::GetCurrent(); if (isolate != nullptr) { isolate->LowMemoryNotification(); diff --git a/src/util.h b/src/util.h index ffa5a308a7788f..1205f2d06b142d 100644 --- a/src/util.h +++ b/src/util.h @@ -74,6 +74,12 @@ inline char* UncheckedCalloc(size_t n); template inline T MultiplyWithOverflowCheck(T a, T b); +namespace per_process { +// Tells whether the per-process V8::Initialize() is called and +// if it is safe to call v8::Isolate::GetCurrent(). +extern bool v8_initialized; +} // namespace per_process + // Used by the allocation functions when allocation fails. // Thin wrapper around v8::Isolate::LowMemoryNotification() that checks // whether V8 is initialized.