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
parent e07be0b0
...@@ -1084,6 +1084,7 @@ class String : public Primitive { ...@@ -1084,6 +1084,7 @@ class String : public Primitive {
* A zero length string. * A zero length string.
*/ */
V8EXPORT static v8::Local<v8::String> Empty(); V8EXPORT static v8::Local<v8::String> Empty();
inline static v8::Local<v8::String> Empty(Isolate* isolate);
/** /**
* Returns true if the string is external * Returns true if the string is external
...@@ -3903,6 +3904,7 @@ class Internals { ...@@ -3903,6 +3904,7 @@ class Internals {
static const int kNullValueRootIndex = 7; static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8; static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9; static const int kFalseValueRootIndex = 9;
static const int kEmptySymbolRootIndex = 128;
static const int kJSObjectType = 0xaa; static const int kJSObjectType = 0xaa;
static const int kFirstNonstringType = 0x80; static const int kFirstNonstringType = 0x80;
...@@ -4221,6 +4223,15 @@ String* String::Cast(v8::Value* value) { ...@@ -4221,6 +4223,15 @@ String* String::Cast(v8::Value* value) {
} }
Local<String> 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<String>(reinterpret_cast<String*>(slot));
}
String::ExternalStringResource* String::GetExternalStringResource() const { String::ExternalStringResource* String::GetExternalStringResource() const {
typedef internal::Object O; typedef internal::Object O;
typedef internal::Internals I; typedef internal::Internals I;
......
...@@ -4630,7 +4630,9 @@ void* External::Value() const { ...@@ -4630,7 +4630,9 @@ void* External::Value() const {
Local<String> v8::String::Empty() { Local<String> v8::String::Empty() {
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::String::Empty()"); if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
return v8::Local<String>();
}
LOG_API(isolate, "String::Empty()"); LOG_API(isolate, "String::Empty()");
return Utils::ToLocal(isolate->factory()->empty_symbol()); return Utils::ToLocal(isolate->factory()->empty_symbol());
} }
......
...@@ -1423,6 +1423,7 @@ class Heap { ...@@ -1423,6 +1423,7 @@ class Heap {
STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex); STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex);
STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex); STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex); STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
STATIC_CHECK(kempty_symbolRootIndex == Internals::kEmptySymbolRootIndex);
MUST_USE_RESULT MaybeObject* NumberToString( MUST_USE_RESULT MaybeObject* NumberToString(
Object* number, bool check_number_string_cache = true); Object* number, bool check_number_string_cache = true);
......
...@@ -16450,6 +16450,13 @@ TEST(PrimaryStubCache) { ...@@ -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) { TEST(StaticGetters) {
v8::HandleScope scope; v8::HandleScope scope;
LocalContext context; LocalContext context;
...@@ -16466,24 +16473,12 @@ TEST(StaticGetters) { ...@@ -16466,24 +16473,12 @@ TEST(StaticGetters) {
i::Handle<i::Object> false_value = FACTORY->false_value(); i::Handle<i::Object> false_value = FACTORY->false_value();
CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value); CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value);
CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value); CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value);
}
static int fatal_error_callback_counter = 0; // Test after-death behavior.
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();
CHECK(i::Internals::IsInitialized(isolate)); CHECK(i::Internals::IsInitialized(isolate));
CHECK_EQ(0, fatal_error_callback_counter); CHECK_EQ(0, fatal_error_callback_counter);
v8::V8::SetFatalErrorHandler(CountingErrorCallback); v8::V8::SetFatalErrorHandler(CountingErrorCallback);
v8::Utils::ReportApiFailure("StaticGettersAfterDeath()", "Kill V8"); v8::Utils::ReportApiFailure("StaticGetters()", "Kill V8");
i::Isolate::Current()->TearDown(); i::Isolate::Current()->TearDown();
CHECK(!i::Internals::IsInitialized(isolate)); CHECK(!i::Internals::IsInitialized(isolate));
CHECK_EQ(1, fatal_error_callback_counter); CHECK_EQ(1, fatal_error_callback_counter);
...@@ -16522,3 +16517,26 @@ TEST(IsolateEmbedderData) { ...@@ -16522,3 +16517,26 @@ TEST(IsolateEmbedderData) {
CHECK_EQ(data2, isolate->GetData()); CHECK_EQ(data2, isolate->GetData());
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<i::Object> 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment