From b8aea57fb8691de9bb2fe674f23fde35db0f138b Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 27 Jun 2017 20:56:15 -0700 Subject: [PATCH] n-api: adds function to adjust external memory Added a wrapper around v8::Isolate::AdjustAmountOfExternalAllocatedMemory PR-URL: https://github.com/nodejs/node/pull/14310 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Michael Dawson Reviewed-By: Benjamin Gruenbaum Fixes: https://github.com/nodejs/node/issues/13928 --- doc/api/n-api.md | 25 ++++++++++++++++++++ src/node_api.cc | 13 ++++++++++ src/node_api.h | 5 ++++ test/addons-napi/test_general/test.js | 5 ++++ test/addons-napi/test_general/test_general.c | 11 +++++++++ 5 files changed, 59 insertions(+) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index e41465475e..3a3cce0364 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3394,6 +3394,31 @@ support it: * If the function is not available, provide an alternate implementation that does not use the function. +## Memory Management + +### napi_adjust_external_memory + +```C +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 `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 +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 diff --git a/src/node_api.cc b/src/node_api.cc index 7a2b5bc48e..16549120b2 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 6a4b294187..702ddf2d9e 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 484707e868..e9e2b9614c 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -91,3 +91,8 @@ 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'); +assert(adjustedValue > 0); diff --git a/test/addons-napi/test_general/test_general.c b/test/addons-napi/test_general/test_general.c index ecec3e014b..ea1f2ece0a 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(