| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11225 } | 11225 } |
| 11226 } | 11226 } |
| 11227 Handle<FixedArrayBase> old_elements(object->elements()); | 11227 Handle<FixedArrayBase> old_elements(object->elements()); |
| 11228 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); | 11228 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); |
| 11229 accessor->CopyElements(object, new_elements, elements_kind); | 11229 accessor->CopyElements(object, new_elements, elements_kind); |
| 11230 | 11230 |
| 11231 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { | 11231 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { |
| 11232 Handle<Map> new_map = (new_elements_kind != elements_kind) | 11232 Handle<Map> new_map = (new_elements_kind != elements_kind) |
| 11233 ? GetElementsTransitionMap(object, new_elements_kind) | 11233 ? GetElementsTransitionMap(object, new_elements_kind) |
| 11234 : handle(object->map()); | 11234 : handle(object->map()); |
| 11235 object->ValidateElements(); | 11235 JSObject::ValidateElements(object); |
| 11236 JSObject::SetMapAndElements(object, new_map, new_elements); | 11236 JSObject::SetMapAndElements(object, new_map, new_elements); |
| 11237 | 11237 |
| 11238 // Transition through the allocation site as well if present. | 11238 // Transition through the allocation site as well if present. |
| 11239 JSObject::UpdateAllocationSite(object, new_elements_kind); | 11239 JSObject::UpdateAllocationSite(object, new_elements_kind); |
| 11240 } else { | 11240 } else { |
| 11241 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements); | 11241 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements); |
| 11242 parameter_map->set(1, *new_elements); | 11242 parameter_map->set(1, *new_elements); |
| 11243 } | 11243 } |
| 11244 | 11244 |
| 11245 if (FLAG_trace_elements_transitions) { | 11245 if (FLAG_trace_elements_transitions) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 11271 } else { | 11271 } else { |
| 11272 new_elements_kind = FAST_DOUBLE_ELEMENTS; | 11272 new_elements_kind = FAST_DOUBLE_ELEMENTS; |
| 11273 } | 11273 } |
| 11274 | 11274 |
| 11275 Handle<Map> new_map = GetElementsTransitionMap(object, new_elements_kind); | 11275 Handle<Map> new_map = GetElementsTransitionMap(object, new_elements_kind); |
| 11276 | 11276 |
| 11277 Handle<FixedArrayBase> old_elements(object->elements()); | 11277 Handle<FixedArrayBase> old_elements(object->elements()); |
| 11278 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); | 11278 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); |
| 11279 accessor->CopyElements(object, elems, elements_kind); | 11279 accessor->CopyElements(object, elems, elements_kind); |
| 11280 | 11280 |
| 11281 object->ValidateElements(); | 11281 JSObject::ValidateElements(object); |
| 11282 JSObject::SetMapAndElements(object, new_map, elems); | 11282 JSObject::SetMapAndElements(object, new_map, elems); |
| 11283 | 11283 |
| 11284 if (FLAG_trace_elements_transitions) { | 11284 if (FLAG_trace_elements_transitions) { |
| 11285 PrintElementsTransition(stdout, object, elements_kind, old_elements, | 11285 PrintElementsTransition(stdout, object, elements_kind, old_elements, |
| 11286 object->GetElementsKind(), elems); | 11286 object->GetElementsKind(), elems); |
| 11287 } | 11287 } |
| 11288 | 11288 |
| 11289 if (object->IsJSArray()) { | 11289 if (object->IsJSArray()) { |
| 11290 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); | 11290 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); |
| 11291 } | 11291 } |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12150 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 12150 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
| 12151 // Consider fixing the boilerplate as well if we have one. | 12151 // Consider fixing the boilerplate as well if we have one. |
| 12152 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 12152 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
| 12153 ? FAST_HOLEY_DOUBLE_ELEMENTS | 12153 ? FAST_HOLEY_DOUBLE_ELEMENTS |
| 12154 : FAST_DOUBLE_ELEMENTS; | 12154 : FAST_DOUBLE_ELEMENTS; |
| 12155 | 12155 |
| 12156 UpdateAllocationSite(object, to_kind); | 12156 UpdateAllocationSite(object, to_kind); |
| 12157 | 12157 |
| 12158 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); | 12158 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); |
| 12159 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); | 12159 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); |
| 12160 object->ValidateElements(); | 12160 JSObject::ValidateElements(object); |
| 12161 return value; | 12161 return value; |
| 12162 } | 12162 } |
| 12163 // Change elements kind from Smi-only to generic FAST if necessary. | 12163 // Change elements kind from Smi-only to generic FAST if necessary. |
| 12164 if (object->HasFastSmiElements() && !value->IsSmi()) { | 12164 if (object->HasFastSmiElements() && !value->IsSmi()) { |
| 12165 ElementsKind kind = object->HasFastHoleyElements() | 12165 ElementsKind kind = object->HasFastHoleyElements() |
| 12166 ? FAST_HOLEY_ELEMENTS | 12166 ? FAST_HOLEY_ELEMENTS |
| 12167 : FAST_ELEMENTS; | 12167 : FAST_ELEMENTS; |
| 12168 | 12168 |
| 12169 UpdateAllocationSite(object, kind); | 12169 UpdateAllocationSite(object, kind); |
| 12170 Handle<Map> new_map = GetElementsTransitionMap(object, kind); | 12170 Handle<Map> new_map = GetElementsTransitionMap(object, kind); |
| 12171 JSObject::MigrateToMap(object, new_map); | 12171 JSObject::MigrateToMap(object, new_map); |
| 12172 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); | 12172 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); |
| 12173 } | 12173 } |
| 12174 // Increase backing store capacity if that's been decided previously. | 12174 // Increase backing store capacity if that's been decided previously. |
| 12175 if (new_capacity != capacity) { | 12175 if (new_capacity != capacity) { |
| 12176 SetFastElementsCapacitySmiMode smi_mode = | 12176 SetFastElementsCapacitySmiMode smi_mode = |
| 12177 value->IsSmi() && object->HasFastSmiElements() | 12177 value->IsSmi() && object->HasFastSmiElements() |
| 12178 ? kAllowSmiElements | 12178 ? kAllowSmiElements |
| 12179 : kDontAllowSmiElements; | 12179 : kDontAllowSmiElements; |
| 12180 Handle<FixedArray> new_elements = | 12180 Handle<FixedArray> new_elements = |
| 12181 SetFastElementsCapacityAndLength(object, new_capacity, array_length, | 12181 SetFastElementsCapacityAndLength(object, new_capacity, array_length, |
| 12182 smi_mode); | 12182 smi_mode); |
| 12183 new_elements->set(index, *value); | 12183 new_elements->set(index, *value); |
| 12184 object->ValidateElements(); | 12184 JSObject::ValidateElements(object); |
| 12185 return value; | 12185 return value; |
| 12186 } | 12186 } |
| 12187 | 12187 |
| 12188 // Finally, set the new element and length. | 12188 // Finally, set the new element and length. |
| 12189 ASSERT(object->elements()->IsFixedArray()); | 12189 ASSERT(object->elements()->IsFixedArray()); |
| 12190 backing_store->set(index, *value); | 12190 backing_store->set(index, *value); |
| 12191 if (must_update_array_length) { | 12191 if (must_update_array_length) { |
| 12192 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | 12192 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
| 12193 } | 12193 } |
| 12194 return value; | 12194 return value; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12320 if (has_smi_only_elements) { | 12320 if (has_smi_only_elements) { |
| 12321 smi_mode = kForceSmiElements; | 12321 smi_mode = kForceSmiElements; |
| 12322 } | 12322 } |
| 12323 | 12323 |
| 12324 if (should_convert_to_fast_double_elements) { | 12324 if (should_convert_to_fast_double_elements) { |
| 12325 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); | 12325 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); |
| 12326 } else { | 12326 } else { |
| 12327 SetFastElementsCapacityAndLength(object, new_length, new_length, | 12327 SetFastElementsCapacityAndLength(object, new_length, new_length, |
| 12328 smi_mode); | 12328 smi_mode); |
| 12329 } | 12329 } |
| 12330 object->ValidateElements(); | 12330 JSObject::ValidateElements(object); |
| 12331 #ifdef DEBUG | 12331 #ifdef DEBUG |
| 12332 if (FLAG_trace_normalization) { | 12332 if (FLAG_trace_normalization) { |
| 12333 PrintF("Object elements are fast case again:\n"); | 12333 PrintF("Object elements are fast case again:\n"); |
| 12334 object->Print(); | 12334 object->Print(); |
| 12335 } | 12335 } |
| 12336 #endif | 12336 #endif |
| 12337 } | 12337 } |
| 12338 return value; | 12338 return value; |
| 12339 } | 12339 } |
| 12340 | 12340 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12372 introduces_holes = index >= elms_length; | 12372 introduces_holes = index >= elms_length; |
| 12373 } | 12373 } |
| 12374 | 12374 |
| 12375 if (!value->IsNumber()) { | 12375 if (!value->IsNumber()) { |
| 12376 SetFastElementsCapacityAndLength(object, elms_length, length, | 12376 SetFastElementsCapacityAndLength(object, elms_length, length, |
| 12377 kDontAllowSmiElements); | 12377 kDontAllowSmiElements); |
| 12378 Handle<Object> result = SetFastElement(object, index, value, strict_mode, | 12378 Handle<Object> result = SetFastElement(object, index, value, strict_mode, |
| 12379 check_prototype); | 12379 check_prototype); |
| 12380 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, | 12380 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, |
| 12381 Handle<Object>()); | 12381 Handle<Object>()); |
| 12382 object->ValidateElements(); | 12382 JSObject::ValidateElements(object); |
| 12383 return result; | 12383 return result; |
| 12384 } | 12384 } |
| 12385 | 12385 |
| 12386 double double_value = value_is_smi | 12386 double double_value = value_is_smi |
| 12387 ? static_cast<double>(Handle<Smi>::cast(value)->value()) | 12387 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
| 12388 : Handle<HeapNumber>::cast(value)->value(); | 12388 : Handle<HeapNumber>::cast(value)->value(); |
| 12389 | 12389 |
| 12390 // If the array is growing, and it's not growth by a single element at the | 12390 // If the array is growing, and it's not growth by a single element at the |
| 12391 // end, make sure that the ElementsKind is HOLEY. | 12391 // end, make sure that the ElementsKind is HOLEY. |
| 12392 ElementsKind elements_kind = object->GetElementsKind(); | 12392 ElementsKind elements_kind = object->GetElementsKind(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 12412 } | 12412 } |
| 12413 | 12413 |
| 12414 // Allow gap in fast case. | 12414 // Allow gap in fast case. |
| 12415 if ((index - elms_length) < kMaxGap) { | 12415 if ((index - elms_length) < kMaxGap) { |
| 12416 // Try allocating extra space. | 12416 // Try allocating extra space. |
| 12417 int new_capacity = NewElementsCapacity(index+1); | 12417 int new_capacity = NewElementsCapacity(index+1); |
| 12418 if (!object->ShouldConvertToSlowElements(new_capacity)) { | 12418 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
| 12419 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 12419 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
| 12420 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); | 12420 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); |
| 12421 FixedDoubleArray::cast(object->elements())->set(index, double_value); | 12421 FixedDoubleArray::cast(object->elements())->set(index, double_value); |
| 12422 object->ValidateElements(); | 12422 JSObject::ValidateElements(object); |
| 12423 return value; | 12423 return value; |
| 12424 } | 12424 } |
| 12425 } | 12425 } |
| 12426 | 12426 |
| 12427 // Otherwise default to slow case. | 12427 // Otherwise default to slow case. |
| 12428 ASSERT(object->HasFastDoubleElements()); | 12428 ASSERT(object->HasFastDoubleElements()); |
| 12429 ASSERT(object->map()->has_fast_double_elements()); | 12429 ASSERT(object->map()->has_fast_double_elements()); |
| 12430 ASSERT(object->elements()->IsFixedDoubleArray() || | 12430 ASSERT(object->elements()->IsFixedDoubleArray() || |
| 12431 object->elements()->length() == 0); | 12431 object->elements()->length() == 0); |
| 12432 | 12432 |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12871 // elements, assume a length of zero. | 12871 // elements, assume a length of zero. |
| 12872 length = 0; | 12872 length = 0; |
| 12873 } else { | 12873 } else { |
| 12874 CHECK(raw_length->ToArrayIndex(&length)); | 12874 CHECK(raw_length->ToArrayIndex(&length)); |
| 12875 } | 12875 } |
| 12876 } | 12876 } |
| 12877 | 12877 |
| 12878 if (IsFastSmiElementsKind(from_kind) && | 12878 if (IsFastSmiElementsKind(from_kind) && |
| 12879 IsFastDoubleElementsKind(to_kind)) { | 12879 IsFastDoubleElementsKind(to_kind)) { |
| 12880 SetFastDoubleElementsCapacityAndLength(object, capacity, length); | 12880 SetFastDoubleElementsCapacityAndLength(object, capacity, length); |
| 12881 object->ValidateElements(); | 12881 JSObject::ValidateElements(object); |
| 12882 return; | 12882 return; |
| 12883 } | 12883 } |
| 12884 | 12884 |
| 12885 if (IsFastDoubleElementsKind(from_kind) && | 12885 if (IsFastDoubleElementsKind(from_kind) && |
| 12886 IsFastObjectElementsKind(to_kind)) { | 12886 IsFastObjectElementsKind(to_kind)) { |
| 12887 SetFastElementsCapacityAndLength(object, capacity, length, | 12887 SetFastElementsCapacityAndLength(object, capacity, length, |
| 12888 kDontAllowSmiElements); | 12888 kDontAllowSmiElements); |
| 12889 object->ValidateElements(); | 12889 JSObject::ValidateElements(object); |
| 12890 return; | 12890 return; |
| 12891 } | 12891 } |
| 12892 | 12892 |
| 12893 // This method should never be called for any other case than the ones | 12893 // This method should never be called for any other case than the ones |
| 12894 // handled above. | 12894 // handled above. |
| 12895 UNREACHABLE(); | 12895 UNREACHABLE(); |
| 12896 } | 12896 } |
| 12897 | 12897 |
| 12898 | 12898 |
| 12899 // static | 12899 // static |
| (...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14405 // Convert to fast elements. | 14405 // Convert to fast elements. |
| 14406 | 14406 |
| 14407 Handle<Map> new_map = | 14407 Handle<Map> new_map = |
| 14408 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); | 14408 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS); |
| 14409 | 14409 |
| 14410 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? | 14410 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ? |
| 14411 NOT_TENURED: TENURED; | 14411 NOT_TENURED: TENURED; |
| 14412 Handle<FixedArray> fast_elements = | 14412 Handle<FixedArray> fast_elements = |
| 14413 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14413 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
| 14414 dict->CopyValuesTo(*fast_elements); | 14414 dict->CopyValuesTo(*fast_elements); |
| 14415 object->ValidateElements(); | 14415 JSObject::ValidateElements(object); |
| 14416 | 14416 |
| 14417 JSObject::SetMapAndElements(object, new_map, fast_elements); | 14417 JSObject::SetMapAndElements(object, new_map, fast_elements); |
| 14418 } else if (object->HasExternalArrayElements() || | 14418 } else if (object->HasExternalArrayElements() || |
| 14419 object->HasFixedTypedArrayElements()) { | 14419 object->HasFixedTypedArrayElements()) { |
| 14420 // Typed arrays cannot have holes or undefined elements. | 14420 // Typed arrays cannot have holes or undefined elements. |
| 14421 return handle(Smi::FromInt( | 14421 return handle(Smi::FromInt( |
| 14422 FixedArrayBase::cast(object->elements())->length()), isolate); | 14422 FixedArrayBase::cast(object->elements())->length()), isolate); |
| 14423 } else if (!object->HasFastDoubleElements()) { | 14423 } else if (!object->HasFastDoubleElements()) { |
| 14424 EnsureWritableFastElements(object); | 14424 EnsureWritableFastElements(object); |
| 14425 } | 14425 } |
| (...skipping 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16486 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16486 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16487 static const char* error_messages_[] = { | 16487 static const char* error_messages_[] = { |
| 16488 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16488 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16489 }; | 16489 }; |
| 16490 #undef ERROR_MESSAGES_TEXTS | 16490 #undef ERROR_MESSAGES_TEXTS |
| 16491 return error_messages_[reason]; | 16491 return error_messages_[reason]; |
| 16492 } | 16492 } |
| 16493 | 16493 |
| 16494 | 16494 |
| 16495 } } // namespace v8::internal | 16495 } } // namespace v8::internal |
| OLD | NEW |