Chromium Code Reviews| 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 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 Handle<JSObject> result = | 1052 Handle<JSObject> result = |
| 1053 isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); | 1053 isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); |
| 1054 isolate->counters()->constructed_objects()->Increment(); | 1054 isolate->counters()->constructed_objects()->Increment(); |
| 1055 isolate->counters()->constructed_objects_runtime()->Increment(); | 1055 isolate->counters()->constructed_objects_runtime()->Increment(); |
| 1056 return result; | 1056 return result; |
| 1057 } | 1057 } |
| 1058 | 1058 |
| 1059 | 1059 |
| 1060 Handle<FixedArray> JSObject::EnsureWritableFastElements( | 1060 Handle<FixedArray> JSObject::EnsureWritableFastElements( |
| 1061 Handle<JSObject> object) { | 1061 Handle<JSObject> object) { |
| 1062 DCHECK(object->HasFastSmiOrObjectElements()); | 1062 DCHECK(object->HasFastSmiOrObjectElements() || |
| 1063 object->HasFastStringWrapperElements()); | |
| 1063 Isolate* isolate = object->GetIsolate(); | 1064 Isolate* isolate = object->GetIsolate(); |
| 1064 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); | 1065 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
| 1065 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 1066 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
| 1066 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( | 1067 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
| 1067 elems, isolate->factory()->fixed_array_map()); | 1068 elems, isolate->factory()->fixed_array_map()); |
| 1068 object->set_elements(*writable_elems); | 1069 object->set_elements(*writable_elems); |
| 1069 isolate->counters()->cow_arrays_converted()->Increment(); | 1070 isolate->counters()->cow_arrays_converted()->Increment(); |
| 1070 return writable_elems; | 1071 return writable_elems; |
| 1071 } | 1072 } |
| 1072 | 1073 |
| (...skipping 4793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5866 FixedArray* parameter_map = FixedArray::cast(*elements); | 5867 FixedArray* parameter_map = FixedArray::cast(*elements); |
| 5867 elements = handle(FixedArrayBase::cast(parameter_map->get(1)), isolate); | 5868 elements = handle(FixedArrayBase::cast(parameter_map->get(1)), isolate); |
| 5868 } | 5869 } |
| 5869 | 5870 |
| 5870 if (elements->IsDictionary()) { | 5871 if (elements->IsDictionary()) { |
| 5871 return Handle<SeededNumberDictionary>::cast(elements); | 5872 return Handle<SeededNumberDictionary>::cast(elements); |
| 5872 } | 5873 } |
| 5873 | 5874 |
| 5874 DCHECK(object->HasFastSmiOrObjectElements() || | 5875 DCHECK(object->HasFastSmiOrObjectElements() || |
| 5875 object->HasFastDoubleElements() || | 5876 object->HasFastDoubleElements() || |
| 5876 object->HasFastArgumentsElements()); | 5877 object->HasFastArgumentsElements() || |
| 5878 object->HasFastStringWrapperElements()); | |
| 5877 | 5879 |
| 5878 Handle<SeededNumberDictionary> dictionary = | 5880 Handle<SeededNumberDictionary> dictionary = |
| 5879 GetNormalizedElementDictionary(object, elements); | 5881 GetNormalizedElementDictionary(object, elements); |
| 5880 | 5882 |
| 5881 // Switch to using the dictionary as the backing storage for elements. | 5883 // Switch to using the dictionary as the backing storage for elements. |
| 5882 ElementsKind target_kind = | 5884 ElementsKind target_kind = is_arguments |
| 5883 is_arguments ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS : DICTIONARY_ELEMENTS; | 5885 ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS |
| 5886 : object->HasFastStringWrapperElements() | |
| 5887 ? SLOW_STRING_WRAPPER_ELEMENTS | |
| 5888 : DICTIONARY_ELEMENTS; | |
| 5884 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); | 5889 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind); |
| 5885 // Set the new map first to satify the elements type assert in set_elements(). | 5890 // Set the new map first to satify the elements type assert in set_elements(). |
| 5886 JSObject::MigrateToMap(object, new_map); | 5891 JSObject::MigrateToMap(object, new_map); |
| 5887 | 5892 |
| 5888 if (is_arguments) { | 5893 if (is_arguments) { |
| 5889 FixedArray::cast(object->elements())->set(1, *dictionary); | 5894 FixedArray::cast(object->elements())->set(1, *dictionary); |
| 5890 } else { | 5895 } else { |
| 5891 object->set_elements(*dictionary); | 5896 object->set_elements(*dictionary); |
| 5892 } | 5897 } |
| 5893 | 5898 |
| 5894 isolate->counters()->elements_to_dictionary()->Increment(); | 5899 isolate->counters()->elements_to_dictionary()->Increment(); |
| 5895 | 5900 |
| 5896 #ifdef DEBUG | 5901 #ifdef DEBUG |
| 5897 if (FLAG_trace_normalization) { | 5902 if (FLAG_trace_normalization) { |
| 5898 OFStream os(stdout); | 5903 OFStream os(stdout); |
| 5899 os << "Object elements have been normalized:\n"; | 5904 os << "Object elements have been normalized:\n"; |
| 5900 object->Print(os); | 5905 object->Print(os); |
| 5901 } | 5906 } |
| 5902 #endif | 5907 #endif |
| 5903 | 5908 |
| 5904 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); | 5909 DCHECK(object->HasDictionaryElements() || |
| 5910 object->HasSlowArgumentsElements() || | |
| 5911 object->HasSlowStringWrapperElements()); | |
| 5905 return dictionary; | 5912 return dictionary; |
| 5906 } | 5913 } |
| 5907 | 5914 |
| 5908 | 5915 |
| 5909 static Smi* GenerateIdentityHash(Isolate* isolate) { | 5916 static Smi* GenerateIdentityHash(Isolate* isolate) { |
| 5910 int hash_value; | 5917 int hash_value; |
| 5911 int attempts = 0; | 5918 int attempts = 0; |
| 5912 do { | 5919 do { |
| 5913 // Generate a random 32-bit hash value but limit range to fit | 5920 // Generate a random 32-bit hash value but limit range to fit |
| 5914 // within a smi. | 5921 // within a smi. |
| (...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7397 } | 7404 } |
| 7398 } | 7405 } |
| 7399 // 18. Return resultDesc. | 7406 // 18. Return resultDesc. |
| 7400 return Just(true); | 7407 return Just(true); |
| 7401 } | 7408 } |
| 7402 | 7409 |
| 7403 | 7410 |
| 7404 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 7411 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 7405 ElementsKind kind, | 7412 ElementsKind kind, |
| 7406 Object* object) { | 7413 Object* object) { |
| 7407 DCHECK(IsFastObjectElementsKind(kind) || | 7414 if (IsFastObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) { |
| 7408 kind == DICTIONARY_ELEMENTS); | |
| 7409 if (IsFastObjectElementsKind(kind)) { | |
| 7410 int length = IsJSArray() | 7415 int length = IsJSArray() |
| 7411 ? Smi::cast(JSArray::cast(this)->length())->value() | 7416 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 7412 : elements->length(); | 7417 : elements->length(); |
| 7413 for (int i = 0; i < length; ++i) { | 7418 for (int i = 0; i < length; ++i) { |
| 7414 Object* element = elements->get(i); | 7419 Object* element = elements->get(i); |
| 7415 if (!element->IsTheHole() && element == object) return true; | 7420 if (!element->IsTheHole() && element == object) return true; |
| 7416 } | 7421 } |
| 7417 } else { | 7422 } else { |
| 7423 DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS); | |
| 7418 Object* key = | 7424 Object* key = |
| 7419 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); | 7425 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); |
| 7420 if (!key->IsUndefined()) return true; | 7426 if (!key->IsUndefined()) return true; |
| 7421 } | 7427 } |
| 7422 return false; | 7428 return false; |
| 7423 } | 7429 } |
| 7424 | 7430 |
| 7425 | 7431 |
| 7426 // Check whether this object references another object. | 7432 // Check whether this object references another object. |
| 7427 bool JSObject::ReferencesObject(Object* obj) { | 7433 bool JSObject::ReferencesObject(Object* obj) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 7458 #undef TYPED_ARRAY_CASE | 7464 #undef TYPED_ARRAY_CASE |
| 7459 | 7465 |
| 7460 case FAST_DOUBLE_ELEMENTS: | 7466 case FAST_DOUBLE_ELEMENTS: |
| 7461 case FAST_HOLEY_DOUBLE_ELEMENTS: | 7467 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 7462 break; | 7468 break; |
| 7463 case FAST_SMI_ELEMENTS: | 7469 case FAST_SMI_ELEMENTS: |
| 7464 case FAST_HOLEY_SMI_ELEMENTS: | 7470 case FAST_HOLEY_SMI_ELEMENTS: |
| 7465 break; | 7471 break; |
| 7466 case FAST_ELEMENTS: | 7472 case FAST_ELEMENTS: |
| 7467 case FAST_HOLEY_ELEMENTS: | 7473 case FAST_HOLEY_ELEMENTS: |
| 7468 case DICTIONARY_ELEMENTS: { | 7474 case DICTIONARY_ELEMENTS: |
| 7475 case FAST_STRING_WRAPPER_ELEMENTS: | |
| 7476 case SLOW_STRING_WRAPPER_ELEMENTS: { | |
| 7469 FixedArray* elements = FixedArray::cast(this->elements()); | 7477 FixedArray* elements = FixedArray::cast(this->elements()); |
| 7470 if (ReferencesObjectFromElements(elements, kind, obj)) return true; | 7478 if (ReferencesObjectFromElements(elements, kind, obj)) return true; |
| 7471 break; | 7479 break; |
| 7472 } | 7480 } |
| 7473 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 7481 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 7474 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 7482 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
| 7475 FixedArray* parameter_map = FixedArray::cast(elements()); | 7483 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 7476 // Check the mapped parameters. | 7484 // Check the mapped parameters. |
| 7477 int length = parameter_map->length(); | 7485 int length = parameter_map->length(); |
| 7478 for (int i = 2; i < length; ++i) { | 7486 for (int i = 2; i < length; ++i) { |
| 7479 Object* value = parameter_map->get(i); | 7487 Object* value = parameter_map->get(i); |
| 7480 if (!value->IsTheHole() && value == obj) return true; | 7488 if (!value->IsTheHole() && value == obj) return true; |
| 7481 } | 7489 } |
| 7482 // Check the arguments. | 7490 // Check the arguments. |
| 7483 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 7491 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 7484 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : | 7492 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : |
| 7485 FAST_HOLEY_ELEMENTS; | 7493 FAST_HOLEY_ELEMENTS; |
| 7486 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; | 7494 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; |
| 7487 break; | 7495 break; |
| 7488 } | 7496 } |
| 7497 case NO_ELEMENTS: | |
| 7498 break; | |
| 7489 } | 7499 } |
| 7490 | 7500 |
| 7491 // For functions check the context. | 7501 // For functions check the context. |
| 7492 if (IsJSFunction()) { | 7502 if (IsJSFunction()) { |
| 7493 // Get the constructor function for arguments array. | 7503 // Get the constructor function for arguments array. |
| 7494 Map* arguments_map = | 7504 Map* arguments_map = |
| 7495 heap->isolate()->context()->native_context()->sloppy_arguments_map(); | 7505 heap->isolate()->context()->native_context()->sloppy_arguments_map(); |
| 7496 JSFunction* arguments_function = | 7506 JSFunction* arguments_function = |
| 7497 JSFunction::cast(arguments_map->GetConstructor()); | 7507 JSFunction::cast(arguments_map->GetConstructor()); |
| 7498 | 7508 |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8124 JSObject); | 8134 JSObject); |
| 8125 if (copying) { | 8135 if (copying) { |
| 8126 // Creating object copy for literals. No strict mode needed. | 8136 // Creating object copy for literals. No strict mode needed. |
| 8127 JSObject::SetProperty(copy, name, result, SLOPPY).Assert(); | 8137 JSObject::SetProperty(copy, name, result, SLOPPY).Assert(); |
| 8128 } | 8138 } |
| 8129 } | 8139 } |
| 8130 } | 8140 } |
| 8131 } | 8141 } |
| 8132 | 8142 |
| 8133 // Deep copy own elements. | 8143 // Deep copy own elements. |
| 8134 // Pixel elements cannot be created using an object literal. | |
| 8135 DCHECK(!copy->HasFixedTypedArrayElements()); | |
| 8136 switch (kind) { | 8144 switch (kind) { |
| 8137 case FAST_SMI_ELEMENTS: | |
| 8138 case FAST_ELEMENTS: | 8145 case FAST_ELEMENTS: |
| 8139 case FAST_HOLEY_SMI_ELEMENTS: | |
| 8140 case FAST_HOLEY_ELEMENTS: { | 8146 case FAST_HOLEY_ELEMENTS: { |
| 8141 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 8147 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
| 8142 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 8148 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 8143 #ifdef DEBUG | 8149 #ifdef DEBUG |
| 8144 for (int i = 0; i < elements->length(); i++) { | 8150 for (int i = 0; i < elements->length(); i++) { |
| 8145 DCHECK(!elements->get(i)->IsJSObject()); | 8151 DCHECK(!elements->get(i)->IsJSObject()); |
| 8146 } | 8152 } |
| 8147 #endif | 8153 #endif |
| 8148 } else { | 8154 } else { |
| 8149 for (int i = 0; i < elements->length(); i++) { | 8155 for (int i = 0; i < elements->length(); i++) { |
| 8150 Handle<Object> value(elements->get(i), isolate); | 8156 Handle<Object> value(elements->get(i), isolate); |
| 8151 DCHECK(value->IsSmi() || | |
| 8152 value->IsTheHole() || | |
| 8153 (IsFastObjectElementsKind(copy->GetElementsKind()))); | |
| 8154 if (value->IsJSObject()) { | 8157 if (value->IsJSObject()) { |
| 8155 Handle<JSObject> result; | 8158 Handle<JSObject> result; |
| 8156 ASSIGN_RETURN_ON_EXCEPTION( | 8159 ASSIGN_RETURN_ON_EXCEPTION( |
| 8157 isolate, result, | 8160 isolate, result, |
| 8158 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 8161 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
| 8159 JSObject); | 8162 JSObject); |
| 8160 if (copying) { | 8163 if (copying) { |
| 8161 elements->set(i, *result); | 8164 elements->set(i, *result); |
| 8162 } | 8165 } |
| 8163 } | 8166 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 8184 } | 8187 } |
| 8185 } | 8188 } |
| 8186 } | 8189 } |
| 8187 } | 8190 } |
| 8188 break; | 8191 break; |
| 8189 } | 8192 } |
| 8190 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 8193 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 8191 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 8194 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 8192 UNIMPLEMENTED(); | 8195 UNIMPLEMENTED(); |
| 8193 break; | 8196 break; |
| 8194 | 8197 case FAST_STRING_WRAPPER_ELEMENTS: |
| 8198 case SLOW_STRING_WRAPPER_ELEMENTS: | |
| 8199 UNREACHABLE(); | |
| 8200 break; | |
| 8195 | 8201 |
| 8196 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 8202 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 8197 case TYPE##_ELEMENTS: \ | 8203 case TYPE##_ELEMENTS: \ |
| 8198 | 8204 |
| 8199 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 8205 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 8200 #undef TYPED_ARRAY_CASE | 8206 #undef TYPED_ARRAY_CASE |
| 8207 // Typed elements cannot be created using an object literal. | |
| 8208 UNREACHABLE(); | |
| 8209 break; | |
| 8201 | 8210 |
| 8211 case FAST_SMI_ELEMENTS: | |
| 8212 case FAST_HOLEY_SMI_ELEMENTS: | |
| 8202 case FAST_DOUBLE_ELEMENTS: | 8213 case FAST_DOUBLE_ELEMENTS: |
| 8203 case FAST_HOLEY_DOUBLE_ELEMENTS: | 8214 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 8215 case NO_ELEMENTS: | |
| 8204 // No contained objects, nothing to do. | 8216 // No contained objects, nothing to do. |
| 8205 break; | 8217 break; |
| 8206 } | 8218 } |
| 8207 } | 8219 } |
| 8208 | 8220 |
| 8209 return copy; | 8221 return copy; |
| 8210 } | 8222 } |
| 8211 | 8223 |
| 8212 | 8224 |
| 8213 MaybeHandle<JSObject> JSObject::DeepWalk( | 8225 MaybeHandle<JSObject> JSObject::DeepWalk( |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8299 } | 8311 } |
| 8300 } | 8312 } |
| 8301 THROW_NEW_ERROR(isolate, | 8313 THROW_NEW_ERROR(isolate, |
| 8302 NewTypeError(MessageTemplate::kCannotConvertToPrimitive), | 8314 NewTypeError(MessageTemplate::kCannotConvertToPrimitive), |
| 8303 Object); | 8315 Object); |
| 8304 } | 8316 } |
| 8305 | 8317 |
| 8306 | 8318 |
| 8307 // TODO(cbruni/jkummerow): Consider moving this into elements.cc. | 8319 // TODO(cbruni/jkummerow): Consider moving this into elements.cc. |
| 8308 bool HasEnumerableElements(JSObject* object) { | 8320 bool HasEnumerableElements(JSObject* object) { |
| 8309 if (object->IsJSValue()) { | |
| 8310 Object* value = JSValue::cast(object)->value(); | |
| 8311 if (value->IsString()) { | |
| 8312 if (String::cast(value)->length() > 0) return true; | |
| 8313 } | |
| 8314 } | |
| 8315 switch (object->GetElementsKind()) { | 8321 switch (object->GetElementsKind()) { |
| 8316 case FAST_SMI_ELEMENTS: | 8322 case FAST_SMI_ELEMENTS: |
| 8317 case FAST_ELEMENTS: | 8323 case FAST_ELEMENTS: |
| 8318 case FAST_DOUBLE_ELEMENTS: { | 8324 case FAST_DOUBLE_ELEMENTS: { |
| 8319 int length = object->IsJSArray() | 8325 int length = object->IsJSArray() |
| 8320 ? Smi::cast(JSArray::cast(object)->length())->value() | 8326 ? Smi::cast(JSArray::cast(object)->length())->value() |
| 8321 : object->elements()->length(); | 8327 : object->elements()->length(); |
| 8322 return length > 0; | 8328 return length > 0; |
| 8323 } | 8329 } |
| 8324 case FAST_HOLEY_SMI_ELEMENTS: | 8330 case FAST_HOLEY_SMI_ELEMENTS: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8356 } | 8362 } |
| 8357 case DICTIONARY_ELEMENTS: { | 8363 case DICTIONARY_ELEMENTS: { |
| 8358 SeededNumberDictionary* elements = | 8364 SeededNumberDictionary* elements = |
| 8359 SeededNumberDictionary::cast(object->elements()); | 8365 SeededNumberDictionary::cast(object->elements()); |
| 8360 return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0; | 8366 return elements->NumberOfElementsFilterAttributes(ONLY_ENUMERABLE) > 0; |
| 8361 } | 8367 } |
| 8362 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 8368 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 8363 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 8369 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 8364 // We're approximating non-empty arguments objects here. | 8370 // We're approximating non-empty arguments objects here. |
| 8365 return true; | 8371 return true; |
| 8372 case FAST_STRING_WRAPPER_ELEMENTS: | |
| 8373 case SLOW_STRING_WRAPPER_ELEMENTS: | |
| 8374 if (String::cast(JSValue::cast(object)->value())->length() > 0) { | |
| 8375 return true; | |
| 8376 } | |
| 8377 return object->elements()->length() > 0; | |
| 8378 case NO_ELEMENTS: | |
| 8379 return false; | |
| 8366 } | 8380 } |
| 8367 UNREACHABLE(); | 8381 UNREACHABLE(); |
| 8368 return true; | 8382 return true; |
| 8369 } | 8383 } |
| 8370 | 8384 |
| 8371 | 8385 |
| 8372 // Tests for the fast common case for property enumeration: | 8386 // Tests for the fast common case for property enumeration: |
| 8373 // - This object and all prototypes has an enum cache (which means that | 8387 // - This object and all prototypes has an enum cache (which means that |
| 8374 // it is no proxy, has no interceptors and needs no access checks). | 8388 // it is no proxy, has no interceptors and needs no access checks). |
| 8375 // - This object has no elements. | 8389 // - This object has no elements. |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8588 if (result.IsEmpty()) return Just(true); | 8602 if (result.IsEmpty()) return Just(true); |
| 8589 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || | 8603 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || |
| 8590 (v8::Utils::OpenHandle(*result)->IsJSObject() && | 8604 (v8::Utils::OpenHandle(*result)->IsJSObject() && |
| 8591 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) | 8605 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) |
| 8592 ->HasSloppyArgumentsElements())); | 8606 ->HasSloppyArgumentsElements())); |
| 8593 // The accumulator takes care of string/symbol filtering. | 8607 // The accumulator takes care of string/symbol filtering. |
| 8594 if (type == kIndexed) { | 8608 if (type == kIndexed) { |
| 8595 accumulator->AddElementKeysFromInterceptor( | 8609 accumulator->AddElementKeysFromInterceptor( |
| 8596 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8610 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); |
| 8597 } else { | 8611 } else { |
| 8598 accumulator->AddKeys( | 8612 accumulator->AddKeys(Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)), |
| 8599 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8613 DO_NOT_CONVERT); |
| 8600 } | 8614 } |
| 8601 return Just(true); | 8615 return Just(true); |
| 8602 } | 8616 } |
| 8603 | 8617 |
| 8604 | 8618 |
| 8605 // Returns |true| on success, |false| if prototype walking should be stopped, | 8619 // Returns |true| on success, |false| if prototype walking should be stopped, |
| 8606 // |nothing| if an exception was thrown. | 8620 // |nothing| if an exception was thrown. |
| 8607 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, | 8621 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, |
| 8608 Handle<JSReceiver> receiver, | 8622 Handle<JSReceiver> receiver, |
| 8609 Handle<JSObject> object, | 8623 Handle<JSObject> object, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8645 // use the cache says yes, so we should not create a cache. | 8659 // use the cache says yes, so we should not create a cache. |
| 8646 Handle<JSFunction> arguments_function( | 8660 Handle<JSFunction> arguments_function( |
| 8647 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 8661 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
| 8648 bool cache_enum_length = | 8662 bool cache_enum_length = |
| 8649 ((object->map()->GetConstructor() != *arguments_function) && | 8663 ((object->map()->GetConstructor() != *arguments_function) && |
| 8650 !object->IsJSValue() && !object->IsAccessCheckNeeded() && | 8664 !object->IsJSValue() && !object->IsAccessCheckNeeded() && |
| 8651 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); | 8665 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); |
| 8652 // Compute the property keys and cache them if possible. | 8666 // Compute the property keys and cache them if possible. |
| 8653 Handle<FixedArray> enum_keys = | 8667 Handle<FixedArray> enum_keys = |
| 8654 JSObject::GetEnumPropertyKeys(object, cache_enum_length); | 8668 JSObject::GetEnumPropertyKeys(object, cache_enum_length); |
| 8655 accumulator->AddKeys(enum_keys); | 8669 accumulator->AddKeys(enum_keys, DO_NOT_CONVERT); |
| 8656 } else { | 8670 } else { |
| 8657 object->CollectOwnPropertyNames(accumulator, *filter); | 8671 object->CollectOwnPropertyNames(accumulator, *filter); |
| 8658 } | 8672 } |
| 8659 | 8673 |
| 8660 // Add the property keys from the interceptor. | 8674 // Add the property keys from the interceptor. |
| 8661 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, | 8675 success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, |
| 8662 kNamed>(isolate, receiver, object, *filter, | 8676 kNamed>(isolate, receiver, object, *filter, |
| 8663 accumulator); | 8677 accumulator); |
| 8664 MAYBE_RETURN(success, Nothing<bool>()); | 8678 MAYBE_RETURN(success, Nothing<bool>()); |
| 8665 return Just(true); | 8679 return Just(true); |
| (...skipping 7099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15765 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); | 15779 return ShouldConvertToSlowElements(this, capacity, index, &new_capacity); |
| 15766 } | 15780 } |
| 15767 return false; | 15781 return false; |
| 15768 } | 15782 } |
| 15769 | 15783 |
| 15770 | 15784 |
| 15771 static ElementsKind BestFittingFastElementsKind(JSObject* object) { | 15785 static ElementsKind BestFittingFastElementsKind(JSObject* object) { |
| 15772 if (object->HasSloppyArgumentsElements()) { | 15786 if (object->HasSloppyArgumentsElements()) { |
| 15773 return FAST_SLOPPY_ARGUMENTS_ELEMENTS; | 15787 return FAST_SLOPPY_ARGUMENTS_ELEMENTS; |
| 15774 } | 15788 } |
| 15789 if (object->HasStringWrapperElements()) { | |
| 15790 return FAST_STRING_WRAPPER_ELEMENTS; | |
| 15791 } | |
| 15775 DCHECK(object->HasDictionaryElements()); | 15792 DCHECK(object->HasDictionaryElements()); |
| 15776 SeededNumberDictionary* dictionary = object->element_dictionary(); | 15793 SeededNumberDictionary* dictionary = object->element_dictionary(); |
| 15777 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; | 15794 ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS; |
| 15778 for (int i = 0; i < dictionary->Capacity(); i++) { | 15795 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 15779 Object* key = dictionary->KeyAt(i); | 15796 Object* key = dictionary->KeyAt(i); |
| 15780 if (key->IsNumber()) { | 15797 if (key->IsNumber()) { |
| 15781 Object* value = dictionary->ValueAt(i); | 15798 Object* value = dictionary->ValueAt(i); |
| 15782 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; | 15799 if (!value->IsNumber()) return FAST_HOLEY_ELEMENTS; |
| 15783 if (!value->IsSmi()) { | 15800 if (!value->IsSmi()) { |
| 15784 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; | 15801 if (!FLAG_unbox_double_arrays) return FAST_HOLEY_ELEMENTS; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15848 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); | 15865 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); |
| 15849 } | 15866 } |
| 15850 } | 15867 } |
| 15851 | 15868 |
| 15852 ElementsKind kind = object->GetElementsKind(); | 15869 ElementsKind kind = object->GetElementsKind(); |
| 15853 FixedArrayBase* elements = object->elements(); | 15870 FixedArrayBase* elements = object->elements(); |
| 15854 ElementsKind dictionary_kind = DICTIONARY_ELEMENTS; | 15871 ElementsKind dictionary_kind = DICTIONARY_ELEMENTS; |
| 15855 if (IsSloppyArgumentsElements(kind)) { | 15872 if (IsSloppyArgumentsElements(kind)) { |
| 15856 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); | 15873 elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1)); |
| 15857 dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS; | 15874 dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS; |
| 15875 } else if (IsStringWrapperElementsKind(kind)) { | |
| 15876 dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS; | |
| 15858 } | 15877 } |
| 15859 | 15878 |
| 15860 if (attributes != NONE) { | 15879 if (attributes != NONE) { |
| 15861 kind = dictionary_kind; | 15880 kind = dictionary_kind; |
| 15862 } else if (elements->IsSeededNumberDictionary()) { | 15881 } else if (elements->IsSeededNumberDictionary()) { |
| 15863 kind = ShouldConvertToFastElements(*object, | 15882 kind = ShouldConvertToFastElements(*object, |
| 15864 SeededNumberDictionary::cast(elements), | 15883 SeededNumberDictionary::cast(elements), |
| 15865 index, &new_capacity) | 15884 index, &new_capacity) |
| 15866 ? BestFittingFastElementsKind(*object) | 15885 ? BestFittingFastElementsKind(*object) |
| 15867 : dictionary_kind; // Overwrite in case of arguments. | 15886 : dictionary_kind; // Overwrite in case of arguments. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16142 case FAST_SMI_ELEMENTS: | 16161 case FAST_SMI_ELEMENTS: |
| 16143 case FAST_DOUBLE_ELEMENTS: | 16162 case FAST_DOUBLE_ELEMENTS: |
| 16144 case FAST_ELEMENTS: | 16163 case FAST_ELEMENTS: |
| 16145 return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() | 16164 return IsJSArray() ? Smi::cast(JSArray::cast(this)->length())->value() |
| 16146 : store->length(); | 16165 : store->length(); |
| 16147 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 16166 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 16148 store = FixedArray::cast(FixedArray::cast(store)->get(1)); | 16167 store = FixedArray::cast(FixedArray::cast(store)->get(1)); |
| 16149 // Fall through. | 16168 // Fall through. |
| 16150 case FAST_HOLEY_SMI_ELEMENTS: | 16169 case FAST_HOLEY_SMI_ELEMENTS: |
| 16151 case FAST_HOLEY_ELEMENTS: | 16170 case FAST_HOLEY_ELEMENTS: |
| 16171 case FAST_STRING_WRAPPER_ELEMENTS: | |
| 16152 return FastHoleyElementsUsage(this, FixedArray::cast(store)); | 16172 return FastHoleyElementsUsage(this, FixedArray::cast(store)); |
| 16153 case FAST_HOLEY_DOUBLE_ELEMENTS: | 16173 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 16154 if (elements()->length() == 0) return 0; | 16174 if (elements()->length() == 0) return 0; |
| 16155 return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store)); | 16175 return FastHoleyElementsUsage(this, FixedDoubleArray::cast(store)); |
| 16156 | 16176 |
| 16157 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 16177 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 16178 case SLOW_STRING_WRAPPER_ELEMENTS: | |
| 16158 case DICTIONARY_ELEMENTS: | 16179 case DICTIONARY_ELEMENTS: |
| 16180 case NO_ELEMENTS: | |
| 16159 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 16181 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 16160 case TYPE##_ELEMENTS: \ | 16182 case TYPE##_ELEMENTS: \ |
| 16161 | 16183 |
| 16162 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 16184 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 16163 #undef TYPED_ARRAY_CASE | 16185 #undef TYPED_ARRAY_CASE |
| 16164 UNREACHABLE(); | 16186 UNREACHABLE(); |
| 16165 } | 16187 } |
| 16166 return 0; | 16188 return 0; |
| 16167 } | 16189 } |
| 16168 | 16190 |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16420 PropertyDetails details = descs->GetDetails(i); | 16442 PropertyDetails details = descs->GetDetails(i); |
| 16421 if ((details.attributes() & filter) != 0) continue; | 16443 if ((details.attributes() & filter) != 0) continue; |
| 16422 if (filter & ONLY_ALL_CAN_READ) { | 16444 if (filter & ONLY_ALL_CAN_READ) { |
| 16423 if (details.kind() != kAccessor) continue; | 16445 if (details.kind() != kAccessor) continue; |
| 16424 Object* accessors = descs->GetValue(i); | 16446 Object* accessors = descs->GetValue(i); |
| 16425 if (!accessors->IsAccessorInfo()) continue; | 16447 if (!accessors->IsAccessorInfo()) continue; |
| 16426 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; | 16448 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
| 16427 } | 16449 } |
| 16428 Name* key = descs->GetKey(i); | 16450 Name* key = descs->GetKey(i); |
| 16429 if (key->FilterKey(filter)) continue; | 16451 if (key->FilterKey(filter)) continue; |
| 16430 keys->AddKey(key); | 16452 keys->AddKey(key, DO_NOT_CONVERT); |
| 16431 } | 16453 } |
| 16432 } else if (IsJSGlobalObject()) { | 16454 } else if (IsJSGlobalObject()) { |
| 16433 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); | 16455 GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); |
| 16434 } else { | 16456 } else { |
| 16435 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); | 16457 NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); |
| 16436 } | 16458 } |
| 16437 } | 16459 } |
| 16438 | 16460 |
| 16439 | 16461 |
| 16440 int JSObject::NumberOfOwnElements(PropertyFilter filter) { | 16462 int JSObject::NumberOfOwnElements(PropertyFilter filter) { |
| 16441 // Fast case for objects with no elements. | 16463 // Fast case for objects with no elements. |
| 16442 if (!IsJSValue() && HasFastElements()) { | 16464 if (!IsJSValue() && HasFastElements()) { |
| 16443 uint32_t length = | 16465 uint32_t length = |
| 16444 IsJSArray() | 16466 IsJSArray() |
| 16445 ? static_cast<uint32_t>( | 16467 ? static_cast<uint32_t>( |
| 16446 Smi::cast(JSArray::cast(this)->length())->value()) | 16468 Smi::cast(JSArray::cast(this)->length())->value()) |
| 16447 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); | 16469 : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length()); |
| 16448 if (length == 0) return 0; | 16470 if (length == 0) return 0; |
| 16449 } | 16471 } |
| 16450 // Compute the number of enumerable elements. | 16472 // Compute the number of enumerable elements. |
| 16451 return GetOwnElementKeys(NULL, filter); | 16473 return GetOwnElementKeys(NULL, filter); |
| 16452 } | 16474 } |
| 16453 | 16475 |
| 16454 | 16476 |
| 16455 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, | 16477 void JSObject::CollectOwnElementKeys(Handle<JSObject> object, |
| 16456 KeyAccumulator* keys, | 16478 KeyAccumulator* keys, |
| 16457 PropertyFilter filter) { | 16479 PropertyFilter filter) { |
| 16458 if (filter & SKIP_STRINGS) return; | 16480 if (filter & SKIP_STRINGS) return; |
| 16459 uint32_t string_keys = 0; | |
| 16460 | |
| 16461 // If this is a String wrapper, add the string indices first, | |
| 16462 // as they're guaranteed to precede the elements in numerical order | |
| 16463 // and ascending order is required by ECMA-262, 6th, 9.1.12. | |
| 16464 if (object->IsJSValue()) { | |
| 16465 Object* val = JSValue::cast(*object)->value(); | |
| 16466 if (val->IsString() && (filter & ONLY_ALL_CAN_READ) == 0) { | |
| 16467 String* str = String::cast(val); | |
| 16468 string_keys = str->length(); | |
| 16469 for (uint32_t i = 0; i < string_keys; i++) { | |
| 16470 keys->AddKey(i); | |
| 16471 } | |
| 16472 } | |
| 16473 } | |
| 16474 ElementsAccessor* accessor = object->GetElementsAccessor(); | 16481 ElementsAccessor* accessor = object->GetElementsAccessor(); |
| 16475 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); | 16482 accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); |
| 16476 } | 16483 } |
| 16477 | 16484 |
| 16478 | 16485 |
| 16479 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) { | 16486 int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) { |
| 16480 int counter = 0; | 16487 int counter = 0; |
| 16481 | 16488 |
| 16482 // If this is a String wrapper, add the string indices first, | 16489 // If this is a String wrapper, add the string indices first, |
| 16483 // as they're guaranteed to precede the elements in numerical order | 16490 // as they're guaranteed to precede the elements in numerical order |
| 16484 // and ascending order is required by ECMA-262, 6th, 9.1.12. | 16491 // and ascending order is required by ECMA-262, 6th, 9.1.12. |
| 16485 if (IsJSValue()) { | 16492 if (IsJSValue()) { |
|
Jakob Kummerow
2016/01/26 14:21:24
Intentionally not ElementsAccessor-izing this beca
| |
| 16486 Object* val = JSValue::cast(this)->value(); | 16493 Object* val = JSValue::cast(this)->value(); |
| 16487 if (val->IsString()) { | 16494 if (val->IsString()) { |
| 16488 String* str = String::cast(val); | 16495 String* str = String::cast(val); |
| 16489 if (storage) { | 16496 if (storage) { |
| 16490 for (int i = 0; i < str->length(); i++) { | 16497 for (int i = 0; i < str->length(); i++) { |
| 16491 storage->set(counter + i, Smi::FromInt(i)); | 16498 storage->set(counter + i, Smi::FromInt(i)); |
| 16492 } | 16499 } |
| 16493 } | 16500 } |
| 16494 counter += str->length(); | 16501 counter += str->length(); |
| 16495 } | 16502 } |
| 16496 } | 16503 } |
| 16497 | 16504 |
| 16498 switch (GetElementsKind()) { | 16505 switch (GetElementsKind()) { |
| 16499 case FAST_SMI_ELEMENTS: | 16506 case FAST_SMI_ELEMENTS: |
| 16500 case FAST_ELEMENTS: | 16507 case FAST_ELEMENTS: |
| 16501 case FAST_HOLEY_SMI_ELEMENTS: | 16508 case FAST_HOLEY_SMI_ELEMENTS: |
| 16502 case FAST_HOLEY_ELEMENTS: { | 16509 case FAST_HOLEY_ELEMENTS: |
| 16510 case FAST_STRING_WRAPPER_ELEMENTS: { | |
| 16503 int length = IsJSArray() ? | 16511 int length = IsJSArray() ? |
| 16504 Smi::cast(JSArray::cast(this)->length())->value() : | 16512 Smi::cast(JSArray::cast(this)->length())->value() : |
| 16505 FixedArray::cast(elements())->length(); | 16513 FixedArray::cast(elements())->length(); |
| 16506 for (int i = 0; i < length; i++) { | 16514 for (int i = 0; i < length; i++) { |
| 16507 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 16515 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
| 16508 if (storage != NULL) { | 16516 if (storage != NULL) { |
| 16509 storage->set(counter, Smi::FromInt(i)); | 16517 storage->set(counter, Smi::FromInt(i)); |
| 16510 } | 16518 } |
| 16511 counter++; | 16519 counter++; |
| 16512 } | 16520 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 16541 while (counter < length) { | 16549 while (counter < length) { |
| 16542 if (storage != NULL) { | 16550 if (storage != NULL) { |
| 16543 storage->set(counter, Smi::FromInt(counter)); | 16551 storage->set(counter, Smi::FromInt(counter)); |
| 16544 } | 16552 } |
| 16545 counter++; | 16553 counter++; |
| 16546 } | 16554 } |
| 16547 DCHECK(!storage || storage->length() >= counter); | 16555 DCHECK(!storage || storage->length() >= counter); |
| 16548 break; | 16556 break; |
| 16549 } | 16557 } |
| 16550 | 16558 |
| 16551 case DICTIONARY_ELEMENTS: { | 16559 case DICTIONARY_ELEMENTS: |
| 16560 case SLOW_STRING_WRAPPER_ELEMENTS: { | |
| 16552 if (storage != NULL) { | 16561 if (storage != NULL) { |
| 16553 element_dictionary()->CopyKeysTo(storage, counter, filter, | 16562 element_dictionary()->CopyKeysTo(storage, counter, filter, |
| 16554 SeededNumberDictionary::SORTED); | 16563 SeededNumberDictionary::SORTED); |
| 16555 } | 16564 } |
| 16556 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 16565 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 16557 break; | 16566 break; |
| 16558 } | 16567 } |
| 16559 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 16568 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 16560 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { | 16569 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { |
| 16561 FixedArray* parameter_map = FixedArray::cast(elements()); | 16570 FixedArray* parameter_map = FixedArray::cast(elements()); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 16591 ++counter; | 16600 ++counter; |
| 16592 } | 16601 } |
| 16593 } | 16602 } |
| 16594 for (; i < backing_length; ++i) { | 16603 for (; i < backing_length; ++i) { |
| 16595 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | 16604 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
| 16596 ++counter; | 16605 ++counter; |
| 16597 } | 16606 } |
| 16598 } | 16607 } |
| 16599 break; | 16608 break; |
| 16600 } | 16609 } |
| 16610 case NO_ELEMENTS: | |
| 16611 break; | |
| 16601 } | 16612 } |
| 16602 | 16613 |
| 16603 DCHECK(!storage || storage->length() == counter); | 16614 DCHECK(!storage || storage->length() == counter); |
| 16604 return counter; | 16615 return counter; |
| 16605 } | 16616 } |
| 16606 | 16617 |
| 16607 | 16618 |
| 16608 MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate, | 16619 MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate, |
| 16609 Handle<Object> object) { | 16620 Handle<Object> object) { |
| 16610 if (object->IsUndefined()) return isolate->factory()->undefined_to_string(); | 16621 if (object->IsUndefined()) return isolate->factory()->undefined_to_string(); |
| (...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18488 array->set(array_size++, Smi::FromInt(i)); | 18499 array->set(array_size++, Smi::FromInt(i)); |
| 18489 } | 18500 } |
| 18490 | 18501 |
| 18491 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); | 18502 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); |
| 18492 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); | 18503 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); |
| 18493 std::sort(start, start + array_size, cmp); | 18504 std::sort(start, start + array_size, cmp); |
| 18494 } | 18505 } |
| 18495 | 18506 |
| 18496 for (int i = 0; i < array_size; i++) { | 18507 for (int i = 0; i < array_size; i++) { |
| 18497 int index = Smi::cast(array->get(i))->value(); | 18508 int index = Smi::cast(array->get(i))->value(); |
| 18498 keys->AddKey(dictionary->KeyAt(index)); | 18509 keys->AddKey(dictionary->KeyAt(index), DO_NOT_CONVERT); |
| 18499 } | 18510 } |
| 18500 } | 18511 } |
| 18501 | 18512 |
| 18502 | 18513 |
| 18503 // Backwards lookup (slow). | 18514 // Backwards lookup (slow). |
| 18504 template<typename Derived, typename Shape, typename Key> | 18515 template<typename Derived, typename Shape, typename Key> |
| 18505 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 18516 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 18506 int capacity = this->Capacity(); | 18517 int capacity = this->Capacity(); |
| 18507 for (int i = 0; i < capacity; i++) { | 18518 for (int i = 0; i < capacity; i++) { |
| 18508 Object* k = this->KeyAt(i); | 18519 Object* k = this->KeyAt(i); |
| (...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 19745 if (cell->value() != *new_value) { | 19756 if (cell->value() != *new_value) { |
| 19746 cell->set_value(*new_value); | 19757 cell->set_value(*new_value); |
| 19747 Isolate* isolate = cell->GetIsolate(); | 19758 Isolate* isolate = cell->GetIsolate(); |
| 19748 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19759 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19749 isolate, DependentCode::kPropertyCellChangedGroup); | 19760 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19750 } | 19761 } |
| 19751 } | 19762 } |
| 19752 | 19763 |
| 19753 } // namespace internal | 19764 } // namespace internal |
| 19754 } // namespace v8 | 19765 } // namespace v8 |
| OLD | NEW |