@@ -51,7 +51,11 @@ class MsgpackSbuffer {
5151 }
5252
5353 ~MsgpackSbuffer () {
54- msgpack_sbuffer_destroy (&this ->_sbuf );
54+ // godsflaw: No longer call msgpack_sbuffer_destroy here, as the
55+ // memory from _sbuf will be freed in the _free_sbuf callback,
56+ // which is called by the Buffer destructor. While this is more
57+ // complicated, it should yield a decent performance increase.
58+ msgpack_sbuffer_release (&this ->_sbuf );
5559 }
5660};
5761
@@ -74,6 +78,16 @@ class MsgpackSbuffer {
7478 } \
7579 } while (0 )
7680
81+ // This will be passed to Buffer::New so that we can manage our own memory.
82+ // In other news, I am unsure what to do with hint, as I've never seen this
83+ // coding pattern before.
84+ static void
85+ _free_sbuf (char *data, void *hint) {
86+ if (data != NULL ) {
87+ free (data);
88+ }
89+ }
90+
7791// Convert a V8 object to a MessagePack object.
7892//
7993// This method is recursive. It will probably blow out the stack on objects
@@ -229,7 +243,7 @@ msgpack_to_v8(msgpack_object *mo) {
229243// will be accumulated to the end of the previous value(s).
230244//
231245// Any number of objects can be provided as arguments, and all will be
232- // serialized to the same bytestream, back-ty -back.
246+ // serialized to the same bytestream, back-to -back.
233247static Handle<Value>
234248pack (const Arguments &args) {
235249 HandleScope scope;
@@ -244,7 +258,7 @@ pack(const Arguments &args) {
244258 msgpack_object mo;
245259
246260 try {
247- v8_to_msgpack (args[0 ], &mo, &mz._mz , 0 );
261+ v8_to_msgpack (args[i ], &mo, &mz._mz , 0 );
248262 } catch (MsgpackException e) {
249263 return ThrowException (e.getThrownException ());
250264 }
@@ -255,10 +269,24 @@ pack(const Arguments &args) {
255269 }
256270 }
257271
258- Buffer *bp = Buffer::New (sb._sbuf .size );
259- memcpy (Buffer::Data (bp), sb._sbuf .data , sb._sbuf .size );
272+ v8::Local<Buffer> slowBuffer = node::Buffer::New (
273+ sb._sbuf .data , sb._sbuf .size , _free_sbuf, 0
274+ );
260275
261- return scope.Close (bp->handle_ );
276+ v8::Local<Object> global = v8::Context::GetCurrent ()->Global ();
277+ v8::Local<Value> bv = global->Get (String::NewSymbol (" Buffer" ));
278+
279+ assert (bv->IsFunction ());
280+
281+ Local<Function> bc = v8::Local<Function>::Cast (bv);
282+ Handle<Value> cArgs[3 ] = {
283+ slowBuffer->handle_ ,
284+ v8::Integer::New (sb._sbuf .size ),
285+ v8::Integer::New (0 )
286+ };
287+ v8::Local<Object> fastBuffer = bc->NewInstance (3 , cArgs);
288+
289+ return scope.Close (fastBuffer);
262290}
263291
264292// var o = msgpack.unpack(buf);
0 commit comments