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