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 |