Skip to content

Commit

Permalink
Add memory management feature
Browse files Browse the repository at this point in the history
Add memory mangament feature For more info see the following issue:
nodejs/node-addon-api#260

PR-URL: nodejs/node-addon-api#286
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
  • Loading branch information
wroy7860 committed Jul 4, 2018
1 parent 12a3bd0 commit 320704b
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ still a work in progress as its not yet complete).
- [ArrayBuffer](doc/array_buffer.md)
- [TypedArray](doc/typed_array.md)
- [TypedArrayOf](doc/typed_array_of.md)
- [Memory Management](doc/memory_management.md)
- [Async Operations](doc/async_operations.md)
- [AsyncWorker](doc/async_worker.md)
- [Promises](doc/promises.md)
Expand Down
27 changes: 27 additions & 0 deletions doc/memory_management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# MemoryManagement

The `MemoryManagement` class contains functions that give the JavaScript engine
an indication of the amount of externally allocated memory that is kept alive by
JavaScript objects.

## Methods

### AdjustExternalMemory

The function `AdjustExternalMemory` adjusts the amount of registered external
memory used to give the JavaScript engine an indication of the amount of externally
allocated memory that is kept alive by JavaScript objects.
The JavaScript engine uses this to decide when to perform global garbage collections.
Registering externally allocated memory will trigger global garbage collections
more often than it would otherwise in an attempt to garbage collect the JavaScript
objects that keep the externally allocated memory alive.

```cpp
static int64_t MemoryManagement::AdjustExternalMemory(Env env, int64_t change_in_bytes);
```
- `[in] env`: The environment in which the API is invoked under.
- `[in] change_in_bytes`: The change in externally allocated memory that is kept
alive by JavaScript objects expressed in bytes.
Returns the adjusted memory value.
11 changes: 11 additions & 0 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3224,6 +3224,17 @@ inline void AsyncWorker::OnWorkComplete(
delete self;
}

////////////////////////////////////////////////////////////////////////////////
// Memory Management class
////////////////////////////////////////////////////////////////////////////////

inline int64_t MemoryManagement::AdjustExternalMemory(Env env, int64_t change_in_bytes) {
int64_t result;
napi_status status = napi_adjust_external_memory(env, change_in_bytes, &result);
NAPI_THROW_IF_FAILED(env, status, 0);
return result;
}

// These macros shouldn't be useful in user code.
#undef NAPI_THROW
#undef NAPI_THROW_IF_FAILED
Expand Down
8 changes: 8 additions & 0 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ namespace Napi {
/// Defines the signature of a N-API C++ module's registration callback (init) function.
typedef Object (*ModuleRegisterCallback)(Env env, Object exports);

class MemoryManagement;

/// Environment for N-API values and operations.
///
/// All N-API values and operations must be associated with an environment. An environment
Expand Down Expand Up @@ -1549,6 +1551,12 @@ namespace Napi {
std::string _error;
};

// Memory management.
class MemoryManagement {
public:
static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
};

} // namespace Napi

// Inline implementations of all the above class methods are included here.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"Anna Henningsen (https://github.com/addaleax)",
"Arunesh Chandra (https://github.com/aruneshchandra)",
"Benjamin Byholm (https://github.com/kkoopa)",
"Cory Mickelson (https://github.com/corymickelson)",
"Cory Mickelson (https://github.com/corymickelson)",
"David Halls (https://github.com/davedoesdev)",
"Eric Bickle (https://github.com/ebickle)",
"Gabriel Schulhof (https://github.com/gabrielschulhof)",
Expand Down
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Object InitError(Env env);
Object InitExternal(Env env);
Object InitFunction(Env env);
Object InitHandleScope(Env env);
Object InitMemoryManagement(Env env);
Object InitName(Env env);
Object InitObject(Env env);
Object InitPromise(Env env);
Expand All @@ -33,6 +34,7 @@ Object Init(Env env, Object exports) {
exports.Set("function", InitFunction(env));
exports.Set("name", InitName(env));
exports.Set("handlescope", InitHandleScope(env));
exports.Set("memory_management", InitMemoryManagement(env));
exports.Set("object", InitObject(env));
exports.Set("promise", InitPromise(env));
exports.Set("typedarray", InitTypedArray(env));
Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'external.cc',
'function.cc',
'handlescope.cc',
'memory_management.cc',
'name.cc',
'object/delete_property.cc',
'object/get_property.cc',
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ let testModules = [
'external',
'function',
'handlescope',
'memory_management',
'name',
'object/delete_property',
'object/get_property',
Expand Down
17 changes: 17 additions & 0 deletions test/memory_management.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "napi.h"

using namespace Napi;

Value externalAllocatedMemory(const CallbackInfo& info) {
int64_t kSize = 1024 * 1024;
int64_t baseline = MemoryManagement::AdjustExternalMemory(info.Env(), 0);
int64_t tmp = MemoryManagement::AdjustExternalMemory(info.Env(), kSize);
tmp = MemoryManagement::AdjustExternalMemory(info.Env(), -kSize);
return Boolean::New(info.Env(), tmp == baseline);
}

Object InitMemoryManagement(Env env) {
Object exports = Object::New(env);
exports["externalAllocatedMemory"] = Function::New(env, externalAllocatedMemory);
return exports;
}
10 changes: 10 additions & 0 deletions test/memory_management.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));

function test(binding) {
assert.strictEqual(binding.memory_management.externalAllocatedMemory(), true)
}

0 comments on commit 320704b

Please sign in to comment.