1#include <node.h> 2#include <v8.h> 3#include <stdlib.h> 4 5#ifdef _AIX 6// AIX allows over-allocation, and will SIGKILL when the allocated pages are 7// used if there is not enough VM. Check for available space until 8// out-of-memory. Don't allow more then some (large) proportion of it to be 9// used for the test strings, so Node & V8 have some space for allocations. 10#include <signal.h> 11#include <sys/vminfo.h> 12 13static void* Allowed(size_t size) { 14 blkcnt_t allowedBlocks = psdanger(SIGKILL); 15 16 if (allowedBlocks < 1) { 17 // Already OOM 18 return nullptr; 19 } 20 const size_t BYTES_PER_BLOCK = 512; 21 size_t allowed = (allowedBlocks * BYTES_PER_BLOCK * 4) / 5; 22 if (size < allowed) { 23 return malloc(size); 24 } 25 return nullptr; 26} 27#else 28// Other systems also allow over-allocation, but this malloc-and-free approach 29// seems to be working for them. 30static void* Allowed(size_t size) { 31 return malloc(size); 32} 33#endif // _AIX 34 35void EnsureAllocation(const v8::FunctionCallbackInfo<v8::Value> &args) { 36 v8::Isolate* isolate = args.GetIsolate(); 37 uintptr_t size = args[0].As<v8::Integer>()->Value(); 38 v8::Local<v8::Boolean> success; 39 40 void* buffer = Allowed(size); 41 if (buffer) { 42 success = v8::Boolean::New(isolate, true); 43 free(buffer); 44 } else { 45 success = v8::Boolean::New(isolate, false); 46 } 47 args.GetReturnValue().Set(success); 48} 49 50void init(v8::Local<v8::Object> exports) { 51 NODE_SET_METHOD(exports, "ensureAllocation", EnsureAllocation); 52} 53 54NODE_MODULE(NODE_GYP_MODULE_NAME, init) 55