diff options
author | Anna Henningsen <anna@addaleax.net> | 2016-09-10 18:21:20 +0200 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2016-09-29 09:46:42 +0200 |
commit | 72c60e892c6f5ca309e20953e032a590be7787db (patch) | |
tree | 05d996c1be5fe6efd1b51580a34709263bb86ee8 /src | |
parent | ea94086ad2b53268b5cb870f9ba5a1f84741fa41 (diff) | |
download | android-node-v8-72c60e892c6f5ca309e20953e032a590be7787db.tar.gz android-node-v8-72c60e892c6f5ca309e20953e032a590be7787db.tar.bz2 android-node-v8-72c60e892c6f5ca309e20953e032a590be7787db.zip |
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).
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/node.cc | 4 | ||||
-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, 30 insertions, 1 deletions
diff --git a/src/node.cc b/src/node.cc index 12c28a5d0a..5ced5a3db6 100644 --- a/src/node.cc +++ b/src/node.cc @@ -183,6 +183,8 @@ bool trace_warnings = false; // that is used by lib/module.js bool config_preserve_symlinks = false; +bool v8_initialized = false; + // process-relative uptime base, initialized at start-up static double prog_start_time; static bool debugger_running; @@ -4490,6 +4492,7 @@ int Start(int argc, char** argv) { v8_platform.Initialize(v8_thread_pool_size); V8::Initialize(); + v8_initialized = true; int exit_code = 1; { @@ -4503,6 +4506,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 a54ead49ee..72888ef36d 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -37,6 +37,9 @@ namespace node { // 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; + // Forward declaration class Environment; diff --git a/src/util-inl.h b/src/util-inl.h index a3d446c2a5..51adb81692 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -253,7 +253,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 dba5824894..25f2eb0178 100644 --- a/src/util.h +++ b/src/util.h @@ -44,6 +44,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 |