Browse Source

smalloc: check if object has external memory

Add HasExternalData API to check if Object has externally allocated
memory, and accompanying tests.
v0.11.9-release
Trevor Norris 11 years ago
parent
commit
c414ec1c2c
  1. 29
      doc/api/smalloc.markdown
  2. 1
      lib/smalloc.js
  3. 14
      src/smalloc.cc
  4. 6
      src/smalloc.h
  5. 19
      test/simple/test-smalloc.js

29
doc/api/smalloc.markdown

@ -2,11 +2,14 @@
Stability: 1 - Experimental Stability: 1 - Experimental
`Smalloc` is a light weight API that allows developers to attach external data
to arbitrary `Object`s.
## smalloc.alloc(length[, receiver][, type]) ## smalloc.alloc(length[, receiver][, type])
* `length` {Number} `<= smalloc.kMaxLength` * `length` {Number} `<= kMaxLength` (maximum allowed Buffer size by v8)
* `receiver` {Object}, Optional, Default: `new Object` * `receiver` {Object} Optional, Default: `new Object()`
* `type` {Enum}, Optional, Default: `Uint8` * `type` {Enum} Optional, Default: `Uint8`
Returns `receiver` with allocated external array data. If no `receiver` is Returns `receiver` with allocated external array data. If no `receiver` is
passed then a new Object will be created and returned. passed then a new Object will be created and returned.
@ -46,13 +49,13 @@ possible options are listed in `smalloc.Types`. Example usage:
// { '0': 0, '1': 0.1, '2': 0.2 } // { '0': 0, '1': 0.1, '2': 0.2 }
## smalloc.copyOnto(source, sourceStart, dest, destStart, copyLength); ## smalloc.copyOnto(source, sourceStart, dest, destStart, copyLength)
* `source` Object with external array allocation * `source` {Object} with external array allocation
* `sourceStart` Position to begin copying from * `sourceStart` {Position} to begin copying from
* `dest` Object with external array allocation * `dest` {Object} with external array allocation
* `destStart` Position to begin copying onto * `destStart` {Position} to begin copying onto
* `copyLength` Length of copy * `copyLength` {Length} of copy
Copy memory from one external array allocation to another. No arguments are Copy memory from one external array allocation to another. No arguments are
optional, and any violation will throw. optional, and any violation will throw.
@ -77,7 +80,7 @@ need to set any additional properties for this to work.
## smalloc.dispose(obj) ## smalloc.dispose(obj)
* `obj` Object * `obj` {Object}
Free memory that has been allocated to an object via `smalloc.alloc`. Free memory that has been allocated to an object via `smalloc.alloc`.
@ -107,6 +110,12 @@ careful. Cryptic errors may arise in applications that are difficult to trace.
`dispose()` does not support Buffers, and will throw if passed. `dispose()` does not support Buffers, and will throw if passed.
## smalloc.hasExternalData(obj)
* `obj` {Object}
Returns `true` if the `obj` has externally allocated memory.
## smalloc.kMaxLength ## smalloc.kMaxLength
Size of maximum allocation. This is also applicable to Buffer creation. Size of maximum allocation. This is also applicable to Buffer creation.

1
lib/smalloc.js

@ -26,6 +26,7 @@ var util = require('util');
exports.alloc = alloc; exports.alloc = alloc;
exports.copyOnto = smalloc.copyOnto; exports.copyOnto = smalloc.copyOnto;
exports.dispose = dispose; exports.dispose = dispose;
exports.hasExternalData = smalloc.hasExternalData;
// don't allow kMaxLength to accidentally be overwritten. it's a lot less // don't allow kMaxLength to accidentally be overwritten. it's a lot less
// apparent when a primitive is accidentally changed. // apparent when a primitive is accidentally changed.

14
src/smalloc.cc

@ -23,6 +23,7 @@
#include "env.h" #include "env.h"
#include "env-inl.h" #include "env-inl.h"
#include "node.h"
#include "node_internals.h" #include "node_internals.h"
#include "v8-profiler.h" #include "v8-profiler.h"
#include "v8.h" #include "v8.h"
@ -402,6 +403,17 @@ void TargetFreeCallback(Isolate* isolate,
} }
void HasExternalData(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(args[0]->IsObject() &&
HasExternalData(args[0].As<Object>()));
}
bool HasExternalData(Local<Object> obj) {
return obj->HasIndexedPropertiesInExternalArrayData();
}
class RetainedAllocInfo: public RetainedObjectInfo { class RetainedAllocInfo: public RetainedObjectInfo {
public: public:
explicit RetainedAllocInfo(Handle<Value> wrapper); explicit RetainedAllocInfo(Handle<Value> wrapper);
@ -471,6 +483,8 @@ void Initialize(Handle<Object> exports,
NODE_SET_METHOD(exports, "alloc", Alloc); NODE_SET_METHOD(exports, "alloc", Alloc);
NODE_SET_METHOD(exports, "dispose", AllocDispose); NODE_SET_METHOD(exports, "dispose", AllocDispose);
NODE_SET_METHOD(exports, "hasExternalData", HasExternalData);
exports->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kMaxLength"), exports->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kMaxLength"),
Uint32::NewFromUnsigned(kMaxLength, env->isolate())); Uint32::NewFromUnsigned(kMaxLength, env->isolate()));

6
src/smalloc.h

@ -101,6 +101,12 @@ NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
*/ */
NODE_EXTERN void AllocDispose(v8::Handle<v8::Object> obj); NODE_EXTERN void AllocDispose(v8::Handle<v8::Object> obj);
/**
* Check if the Object has externally allocated memory.
*/
NODE_EXTERN bool HasExternalData(v8::Local<v8::Object> obj);
} // namespace smalloc } // namespace smalloc
} // namespace node } // namespace node

19
test/simple/test-smalloc.js

@ -156,6 +156,25 @@ copyOnto(c, 0, b, 0, 2);
assert.equal(b[0], 0.1); assert.equal(b[0], 0.1);
// verify checking external if has external memory
// check objects
var b = {};
assert.ok(!smalloc.hasExternalData(b));
alloc(1, b);
assert.ok(smalloc.hasExternalData(b));
var f = function() { };
alloc(1, f);
assert.ok(smalloc.hasExternalData(f));
// and non-objects
assert.ok(!smalloc.hasExternalData(true));
assert.ok(!smalloc.hasExternalData(1));
assert.ok(!smalloc.hasExternalData('string'));
assert.ok(!smalloc.hasExternalData(null));
assert.ok(!smalloc.hasExternalData());
// verify alloc throws properly // verify alloc throws properly
// arrays are not supported // arrays are not supported

Loading…
Cancel
Save