diff --git a/src/env-inl.h b/src/env-inl.h index cc9dd9ec3e2082..a3f4a797adaeae 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -36,12 +36,26 @@ inline void Environment::IsolateData::Put() { } } +// Create string properties as internalized one byte strings. +// +// Internalized because it makes property lookups a little faster and because +// the string is created in the old space straight away. It's going to end up +// in the old space sooner or later anyway but now it doesn't go through +// v8::Eternal's new space handling first. +// +// One byte because our strings are ASCII and we can safely skip V8's UTF-8 +// decoding step. It's a one-time cost, but why pay it when you don't have to? inline Environment::IsolateData::IsolateData(v8::Isolate* isolate, uv_loop_t* loop) : event_loop_(loop), isolate_(isolate), #define V(PropertyName, StringValue) \ - PropertyName ## _(isolate, FIXED_ONE_BYTE_STRING(isolate, StringValue)), + PropertyName ## _(isolate, \ + v8::String::NewFromOneByte( \ + isolate, \ + reinterpret_cast(StringValue), \ + v8::NewStringType::kInternalized, \ + sizeof(StringValue) - 1).ToLocalChecked()), PER_ISOLATE_STRING_PROPERTIES(V) #undef V ref_count_(0) {} @@ -464,7 +478,10 @@ inline void Environment::SetMethod(v8::Local that, v8::FunctionCallback callback) { v8::Local function = NewFunctionTemplate(callback)->GetFunction(); - v8::Local name_string = v8::String::NewFromUtf8(isolate(), name); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); that->Set(name_string, function); function->SetName(name_string); // NODE_SET_METHOD() compatibility. } @@ -475,7 +492,10 @@ inline void Environment::SetProtoMethod(v8::Local that, v8::Local signature = v8::Signature::New(isolate(), that); v8::Local function = NewFunctionTemplate(callback, signature)->GetFunction(); - v8::Local name_string = v8::String::NewFromUtf8(isolate(), name); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); that->PrototypeTemplate()->Set(name_string, function); function->SetName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. } @@ -485,7 +505,10 @@ inline void Environment::SetTemplateMethod(v8::Local that, v8::FunctionCallback callback) { v8::Local function = NewFunctionTemplate(callback)->GetFunction(); - v8::Local name_string = v8::String::NewFromUtf8(isolate(), name); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); that->Set(name_string, function); function->SetName(name_string); // NODE_SET_METHOD() compatibility. } diff --git a/src/env.h b/src/env.h index 1107dcb174bd35..fbbcaf2a8a2720 100644 --- a/src/env.h +++ b/src/env.h @@ -39,7 +39,7 @@ namespace node { #endif // Strings are per-isolate primitives but Environment proxies them -// for the sake of convenience. +// for the sake of convenience. Strings should be ASCII-only. #define PER_ISOLATE_STRING_PROPERTIES(V) \ V(address_string, "address") \ V(args_string, "args") \