Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Unified Diff: src/objects.cc

Issue 1612323003: Introduce {FAST,SLOW}_STRING_WRAPPER_ELEMENTS (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: one more DCHECK fix Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index ab6fa54859416d80a4601f1d25358bfe2cbd5221..258f806818a83067e8576d28ac6d87ed6387690a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1058,7 +1058,8 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
Handle<FixedArray> JSObject::EnsureWritableFastElements(
Handle<JSObject> object) {
- DCHECK(object->HasFastSmiOrObjectElements());
+ DCHECK(object->HasFastSmiOrObjectElements() ||
+ object->HasFastStringWrapperElements());
Isolate* isolate = object->GetIsolate();
Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate);
if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
@@ -5876,14 +5877,18 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
DCHECK(object->HasFastSmiOrObjectElements() ||
object->HasFastDoubleElements() ||
- object->HasFastArgumentsElements());
+ object->HasFastArgumentsElements() ||
+ object->HasFastStringWrapperElements());
Handle<SeededNumberDictionary> dictionary =
GetNormalizedElementDictionary(object, elements);
// Switch to using the dictionary as the backing storage for elements.
- ElementsKind target_kind =
- is_arguments ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS : DICTIONARY_ELEMENTS;
+ ElementsKind target_kind = is_arguments
+ ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
+ : object->HasFastStringWrapperElements()
+ ? SLOW_STRING_WRAPPER_ELEMENTS
+ : DICTIONARY_ELEMENTS;
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
// Set the new map first to satify the elements type assert in set_elements().
JSObject::MigrateToMap(object, new_map);
@@ -5904,7 +5909,9 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
}
#endif
- DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
+ DCHECK(object->HasDictionaryElements() ||
+ object->HasSlowArgumentsElements() ||
+ object->HasSlowStringWrapperElements());
return dictionary;
}
@@ -7407,9 +7414,7 @@ Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,
Object* object) {
- DCHECK(IsFastObjectElementsKind(kind) ||
- kind == DICTIONARY_ELEMENTS);
- if (IsFastObjectElementsKind(kind)) {
+ if (IsFastObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) {
int length = IsJSArray()
? Smi::cast(JSArray::cast(this)->length())->value()
: elements->length();
@@ -7418,6 +7423,7 @@ bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
if (!element->IsTheHole() && element == object) return true;
}
} else {
+ DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
Object* key =
SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
if (!key->IsUndefined()) return true;
@@ -7468,7 +7474,9 @@ bool JSObject::ReferencesObject(Object* obj) {
break;
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
- case DICTIONARY_ELEMENTS: {
+ case DICTIONARY_ELEMENTS:
+ case FAST_STRING_WRAPPER_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS: {
FixedArray* elements = FixedArray::cast(this->elements());
if (ReferencesObjectFromElements(elements, kind, obj)) return true;
break;
@@ -7489,6 +7497,8 @@ bool JSObject::ReferencesObject(Object* obj) {
if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
break;
}
+ case NO_ELEMENTS:
+ break;
}
// For functions check the context.
@@ -7870,7 +7880,8 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
Handle<SeededNumberDictionary> new_element_dictionary;
if (!object->HasFixedTypedArrayElements() &&
- !object->HasDictionaryElements()) {
+ !object->HasDictionaryElements() &&
+ !object->HasSlowStringWrapperElements()) {
int length =
object->IsJSArray()
? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
@@ -7917,7 +7928,11 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
new_map->set_is_extensible(false);
if (!new_element_dictionary.is_null()) {
- new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ ElementsKind new_kind =
+ IsStringWrapperElementsKind(old_map->elements_kind())
+ ? SLOW_STRING_WRAPPER_ELEMENTS
+ : DICTIONARY_ELEMENTS;
+ new_map->set_elements_kind(new_kind);
}
JSObject::MigrateToMap(object, new_map);
@@ -7942,7 +7957,8 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
return Just(true);
}
- DCHECK(object->map()->has_dictionary_elements());
+ DCHECK(object->map()->has_dictionary_elements() ||
+ object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
if (!new_element_dictionary.is_null()) {
object->set_elements(*new_element_dictionary);
}
@@ -8134,12 +8150,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
}
// Deep copy own elements.
- // Pixel elements cannot be created using an object literal.
- DCHECK(!copy->HasFixedTypedArrayElements());
switch (kind) {
- case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
- case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
@@ -8151,9 +8163,6 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} else {
for (int i = 0; i < elements->length(); i++) {
Handle<Object> value(elements->get(i), isolate);
- DCHECK(value->IsSmi() ||
- value->IsTheHole() ||
- (IsFastObjectElementsKind(copy->GetElementsKind())));
if (value->IsJSObject()) {
Handle<JSObject> result;
ASSIGN_RETURN_ON_EXCEPTION(
@@ -8194,16 +8203,25 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
break;
-
+ case FAST_STRING_WRAPPER_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS:
+ UNREACHABLE();
+ break;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
+ // Typed elements cannot be created using an object literal.
+ UNREACHABLE();
+ break;
+ case FAST_SMI_ELEMENTS:
+ case FAST_HOLEY_SMI_ELEMENTS:
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
+ case NO_ELEMENTS:
// No contained objects, nothing to do.
break;
}
@@ -8309,12 +8327,6 @@ MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
// TODO(cbruni/jkummerow): Consider moving this into elements.cc.
bool HasEnumerableElements(JSObject* object) {
- if (object->IsJSValue()) {
- Object* value = JSValue::cast(object)->value();
- if (value->IsString()) {
- if (String::cast(value)->length() > 0) return true;
- }
- }
switch (object->GetElementsKind()) {
case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
@@ -8366,6 +8378,14 @@ bool HasEnumerableElements(JSObject* object) {
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
// We're approximating non-empty arguments objects here.
return true;
+ case FAST_STRING_WRAPPER_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS:
+ if (String::cast(JSValue::cast(object)->value())->length() > 0) {
+ return true;
+ }
+ return object->elements()->length() > 0;
+ case NO_ELEMENTS:
+ return false;
}
UNREACHABLE();
return true;
@@ -8598,8 +8618,8 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate,
accumulator->AddElementKeysFromInterceptor(
Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)));
} else {
- accumulator->AddKeys(
- Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)));
+ accumulator->AddKeys(Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)),
+ DO_NOT_CONVERT);
}
return Just(true);
}
@@ -8655,7 +8675,7 @@ static Maybe<bool> GetKeysFromJSObject(Isolate* isolate,
// Compute the property keys and cache them if possible.
Handle<FixedArray> enum_keys =
JSObject::GetEnumPropertyKeys(object, cache_enum_length);
- accumulator->AddKeys(enum_keys);
+ accumulator->AddKeys(enum_keys, DO_NOT_CONVERT);
} else {
object->CollectOwnPropertyNames(accumulator, *filter);
}
@@ -9748,7 +9768,10 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
transition_marker, reason, SPECIAL_TRANSITION);
new_map->set_is_extensible(false);
if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
- new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
+ ? SLOW_STRING_WRAPPER_ELEMENTS
+ : DICTIONARY_ELEMENTS;
+ new_map->set_elements_kind(new_kind);
}
return new_map;
}
@@ -15783,6 +15806,9 @@ static ElementsKind BestFittingFastElementsKind(JSObject* object) {
if (object->HasSloppyArgumentsElements()) {
return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
}
+ if (object->HasStringWrapperElements()) {
+ return FAST_STRING_WRAPPER_ELEMENTS;
+ }
DCHECK(object->HasDictionaryElements());
SeededNumberDictionary* dictionary = object->element_dictionary();
ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS;
@@ -15866,6 +15892,8 @@ Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
if (IsSloppyArgumentsElements(kind)) {
elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1));
dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
+ } else if (IsStringWrapperElementsKind(kind)) {
+ dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
}
if (attributes != NONE) {
@@ -16161,13 +16189,16 @@ int JSObject::GetFastElementsUsage() {
// Fall through.
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
+ case FAST_STRING_WRAPPER_ELEMENTS:
return FastHoleyElementsUsage(this, FixedArray::cast(store));
case FAST_HOLEY_DOUBLE_ELEMENTS:
if (elements()->length() == 0) return 0;
return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store));
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS:
case DICTIONARY_ELEMENTS:
+ case NO_ELEMENTS:
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
@@ -16439,7 +16470,7 @@ void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
}
Name* key = descs->GetKey(i);
if (key->FilterKey(filter)) continue;
- keys->AddKey(key);
+ keys->AddKey(key, DO_NOT_CONVERT);
}
} else if (IsJSGlobalObject()) {
GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter);
@@ -16468,21 +16499,6 @@ void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
KeyAccumulator* keys,
PropertyFilter filter) {
if (filter & SKIP_STRINGS) return;
- uint32_t string_keys = 0;
-
- // If this is a String wrapper, add the string indices first,
- // as they're guaranteed to precede the elements in numerical order
- // and ascending order is required by ECMA-262, 6th, 9.1.12.
- if (object->IsJSValue()) {
- Object* val = JSValue::cast(*object)->value();
- if (val->IsString() && (filter & ONLY_ALL_CAN_READ) == 0) {
- String* str = String::cast(val);
- string_keys = str->length();
- for (uint32_t i = 0; i < string_keys; i++) {
- keys->AddKey(i);
- }
- }
- }
ElementsAccessor* accessor = object->GetElementsAccessor();
accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0);
}
@@ -16511,7 +16527,8 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
- case FAST_HOLEY_ELEMENTS: {
+ case FAST_HOLEY_ELEMENTS:
+ case FAST_STRING_WRAPPER_ELEMENTS: {
int length = IsJSArray() ?
Smi::cast(JSArray::cast(this)->length())->value() :
FixedArray::cast(elements())->length();
@@ -16560,7 +16577,8 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
break;
}
- case DICTIONARY_ELEMENTS: {
+ case DICTIONARY_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS: {
if (storage != NULL) {
element_dictionary()->CopyKeysTo(storage, counter, filter,
SeededNumberDictionary::SORTED);
@@ -16610,6 +16628,8 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
}
break;
}
+ case NO_ELEMENTS:
+ break;
}
DCHECK(!storage || storage->length() == counter);
@@ -18507,7 +18527,7 @@ void Dictionary<Derived, Shape, Key>::CollectKeysTo(
for (int i = 0; i < array_size; i++) {
int index = Smi::cast(array->get(i))->value();
- keys->AddKey(dictionary->KeyAt(index));
+ keys->AddKey(dictionary->KeyAt(index), DO_NOT_CONVERT);
}
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698