diff options
author | Anna Henningsen <anna@addaleax.net> | 2016-09-10 18:21:20 +0200 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2017-11-14 13:57:35 -0500 |
commit | e18df46092624980a0218982af757a0743cf1d98 (patch) | |
tree | 14b26cee5700fa86ba236e08a6ec906f2930f597 | |
parent | 6a0eb9f6cfbe3c76a3508418997de7ab2becd4b5 (diff) | |
download | node-new-e18df46092624980a0218982af757a0743cf1d98.tar.gz |
src: notify V8 for low memory when alloc fails
Call `v8::Isolate::GetCurrent()->LowMemoryNotification()` when
an allocation fails to give V8 a chance to clean up and return
memory before retrying (and possibly giving up).
Backport-PR-URL: https://github.com/nodejs/node/pull/16587
PR-URL: https://github.com/nodejs/node/pull/8482
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
-rw-r--r-- | src/node.cc | 3 | ||||
-rw-r--r-- | src/node_internals.h | 3 | ||||
-rw-r--r-- | src/util-inl.h | 10 | ||||
-rw-r--r-- | src/util.cc | 9 | ||||
-rw-r--r-- | src/util.h | 5 |
5 files changed, 29 insertions, 1 deletions
diff --git a/src/node.cc b/src/node.cc index 6345abdb31..98fde0dbbe 100644 --- a/src/node.cc +++ b/src/node.cc @@ -198,6 +198,7 @@ bool trace_warnings = false; // that is used by lib/module.js bool config_preserve_symlinks = false; +bool v8_initialized = false; // Set in node.cc by ParseArgs when --expose-internals or --expose_internals is // used. @@ -4895,6 +4896,7 @@ int Start(int argc, char** argv) { v8_platform.Initialize(v8_thread_pool_size); V8::Initialize(); + v8_initialized = true; int exit_code = 1; { @@ -4908,6 +4910,7 @@ int Start(int argc, char** argv) { StartNodeInstance(&instance_data); exit_code = instance_data.exit_code(); } + v8_initialized = false; V8::Dispose(); v8_platform.Dispose(); diff --git a/src/node_internals.h b/src/node_internals.h index 130af5d1c0..9ead8b1037 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -43,6 +43,9 @@ extern std::string openssl_config; // that is used by lib/module.js extern bool config_preserve_symlinks; +// Tells whether it is safe to call v8::Isolate::GetCurrent(). +extern bool v8_initialized; + // Set in node.cc by ParseArgs when --expose-internals or --expose_internals is // used. // Used in node_config.cc to set a constant on process.binding('config') diff --git a/src/util-inl.h b/src/util-inl.h index 886b8569d6..5ffe5b857f 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -344,7 +344,15 @@ T* UncheckedRealloc(T* pointer, size_t n) { return nullptr; } - return static_cast<T*>(realloc(pointer, full_size)); + void* allocated = realloc(pointer, full_size); + + if (UNLIKELY(allocated == nullptr)) { + // Tell V8 that memory is low and retry. + LowMemoryNotification(); + allocated = realloc(pointer, full_size); + } + + return static_cast<T*>(allocated); } // As per spec realloc behaves like malloc if passed nullptr. diff --git a/src/util.cc b/src/util.cc index 14aa68996f..9fb5c3fd28 100644 --- a/src/util.cc +++ b/src/util.cc @@ -77,4 +77,13 @@ BufferValue::BufferValue(Isolate* isolate, Local<Value> value) { } } +void LowMemoryNotification() { + if (v8_initialized) { + auto isolate = v8::Isolate::GetCurrent(); + if (isolate != nullptr) { + isolate->LowMemoryNotification(); + } + } +} + } // namespace node diff --git a/src/util.h b/src/util.h index 8b2db6f5c3..4ce25e4622 100644 --- a/src/util.h +++ b/src/util.h @@ -53,6 +53,11 @@ inline char* Calloc(size_t n) { return Calloc<char>(n); } inline char* UncheckedMalloc(size_t n) { return UncheckedMalloc<char>(n); } inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc<char>(n); } +// Used by the allocation functions when allocation fails. +// Thin wrapper around v8::Isolate::LowMemoryNotification() that checks +// whether V8 is initialized. +void LowMemoryNotification(); + #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) #else |