summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBert Belder <bertbelder@gmail.com>2015-01-13 02:32:09 +0100
committerBert Belder <bertbelder@gmail.com>2015-01-13 02:35:27 +0100
commit0bf1d124af481ac9be095fcb846a1aad08595233 (patch)
treea86f47d152523eda52a2e7ecb9fb564410386190 /src
parentf468e5f1ec34d51f1691ab1f8c9cd813ebee85ef (diff)
downloadnode-new-0bf1d124af481ac9be095fcb846a1aad08595233.tar.gz
http: optimize on_headers_complete
Use an array instead of an object to pass a parsed header chunk from c++ to javascript. This offers a 5-10% speedup on the http_simple benchmark, as evidenced by running: ab -k -t 100 -c 100 http://127.0.0.1:8000/bytes/100 PR: https://github.com/iojs/io.js/pull/292 Reviewed-by: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src')
-rw-r--r--src/env.h9
-rw-r--r--src/node_http_parser.cc59
2 files changed, 37 insertions, 31 deletions
diff --git a/src/env.h b/src/env.h
index 7e28fb3ac1..e2002ee92f 100644
--- a/src/env.h
+++ b/src/env.h
@@ -92,7 +92,6 @@ namespace node {
V(fsevent_string, "FSEvent") \
V(gid_string, "gid") \
V(handle_string, "handle") \
- V(headers_string, "headers") \
V(heap_size_limit_string, "heap_size_limit") \
V(heap_total_string, "heapTotal") \
V(heap_used_string, "heapUsed") \
@@ -114,7 +113,6 @@ namespace node {
V(mark_sweep_compact_string, "mark-sweep-compact") \
V(max_buffer_string, "maxBuffer") \
V(message_string, "message") \
- V(method_string, "method") \
V(minttl_string, "minttl") \
V(mode_string, "mode") \
V(model_string, "model") \
@@ -176,7 +174,6 @@ namespace node {
V(service_string, "service") \
V(servername_string, "servername") \
V(session_id_string, "sessionId") \
- V(should_keep_alive_string, "shouldKeepAlive") \
V(signal_string, "signal") \
V(size_string, "size") \
V(smalloc_p_string, "_smalloc_p") \
@@ -184,8 +181,6 @@ namespace node {
V(sni_context_string, "sni_context") \
V(speed_string, "speed") \
V(stack_string, "stack") \
- V(status_code_string, "statusCode") \
- V(status_message_string, "statusMessage") \
V(status_string, "status") \
V(stdio_string, "stdio") \
V(subject_string, "subject") \
@@ -209,16 +204,12 @@ namespace node {
V(type_string, "type") \
V(uid_string, "uid") \
V(unknown_string, "<unknown>") \
- V(upgrade_string, "upgrade") \
- V(url_string, "url") \
V(used_heap_size_string, "used_heap_size") \
V(user_string, "user") \
V(uv_string, "uv") \
V(valid_from_string, "valid_from") \
V(valid_to_string, "valid_to") \
V(verify_error_string, "verifyError") \
- V(version_major_string, "versionMajor") \
- V(version_minor_string, "versionMinor") \
V(version_string, "version") \
V(weight_string, "weight") \
V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc
index 284e786917..f71302d313 100644
--- a/src/node_http_parser.cc
+++ b/src/node_http_parser.cc
@@ -34,6 +34,7 @@
namespace node {
using v8::Array;
+using v8::Boolean;
using v8::Context;
using v8::Exception;
using v8::Function;
@@ -46,6 +47,7 @@ using v8::Local;
using v8::Object;
using v8::String;
using v8::Uint32;
+using v8::Undefined;
using v8::Value;
const uint32_t kOnHeaders = 0;
@@ -218,55 +220,68 @@ class Parser : public BaseObject {
HTTP_CB(on_headers_complete) {
+ // Arguments for the on-headers-complete javascript callback. This
+ // list needs to be kept in sync with the actual argument list for
+ // `parserOnHeadersComplete` in lib/_http_common.js.
+ enum on_headers_complete_arg_index {
+ A_VERSION_MAJOR = 0,
+ A_VERSION_MINOR,
+ A_HEADERS,
+ A_METHOD,
+ A_URL,
+ A_STATUS_CODE,
+ A_STATUS_MESSAGE,
+ A_UPGRADE,
+ A_SHOULD_KEEP_ALIVE,
+ A_MAX
+ };
+
+ Local<Value> argv[A_MAX];
Local<Object> obj = object();
Local<Value> cb = obj->Get(kOnHeadersComplete);
if (!cb->IsFunction())
return 0;
- Local<Object> message_info = Object::New(env()->isolate());
+ Local<Value> undefined = Undefined(env()->isolate());
+ for (size_t i = 0; i < ARRAY_SIZE(argv); i++)
+ argv[i] = undefined;
if (have_flushed_) {
// Slow case, flush remaining headers.
Flush();
} else {
// Fast case, pass headers and URL to JS land.
- message_info->Set(env()->headers_string(), CreateHeaders());
+ argv[A_HEADERS] = CreateHeaders();
if (parser_.type == HTTP_REQUEST)
- message_info->Set(env()->url_string(), url_.ToString(env()));
+ argv[A_URL] = url_.ToString(env());
}
- num_fields_ = num_values_ = 0;
+
+ num_fields_ = 0;
+ num_values_ = 0;
// METHOD
if (parser_.type == HTTP_REQUEST) {
- message_info->Set(env()->method_string(),
- Uint32::NewFromUnsigned(env()->isolate(),
- parser_.method));
+ argv[A_METHOD] =
+ Uint32::NewFromUnsigned(env()->isolate(), parser_.method);
}
// STATUS
if (parser_.type == HTTP_RESPONSE) {
- message_info->Set(env()->status_code_string(),
- Integer::New(env()->isolate(), parser_.status_code));
- message_info->Set(env()->status_message_string(),
- status_message_.ToString(env()));
+ argv[A_STATUS_CODE] =
+ Integer::New(env()->isolate(), parser_.status_code);
+ argv[A_STATUS_MESSAGE] = status_message_.ToString(env());
}
// VERSION
- message_info->Set(env()->version_major_string(),
- Integer::New(env()->isolate(), parser_.http_major));
- message_info->Set(env()->version_minor_string(),
- Integer::New(env()->isolate(), parser_.http_minor));
+ argv[A_VERSION_MAJOR] = Integer::New(env()->isolate(), parser_.http_major);
+ argv[A_VERSION_MINOR] = Integer::New(env()->isolate(), parser_.http_minor);
- message_info->Set(env()->should_keep_alive_string(),
- http_should_keep_alive(&parser_) ?
- True(env()->isolate()) : False(env()->isolate()));
+ argv[A_SHOULD_KEEP_ALIVE] =
+ Boolean::New(env()->isolate(), http_should_keep_alive(&parser_));
- message_info->Set(env()->upgrade_string(),
- parser_.upgrade ? True(env()->isolate())
- : False(env()->isolate()));
+ argv[A_UPGRADE] = Boolean::New(env()->isolate(), parser_.upgrade);
- Local<Value> argv[1] = { message_info };
Local<Value> head_response =
cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv);