Commit 1aeaeb2b authored by verwaest@chromium.org's avatar verwaest@chromium.org

Allow objects with "" properties to stay fast.

R=danno@chromium.org

Review URL: https://codereview.chromium.org/184453003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19648 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1d3f32ea
...@@ -5414,7 +5414,7 @@ class Internals { ...@@ -5414,7 +5414,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 kEmptyStringRootIndex = 141; static const int kEmptyStringRootIndex = 142;
static const int kNodeClassIdOffset = 1 * kApiPointerSize; static const int kNodeClassIdOffset = 1 * kApiPointerSize;
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
......
...@@ -3303,6 +3303,12 @@ bool Heap::CreateInitialObjects() { ...@@ -3303,6 +3303,12 @@ bool Heap::CreateInitialObjects() {
Symbol::cast(obj)->set_is_private(true); Symbol::cast(obj)->set_is_private(true);
set_frozen_symbol(Symbol::cast(obj)); set_frozen_symbol(Symbol::cast(obj));
{ MaybeObject* maybe_obj = AllocateSymbol();
if (!maybe_obj->ToObject(&obj)) return false;
}
Symbol::cast(obj)->set_is_private(true);
set_nonexistent_symbol(Symbol::cast(obj));
{ MaybeObject* maybe_obj = AllocateSymbol(); { MaybeObject* maybe_obj = AllocateSymbol();
if (!maybe_obj->ToObject(&obj)) return false; if (!maybe_obj->ToObject(&obj)) return false;
} }
......
...@@ -191,6 +191,7 @@ namespace internal { ...@@ -191,6 +191,7 @@ namespace internal {
V(JSObject, observation_state, ObservationState) \ V(JSObject, observation_state, ObservationState) \
V(Map, external_map, ExternalMap) \ V(Map, external_map, ExternalMap) \
V(Symbol, frozen_symbol, FrozenSymbol) \ V(Symbol, frozen_symbol, FrozenSymbol) \
V(Symbol, nonexistent_symbol, NonExistentSymbol) \
V(Symbol, elements_transition_symbol, ElementsTransitionSymbol) \ V(Symbol, elements_transition_symbol, ElementsTransitionSymbol) \
V(SeededNumberDictionary, empty_slow_element_dictionary, \ V(SeededNumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \ EmptySlowElementDictionary) \
......
...@@ -8242,7 +8242,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) { ...@@ -8242,7 +8242,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) {
// Checks whether the buffer contains an identifier (no escape). // Checks whether the buffer contains an identifier (no escape).
if (!name->IsString()) return false; if (!name->IsString()) return false;
String* string = String::cast(name); String* string = String::cast(name);
if (string->length() == 0) return false; if (string->length() == 0) return true;
ConsStringIteratorOp op; ConsStringIteratorOp op;
StringCharacterStream stream(string, &op); StringCharacterStream stream(string, &op);
if (!cache->IsIdentifierStart(stream.GetNext())) { if (!cache->IsIdentifierStart(stream.GetNext())) {
...@@ -8258,9 +8258,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) { ...@@ -8258,9 +8258,7 @@ static bool IsIdentifier(UnicodeCache* cache, Name* name) {
bool Name::IsCacheable(Isolate* isolate) { bool Name::IsCacheable(Isolate* isolate) {
return IsSymbol() || return IsSymbol() || IsIdentifier(isolate->unicode_cache(), this);
IsIdentifier(isolate->unicode_cache(), this) ||
this == isolate->heap()->hidden_string();
} }
...@@ -15728,7 +15726,6 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor( ...@@ -15728,7 +15726,6 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor(
// instance descriptor. // instance descriptor.
MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
if (!maybe_key->To(&key)) return maybe_key; if (!maybe_key->To(&key)) return maybe_key;
if (key->Equals(heap->empty_string())) return this;
} }
PropertyDetails details = DetailsAt(i); PropertyDetails details = DetailsAt(i);
......
...@@ -5356,6 +5356,17 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, ...@@ -5356,6 +5356,17 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
} }
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHiddenProperty) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
return *JSObject::SetHiddenProperty(object, key, value);
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
HandleScope scope(isolate); HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
......
...@@ -285,6 +285,7 @@ namespace internal { ...@@ -285,6 +285,7 @@ namespace internal {
F(DefineOrRedefineAccessorProperty, 5, 1) \ F(DefineOrRedefineAccessorProperty, 5, 1) \
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \ F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
F(GetDataProperty, 2, 1) \ F(GetDataProperty, 2, 1) \
F(SetHiddenProperty, 3, 1) \
\ \
/* Arrays */ \ /* Arrays */ \
F(RemoveArrayHoles, 2, 1) \ F(RemoveArrayHoles, 2, 1) \
......
...@@ -179,7 +179,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, ...@@ -179,7 +179,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
// therefore the stub will be specific to the name. // therefore the stub will be specific to the name.
Handle<Map> current_map = stub_holder; Handle<Map> current_map = stub_holder;
Handle<Name> cache_name = current_map->is_dictionary_map() Handle<Name> cache_name = current_map->is_dictionary_map()
? name : Handle<Name>::cast(isolate()->factory()->empty_string()); ? name : Handle<Name>::cast(isolate()->factory()->nonexistent_symbol());
Handle<Object> next(current_map->prototype(), isolate()); Handle<Object> next(current_map->prototype(), isolate());
Handle<JSObject> last = Handle<JSObject>::null(); Handle<JSObject> last = Handle<JSObject>::null();
while (!next->IsNull()) { while (!next->IsNull()) {
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var o = {};
%SetHiddenProperty(o, "test", 1);
// Create non-internalized ""
var empty = "a".substring(1, 1);
assertEquals(undefined, o[empty]);
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