OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 10454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10465 | 10465 |
10466 // If estimated number of elements is more than half of length, a | 10466 // If estimated number of elements is more than half of length, a |
10467 // fixed array (fast case) is more time and space-efficient than a | 10467 // fixed array (fast case) is more time and space-efficient than a |
10468 // dictionary. | 10468 // dictionary. |
10469 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; | 10469 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; |
10470 | 10470 |
10471 if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { | 10471 if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { |
10472 Handle<FixedArrayBase> storage = | 10472 Handle<FixedArrayBase> storage = |
10473 isolate->factory()->NewFixedDoubleArray(estimate_result_length); | 10473 isolate->factory()->NewFixedDoubleArray(estimate_result_length); |
10474 int j = 0; | 10474 int j = 0; |
| 10475 bool failure = false; |
10475 if (estimate_result_length > 0) { | 10476 if (estimate_result_length > 0) { |
10476 Handle<FixedDoubleArray> double_storage = | 10477 Handle<FixedDoubleArray> double_storage = |
10477 Handle<FixedDoubleArray>::cast(storage); | 10478 Handle<FixedDoubleArray>::cast(storage); |
10478 bool failure = false; | |
10479 for (int i = 0; i < argument_count; i++) { | 10479 for (int i = 0; i < argument_count; i++) { |
10480 Handle<Object> obj(elements->get(i), isolate); | 10480 Handle<Object> obj(elements->get(i), isolate); |
10481 if (obj->IsSmi()) { | 10481 if (obj->IsSmi()) { |
10482 double_storage->set(j, Smi::cast(*obj)->value()); | 10482 double_storage->set(j, Smi::cast(*obj)->value()); |
10483 j++; | 10483 j++; |
10484 } else if (obj->IsNumber()) { | 10484 } else if (obj->IsNumber()) { |
10485 double_storage->set(j, obj->Number()); | 10485 double_storage->set(j, obj->Number()); |
10486 j++; | 10486 j++; |
10487 } else { | 10487 } else { |
10488 JSArray* array = JSArray::cast(*obj); | 10488 JSArray* array = JSArray::cast(*obj); |
10489 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 10489 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
10490 switch (array->map()->elements_kind()) { | 10490 switch (array->map()->elements_kind()) { |
10491 case FAST_HOLEY_DOUBLE_ELEMENTS: | 10491 case FAST_HOLEY_DOUBLE_ELEMENTS: |
10492 case FAST_DOUBLE_ELEMENTS: { | 10492 case FAST_DOUBLE_ELEMENTS: { |
10493 // Empty array is FixedArray but not FixedDoubleArray. | 10493 // Empty array is FixedArray but not FixedDoubleArray. |
10494 if (length == 0) break; | 10494 if (length == 0) break; |
10495 FixedDoubleArray* elements = | 10495 FixedDoubleArray* elements = |
10496 FixedDoubleArray::cast(array->elements()); | 10496 FixedDoubleArray::cast(array->elements()); |
10497 for (uint32_t i = 0; i < length; i++) { | 10497 for (uint32_t i = 0; i < length; i++) { |
10498 if (elements->is_the_hole(i)) { | 10498 if (elements->is_the_hole(i)) { |
| 10499 // TODO(jkummerow/verwaest): We could be a bit more clever |
| 10500 // here: Check if there are no elements/getters on the |
| 10501 // prototype chain, and if so, allow creation of a holey |
| 10502 // result array. |
| 10503 // Same thing below (holey smi case). |
10499 failure = true; | 10504 failure = true; |
10500 break; | 10505 break; |
10501 } | 10506 } |
10502 double double_value = elements->get_scalar(i); | 10507 double double_value = elements->get_scalar(i); |
10503 double_storage->set(j, double_value); | 10508 double_storage->set(j, double_value); |
10504 j++; | 10509 j++; |
10505 } | 10510 } |
10506 break; | 10511 break; |
10507 } | 10512 } |
10508 case FAST_HOLEY_SMI_ELEMENTS: | 10513 case FAST_HOLEY_SMI_ELEMENTS: |
10509 case FAST_SMI_ELEMENTS: { | 10514 case FAST_SMI_ELEMENTS: { |
10510 FixedArray* elements( | 10515 FixedArray* elements( |
10511 FixedArray::cast(array->elements())); | 10516 FixedArray::cast(array->elements())); |
10512 for (uint32_t i = 0; i < length; i++) { | 10517 for (uint32_t i = 0; i < length; i++) { |
10513 Object* element = elements->get(i); | 10518 Object* element = elements->get(i); |
10514 if (element->IsTheHole()) { | 10519 if (element->IsTheHole()) { |
10515 failure = true; | 10520 failure = true; |
10516 break; | 10521 break; |
10517 } | 10522 } |
10518 int32_t int_value = Smi::cast(element)->value(); | 10523 int32_t int_value = Smi::cast(element)->value(); |
10519 double_storage->set(j, int_value); | 10524 double_storage->set(j, int_value); |
10520 j++; | 10525 j++; |
10521 } | 10526 } |
10522 break; | 10527 break; |
10523 } | 10528 } |
10524 case FAST_HOLEY_ELEMENTS: | 10529 case FAST_HOLEY_ELEMENTS: |
| 10530 case FAST_ELEMENTS: |
10525 DCHECK_EQ(0, length); | 10531 DCHECK_EQ(0, length); |
10526 break; | 10532 break; |
10527 default: | 10533 default: |
10528 UNREACHABLE(); | 10534 UNREACHABLE(); |
10529 } | 10535 } |
10530 } | 10536 } |
10531 if (failure) break; | 10537 if (failure) break; |
10532 } | 10538 } |
10533 } | 10539 } |
10534 Handle<JSArray> array = isolate->factory()->NewJSArray(0); | 10540 if (!failure) { |
10535 Smi* length = Smi::FromInt(j); | 10541 Handle<JSArray> array = isolate->factory()->NewJSArray(0); |
10536 Handle<Map> map; | 10542 Smi* length = Smi::FromInt(j); |
10537 map = JSObject::GetElementsTransitionMap(array, kind); | 10543 Handle<Map> map; |
10538 array->set_map(*map); | 10544 map = JSObject::GetElementsTransitionMap(array, kind); |
10539 array->set_length(length); | 10545 array->set_map(*map); |
10540 array->set_elements(*storage); | 10546 array->set_length(length); |
10541 return *array; | 10547 array->set_elements(*storage); |
| 10548 return *array; |
| 10549 } |
| 10550 // In case of failure, fall through. |
10542 } | 10551 } |
10543 | 10552 |
10544 Handle<FixedArray> storage; | 10553 Handle<FixedArray> storage; |
10545 if (fast_case) { | 10554 if (fast_case) { |
10546 // The backing storage array must have non-existing elements to preserve | 10555 // The backing storage array must have non-existing elements to preserve |
10547 // holes across concat operations. | 10556 // holes across concat operations. |
10548 storage = isolate->factory()->NewFixedArrayWithHoles( | 10557 storage = isolate->factory()->NewFixedArrayWithHoles( |
10549 estimate_result_length); | 10558 estimate_result_length); |
10550 } else { | 10559 } else { |
10551 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 10560 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
(...skipping 5009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15561 } | 15570 } |
15562 return NULL; | 15571 return NULL; |
15563 } | 15572 } |
15564 | 15573 |
15565 | 15574 |
15566 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15575 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15567 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15576 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15568 } | 15577 } |
15569 | 15578 |
15570 } } // namespace v8::internal | 15579 } } // namespace v8::internal |
OLD | NEW |