From 6aeed46180baea2cd3e83df0d05926360c3f69d9 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 25 Apr 2012 08:45:45 +0000 Subject: [PATCH] Make String::Empty inlineable. R=svenpanne@chromium.org TEST=cctest/test-api/StringEmpty Review URL: https://chromiumcodereview.appspot.com/10199019 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11429 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 11 +++++++++++ src/api.cc | 4 +++- src/heap.h | 1 + test/cctest/test-api.cc | 46 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/include/v8.h b/include/v8.h index 7b94a59..9024531 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1084,6 +1084,7 @@ class String : public Primitive { * A zero length string. */ V8EXPORT static v8::Local Empty(); + inline static v8::Local Empty(Isolate* isolate); /** * Returns true if the string is external @@ -3903,6 +3904,7 @@ class Internals { static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; static const int kFalseValueRootIndex = 9; + static const int kEmptySymbolRootIndex = 128; static const int kJSObjectType = 0xaa; static const int kFirstNonstringType = 0x80; @@ -4221,6 +4223,15 @@ String* String::Cast(v8::Value* value) { } +Local String::Empty(Isolate* isolate) { + typedef internal::Object* S; + typedef internal::Internals I; + if (!I::IsInitialized(isolate)) return Empty(); + S* slot = I::GetRoot(isolate, I::kEmptySymbolRootIndex); + return Local(reinterpret_cast(slot)); +} + + String::ExternalStringResource* String::GetExternalStringResource() const { typedef internal::Object O; typedef internal::Internals I; diff --git a/src/api.cc b/src/api.cc index 8cdd391..0bc93c2 100644 --- a/src/api.cc +++ b/src/api.cc @@ -4630,7 +4630,9 @@ void* External::Value() const { Local v8::String::Empty() { i::Isolate* isolate = i::Isolate::Current(); - EnsureInitializedForIsolate(isolate, "v8::String::Empty()"); + if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { + return v8::Local(); + } LOG_API(isolate, "String::Empty()"); return Utils::ToLocal(isolate->factory()->empty_symbol()); } diff --git a/src/heap.h b/src/heap.h index b8bb067..84f6b34 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1423,6 +1423,7 @@ class Heap { STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex); STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex); STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex); + STATIC_CHECK(kempty_symbolRootIndex == Internals::kEmptySymbolRootIndex); MUST_USE_RESULT MaybeObject* NumberToString( Object* number, bool check_number_string_cache = true); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 6a5e6f8..87860f4 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -16450,6 +16450,13 @@ TEST(PrimaryStubCache) { } +static int fatal_error_callback_counter = 0; +static void CountingErrorCallback(const char* location, const char* message) { + printf("CountingErrorCallback(\"%s\", \"%s\")\n", location, message); + fatal_error_callback_counter++; +} + + TEST(StaticGetters) { v8::HandleScope scope; LocalContext context; @@ -16466,24 +16473,12 @@ TEST(StaticGetters) { i::Handle false_value = FACTORY->false_value(); CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value); CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value); -} - -static int fatal_error_callback_counter = 0; -static void CountingErrorCallback(const char* location, const char* message) { - printf("CountingErrorCallback(\"%s\", \"%s\")\n", location, message); - fatal_error_callback_counter++; -} - - -TEST(StaticGettersAfterDeath) { - v8::HandleScope scope; - LocalContext context; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + // Test after-death behavior. CHECK(i::Internals::IsInitialized(isolate)); CHECK_EQ(0, fatal_error_callback_counter); v8::V8::SetFatalErrorHandler(CountingErrorCallback); - v8::Utils::ReportApiFailure("StaticGettersAfterDeath()", "Kill V8"); + v8::Utils::ReportApiFailure("StaticGetters()", "Kill V8"); i::Isolate::Current()->TearDown(); CHECK(!i::Internals::IsInitialized(isolate)); CHECK_EQ(1, fatal_error_callback_counter); @@ -16522,3 +16517,26 @@ TEST(IsolateEmbedderData) { CHECK_EQ(data2, isolate->GetData()); CHECK_EQ(data2, ISOLATE->GetData()); } + + +TEST(StringEmpty) { + v8::HandleScope scope; + LocalContext context; + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + i::Handle empty_string = FACTORY->empty_symbol(); + CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string); + CHECK(*v8::Utils::OpenHandle(*v8::String::Empty(isolate)) == *empty_string); + + // Test after-death behavior. + CHECK(i::Internals::IsInitialized(isolate)); + CHECK_EQ(0, fatal_error_callback_counter); + v8::V8::SetFatalErrorHandler(CountingErrorCallback); + v8::Utils::ReportApiFailure("StringEmpty()", "Kill V8"); + i::Isolate::Current()->TearDown(); + CHECK(!i::Internals::IsInitialized(isolate)); + CHECK_EQ(1, fatal_error_callback_counter); + CHECK(v8::String::Empty().IsEmpty()); + CHECK_EQ(2, fatal_error_callback_counter); + CHECK(v8::String::Empty(isolate).IsEmpty()); + CHECK_EQ(3, fatal_error_callback_counter); +} -- 2.7.4