OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 Handle<JSObject> result = | 1051 Handle<JSObject> result = |
1052 isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); | 1052 isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); |
1053 isolate->counters()->constructed_objects()->Increment(); | 1053 isolate->counters()->constructed_objects()->Increment(); |
1054 isolate->counters()->constructed_objects_runtime()->Increment(); | 1054 isolate->counters()->constructed_objects_runtime()->Increment(); |
1055 return result; | 1055 return result; |
1056 } | 1056 } |
1057 | 1057 |
1058 | 1058 |
1059 Handle<FixedArray> JSObject::EnsureWritableFastElements( | 1059 Handle<FixedArray> JSObject::EnsureWritableFastElements( |
1060 Handle<JSObject> object) { | 1060 Handle<JSObject> object) { |
1061 DCHECK(object->HasFastSmiOrObjectElements()); | 1061 DCHECK(object->HasFastSmiOrObjectElements() || |
| 1062 object->HasFastStringWrapperElements()); |
1062 Isolate* isolate = object->GetIsolate(); | 1063 Isolate* isolate = object->GetIsolate(); |
1063 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); | 1064 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
1064 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 1065 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
1065 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( | 1066 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
1066 elems, isolate->factory()->fixed_array_map()); | 1067 elems, isolate->factory()->fixed_array_map()); |
1067 object->set_elements(*writable_elems); | 1068 object->set_elements(*writable_elems); |
1068 isolate->counters()->cow_arrays_converted()->Increment(); | 1069 isolate->counters()->cow_arrays_converted()->Increment(); |
1069 return writable_elems; | 1070 return writable_elems; |
1070 } | 1071 } |
1071 | 1072 |
(...skipping 4797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5869 FixedArray* parameter_map = FixedArray::cast(*elements); | 5870 FixedArray* parameter_map = FixedArray::cast(*elements); |
5870 elements = handle(FixedArrayBase::cast(parameter_map->get(1)), isolate); | 5871 elements = handle(FixedArrayBase::cast(parameter_map->get(1)), isolate); |
5871 } | 5872 } |
5872 | 5873 |
5873 if (elements->IsDictionary()) { | 5874 if (elements->IsDictionary()) { |
5874 return Handle<SeededNumberDictionary>::cast(elements); | 5875 return Handle<SeededNumberDictionary>::cast(elements); |
5875 } | 5876 } |
5876 | 5877 |
5877 DCHECK(object->HasFastSmiOrObjectElements() || | 5878 DCHECK(object->HasFastSmiOrObjectElements() || |
5878 object->HasFastDoubleElements() || | 5879 object->HasFastDoubleElements() || |
5879 object->HasFastArgumentsElements()); | 5880 object->HasFastArgumentsElements() || |
| 5881 object->HasFastStringWrapperElements()); |
5880 | 5882 |
5881 Handle<SeededNumberDictionary> dictionary = | 5883 Handle<SeededNumberDictionary> dictionary = |
5882 GetNormalizedElementDictionary(object, elements); | 5884 GetNormalizedElementDictionary(object, elements); |
5883 | 5885 |
5884 // Switch to using the dictionary as the backing storage for elements. | 5886 // Switch to using the dictionary as the backing storage for elements. |
5885 ElementsKind target_kind = | 5887 ElementsKind target_kind = is_arguments |
5886 is_arguments ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS : DICTIONARY_ELEMENTS; | 5888 ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS |
| 5889 : object->HasFastStringWrapperElements() |
| 5890 ? SLOW_STRING_WRAPPER_ELEMENTS |
| 5891 : DICTIONARY_ELEMENTS; |
5887 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); | 5892 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); |
5888 // Set the new map first to satify the elements type assert in set_elements(). | 5893 // Set the new map first to satify the elements type assert in set_elements(). |
5889 JSObject::MigrateToMap(object, new_map); | 5894 JSObject::MigrateToMap(object, new_map); |
5890 | 5895 |
5891 if (is_arguments) { | 5896 if (is_arguments) { |
5892 FixedArray::cast(object->elements())->set(1, *dictionary); | 5897 FixedArray::cast(object->elements())->set(1, *dictionary); |
5893 } else { | 5898 } else { |
5894 object->set_elements(*dictionary); | 5899 object->set_elements(*dictionary); |
5895 } | 5900 } |
5896 | 5901 |
5897 isolate->counters()->elements_to_dictionary()->Increment(); | 5902 isolate->counters()->elements_to_dictionary()->Increment(); |
5898 | 5903 |
5899 #ifdef DEBUG | 5904 #ifdef DEBUG |
5900 if (FLAG_trace_normalization) { | 5905 if (FLAG_trace_normalization) { |
5901 OFStream os(stdout); | 5906 OFStream os(stdout); |
5902 os << "Object elements have been normalized:\n"; | 5907 os << "Object elements have been normalized:\n"; |
5903 object->Print(os); | 5908 object->Print(os); |
5904 } | 5909 } |
5905 #endif | 5910 #endif |
5906 | 5911 |
5907 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); | 5912 DCHECK(object->HasDictionaryElements() || |
| 5913 object->HasSlowArgumentsElements() || |
| 5914 object->HasSlowStringWrapperElements()); |
5908 return dictionary; | 5915 return dictionary; |
5909 } | 5916 } |
5910 | 5917 |
5911 | 5918 |
5912 static Smi* GenerateIdentityHash(Isolate* isolate) { | 5919 static Smi* GenerateIdentityHash(Isolate* isolate) { |
5913 int hash_value; | 5920 int hash_value; |
5914 int attempts = 0; | 5921 int attempts = 0; |
5915 do { | 5922 do { |
5916 // Generate a random 32-bit hash value but limit range to fit | 5923 // Generate a random 32-bit hash value but limit range to fit |
5917 // within a smi. | 5924 // within a smi. |
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7400 } | 7407 } |
7401 } | 7408 } |
7402 // 18. Return resultDesc. | 7409 // 18. Return resultDesc. |
7403 return Just(true); | 7410 return Just(true); |
7404 } | 7411 } |
7405 | 7412 |
7406 | 7413 |
7407 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 7414 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
7408 ElementsKind kind, | 7415 ElementsKind kind, |
7409 Object* object) { | 7416 Object* object) { |
7410 DCHECK(IsFastObjectElementsKind(kind) || | 7417 if (IsFastObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) { |
7411 kind == DICTIONARY_ELEMENTS); | |
7412 if (IsFastObjectElementsKind(kind)) { | |
7413 int length = IsJSArray() | 7418 int length = IsJSArray() |
7414 ? Smi::cast(JSArray::cast(this)->length())->value() | 7419 ? Smi::cast(JSArray::cast(this)->length())->value() |
7415 : elements->length(); | 7420 : elements->length(); |
7416 for (int i = 0; i < length; ++i) { | 7421 for (int i = 0; i < length; ++i) { |
7417 Object* element = elements->get(i); | 7422 Object* element = elements->get(i); |
7418 if (!element->IsTheHole() && element == object) return true; | 7423 if (!element->IsTheHole() && element == object) return true; |
7419 } | 7424 } |
7420 } else { | 7425 } else { |
| 7426 DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS); |
7421 Object* key = | 7427 Object* key = |
7422 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); | 7428 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); |
7423 if (!key->IsUndefined()) return true; | 7429 if (!key->IsUndefined()) return true; |
7424 } | 7430 } |
7425 return false; | 7431 return false; |
7426 } | 7432 } |
7427 | 7433 |
7428 | 7434 |
7429 // Check whether this object references another object. | 7435 // Check whether this object references another object. |
7430 bool JSObject::ReferencesObject(Object* obj) { | 7436 bool JSObject::ReferencesObject(Object* obj) { |
(...skipping 30 matching lines...) Expand all Loading... |
7461 #undef TYPED_ARRAY_CASE | 7467 #undef TYPED_ARRAY_CASE |
7462 | 7468 |
7463 case FAST_DOUBLE_ELEMENTS: | 7469 case FAST_DOUBLE_ELEMENTS: |
7464 case FAST_HOLEY_DOUBLE_ELEMENTS: | 7470 case FAST_HOLEY_DOUBLE_ELEMENTS: |
7465 break; | 7471 break; |
7466 case FAST_SMI_ELEMENTS: | 7472 case FAST_SMI_ELEMENTS: |
7467 case FAST_HOLEY_SMI_ELEMENTS: | 7473 case FAST_HOLEY_SMI_ELEMENTS: |
7468 break; | 7474 break; |
7469 case FAST_ELEMENTS: | 7475 case FAST_ELEMENTS: |
7470 case FAST_HOLEY_ELEMENTS: | 7476 case FAST_HOLEY_ELEMENTS: |
7471 case DICTIONARY_ELEMENTS: { | 7477 case DICTIONARY_ELEMENTS: |
| 7478 case FAST_STRING_WRAPPER_ELEMENTS: |
| 7479 case SLOW_STRING_WRAPPER_ELEMENTS: { |
7472 FixedArray* elements = FixedArray::cast(this->elements()); | 7480 FixedArray* elements = FixedArray::cast(this->elements()); |
7473 if (ReferencesObjectFromElements(elements, kind, obj)) return true; | 7481 if (ReferencesObjectFromElements(elements, kind, obj)) return true; |
7474 break; | 7482 break; |
7475 } | 7483 } |
7476 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 7484 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
7477 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 7485 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
7478 FixedArray* parameter_map = FixedArray::cast(elements()); | 7486 FixedArray* parameter_map = FixedArray::cast(elements()); |
7479 // Check the mapped parameters. | 7487 // Check the mapped parameters. |
7480 int length = parameter_map->length(); | 7488 int length = parameter_map->length(); |
7481 for (int i = 2; i < length; ++i) { | 7489 for (int i = 2; i < length; ++i) { |
7482 Object* value = parameter_map->get(i); | 7490 Object* value = parameter_map->get(i); |
7483 if (!value->IsTheHole() && value == obj) return true; | 7491 if (!value->IsTheHole() && value == obj) return true; |
7484 } | 7492 } |
7485 // Check the arguments. | 7493 // Check the arguments. |
7486 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 7494 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
7487 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : | 7495 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : |
7488 FAST_HOLEY_ELEMENTS; | 7496 FAST_HOLEY_ELEMENTS; |
7489 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; | 7497 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; |
7490 break; | 7498 break; |
7491 } | 7499 } |
| 7500 case NO_ELEMENTS: |
| 7501 break; |
7492 } | 7502 } |
7493 | 7503 |
7494 // For functions check the context. | 7504 // For functions check the context. |
7495 if (IsJSFunction()) { | 7505 if (IsJSFunction()) { |
7496 // Get the constructor function for arguments array. | 7506 // Get the constructor function for arguments array. |
7497 Map* arguments_map = | 7507 Map* arguments_map = |
7498 heap->isolate()->context()->native_context()->sloppy_arguments_map(); | 7508 heap->isolate()->context()->native_context()->sloppy_arguments_map(); |
7499 JSFunction* arguments_function = | 7509 JSFunction* arguments_function = |
7500 JSFunction::cast(arguments_map->GetConstructor()); | 7510 JSFunction::cast(arguments_map->GetConstructor()); |
7501 | 7511 |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7863 if (object->IsJSGlobalProxy()) { | 7873 if (object->IsJSGlobalProxy()) { |
7864 PrototypeIterator iter(isolate, object); | 7874 PrototypeIterator iter(isolate, object); |
7865 if (iter.IsAtEnd()) return Just(true); | 7875 if (iter.IsAtEnd()) return Just(true); |
7866 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 7876 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
7867 return PreventExtensionsWithTransition<attrs>( | 7877 return PreventExtensionsWithTransition<attrs>( |
7868 PrototypeIterator::GetCurrent<JSObject>(iter), should_throw); | 7878 PrototypeIterator::GetCurrent<JSObject>(iter), should_throw); |
7869 } | 7879 } |
7870 | 7880 |
7871 Handle<SeededNumberDictionary> new_element_dictionary; | 7881 Handle<SeededNumberDictionary> new_element_dictionary; |
7872 if (!object->HasFixedTypedArrayElements() && | 7882 if (!object->HasFixedTypedArrayElements() && |
7873 !object->HasDictionaryElements()) { | 7883 !object->HasDictionaryElements() && |
| 7884 !object->HasSlowStringWrapperElements()) { |
7874 int length = | 7885 int length = |
7875 object->IsJSArray() | 7886 object->IsJSArray() |
7876 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 7887 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
7877 : object->elements()->length(); | 7888 : object->elements()->length(); |
7878 new_element_dictionary = | 7889 new_element_dictionary = |
7879 length == 0 ? isolate->factory()->empty_slow_element_dictionary() | 7890 length == 0 ? isolate->factory()->empty_slow_element_dictionary() |
7880 : GetNormalizedElementDictionary( | 7891 : GetNormalizedElementDictionary( |
7881 object, handle(object->elements())); | 7892 object, handle(object->elements())); |
7882 } | 7893 } |
7883 | 7894 |
(...skipping 26 matching lines...) Expand all Loading... |
7910 // Slow path: need to normalize properties for safety | 7921 // Slow path: need to normalize properties for safety |
7911 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, | 7922 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0, |
7912 "SlowPreventExtensions"); | 7923 "SlowPreventExtensions"); |
7913 | 7924 |
7914 // Create a new map, since other objects with this map may be extensible. | 7925 // Create a new map, since other objects with this map may be extensible. |
7915 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 7926 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
7916 Handle<Map> new_map = | 7927 Handle<Map> new_map = |
7917 Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions"); | 7928 Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions"); |
7918 new_map->set_is_extensible(false); | 7929 new_map->set_is_extensible(false); |
7919 if (!new_element_dictionary.is_null()) { | 7930 if (!new_element_dictionary.is_null()) { |
7920 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 7931 ElementsKind new_kind = |
| 7932 IsStringWrapperElementsKind(old_map->elements_kind()) |
| 7933 ? SLOW_STRING_WRAPPER_ELEMENTS |
| 7934 : DICTIONARY_ELEMENTS; |
| 7935 new_map->set_elements_kind(new_kind); |
7921 } | 7936 } |
7922 JSObject::MigrateToMap(object, new_map); | 7937 JSObject::MigrateToMap(object, new_map); |
7923 | 7938 |
7924 if (attrs != NONE) { | 7939 if (attrs != NONE) { |
7925 if (object->IsJSGlobalObject()) { | 7940 if (object->IsJSGlobalObject()) { |
7926 ApplyAttributesToDictionary(object->global_dictionary(), attrs); | 7941 ApplyAttributesToDictionary(object->global_dictionary(), attrs); |
7927 } else { | 7942 } else { |
7928 ApplyAttributesToDictionary(object->property_dictionary(), attrs); | 7943 ApplyAttributesToDictionary(object->property_dictionary(), attrs); |
7929 } | 7944 } |
7930 } | 7945 } |
7931 } | 7946 } |
7932 | 7947 |
7933 // Both seal and preventExtensions always go through without modifications to | 7948 // Both seal and preventExtensions always go through without modifications to |
7934 // typed array elements. Freeze works only if there are no actual elements. | 7949 // typed array elements. Freeze works only if there are no actual elements. |
7935 if (object->HasFixedTypedArrayElements()) { | 7950 if (object->HasFixedTypedArrayElements()) { |
7936 if (attrs == FROZEN && | 7951 if (attrs == FROZEN && |
7937 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) { | 7952 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) { |
7938 isolate->Throw(*isolate->factory()->NewTypeError( | 7953 isolate->Throw(*isolate->factory()->NewTypeError( |
7939 MessageTemplate::kCannotFreezeArrayBufferView)); | 7954 MessageTemplate::kCannotFreezeArrayBufferView)); |
7940 return Nothing<bool>(); | 7955 return Nothing<bool>(); |
7941 } | 7956 } |
7942 return Just(true); | 7957 return Just(true); |
7943 } | 7958 } |
7944 | 7959 |
7945 DCHECK(object->map()->has_dictionary_elements()); | 7960 DCHECK(object->map()->has_dictionary_elements() || |
| 7961 object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS); |
7946 if (!new_element_dictionary.is_null()) { | 7962 if (!new_element_dictionary.is_null()) { |
7947 object->set_elements(*new_element_dictionary); | 7963 object->set_elements(*new_element_dictionary); |
7948 } | 7964 } |
7949 | 7965 |
7950 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { | 7966 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { |
7951 SeededNumberDictionary* dictionary = object->element_dictionary(); | 7967 SeededNumberDictionary* dictionary = object->element_dictionary(); |
7952 // Make sure we never go back to the fast case | 7968 // Make sure we never go back to the fast case |
7953 object->RequireSlowElements(dictionary); | 7969 object->RequireSlowElements(dictionary); |
7954 if (attrs != NONE) { | 7970 if (attrs != NONE) { |
7955 ApplyAttributesToDictionary(dictionary, attrs); | 7971 ApplyAttributesToDictionary(dictionary, attrs); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8127 JSObject); | 8143 JSObject); |
8128 if (copying) { | 8144 if (copying) { |
8129 // Creating object copy for literals. No strict mode needed. | 8145 // Creating object copy for literals. No strict mode needed. |
8130 JSObject::SetProperty(copy, name, result, SLOPPY).Assert(); | 8146 JSObject::SetProperty(copy, name, result, SLOPPY).Assert(); |
8131 } | 8147 } |
8132 } | 8148 } |
8133 } | 8149 } |
8134 } | 8150 } |
8135 | 8151 |
8136 // Deep copy own elements. | 8152 // Deep copy own elements. |
8137 // Pixel elements cannot be created using an object literal. | |
8138 DCHECK(!copy->HasFixedTypedArrayElements()); | |
8139 switch (kind) { | 8153 switch (kind) { |
8140 case FAST_SMI_ELEMENTS: | |
8141 case FAST_ELEMENTS: | 8154 case FAST_ELEMENTS: |
8142 case FAST_HOLEY_SMI_ELEMENTS: | |
8143 case FAST_HOLEY_ELEMENTS: { | 8155 case FAST_HOLEY_ELEMENTS: { |
8144 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 8156 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
8145 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 8157 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
8146 #ifdef DEBUG | 8158 #ifdef DEBUG |
8147 for (int i = 0; i < elements->length(); i++) { | 8159 for (int i = 0; i < elements->length(); i++) { |
8148 DCHECK(!elements->get(i)->IsJSObject()); | 8160 DCHECK(!elements->get(i)->IsJSObject()); |
8149 } | 8161 } |
8150 #endif | 8162 #endif |
8151 } else { | 8163 } else { |
8152 for (int i = 0; i < elements->length(); i++) { | 8164 for (int i = 0; i < elements->length(); i++) { |
8153 Handle<Object> value(elements->get(i), isolate); | 8165 Handle<Object> value(elements->get(i), isolate); |
8154 DCHECK(value->IsSmi() || | |
8155 value->IsTheHole() || | |
8156 (IsFastObjectElementsKind(copy->GetElementsKind()))); | |
8157 if (value->IsJSObject()) { | 8166 if (value->IsJSObject()) { |
8158 Handle<JSObject> result; | 8167 Handle<JSObject> result; |
8159 ASSIGN_RETURN_ON_EXCEPTION( | 8168 ASSIGN_RETURN_ON_EXCEPTION( |
8160 isolate, result, | 8169 isolate, result, |
8161 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 8170 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
8162 JSObject); | 8171 JSObject); |
8163 if (copying) { | 8172 if (copying) { |
8164 elements->set(i, *result); | 8173 elements->set(i, *result); |
8165 } | 8174 } |
8166 } | 8175 } |
(...skipping 20 matching lines...) Expand all Loading... |
8187 } | 8196 } |
8188 } | 8197 } |
8189 } | 8198 } |
8190 } | 8199 } |
8191 break; | 8200 break; |
8192 } | 8201 } |
8193 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 8202 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
8194 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 8203 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
8195 UNIMPLEMENTED(); | 8204 UNIMPLEMENTED(); |
8196 break; | 8205 break; |
8197 | 8206 case FAST_STRING_WRAPPER_ELEMENTS: |
| 8207 case SLOW_STRING_WRAPPER_ELEMENTS: |
| 8208 UNREACHABLE(); |
| 8209 break; |
8198 | 8210 |
8199 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 8211 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
8200 case TYPE##_ELEMENTS: \ | 8212 case TYPE##_ELEMENTS: \ |
8201 | 8213 |
8202 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 8214 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
8203 #undef TYPED_ARRAY_CASE | 8215 #undef TYPED_ARRAY_CASE |
| 8216 // Typed elements cannot be created using an object literal. |
| 8217 UNREACHABLE(); |
| 8218 break; |
8204 | 8219 |
| 8220 case FAST_SMI_ELEMENTS: |
| 8221 case FAST_HOLEY_SMI_ELEMENTS: |
8205 case FAST_DOUBLE_ELEMENTS: | 8222 case FAST_DOUBLE_ELEMENTS: |
8206 case FAST_HOLEY_DOUBLE_ELEMENTS: | 8223 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 8224 case NO_ELEMENTS: |
8207 // No contained objects, nothing to do. | 8225 // No contained objects, nothing to do. |
8208 break; | 8226 break; |
8209 } | 8227 } |
8210 } | 8228 } |
8211 | 8229 |
8212 return copy; | 8230 return copy; |
8213 } | 8231 } |
8214 | 8232 |
8215 | 8233 |
8216 MaybeHandle<JSObject> JSObject::DeepWalk( | 8234 MaybeHandle<JSObject> JSObject::DeepWalk( |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8302 } | 8320 } |
8303 } | 8321 } |
8304 THROW_NEW_ERROR(isolate, | 8322 THROW_NEW_ERROR(isolate, |
8305 NewTypeError(MessageTemplate::kCannotConvertToPrimitive), | 8323 NewTypeError(MessageTemplate::kCannotConvertToPrimitive), |
8306 Object); | 8324 Object); |
8307 } | 8325 } |
8308 | 8326 |
8309 | 8327 |
8310 // TODO(cbruni/jkummerow): Consider moving this into elements.cc. | 8328 // TODO(cbruni/jkummerow): Consider moving this into elements.cc. |
8311 bool HasEnumerableElements(JSObject* object) { | 8329 bool HasEnumerableElements(JSObject* object) { |
8312 if (object->IsJSValue()) { | |
8313 Object* value = JSValue::cast(object)->value(); | |
8314 if (value->IsString()) { | |
8315 if (String::cast(value)->length() > 0) return true; | |
8316 } | |
8317 } | |
8318 switch (object->GetElementsKind()) { | 8330 switch (object->GetElementsKind()) { |
8319 case FAST_SMI_ELEMENTS: | 8331 case FAST_SMI_ELEMENTS: |
8320 case FAST_ELEMENTS: | 8332 case FAST_ELEMENTS: |
8321 case FAST_DOUBLE_ELEMENTS: { | 8333 case FAST_DOUBLE_ELEMENTS: { |
8322 int length = object->IsJSArray() | 8334 int length = object->IsJSArray() |
8323 ? Smi::cast(JSArray::cast(object)->length())->value() | 8335 ? Smi::cast(JSArray::cast(object)->length())->value() |
8324 : object->elements()->length(); | 8336 : object->elements()->length(); |
8325 return length > 0; | 8337 return length > 0; |
8326 } | 8338 } |
8327 case FAST_HOLEY_SMI_ELEMENTS: | 8339 case FAST_HOLEY_SMI_ELEMENTS: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8359 } | 8371 } |
8360 case DICTIONARY_ELEMENTS: { | 8372 case DICTIONARY_ELEMENTS: { |
8361 SeededNumberDictionary* elements = | 8373 SeededNumberDictionary* elements = |
8362 SeededNumberDictionary::cast(object->elements()); | 8374 SeededNumberDictionary::cast(object->elements()); |
8363 return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0; | 8375 return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0; |
8364 } | 8376 } |
8365 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 8377 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
8366 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 8378 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
8367 // We're approximating non-empty arguments objects here. | 8379 // We're approximating non-empty arguments objects here. |
8368 return true; | 8380 return true; |
| 8381 case FAST_STRING_WRAPPER_ELEMENTS: |
| 8382 case SLOW_STRING_WRAPPER_ELEMENTS: |
| 8383 if (String::cast(JSValue::cast(object)->value())->length() > 0) { |
| 8384 return true; |
| 8385 } |
| 8386 return object->elements()->length() > 0; |
| 8387 case NO_ELEMENTS: |
| 8388 return false; |
8369 } | 8389 } |
8370 UNREACHABLE(); | 8390 UNREACHABLE(); |
8371 return true; | 8391 return true; |
8372 } | 8392 } |
8373 | 8393 |
8374 | 8394 |
8375 // Tests for the fast common case for property enumeration: | 8395 // Tests for the fast common case for property enumeration: |
8376 // - This object and all prototypes has an enum cache (which means that | 8396 // - This object and all prototypes has an enum cache (which means that |
8377 // it is no proxy, has no interceptors and needs no access checks). | 8397 // it is no proxy, has no interceptors and needs no access checks). |
8378 // - This object has no elements. | 8398 // - This object has no elements. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8591 if (result.IsEmpty()) return Just(true); | 8611 if (result.IsEmpty()) return Just(true); |
8592 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || | 8612 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || |
8593 (v8::Utils::OpenHandle(*result)->IsJSObject() && | 8613 (v8::Utils::OpenHandle(*result)->IsJSObject() && |
8594 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) | 8614 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) |
8595 ->HasSloppyArgumentsElements())); | 8615 ->HasSloppyArgumentsElements())); |
8596 // The accumulator takes care of string/symbol filtering. | 8616 // The accumulator takes care of string/symbol filtering. |
8597 if (type == kIndexed) { | 8617 if (type == kIndexed) { |
8598 accumulator->AddElementKeysFromInterceptor( | 8618 accumulator->AddElementKeysFromInterceptor( |
8599 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8619 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); |
8600 } else { | 8620 } else { |
8601 accumulator->AddKeys( | 8621 accumulator->AddKeys(Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)), |
8602 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8622 DO_NOT_CONVERT); |
8603 } | 8623 } |
8604 return Just(true); | 8624 return Just(true); |
8605 } | 8625 } |
8606 | 8626 |
8607 | 8627 |
8608 // Returns |true| on success, |false| if prototype walking should be stopped, | 8628 // Returns |true| on success, |false| if prototype walking should be stopped, |
8609 // |nothing| if an exception was thrown. | 8629 // |nothing| if an exception was thrown. |
8610 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, | 8630 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, |
8611 Handle<JSReceiver> receiver, | 8631 Handle<JSReceiver> receiver, |
8612 Handle<JSObject> object, | 8632 Handle<JSObject> object, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8648 // use the cache says yes, so we should not create a cache. | 8668 // use the cache says yes, so we should not create a cache. |
8649 Handle<JSFunction> arguments_function( | 8669 Handle<JSFunction> arguments_function( |
8650 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 8670 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
8651 bool cache_enum_length = | 8671 bool cache_enum_length = |
8652 ((object->map()->GetConstructor() != *arguments_function) && | 8672 ((object->map()->GetConstructor() != *arguments_function) && |
8653 !object->IsJSValue() && !object->IsAccessCheckNeeded() && | 8673 !object->IsJSValue() && !object->IsAccessCheckNeeded() && |
8654 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); | 8674 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); |
8655 // Compute the property keys and cache them if possible. | 8675 // Compute the property keys and cache them if possible. |
8656 Handle<FixedArray> enum_keys = | 8676 Handle<FixedArray> enum_keys = |
8657 JSObject::GetEnumPropertyKeys(object, cache_enum_length); | 8677 JSObject::GetEnumPropertyKeys(object, cache_enum_length); |
8658 accumulator->AddKeys(enum_keys); | 8678 accumulator->AddKeys(enum_keys, DO_NOT_CONVERT); |
8659 } else { | 8679 } else { |
8660 object->CollectOwnPropertyNames(accumulator, *filter); | 8680 object->CollectOwnPropertyNames(accumulator, *filter); |
8661 } | 8681 } |
8662 | 8682 |
8663 // Add the property keys from the interceptor. | 8683 // Add the property keys from the interceptor. |
8664 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, | 8684 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, |
8665 kNamed>(isolate, receiver, object, *filter, | 8685 kNamed>(isolate, receiver, object, *filter, |
8666 accumulator); | 8686 accumulator); |
8667 MAYBE_RETURN(success, Nothing<bool>()); | 8687 MAYBE_RETURN(success, Nothing<bool>()); |
8668 return Just(true); | 8688 return Just(true); |
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9741 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( | 9761 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( |
9742 handle(map->instance_descriptors(), isolate), num_descriptors, | 9762 handle(map->instance_descriptors(), isolate), num_descriptors, |
9743 attrs_to_add); | 9763 attrs_to_add); |
9744 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), | 9764 Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(), |
9745 isolate); | 9765 isolate); |
9746 Handle<Map> new_map = CopyReplaceDescriptors( | 9766 Handle<Map> new_map = CopyReplaceDescriptors( |
9747 map, new_desc, new_layout_descriptor, INSERT_TRANSITION, | 9767 map, new_desc, new_layout_descriptor, INSERT_TRANSITION, |
9748 transition_marker, reason, SPECIAL_TRANSITION); | 9768 transition_marker, reason, SPECIAL_TRANSITION); |
9749 new_map->set_is_extensible(false); | 9769 new_map->set_is_extensible(false); |
9750 if (!IsFixedTypedArrayElementsKind(map->elements_kind())) { | 9770 if (!IsFixedTypedArrayElementsKind(map->elements_kind())) { |
9751 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 9771 ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind()) |
| 9772 ? SLOW_STRING_WRAPPER_ELEMENTS |
| 9773 : DICTIONARY_ELEMENTS; |
| 9774 new_map->set_elements_kind(new_kind); |
9752 } | 9775 } |
9753 return new_map; | 9776 return new_map; |
9754 } | 9777 } |
9755 | 9778 |
9756 | 9779 |
9757 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 9780 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
9758 PropertyDetails details = GetDetails(descriptor); | 9781 PropertyDetails details = GetDetails(descriptor); |
9759 switch (details.type()) { | 9782 switch (details.type()) { |
9760 case DATA: | 9783 case DATA: |
9761 return value->FitsRepresentation(details.representation()) && | 9784 return value->FitsRepresentation(details.representation()) && |
(...skipping 6014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15776 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); | 15799 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); |
15777 } | 15800 } |
15778 return false; | 15801 return false; |
15779 } | 15802 } |
15780 | 15803 |
15781 | 15804 |
15782 static ElementsKind BestFittingFastElementsKind(JSObject* object) { | 15805 static ElementsKind BestFittingFastElementsKind(JSObject* object) { |
15783 if (object->HasSloppyArgumentsElements()) { | 15806 if (object->HasSloppyArgumentsElements()) { |
15784 return FAST_SLOPPY_ARGUMENTS_ELEMENTS; | 15807 return FAST_SLOPPY_ARGUMENTS_ELEMENTS; |
15785 } | 15808 } |
| 15809 if (object->HasStringWrapperElements()) { |
| 15810 return FAST_STRING_WRAPPER_ELEMENTS; |
| 15811 } |
15786 DCHECK(object->HasDictionaryElements()); | 15812 DCHECK(object->HasDictionaryElements()); |
15787 SeededNumberDictionary* dictionary = object->element_dictionary(); | 15813 SeededNumberDictionary* dictionary = object->element_dictionary(); |
15788 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; | 15814 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; |
15789 for (int i = 0; i < dictionary->Capacity(); i++) { | 15815 for (int i = 0; i < dictionary->Capacity(); i++) { |
15790 Object* key = dictionary->KeyAt(i); | 15816 Object* key = dictionary->KeyAt(i); |
15791 if (key->IsNumber()) { | 15817 if (key->IsNumber()) { |
15792 Object* value = dictionary->ValueAt(i); | 15818 Object* value = dictionary->ValueAt(i); |
15793 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; | 15819 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; |
15794 if (!value->IsSmi()) { | 15820 if (!value->IsSmi()) { |
15795 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; | 15821 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15859 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); | 15885 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); |
15860 } | 15886 } |
15861 } | 15887 } |
15862 | 15888 |
15863 ElementsKind kind = object->GetElementsKind(); | 15889 ElementsKind kind = object->GetElementsKind(); |
15864 FixedArrayBase* elements = object->elements(); | 15890 FixedArrayBase* elements = object->elements(); |
15865 ElementsKind dictionary_kind = DICTIONARY_ELEMENTS; | 15891 ElementsKind dictionary_kind = DICTIONARY_ELEMENTS; |
15866 if (IsSloppyArgumentsElements(kind)) { | 15892 if (IsSloppyArgumentsElements(kind)) { |
15867 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); | 15893 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); |
15868 dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS; | 15894 dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS; |
| 15895 } else if (IsStringWrapperElementsKind(kind)) { |
| 15896 dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS; |
15869 } | 15897 } |
15870 | 15898 |
15871 if (attributes != NONE) { | 15899 if (attributes != NONE) { |
15872 kind = dictionary_kind; | 15900 kind = dictionary_kind; |
15873 } else if (elements->IsSeededNumberDictionary()) { | 15901 } else if (elements->IsSeededNumberDictionary()) { |
15874 kind = ShouldConvertToFastElements(*object, | 15902 kind = ShouldConvertToFastElements(*object, |
15875 SeededNumberDictionary::cast(elements), | 15903 SeededNumberDictionary::cast(elements), |
15876 index, &new_capacity) | 15904 index, &new_capacity) |
15877 ? BestFittingFastElementsKind(*object) | 15905 ? BestFittingFastElementsKind(*object) |
15878 : dictionary_kind; // Overwrite in case of arguments. | 15906 : dictionary_kind; // Overwrite in case of arguments. |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16154 case FAST_SMI_ELEMENTS: | 16182 case FAST_SMI_ELEMENTS: |
16155 case FAST_DOUBLE_ELEMENTS: | 16183 case FAST_DOUBLE_ELEMENTS: |
16156 case FAST_ELEMENTS: | 16184 case FAST_ELEMENTS: |
16157 return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() | 16185 return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() |
16158 : store->length(); | 16186 : store->length(); |
16159 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 16187 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
16160 store = FixedArray::cast(FixedArray::cast(store)->get(1)); | 16188 store = FixedArray::cast(FixedArray::cast(store)->get(1)); |
16161 // Fall through. | 16189 // Fall through. |
16162 case FAST_HOLEY_SMI_ELEMENTS: | 16190 case FAST_HOLEY_SMI_ELEMENTS: |
16163 case FAST_HOLEY_ELEMENTS: | 16191 case FAST_HOLEY_ELEMENTS: |
| 16192 case FAST_STRING_WRAPPER_ELEMENTS: |
16164 return FastHoleyElementsUsage(this, FixedArray::cast(store)); | 16193 return FastHoleyElementsUsage(this, FixedArray::cast(store)); |
16165 case FAST_HOLEY_DOUBLE_ELEMENTS: | 16194 case FAST_HOLEY_DOUBLE_ELEMENTS: |
16166 if (elements()->length() == 0) return 0; | 16195 if (elements()->length() == 0) return 0; |
16167 return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store)); | 16196 return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store)); |
16168 | 16197 |
16169 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 16198 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 16199 case SLOW_STRING_WRAPPER_ELEMENTS: |
16170 case DICTIONARY_ELEMENTS: | 16200 case DICTIONARY_ELEMENTS: |
| 16201 case NO_ELEMENTS: |
16171 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 16202 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
16172 case TYPE##_ELEMENTS: \ | 16203 case TYPE##_ELEMENTS: \ |
16173 | 16204 |
16174 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 16205 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
16175 #undef TYPED_ARRAY_CASE | 16206 #undef TYPED_ARRAY_CASE |
16176 UNREACHABLE(); | 16207 UNREACHABLE(); |
16177 } | 16208 } |
16178 return 0; | 16209 return 0; |
16179 } | 16210 } |
16180 | 16211 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16432 PropertyDetails details = descs->GetDetails(i); | 16463 PropertyDetails details = descs->GetDetails(i); |
16433 if ((details.attributes() & filter) != 0) continue; | 16464 if ((details.attributes() & filter) != 0) continue; |
16434 if (filter & ONLY_ALL_CAN_READ) { | 16465 if (filter & ONLY_ALL_CAN_READ) { |
16435 if (details.kind() != kAccessor) continue; | 16466 if (details.kind() != kAccessor) continue; |
16436 Object* accessors = descs->GetValue(i); | 16467 Object* accessors = descs->GetValue(i); |
16437 if (!accessors->IsAccessorInfo()) continue; | 16468 if (!accessors->IsAccessorInfo()) continue; |
16438 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; | 16469 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
16439 } | 16470 } |
16440 Name* key = descs->GetKey(i); | 16471 Name* key = descs->GetKey(i); |
16441 if (key->FilterKey(filter)) continue; | 16472 if (key->FilterKey(filter)) continue; |
16442 keys->AddKey(key); | 16473 keys->AddKey(key, DO_NOT_CONVERT); |
16443 } | 16474 } |
16444 } else if (IsJSGlobalObject()) { | 16475 } else if (IsJSGlobalObject()) { |
16445 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); | 16476 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); |
16446 } else { | 16477 } else { |
16447 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); | 16478 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); |
16448 } | 16479 } |
16449 } | 16480 } |
16450 | 16481 |
16451 | 16482 |
16452 int JSObject::NumberOfOwnElements(PropertyFilter filter) { | 16483 int JSObject::NumberOfOwnElements(PropertyFilter filter) { |
16453 // Fast case for objects with no elements. | 16484 // Fast case for objects with no elements. |
16454 if (!IsJSValue() && HasFastElements()) { | 16485 if (!IsJSValue() && HasFastElements()) { |
16455 uint32_t length = | 16486 uint32_t length = |
16456 IsJSArray() | 16487 IsJSArray() |
16457 ? static_cast<uint32_t>( | 16488 ? static_cast<uint32_t>( |
16458 Smi::cast(JSArray::cast(this)->length())->value()) | 16489 Smi::cast(JSArray::cast(this)->length())->value()) |
16459 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); | 16490 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); |
16460 if (length == 0) return 0; | 16491 if (length == 0) return 0; |
16461 } | 16492 } |
16462 // Compute the number of enumerable elements. | 16493 // Compute the number of enumerable elements. |
16463 return GetOwnElementKeys(NULL, filter); | 16494 return GetOwnElementKeys(NULL, filter); |
16464 } | 16495 } |
16465 | 16496 |
16466 | 16497 |
16467 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, | 16498 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, |
16468 KeyAccumulator* keys, | 16499 KeyAccumulator* keys, |
16469 PropertyFilter filter) { | 16500 PropertyFilter filter) { |
16470 if (filter & SKIP_STRINGS) return; | 16501 if (filter & SKIP_STRINGS) return; |
16471 uint32_t string_keys = 0; | |
16472 | |
16473 // If this is a String wrapper, add the string indices first, | |
16474 // as they're guaranteed to precede the elements in numerical order | |
16475 // and ascending order is required by ECMA-262, 6th, 9.1.12. | |
16476 if (object->IsJSValue()) { | |
16477 Object* val = JSValue::cast(*object)->value(); | |
16478 if (val->IsString() && (filter & ONLY_ALL_CAN_READ) == 0) { | |
16479 String* str = String::cast(val); | |
16480 string_keys = str->length(); | |
16481 for (uint32_t i = 0; i < string_keys; i++) { | |
16482 keys->AddKey(i); | |
16483 } | |
16484 } | |
16485 } | |
16486 ElementsAccessor* accessor = object->GetElementsAccessor(); | 16502 ElementsAccessor* accessor = object->GetElementsAccessor(); |
16487 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); | 16503 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); |
16488 } | 16504 } |
16489 | 16505 |
16490 | 16506 |
16491 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) { | 16507 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) { |
16492 int counter = 0; | 16508 int counter = 0; |
16493 | 16509 |
16494 // If this is a String wrapper, add the string indices first, | 16510 // If this is a String wrapper, add the string indices first, |
16495 // as they're guaranteed to precede the elements in numerical order | 16511 // as they're guaranteed to precede the elements in numerical order |
16496 // and ascending order is required by ECMA-262, 6th, 9.1.12. | 16512 // and ascending order is required by ECMA-262, 6th, 9.1.12. |
16497 if (IsJSValue()) { | 16513 if (IsJSValue()) { |
16498 Object* val = JSValue::cast(this)->value(); | 16514 Object* val = JSValue::cast(this)->value(); |
16499 if (val->IsString()) { | 16515 if (val->IsString()) { |
16500 String* str = String::cast(val); | 16516 String* str = String::cast(val); |
16501 if (storage) { | 16517 if (storage) { |
16502 for (int i = 0; i < str->length(); i++) { | 16518 for (int i = 0; i < str->length(); i++) { |
16503 storage->set(counter + i, Smi::FromInt(i)); | 16519 storage->set(counter + i, Smi::FromInt(i)); |
16504 } | 16520 } |
16505 } | 16521 } |
16506 counter += str->length(); | 16522 counter += str->length(); |
16507 } | 16523 } |
16508 } | 16524 } |
16509 | 16525 |
16510 switch (GetElementsKind()) { | 16526 switch (GetElementsKind()) { |
16511 case FAST_SMI_ELEMENTS: | 16527 case FAST_SMI_ELEMENTS: |
16512 case FAST_ELEMENTS: | 16528 case FAST_ELEMENTS: |
16513 case FAST_HOLEY_SMI_ELEMENTS: | 16529 case FAST_HOLEY_SMI_ELEMENTS: |
16514 case FAST_HOLEY_ELEMENTS: { | 16530 case FAST_HOLEY_ELEMENTS: |
| 16531 case FAST_STRING_WRAPPER_ELEMENTS: { |
16515 int length = IsJSArray() ? | 16532 int length = IsJSArray() ? |
16516 Smi::cast(JSArray::cast(this)->length())->value() : | 16533 Smi::cast(JSArray::cast(this)->length())->value() : |
16517 FixedArray::cast(elements())->length(); | 16534 FixedArray::cast(elements())->length(); |
16518 for (int i = 0; i < length; i++) { | 16535 for (int i = 0; i < length; i++) { |
16519 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 16536 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
16520 if (storage != NULL) { | 16537 if (storage != NULL) { |
16521 storage->set(counter, Smi::FromInt(i)); | 16538 storage->set(counter, Smi::FromInt(i)); |
16522 } | 16539 } |
16523 counter++; | 16540 counter++; |
16524 } | 16541 } |
(...skipping 28 matching lines...) Expand all Loading... |
16553 while (counter < length) { | 16570 while (counter < length) { |
16554 if (storage != NULL) { | 16571 if (storage != NULL) { |
16555 storage->set(counter, Smi::FromInt(counter)); | 16572 storage->set(counter, Smi::FromInt(counter)); |
16556 } | 16573 } |
16557 counter++; | 16574 counter++; |
16558 } | 16575 } |
16559 DCHECK(!storage || storage->length() >= counter); | 16576 DCHECK(!storage || storage->length() >= counter); |
16560 break; | 16577 break; |
16561 } | 16578 } |
16562 | 16579 |
16563 case DICTIONARY_ELEMENTS: { | 16580 case DICTIONARY_ELEMENTS: |
| 16581 case SLOW_STRING_WRAPPER_ELEMENTS: { |
16564 if (storage != NULL) { | 16582 if (storage != NULL) { |
16565 element_dictionary()->CopyKeysTo(storage, counter, filter, | 16583 element_dictionary()->CopyKeysTo(storage, counter, filter, |
16566 SeededNumberDictionary::SORTED); | 16584 SeededNumberDictionary::SORTED); |
16567 } | 16585 } |
16568 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 16586 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
16569 break; | 16587 break; |
16570 } | 16588 } |
16571 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 16589 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
16572 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 16590 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
16573 FixedArray* parameter_map = FixedArray::cast(elements()); | 16591 FixedArray* parameter_map = FixedArray::cast(elements()); |
(...skipping 29 matching lines...) Expand all Loading... |
16603 ++counter; | 16621 ++counter; |
16604 } | 16622 } |
16605 } | 16623 } |
16606 for (; i < backing_length; ++i) { | 16624 for (; i < backing_length; ++i) { |
16607 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | 16625 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
16608 ++counter; | 16626 ++counter; |
16609 } | 16627 } |
16610 } | 16628 } |
16611 break; | 16629 break; |
16612 } | 16630 } |
| 16631 case NO_ELEMENTS: |
| 16632 break; |
16613 } | 16633 } |
16614 | 16634 |
16615 DCHECK(!storage || storage->length() == counter); | 16635 DCHECK(!storage || storage->length() == counter); |
16616 return counter; | 16636 return counter; |
16617 } | 16637 } |
16618 | 16638 |
16619 | 16639 |
16620 MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate, | 16640 MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate, |
16621 Handle<Object> object) { | 16641 Handle<Object> object) { |
16622 if (object->IsUndefined()) return isolate->factory()->undefined_to_string(); | 16642 if (object->IsUndefined()) return isolate->factory()->undefined_to_string(); |
(...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18500 array->set(array_size++, Smi::FromInt(i)); | 18520 array->set(array_size++, Smi::FromInt(i)); |
18501 } | 18521 } |
18502 | 18522 |
18503 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); | 18523 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); |
18504 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); | 18524 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); |
18505 std::sort(start, start + array_size, cmp); | 18525 std::sort(start, start + array_size, cmp); |
18506 } | 18526 } |
18507 | 18527 |
18508 for (int i = 0; i < array_size; i++) { | 18528 for (int i = 0; i < array_size; i++) { |
18509 int index = Smi::cast(array->get(i))->value(); | 18529 int index = Smi::cast(array->get(i))->value(); |
18510 keys->AddKey(dictionary->KeyAt(index)); | 18530 keys->AddKey(dictionary->KeyAt(index), DO_NOT_CONVERT); |
18511 } | 18531 } |
18512 } | 18532 } |
18513 | 18533 |
18514 | 18534 |
18515 // Backwards lookup (slow). | 18535 // Backwards lookup (slow). |
18516 template<typename Derived, typename Shape, typename Key> | 18536 template<typename Derived, typename Shape, typename Key> |
18517 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 18537 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
18518 int capacity = this->Capacity(); | 18538 int capacity = this->Capacity(); |
18519 for (int i = 0; i < capacity; i++) { | 18539 for (int i = 0; i < capacity; i++) { |
18520 Object* k = this->KeyAt(i); | 18540 Object* k = this->KeyAt(i); |
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19749 if (cell->value() != *new_value) { | 19769 if (cell->value() != *new_value) { |
19750 cell->set_value(*new_value); | 19770 cell->set_value(*new_value); |
19751 Isolate* isolate = cell->GetIsolate(); | 19771 Isolate* isolate = cell->GetIsolate(); |
19752 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19772 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19753 isolate, DependentCode::kPropertyCellChangedGroup); | 19773 isolate, DependentCode::kPropertyCellChangedGroup); |
19754 } | 19774 } |
19755 } | 19775 } |
19756 | 19776 |
19757 } // namespace internal | 19777 } // namespace internal |
19758 } // namespace v8 | 19778 } // namespace v8 |
OLD | NEW |