From 45a806a066b082fa95c56ba9715d72caabf45289 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 9 Dec 2009 09:02:21 +0100 Subject: [PATCH] Statically define symbols ~7% improvement in hello world HTTP response bench. --- src/node.cc | 111 +++++++++++++++++++++++------------ src/node.h | 2 + src/node_child_process.cc | 18 ++++-- src/node_dns.cc | 6 +- src/node_events.cc | 9 ++- src/node_events.h | 4 +- src/node_file.cc | 12 ++-- src/node_http.cc | 86 ++++++++++++++++++++------- src/node_net.cc | 115 +++++++++++++++++++++++-------------- src/node_signal_handler.cc | 5 +- src/node_stat.cc | 10 +++- src/node_timer.cc | 16 ++++-- 12 files changed, 270 insertions(+), 124 deletions(-) diff --git a/src/node.cc b/src/node.cc index 781171b6d0..b830c4ce8d 100644 --- a/src/node.cc +++ b/src/node.cc @@ -34,6 +34,29 @@ namespace node { static Persistent process; +static Persistent dev_symbol; +static Persistent ino_symbol; +static Persistent mode_symbol; +static Persistent nlink_symbol; +static Persistent uid_symbol; +static Persistent gid_symbol; +static Persistent rdev_symbol; +static Persistent size_symbol; +static Persistent blksize_symbol; +static Persistent blocks_symbol; +static Persistent atime_symbol; +static Persistent mtime_symbol; +static Persistent ctime_symbol; + +static Persistent rss_symbol; +static Persistent vsize_symbol; +static Persistent heap_total_symbol; +static Persistent heap_used_symbol; + +static Persistent listeners_symbol; +static Persistent uncaught_exception_symbol; +static Persistent emit_symbol; + static int dash_dash_index = 0; static bool use_debug_agent = false; @@ -160,66 +183,68 @@ ssize_t DecodeWrite(char *buf, size_t buflen, return buflen; } -#define DEV_SYMBOL String::NewSymbol("dev") -#define INO_SYMBOL String::NewSymbol("ino") -#define MODE_SYMBOL String::NewSymbol("mode") -#define NLINK_SYMBOL String::NewSymbol("nlink") -#define UID_SYMBOL String::NewSymbol("uid") -#define GID_SYMBOL String::NewSymbol("gid") -#define RDEV_SYMBOL String::NewSymbol("rdev") -#define SIZE_SYMBOL String::NewSymbol("size") -#define BLKSIZE_SYMBOL String::NewSymbol("blksize") -#define BLOCKS_SYMBOL String::NewSymbol("blocks") -#define ATIME_SYMBOL String::NewSymbol("atime") -#define MTIME_SYMBOL String::NewSymbol("mtime") -#define CTIME_SYMBOL String::NewSymbol("ctime") - static Persistent stats_constructor_template; Local BuildStatsObject(struct stat * s) { HandleScope scope; + if (dev_symbol.IsEmpty()) { + dev_symbol = NODE_PSYMBOL("dev"); + ino_symbol = NODE_PSYMBOL("ino"); + mode_symbol = NODE_PSYMBOL("mode"); + nlink_symbol = NODE_PSYMBOL("nlink"); + uid_symbol = NODE_PSYMBOL("uid"); + gid_symbol = NODE_PSYMBOL("gid"); + rdev_symbol = NODE_PSYMBOL("rdev"); + size_symbol = NODE_PSYMBOL("size"); + blksize_symbol = NODE_PSYMBOL("blksize"); + blocks_symbol = NODE_PSYMBOL("blocks"); + atime_symbol = NODE_PSYMBOL("atime"); + mtime_symbol = NODE_PSYMBOL("mtime"); + ctime_symbol = NODE_PSYMBOL("ctime"); + } + Local stats = stats_constructor_template->GetFunction()->NewInstance(); /* ID of device containing file */ - stats->Set(DEV_SYMBOL, Integer::New(s->st_dev)); + stats->Set(dev_symbol, Integer::New(s->st_dev)); /* inode number */ - stats->Set(INO_SYMBOL, Integer::New(s->st_ino)); + stats->Set(ino_symbol, Integer::New(s->st_ino)); /* protection */ - stats->Set(MODE_SYMBOL, Integer::New(s->st_mode)); + stats->Set(mode_symbol, Integer::New(s->st_mode)); /* number of hard links */ - stats->Set(NLINK_SYMBOL, Integer::New(s->st_nlink)); + stats->Set(nlink_symbol, Integer::New(s->st_nlink)); /* user ID of owner */ - stats->Set(UID_SYMBOL, Integer::New(s->st_uid)); + stats->Set(uid_symbol, Integer::New(s->st_uid)); /* group ID of owner */ - stats->Set(GID_SYMBOL, Integer::New(s->st_gid)); + stats->Set(gid_symbol, Integer::New(s->st_gid)); /* device ID (if special file) */ - stats->Set(RDEV_SYMBOL, Integer::New(s->st_rdev)); + stats->Set(rdev_symbol, Integer::New(s->st_rdev)); /* total size, in bytes */ - stats->Set(SIZE_SYMBOL, Integer::New(s->st_size)); + stats->Set(size_symbol, Integer::New(s->st_size)); /* blocksize for filesystem I/O */ - stats->Set(BLKSIZE_SYMBOL, Integer::New(s->st_blksize)); + stats->Set(blksize_symbol, Integer::New(s->st_blksize)); /* number of blocks allocated */ - stats->Set(BLOCKS_SYMBOL, Integer::New(s->st_blocks)); + stats->Set(blocks_symbol, Integer::New(s->st_blocks)); /* time of last access */ - stats->Set(ATIME_SYMBOL, NODE_UNIXTIME_V8(s->st_atime)); + stats->Set(atime_symbol, NODE_UNIXTIME_V8(s->st_atime)); /* time of last modification */ - stats->Set(MTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_mtime)); + stats->Set(mtime_symbol, NODE_UNIXTIME_V8(s->st_mtime)); /* time of last status change */ - stats->Set(CTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_ctime)); + stats->Set(ctime_symbol, NODE_UNIXTIME_V8(s->st_ctime)); return scope.Close(stats); } @@ -510,15 +535,22 @@ v8::Handle MemoryUsage(const v8::Arguments& args) { Local info = Object::New(); - info->Set(String::NewSymbol("rss"), Integer::NewFromUnsigned(rss)); - info->Set(String::NewSymbol("vsize"), Integer::NewFromUnsigned(vsize)); + if (rss_symbol.IsEmpty()) { + rss_symbol = NODE_PSYMBOL("rss"); + vsize_symbol = NODE_PSYMBOL("vsize"); + heap_total_symbol = NODE_PSYMBOL("heapTotal"); + heap_used_symbol = NODE_PSYMBOL("heapUsed"); + } + + info->Set(rss_symbol, Integer::NewFromUnsigned(rss)); + info->Set(vsize_symbol, Integer::NewFromUnsigned(vsize)); // V8 memory usage HeapStatistics v8_heap_stats; V8::GetHeapStatistics(&v8_heap_stats); - info->Set(String::NewSymbol("heapTotal"), + info->Set(heap_total_symbol, Integer::NewFromUnsigned(v8_heap_stats.total_heap_size())); - info->Set(String::NewSymbol("heapUsed"), + info->Set(heap_used_symbol, Integer::NewFromUnsigned(v8_heap_stats.used_heap_size())); return scope.Close(info); @@ -641,14 +673,19 @@ void FatalException(TryCatch &try_catch) { exit(1); } - Local listeners_v = process->Get(String::NewSymbol("listeners")); + if (listeners_symbol.IsEmpty()) { + listeners_symbol = NODE_PSYMBOL("listeners"); + uncaught_exception_symbol = NODE_PSYMBOL("uncaughtException"); + emit_symbol = NODE_PSYMBOL("emit"); + } + + Local listeners_v = process->Get(listeners_symbol); assert(listeners_v->IsFunction()); Local listeners = Local::Cast(listeners_v); - Local uncaught_exception = String::NewSymbol("uncaughtException"); - - Local argv[1] = { uncaught_exception }; + Local uncaught_exception_symbol_l = Local::New(uncaught_exception_symbol); + Local argv[1] = { uncaught_exception_symbol_l }; Local ret = listeners->Call(process, 1, argv); assert(ret->IsArray()); @@ -663,13 +700,13 @@ void FatalException(TryCatch &try_catch) { } // Otherwise fire the process "uncaughtException" event - Local emit_v = process->Get(String::NewSymbol("emit")); + Local emit_v = process->Get(emit_symbol); assert(emit_v->IsFunction()); Local emit = Local::Cast(emit_v); Local error = try_catch.Exception(); - Local event_argv[2] = { uncaught_exception, error }; + Local event_argv[2] = { uncaught_exception_symbol_l, error }; uncaught_exception_counter++; emit->Call(process, 2, event_argv); diff --git a/src/node.h b/src/node.h index 159cc8c970..fd872a0960 100644 --- a/src/node.h +++ b/src/node.h @@ -13,6 +13,8 @@ namespace node { +#define NODE_PSYMBOL(s) Persistent::New(String::NewSymbol(s)) + /* Converts a unixtime to V8 Date */ #define NODE_UNIXTIME_V8(t) v8::Date::New(1000*static_cast(t)) #define NODE_V8_UNIXTIME(v) (static_cast((v)->IntegerValue())/1000.0); diff --git a/src/node_child_process.cc b/src/node_child_process.cc index 9a78d32344..78d5c5c5be 100644 --- a/src/node_child_process.cc +++ b/src/node_child_process.cc @@ -13,10 +13,13 @@ namespace node { using namespace v8; -#define PID_SYMBOL String::NewSymbol("pid") - Persistent ChildProcess::constructor_template; +static Persistent pid_symbol; +static Persistent exit_symbol; +static Persistent output_symbol; +static Persistent error_symbol; + void ChildProcess::Initialize(Handle target) { HandleScope scope; @@ -26,6 +29,11 @@ void ChildProcess::Initialize(Handle target) { constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("ChildProcess")); + pid_symbol = NODE_PSYMBOL("pid"); + exit_symbol = NODE_PSYMBOL("exit"); + output_symbol = NODE_PSYMBOL("output"); + error_symbol = NODE_PSYMBOL("error"); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "spawn", ChildProcess::Spawn); NODE_SET_PROTOTYPE_METHOD(constructor_template, "write", ChildProcess::Write); NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", ChildProcess::Close); @@ -100,7 +108,7 @@ Handle ChildProcess::Spawn(const Arguments& args) { return ThrowException(Exception::Error(String::New("Error spawning"))); } - child->handle_->Set(PID_SYMBOL, Integer::New(child->pid_)); + child->handle_->Set(pid_symbol, Integer::New(child->pid_)); return Undefined(); } @@ -193,7 +201,7 @@ void ChildProcess::on_read(evcom_reader *r, const void *buf, size_t len) { child->stdout_encoding_ : child->stderr_encoding_; Local data = Encode(buf, len, encoding); - child->Emit(isSTDOUT ? "output" : "error", 1, &data); + child->Emit(isSTDOUT ? output_symbol : error_symbol, 1, &data); child->MaybeShutdown(); } @@ -380,7 +388,7 @@ void ChildProcess::MaybeShutdown(void) { if (stdout_fd_ < 0 && stderr_fd_ < 0 && got_chld_) { HandleScope scope; Handle argv[1] = { Integer::New(exit_code_) }; - Emit("exit", 1, argv); + Emit(exit_symbol, 1, argv); Shutdown(); Unref(); } diff --git a/src/node_dns.cc b/src/node_dns.cc index 36ff90044c..1dadab268f 100644 --- a/src/node_dns.cc +++ b/src/node_dns.cc @@ -19,6 +19,8 @@ using namespace v8; static ev_io io_watcher; static ev_timer timer_watcher; +static Persistent errno_symbol; + static inline Persistent* cb_persist(const Local &v) { Persistent *fn = new Persistent(); *fn = Persistent::New(Local::Cast(v)); @@ -77,7 +79,7 @@ static void ResolveError(Handle *cb) { Local e = Exception::Error(String::NewSymbol(dns_strerror(status))); Local obj = e->ToObject(); - obj->Set(String::NewSymbol("errno"), Integer::New(status)); + obj->Set(errno_symbol, Integer::New(status)); (*cb)->Call(Context::GetCurrent()->Global(), 1, &e); } @@ -308,6 +310,8 @@ void DNS::Initialize(Handle target) { HandleScope scope; + errno_symbol = NODE_PSYMBOL("errno"); + target->Set(String::NewSymbol("TEMPFAIL"), Integer::New(DNS_E_TEMPFAIL)); target->Set(String::NewSymbol("PROTOCOL"), Integer::New(DNS_E_PROTOCOL)); target->Set(String::NewSymbol("NXDOMAIN"), Integer::New(DNS_E_NXDOMAIN)); diff --git a/src/node_events.cc b/src/node_events.cc index 215432374a..27d07a46be 100644 --- a/src/node_events.cc +++ b/src/node_events.cc @@ -22,6 +22,8 @@ using namespace v8; Persistent EventEmitter::constructor_template; +static Persistent events_symbol; + void EventEmitter::Initialize(Local ctemplate) { HandleScope scope; @@ -32,6 +34,8 @@ void EventEmitter::Initialize(Local ctemplate) { __emit); constructor_template->SetClassName(String::NewSymbol("EventEmitter")); + events_symbol = NODE_PSYMBOL("_events"); + // All other prototype methods are defined in events.js } @@ -41,7 +45,7 @@ static bool ReallyEmit(Handle self, Handle argv[]) { HandleScope scope; - Local events_v = self->Get(String::NewSymbol("_events")); + Local events_v = self->Get(events_symbol); if (!events_v->IsObject()) return false; Local events = events_v->ToObject(); @@ -91,9 +95,8 @@ Handle EventEmitter::Emit(const Arguments& args) { return scope.Close(r ? True() : False()); } -bool EventEmitter::Emit(const char *event_s, int argc, Handle argv[]) { +bool EventEmitter::Emit(Handle event, int argc, Handle argv[]) { HandleScope scope; - Local event = String::NewSymbol(event_s); return ReallyEmit(handle_, event, argc, argv); } diff --git a/src/node_events.h b/src/node_events.h index 9c613bbde0..2cfcaf02f9 100644 --- a/src/node_events.h +++ b/src/node_events.h @@ -12,7 +12,9 @@ class EventEmitter : public ObjectWrap { static void Initialize(v8::Local ctemplate); static v8::Persistent constructor_template; - bool Emit(const char *event, int argc, v8::Handle argv[]); + bool Emit(v8::Handle event, + int argc, + v8::Handle argv[]); protected: static v8::Handle Emit(const v8::Arguments& args); diff --git a/src/node_file.cc b/src/node_file.cc index 3772ea4fc1..19ddb0e67b 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -17,12 +17,13 @@ using namespace v8; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define THROW_BAD_ARGS \ ThrowException(Exception::TypeError(String::New("Bad argument"))) -#define ENCODING String::NewSymbol("node:encoding") +static Persistent encoding_symbol; +static Persistent errno_symbol; static inline Local errno_exception(int errorno) { Local e = Exception::Error(String::NewSymbol(strerror(errorno))); Local obj = e->ToObject(); - obj->Set(String::NewSymbol("errno"), Integer::New(errorno)); + obj->Set(errno_symbol, Integer::New(errorno)); return e; } @@ -74,7 +75,7 @@ static int After(eio_req *req) { { argc = 2; Local obj = Local::New(*callback); - Local enc_val = obj->GetHiddenValue(ENCODING); + Local enc_val = obj->GetHiddenValue(encoding_symbol); argv[0] = Encode(req->ptr2, req->result, ParseEncoding(enc_val)); argv[1] = Integer::New(req->result); break; @@ -384,7 +385,7 @@ static Handle Read(const Arguments& args) { if (args[4]->IsFunction()) { Local obj = args[4]->ToObject(); - obj->SetHiddenValue(ENCODING, args[3]); + obj->SetHiddenValue(encoding_symbol, args[3]); ASYNC_CALL(read, args[4], fd, NULL, len, offset) } else { #define READ_BUF_LEN (16*1024) @@ -414,6 +415,9 @@ void File::Initialize(Handle target) { NODE_SET_METHOD(target, "stat", Stat); NODE_SET_METHOD(target, "unlink", Unlink); NODE_SET_METHOD(target, "write", Write); + + errno_symbol = NODE_PSYMBOL("errno"); + encoding_symbol = NODE_PSYMBOL("node:encoding"); } } // end namespace node diff --git a/src/node_http.cc b/src/node_http.cc index fffaf0c2ac..5ccc53bcbb 100644 --- a/src/node_http.cc +++ b/src/node_http.cc @@ -4,17 +4,31 @@ #include #include -#define METHOD_SYMBOL String::NewSymbol("method") -#define STATUS_CODE_SYMBOL String::NewSymbol("statusCode") -#define HTTP_VERSION_SYMBOL String::NewSymbol("httpVersion") -#define SHOULD_KEEP_ALIVE_SYMBOL String::NewSymbol("should_keep_alive") - using namespace v8; using namespace node; Persistent HTTPConnection::client_constructor_template; Persistent HTTPConnection::server_constructor_template; +static Persistent method_symbol; +static Persistent status_code_symbol; +static Persistent http_version_symbol; +static Persistent version_major_symbol; +static Persistent version_minor_symbol; +static Persistent should_keep_alive_symbol; + +static Persistent message_begin_symbol; +static Persistent message_complete_symbol; +static Persistent url_symbol; +static Persistent query_string_symbol; +static Persistent path_symbol; +static Persistent fragment_symbol; +static Persistent header_field_symbol; +static Persistent header_value_symbol; +static Persistent header_complete_symbol; +static Persistent body_symbol; +static Persistent eof_symbol; + void HTTPConnection::Initialize (Handle target) { @@ -34,6 +48,11 @@ HTTPConnection::Initialize (Handle target) server_constructor_template->InstanceTemplate()->SetInternalFieldCount(1); NODE_SET_PROTOTYPE_METHOD(server_constructor_template, "resetParser", ResetParser); server_constructor_template->SetClassName(String::NewSymbol("ServerSideConnection")); + + method_symbol = NODE_PSYMBOL("method"); + status_code_symbol = NODE_PSYMBOL("statusCode"); + http_version_symbol = NODE_PSYMBOL("httpVersion"); + should_keep_alive_symbol = NODE_PSYMBOL("should_keep_alive"); } Handle @@ -96,15 +115,38 @@ HTTPConnection::OnEOF () } else { http_parse_responses(&parser_, NULL, 0); } - Emit("eof", 0, NULL); + Emit(eof_symbol, 0, NULL); } int HTTPConnection::on_message_begin (http_parser *parser) { + HandleScope scope; + + if (message_begin_symbol.IsEmpty()) { + method_symbol = NODE_PSYMBOL("method"); + status_code_symbol = NODE_PSYMBOL("statusCode"); + http_version_symbol = NODE_PSYMBOL("httpVersion"); + version_major_symbol = NODE_PSYMBOL("versionMajor"); + version_minor_symbol = NODE_PSYMBOL("versionMinor"); + should_keep_alive_symbol = NODE_PSYMBOL("should_keep_alive"); + + message_begin_symbol = NODE_PSYMBOL("messageBegin"); + message_complete_symbol = NODE_PSYMBOL("messageComplete"); + url_symbol = NODE_PSYMBOL("url"); + query_string_symbol = NODE_PSYMBOL("queryString"); + path_symbol = NODE_PSYMBOL("path"); + fragment_symbol = NODE_PSYMBOL("fragment"); + header_field_symbol = NODE_PSYMBOL("headerField"); + header_value_symbol = NODE_PSYMBOL("headerValue"); + header_complete_symbol = NODE_PSYMBOL("headerComplete"); + body_symbol = NODE_PSYMBOL("body"); + eof_symbol = NODE_PSYMBOL("eof"); + } + HTTPConnection *connection = static_cast (parser->data); assert(connection->refs_); - connection->Emit("messageBegin", 0, NULL); + connection->Emit(message_begin_symbol, 0, NULL); return 0; } @@ -113,7 +155,7 @@ HTTPConnection::on_message_complete (http_parser *parser) { HTTPConnection *connection = static_cast (parser->data); assert(connection->refs_); - connection->Emit("messageComplete", 0, NULL); + connection->Emit(message_complete_symbol, 0, NULL); return 0; } @@ -124,7 +166,7 @@ HTTPConnection::on_url (http_parser *parser, const char *buf, size_t len) HTTPConnection *connection = static_cast(parser->data); assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; - connection->Emit("url", 1, argv); + connection->Emit(url_symbol, 1, argv); return 0; } @@ -135,7 +177,7 @@ HTTPConnection::on_query_string (http_parser *parser, const char *buf, size_t le HTTPConnection *connection = static_cast(parser->data); assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; - connection->Emit("queryString", 1, argv); + connection->Emit(query_string_symbol, 1, argv); return 0; } @@ -146,7 +188,7 @@ HTTPConnection::on_path (http_parser *parser, const char *buf, size_t len) HTTPConnection *connection = static_cast(parser->data); assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; - connection->Emit("path", 1, argv); + connection->Emit(path_symbol, 1, argv); return 0; } @@ -157,7 +199,7 @@ HTTPConnection::on_fragment (http_parser *parser, const char *buf, size_t len) HTTPConnection *connection = static_cast(parser->data); assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; - connection->Emit("fragment", 1, argv); + connection->Emit(fragment_symbol, 1, argv); return 0; } @@ -184,7 +226,7 @@ HTTPConnection::on_header_field (http_parser *parser, const char *buf, size_t le for (i = 0; i < len; i++) { nonconstbuf[i] = normalizer[buf[i]]; } Local argv[1] = { String::New(buf, len) }; - connection->Emit("headerField", 1, argv); + connection->Emit(header_field_symbol, 1, argv); return 0; } @@ -196,7 +238,7 @@ HTTPConnection::on_header_value (http_parser *parser, const char *buf, size_t le assert(connection->refs_); Local argv[1] = { String::New(buf, len) }; - connection->Emit("headerValue", 1, argv); + connection->Emit(header_value_symbol, 1, argv); return 0; } @@ -211,13 +253,13 @@ HTTPConnection::on_headers_complete (http_parser *parser) // METHOD if (connection->type_ == HTTP_REQUEST) { - message_info->Set(METHOD_SYMBOL, String::NewSymbol( + message_info->Set(method_symbol, String::NewSymbol( http_method_str(connection->parser_.method))); } // STATUS if (connection->type_ == HTTP_RESPONSE) { - message_info->Set(STATUS_CODE_SYMBOL, + message_info->Set(status_code_symbol, Integer::New(connection->parser_.status_code)); } @@ -229,18 +271,18 @@ HTTPConnection::on_headers_complete (http_parser *parser) , connection->parser_.http_major , connection->parser_.http_minor ); - message_info->Set(HTTP_VERSION_SYMBOL, String::New(version)); - message_info->Set(String::NewSymbol("versionMajor"), + message_info->Set(http_version_symbol, String::New(version)); + message_info->Set(version_major_symbol, Integer::New(connection->parser_.http_major)); - message_info->Set(String::NewSymbol("versionMinor"), + message_info->Set(version_minor_symbol, Integer::New(connection->parser_.http_minor)); - message_info->Set(SHOULD_KEEP_ALIVE_SYMBOL, + message_info->Set(should_keep_alive_symbol, http_should_keep_alive(&connection->parser_) ? True() : False()); Local argv[1] = { message_info }; - connection->Emit("headerComplete", 1, argv); + connection->Emit(header_complete_symbol, 1, argv); return 0; } @@ -257,7 +299,7 @@ HTTPConnection::on_body (http_parser *parser, const char *buf, size_t len) // TODO each message should have their encoding. // don't look at the conneciton for encoding Local data = Encode(buf, len, connection->encoding_); - connection->Emit("body", 1, &data); + connection->Emit(body_symbol, 1, &data); return 0; } diff --git a/src/node_net.cc b/src/node_net.cc index 51863cfe3f..5b39ae23bd 100644 --- a/src/node_net.cc +++ b/src/node_net.cc @@ -16,22 +16,29 @@ using namespace v8; namespace node { -#define UTF8_SYMBOL String::NewSymbol("utf8") -#define BINARY_SYMBOL String::NewSymbol("binary") -#define ASCII_SYMBOL String::NewSymbol("ascii") - -#define SERVER_SYMBOL String::NewSymbol("server") -#define REMOTE_ADDRESS_SYMBOL String::NewSymbol("remoteAddress") - -#define FD_SYMBOL String::NewSymbol("fd") - -#define READY_STATE_SYMBOL String::NewSymbol("readyState") -#define OPEN_SYMBOL String::NewSymbol("open") -#define OPENING_SYMBOL String::NewSymbol("opening") -#define READ_ONLY_SYMBOL String::NewSymbol("readOnly") -#define WRITE_ONLY_SYMBOL String::NewSymbol("writeOnly") -#define CLOSING_SYMBOL String::NewSymbol("closing") -#define CLOSED_SYMBOL String::NewSymbol("closed") +static Persistent utf8_symbol; +static Persistent binary_symbol; +static Persistent ascii_symbol; + +static Persistent server_symbol; +static Persistent remote_address_symbol; +static Persistent fd_symbol; + +static Persistent ready_state_symbol; +static Persistent open_symbol; +static Persistent opening_symbol; +static Persistent read_only_symbol; +static Persistent write_only_symbol; +static Persistent closing_symbol; +static Persistent closed_symbol; + +static Persistent receive_symbol; +static Persistent connection_symbol; +static Persistent connect_symbol; +static Persistent timeout_symbol; +static Persistent drain_symbol; +static Persistent eof_symbol; +static Persistent close_symbol; static const struct addrinfo server_tcp_hints = /* ai_flags */ { AI_PASSIVE @@ -53,6 +60,30 @@ Persistent Connection::constructor_template; void Connection::Initialize(v8::Handle target) { HandleScope scope; + utf8_symbol = NODE_PSYMBOL("utf8"); + binary_symbol = NODE_PSYMBOL("binary"); + ascii_symbol = NODE_PSYMBOL("ascii"); + + server_symbol = NODE_PSYMBOL("server"); + remote_address_symbol = NODE_PSYMBOL("remoteAddress"); + fd_symbol = NODE_PSYMBOL("fd"); + + ready_state_symbol = NODE_PSYMBOL("readyState"); + open_symbol = NODE_PSYMBOL("open"); + opening_symbol = NODE_PSYMBOL("opening"); + read_only_symbol = NODE_PSYMBOL("readOnly"); + write_only_symbol = NODE_PSYMBOL("writeOnly"); + closing_symbol = NODE_PSYMBOL("closing"); + closed_symbol = NODE_PSYMBOL("closed"); + + receive_symbol = NODE_PSYMBOL("receive"); + connection_symbol = NODE_PSYMBOL("connection"); + connect_symbol = NODE_PSYMBOL("connect"); + timeout_symbol = NODE_PSYMBOL("timeout"); + drain_symbol = NODE_PSYMBOL("drain"); + eof_symbol = NODE_PSYMBOL("eof"); + close_symbol = NODE_PSYMBOL("close"); + Local t = FunctionTemplate::New(New); constructor_template = Persistent::New(t); @@ -82,12 +113,12 @@ void Connection::Initialize(v8::Handle target) { // Getter for connection.readyState constructor_template->PrototypeTemplate()->SetAccessor( - READY_STATE_SYMBOL, + ready_state_symbol, ReadyStateGetter); // Getter for connection.readyState constructor_template->PrototypeTemplate()->SetAccessor( - FD_SYMBOL, + fd_symbol, FDGetter); // Assign class to its place as tcp.Connection @@ -103,22 +134,22 @@ Handle Connection::ReadyStateGetter(Local property, HandleScope scope; - assert(property == READY_STATE_SYMBOL); + assert(property == ready_state_symbol); // Resolving is not done in evcom, it's done in this file. Thus we add // this "opening" symbol to the native EVCOM ready states. "opening" // really means "resolving". - if (connection->resolving_) return scope.Close(OPENING_SYMBOL); + if (connection->resolving_) return scope.Close(opening_symbol); // Map between the evcom enum and V8 strings: switch (evcom_stream_state(&connection->stream_)) { - case EVCOM_INITIALIZED: return scope.Close(CLOSED_SYMBOL); - case EVCOM_CONNECTING: return scope.Close(OPENING_SYMBOL); - case EVCOM_CONNECTED_RW: return scope.Close(OPEN_SYMBOL); - case EVCOM_CONNECTED_RO: return scope.Close(READ_ONLY_SYMBOL); - case EVCOM_CONNECTED_WO: return scope.Close(WRITE_ONLY_SYMBOL); - case EVCOM_CLOSING: return scope.Close(CLOSING_SYMBOL); - case EVCOM_CLOSED: return scope.Close(CLOSED_SYMBOL); + case EVCOM_INITIALIZED: return scope.Close(closed_symbol); + case EVCOM_CONNECTING: return scope.Close(opening_symbol); + case EVCOM_CONNECTED_RW: return scope.Close(open_symbol); + case EVCOM_CONNECTED_RO: return scope.Close(read_only_symbol); + case EVCOM_CONNECTED_WO: return scope.Close(write_only_symbol); + case EVCOM_CLOSING: return scope.Close(closing_symbol); + case EVCOM_CLOSED: return scope.Close(closed_symbol); } assert(0 && "This shouldnt happen"); @@ -134,7 +165,7 @@ Handle Connection::FDGetter(Local property, HandleScope scope; - assert(property == FD_SYMBOL); + assert(property == fd_symbol); Local fd = Integer::New(connection->stream_.recvfd); @@ -325,21 +356,21 @@ Handle Connection::SetEncoding(const Arguments& args) { if (!args[0]->IsString()) { connection->encoding_ = BINARY; - return scope.Close(BINARY_SYMBOL); + return scope.Close(binary_symbol); } switch (ParseEncoding(args[0])) { case ASCII: connection->encoding_ = ASCII; - return scope.Close(ASCII_SYMBOL); + return scope.Close(ascii_symbol); case UTF8: connection->encoding_ = UTF8; - return scope.Close(UTF8_SYMBOL); + return scope.Close(utf8_symbol); case BINARY: connection->encoding_ = BINARY; - return scope.Close(BINARY_SYMBOL); + return scope.Close(binary_symbol); } assert(0 && "this shouldn't happen"); return ThrowException(Exception::Error( @@ -587,7 +618,7 @@ Handle Connection::Send(const Arguments& args) { void Connection::OnReceive(const void *buf, size_t len) { HandleScope scope; Local data = Encode(buf, len, encoding_); - Emit("receive", 1, &data); + Emit(receive_symbol, 1, &data); } void Connection::OnClose() { @@ -598,7 +629,7 @@ void Connection::OnClose() { String::New(strerror(stream_.errorno)) }; - Emit("close", 2, argv); + Emit(close_symbol, 2, argv); } void Connection::OnConnect() { @@ -607,25 +638,25 @@ void Connection::OnConnect() { if (stream_.server) { Server *server = static_cast(stream_.server->data); Local value = Local::New(handle_); - server->Emit("connection", 1, &value); + server->Emit(connection_symbol, 1, &value); } - Emit("connect", 0, NULL); + Emit(connect_symbol, 0, NULL); } void Connection::OnTimeout() { HandleScope scope; - Emit("timeout", 0, NULL); + Emit(timeout_symbol, 0, NULL); } void Connection::OnDrain() { HandleScope scope; - Emit("drain", 0, NULL); + Emit(drain_symbol, 0, NULL); } void Connection::OnEOF() { HandleScope scope; - Emit("eof", 0, NULL); + Emit(eof_symbol, 0, NULL); } Persistent Server::constructor_template; @@ -693,8 +724,8 @@ Connection* Server::OnConnection(struct sockaddr *addr) { } Local remote_address = GetAddressString(addr); - js_connection->Set(REMOTE_ADDRESS_SYMBOL, remote_address); - js_connection->Set(SERVER_SYMBOL, handle_); + js_connection->Set(remote_address_symbol, remote_address); + js_connection->Set(server_symbol, handle_); Connection *connection = UnwrapConnection(js_connection); if (!connection) return NULL; @@ -719,7 +750,7 @@ void Server::OnClose(int errorno) { Handle argv[1] = { Integer::New(errorno) }; - Emit("close", 1, argv); + Emit(close_symbol, 1, argv); } Handle Server::New(const Arguments& args) { diff --git a/src/node_signal_handler.cc b/src/node_signal_handler.cc index 34e84141ef..2cac9b179e 100644 --- a/src/node_signal_handler.cc +++ b/src/node_signal_handler.cc @@ -7,6 +7,7 @@ namespace node { using namespace v8; Persistent SignalHandler::constructor_template; +static Persistent signal_symbol; void SignalHandler::Initialize(Handle target) { HandleScope scope; @@ -19,6 +20,8 @@ void SignalHandler::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", SignalHandler::Stop); + signal_symbol = NODE_PSYMBOL("signal"); + target->Set(String::NewSymbol("SignalHandler"), constructor_template->GetFunction()); } @@ -29,7 +32,7 @@ void SignalHandler::OnSignal(EV_P_ ev_signal *watcher, int revents) { assert(revents == EV_SIGNAL); - handler->Emit("signal", 0, NULL); + handler->Emit(signal_symbol, 0, NULL); } SignalHandler::~SignalHandler() { diff --git a/src/node_stat.cc b/src/node_stat.cc index 5f864e6f23..d48bd037f9 100644 --- a/src/node_stat.cc +++ b/src/node_stat.cc @@ -11,6 +11,9 @@ using namespace v8; Persistent Stat::constructor_template; +static Persistent change_symbol; +static Persistent stop_symbol; + void Stat::Initialize(Handle target) { HandleScope scope; @@ -20,6 +23,9 @@ void Stat::Initialize(Handle target) { constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("Stat")); + change_symbol = NODE_PSYMBOL("change"); + stop_symbol = NODE_PSYMBOL("stop"); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Stat::Start); NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Stat::Stop); @@ -35,7 +41,7 @@ void Stat::Callback(EV_P_ ev_stat *watcher, int revents) { Handle argv[2]; argv[0] = Handle(BuildStatsObject(&watcher->attr)); argv[1] = Handle(BuildStatsObject(&watcher->prev)); - handler->Emit("change", 2, argv); + handler->Emit(change_symbol, 2, argv); } @@ -83,7 +89,7 @@ Handle Stat::Start(const Arguments& args) { Handle Stat::Stop(const Arguments& args) { HandleScope scope; Stat *handler = ObjectWrap::Unwrap(args.Holder()); - handler->Emit("stop", 0, NULL); + handler->Emit(stop_symbol, 0, NULL); handler->Stop(); return Undefined(); } diff --git a/src/node_timer.cc b/src/node_timer.cc index c0ab046cd8..ac7dc267b2 100644 --- a/src/node_timer.cc +++ b/src/node_timer.cc @@ -5,10 +5,11 @@ using namespace v8; using namespace node; -#define REPEAT_SYMBOL String::NewSymbol("repeat") - Persistent Timer::constructor_template; +static Persistent timeout_symbol; +static Persistent repeat_symbol; + void Timer::Initialize (Handle target) { @@ -20,10 +21,13 @@ Timer::Initialize (Handle target) constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("Timer")); + timeout_symbol = NODE_PSYMBOL("timeout"); + repeat_symbol = NODE_PSYMBOL("repeat"); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Timer::Start); NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Timer::Stop); - constructor_template->PrototypeTemplate()->SetAccessor(REPEAT_SYMBOL, + constructor_template->PrototypeTemplate()->SetAccessor(repeat_symbol, RepeatGetter, RepeatSetter); target->Set(String::NewSymbol("Timer"), constructor_template->GetFunction()); @@ -36,7 +40,7 @@ Timer::RepeatGetter (Local property, const AccessorInfo& info) Timer *timer = ObjectWrap::Unwrap(info.This()); assert(timer); - assert (property == REPEAT_SYMBOL); + assert (property == repeat_symbol); Local v = Integer::New(timer->watcher_.repeat); @@ -50,7 +54,7 @@ Timer::RepeatSetter (Local property, Local value, const AccessorI Timer *timer = ObjectWrap::Unwrap(info.This()); assert(timer); - assert(property == REPEAT_SYMBOL); + assert(property == repeat_symbol); timer->watcher_.repeat = NODE_V8_UNIXTIME(value); } @@ -62,7 +66,7 @@ Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) assert(revents == EV_TIMEOUT); - timer->Emit("timeout", 0, NULL); + timer->Emit(timeout_symbol, 0, NULL); if (timer->watcher_.repeat == 0) timer->Unref(); }