From a785d8c4d86b4ff6c5c743459eb93ae29da25008 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 27 Jun 2017 20:56:15 -0700 Subject: [PATCH 1/4] n-api: adds function to adjust external memory Added a simple wrapper around v8::Isolate::AdjustAmountOfExternalAllocatedMemory Fixes: https://github.com/nodejs/node/issues/13928 --- doc/api/n-api.md | 22 ++++++++++++++++++++ src/node_api.cc | 13 ++++++++++++ src/node_api.h | 5 +++++ test/addons-napi/test_general/test.js | 4 ++++ test/addons-napi/test_general/test_general.c | 11 ++++++++++ 5 files changed, 55 insertions(+) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index e41465475ea72a..d036fd93a81cf0 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3394,6 +3394,27 @@ support it: * If the function is not available, provide an alternate implementation that does not use the function. +### napi_adjust_external_memory + +```C +NAPI_EXTERN int64_t napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes); +``` + +- `[in] env`: The environment that the API is invoked under. +- `[in] change_in_bytes`: The change in externally allocated memory that is +kept alive by JavaScript objects. + +Returns `int64_t` the adjusted value. + +This function gives V8 an indication of the amount of externally allocated +memory that is kept alive by JavaScript objects (i.e. a JavaScript object +that points to its own memory allocated by a native module). Registering +externally allocated memory will trigger global garbage collections more +often than it would otherwise. + ## Promises @@ -3549,6 +3570,7 @@ object - that is, a promise object created by the underlying engine. [Working with JavaScript Values]: #n_api_working_with_javascript_values [Working with JavaScript Values - Abstract Operations]: #n_api_working_with_javascript_values_abstract_operations +[`napi_adjust_external_memory`]: #n_api_napi_adjust_external_memory [`napi_cancel_async_work`]: #n_api_napi_cancel_async_work [`napi_close_escapable_handle_scope`]: #n_api_napi_close_escapable_handle_scope [`napi_close_handle_scope`]: #n_api_napi_close_handle_scope diff --git a/src/node_api.cc b/src/node_api.cc index 7a2b5bc48e1237..16549120b20737 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -3213,6 +3213,19 @@ napi_status napi_get_node_version(napi_env env, return napi_clear_last_error(env); } +napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* adjusted_value) { + CHECK_ENV(env); + CHECK_ARG(env, &change_in_bytes); + CHECK_ARG(env, adjusted_value); + + *adjusted_value = env->isolate->AdjustAmountOfExternalAllocatedMemory( + change_in_bytes); + + return napi_clear_last_error(env); +} + namespace uvimpl { static napi_status ConvertUVErrorCode(int code) { diff --git a/src/node_api.h b/src/node_api.h index 6a4b2941879ff0..702ddf2d9e6a0e 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -557,6 +557,11 @@ NAPI_EXTERN napi_status napi_is_promise(napi_env env, napi_value promise, bool* is_promise); +// Memory management +NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* adjusted_value); + EXTERN_C_END #endif // SRC_NODE_API_H_ diff --git a/test/addons-napi/test_general/test.js b/test/addons-napi/test_general/test.js index 484707e868db58..ed40b1db8af525 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -91,3 +91,7 @@ z = null; global.gc(); assert.strictEqual(test_general.finalizeWasCalled(), false, 'finalize callback was not called upon garbage collection'); + +// test napi_adjust_external_memory +const adjustedValue = test_general.testAdjustExternalMemory(); +assert.strictEqual(typeof adjustedValue, 'number'); diff --git a/test/addons-napi/test_general/test_general.c b/test/addons-napi/test_general/test_general.c index ecec3e014ba0b1..ea1f2ece0a5d30 100644 --- a/test/addons-napi/test_general/test_general.c +++ b/test/addons-napi/test_general/test_general.c @@ -205,6 +205,16 @@ napi_value finalize_was_called(napi_env env, napi_callback_info info) { return it_was_called; } +napi_value testAdjustExternalMemory(napi_env env, napi_callback_info info) { + napi_value result; + int64_t adjustedValue; + + NAPI_CALL(env, napi_adjust_external_memory(env, 1, &adjustedValue)); + NAPI_CALL(env, napi_create_double(env, adjustedValue, &result)); + + return result; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals), @@ -222,6 +232,7 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) { DECLARE_NAPI_PROPERTY("testFinalizeWrap", test_finalize_wrap), DECLARE_NAPI_PROPERTY("finalizeWasCalled", finalize_was_called), DECLARE_NAPI_PROPERTY("derefItemWasCalled", deref_item_was_called), + DECLARE_NAPI_PROPERTY("testAdjustExternalMemory", testAdjustExternalMemory) }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( From 77acfd5ee7a938c350858be25211b19baf9634b6 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 17 Jul 2017 17:59:43 -0700 Subject: [PATCH 2/4] n-api: adds function to adjust external memory Improved documentation based on pull request feedback Fixes: https://github.com/nodejs/node/issues/13928 --- doc/api/n-api.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index d036fd93a81cf0..1c74db991989f6 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3394,13 +3394,15 @@ support it: * If the function is not available, provide an alternate implementation that does not use the function. +## Garbage Collection + ### napi_adjust_external_memory ```C NAPI_EXTERN int64_t napi_adjust_external_memory(napi_env env, - int64_t change_in_bytes); + int64_t change_in_bytes); ``` - `[in] env`: The environment that the API is invoked under. @@ -3570,7 +3572,6 @@ object - that is, a promise object created by the underlying engine. [Working with JavaScript Values]: #n_api_working_with_javascript_values [Working with JavaScript Values - Abstract Operations]: #n_api_working_with_javascript_values_abstract_operations -[`napi_adjust_external_memory`]: #n_api_napi_adjust_external_memory [`napi_cancel_async_work`]: #n_api_napi_cancel_async_work [`napi_close_escapable_handle_scope`]: #n_api_napi_close_escapable_handle_scope [`napi_close_handle_scope`]: #n_api_napi_close_handle_scope From fd40a07606fdd73c24e49831da5e647ce3b3d56c Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sun, 23 Jul 2017 15:30:09 -0700 Subject: [PATCH 3/4] n-api: adds function to adjust external memory Changed napi_adjust_external_memory() signature to be more consistent with the rest of the API Fixes: https://github.com/nodejs/node/issues/13928 --- doc/api/n-api.md | 10 ++++++---- test/addons-napi/test_general/test.js | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 1c74db991989f6..5979a76ffd7ed3 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3394,22 +3394,24 @@ support it: * If the function is not available, provide an alternate implementation that does not use the function. -## Garbage Collection +## Memory Management ### napi_adjust_external_memory ```C -NAPI_EXTERN int64_t napi_adjust_external_memory(napi_env env, - int64_t change_in_bytes); +NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* result); ``` - `[in] env`: The environment that the API is invoked under. - `[in] change_in_bytes`: The change in externally allocated memory that is kept alive by JavaScript objects. +- `[out] result`: The adjusted value -Returns `int64_t` the adjusted value. +Returns `napi_ok` if the API succeeded. This function gives V8 an indication of the amount of externally allocated memory that is kept alive by JavaScript objects (i.e. a JavaScript object diff --git a/test/addons-napi/test_general/test.js b/test/addons-napi/test_general/test.js index ed40b1db8af525..b9590391740fca 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -93,5 +93,4 @@ assert.strictEqual(test_general.finalizeWasCalled(), false, 'finalize callback was not called upon garbage collection'); // test napi_adjust_external_memory -const adjustedValue = test_general.testAdjustExternalMemory(); -assert.strictEqual(typeof adjustedValue, 'number'); +assert.strictEqual(typeof test_general.testAdjustExternalMemory(), 'number'); From 81bc985788f5fe33946b820d63028f17d8ff25d0 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 22 Aug 2017 16:00:13 -0700 Subject: [PATCH 4/4] n-api: adds function to adjust external memory Improved unit tests Fixes: https://github.com/nodejs/node/issues/13928 --- test/addons-napi/test_general/test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/addons-napi/test_general/test.js b/test/addons-napi/test_general/test.js index b9590391740fca..e9e2b9614ca34c 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -93,4 +93,6 @@ assert.strictEqual(test_general.finalizeWasCalled(), false, 'finalize callback was not called upon garbage collection'); // test napi_adjust_external_memory -assert.strictEqual(typeof test_general.testAdjustExternalMemory(), 'number'); +const adjustedValue = test_general.testAdjustExternalMemory(); +assert.strictEqual(typeof adjustedValue, 'number'); +assert(adjustedValue > 0);