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 Allowed(size_t size)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. Allowed(size_t size)30static void* Allowed(size_t size) { 31 return malloc(size); 32 } 33 #endif // _AIX 34 EnsureAllocation(const v8::FunctionCallbackInfo<v8::Value> & args)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 init(v8::Local<v8::Object> exports)50void init(v8::Local<v8::Object> exports) { 51 NODE_SET_METHOD(exports, "ensureAllocation", EnsureAllocation); 52 } 53 54 NODE_MODULE(NODE_GYP_MODULE_NAME, init) 55