summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-01-29 23:23:36 -0800
committerisaacs <i@izs.me>2013-01-30 09:04:30 -0800
commit016810913d48774e61f2c0f187f4121fd29aaa12 (patch)
treee9a2b13f84b0ea4630b1b91836ec82c42e3460b4
parentf64d1febc887b8516ece378abcddfc409a2f0408 (diff)
downloadnode-016810913d48774e61f2c0f187f4121fd29aaa12.tar.gz
node: Do not use fn.apply() in process._makeCallback
-rw-r--r--src/node.cc21
-rw-r--r--src/node.js35
2 files changed, 41 insertions, 15 deletions
diff --git a/src/node.cc b/src/node.cc
index fe7d4bcd3..b88639f70 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -908,6 +908,11 @@ MakeCallback(const Handle<Object> object,
Handle<Value> argv[]) {
HandleScope scope;
+ if (argc > 6) {
+ fprintf(stderr, "node::MakeCallback - Too many args (%d)\n", argc);
+ abort();
+ }
+
Local<Value> callback_v = object->Get(symbol);
if (!callback_v->IsFunction()) {
String::Utf8Value method(symbol);
@@ -918,18 +923,6 @@ MakeCallback(const Handle<Object> object,
abort();
}
- Local<Function> callback = Local<Function>::Cast(callback_v);
-
- return scope.Close(MakeCallback(object, callback, argc, argv));
-}
-
-Handle<Value>
-MakeCallback(const Handle<Object> object,
- const Handle<Function> callback,
- int argc,
- Handle<Value> argv[]) {
- HandleScope scope;
-
// TODO Hook for long stack traces to be made here.
TryCatch try_catch;
@@ -950,9 +943,9 @@ MakeCallback(const Handle<Object> object,
}
Local<Value> object_l = Local<Value>::New(node_isolate, object);
- Local<Value> callback_l = Local<Value>::New(node_isolate, callback);
+ Local<Value> symbol_l = Local<Value>::New(node_isolate, symbol);
- Local<Value> args[3] = { object_l, callback_l, argArray };
+ Local<Value> args[3] = { object_l, symbol_l, argArray };
Local<Value> ret = process_makeCallback->Call(process, ARRAY_SIZE(args), args);
diff --git a/src/node.js b/src/node.js
index f86a95042..9fc68e498 100644
--- a/src/node.js
+++ b/src/node.js
@@ -296,6 +296,8 @@
};
startup.processMakeCallback = function() {
+ // Along with EventEmitter.emit, this is the hottest code in node.
+ // Everything that comes from C++ into JS passes through here.
process._makeCallback = function(obj, fn, args) {
var domain = obj.domain;
if (domain) {
@@ -303,7 +305,38 @@
domain.enter();
}
- var ret = fn.apply(obj, args);
+ // I know what you're thinking, why not just use fn.apply
+ // Because we hit this function a lot, and really want to make sure
+ // that V8 can optimize it as well as possible.
+ var ret;
+ switch (args.length) {
+ case 0:
+ ret = obj[fn]();
+ break;
+ case 1:
+ ret = obj[fn](args[0]);
+ break;
+ case 2:
+ ret = obj[fn](args[0], args[1]);
+ break;
+ case 3:
+ ret = obj[fn](args[0], args[1], args[2]);
+ break;
+ case 4:
+ ret = obj[fn](args[0], args[1], args[2], args[3]);
+ break;
+ case 5:
+ ret = obj[fn](args[0], args[1], args[2], args[3], args[4]);
+ break;
+ case 6:
+ ret = obj[fn](args[0], args[1], args[2], args[3], args[4], args[5]);
+ break;
+
+ default:
+ // How did we even get here? This should abort() in C++ land!
+ throw new Error('too many args to makeCallback');
+ break;
+ }
if (domain) domain.exit();