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 10523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10534 | 10534 |
10535 // If estimated number of elements is more than half of length, a | 10535 // If estimated number of elements is more than half of length, a |
10536 // fixed array (fast case) is more time and space-efficient than a | 10536 // fixed array (fast case) is more time and space-efficient than a |
10537 // dictionary. | 10537 // dictionary. |
10538 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; | 10538 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; |
10539 | 10539 |
10540 if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { | 10540 if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { |
10541 Handle<FixedArrayBase> storage = | 10541 Handle<FixedArrayBase> storage = |
10542 isolate->factory()->NewFixedDoubleArray(estimate_result_length); | 10542 isolate->factory()->NewFixedDoubleArray(estimate_result_length); |
10543 int j = 0; | 10543 int j = 0; |
| 10544 bool failure = false; |
10544 if (estimate_result_length > 0) { | 10545 if (estimate_result_length > 0) { |
10545 Handle<FixedDoubleArray> double_storage = | 10546 Handle<FixedDoubleArray> double_storage = |
10546 Handle<FixedDoubleArray>::cast(storage); | 10547 Handle<FixedDoubleArray>::cast(storage); |
10547 bool failure = false; | |
10548 for (int i = 0; i < argument_count; i++) { | 10548 for (int i = 0; i < argument_count; i++) { |
10549 Handle<Object> obj(elements->get(i), isolate); | 10549 Handle<Object> obj(elements->get(i), isolate); |
10550 if (obj->IsSmi()) { | 10550 if (obj->IsSmi()) { |
10551 double_storage->set(j, Smi::cast(*obj)->value()); | 10551 double_storage->set(j, Smi::cast(*obj)->value()); |
10552 j++; | 10552 j++; |
10553 } else if (obj->IsNumber()) { | 10553 } else if (obj->IsNumber()) { |
10554 double_storage->set(j, obj->Number()); | 10554 double_storage->set(j, obj->Number()); |
10555 j++; | 10555 j++; |
10556 } else { | 10556 } else { |
10557 JSArray* array = JSArray::cast(*obj); | 10557 JSArray* array = JSArray::cast(*obj); |
10558 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 10558 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
10559 switch (array->map()->elements_kind()) { | 10559 switch (array->map()->elements_kind()) { |
10560 case FAST_HOLEY_DOUBLE_ELEMENTS: | 10560 case FAST_HOLEY_DOUBLE_ELEMENTS: |
10561 case FAST_DOUBLE_ELEMENTS: { | 10561 case FAST_DOUBLE_ELEMENTS: { |
10562 // Empty array is FixedArray but not FixedDoubleArray. | 10562 // Empty array is FixedArray but not FixedDoubleArray. |
10563 if (length == 0) break; | 10563 if (length == 0) break; |
10564 FixedDoubleArray* elements = | 10564 FixedDoubleArray* elements = |
10565 FixedDoubleArray::cast(array->elements()); | 10565 FixedDoubleArray::cast(array->elements()); |
10566 for (uint32_t i = 0; i < length; i++) { | 10566 for (uint32_t i = 0; i < length; i++) { |
10567 if (elements->is_the_hole(i)) { | 10567 if (elements->is_the_hole(i)) { |
| 10568 // TODO(jkummerow/verwaest): We could be a bit more clever |
| 10569 // here: Check if there are no elements/getters on the |
| 10570 // prototype chain, and if so, allow creation of a holey |
| 10571 // result array. |
| 10572 // Same thing below (holey smi case). |
10568 failure = true; | 10573 failure = true; |
10569 break; | 10574 break; |
10570 } | 10575 } |
10571 double double_value = elements->get_scalar(i); | 10576 double double_value = elements->get_scalar(i); |
10572 double_storage->set(j, double_value); | 10577 double_storage->set(j, double_value); |
10573 j++; | 10578 j++; |
10574 } | 10579 } |
10575 break; | 10580 break; |
10576 } | 10581 } |
10577 case FAST_HOLEY_SMI_ELEMENTS: | 10582 case FAST_HOLEY_SMI_ELEMENTS: |
10578 case FAST_SMI_ELEMENTS: { | 10583 case FAST_SMI_ELEMENTS: { |
10579 FixedArray* elements( | 10584 FixedArray* elements( |
10580 FixedArray::cast(array->elements())); | 10585 FixedArray::cast(array->elements())); |
10581 for (uint32_t i = 0; i < length; i++) { | 10586 for (uint32_t i = 0; i < length; i++) { |
10582 Object* element = elements->get(i); | 10587 Object* element = elements->get(i); |
10583 if (element->IsTheHole()) { | 10588 if (element->IsTheHole()) { |
10584 failure = true; | 10589 failure = true; |
10585 break; | 10590 break; |
10586 } | 10591 } |
10587 int32_t int_value = Smi::cast(element)->value(); | 10592 int32_t int_value = Smi::cast(element)->value(); |
10588 double_storage->set(j, int_value); | 10593 double_storage->set(j, int_value); |
10589 j++; | 10594 j++; |
10590 } | 10595 } |
10591 break; | 10596 break; |
10592 } | 10597 } |
10593 case FAST_HOLEY_ELEMENTS: | 10598 case FAST_HOLEY_ELEMENTS: |
| 10599 case FAST_ELEMENTS: |
10594 DCHECK_EQ(0, length); | 10600 DCHECK_EQ(0, length); |
10595 break; | 10601 break; |
10596 default: | 10602 default: |
10597 UNREACHABLE(); | 10603 UNREACHABLE(); |
10598 } | 10604 } |
10599 } | 10605 } |
10600 if (failure) break; | 10606 if (failure) break; |
10601 } | 10607 } |
10602 } | 10608 } |
10603 Handle<JSArray> array = isolate->factory()->NewJSArray(0); | 10609 if (!failure) { |
10604 Smi* length = Smi::FromInt(j); | 10610 Handle<JSArray> array = isolate->factory()->NewJSArray(0); |
10605 Handle<Map> map; | 10611 Smi* length = Smi::FromInt(j); |
10606 map = JSObject::GetElementsTransitionMap(array, kind); | 10612 Handle<Map> map; |
10607 array->set_map(*map); | 10613 map = JSObject::GetElementsTransitionMap(array, kind); |
10608 array->set_length(length); | 10614 array->set_map(*map); |
10609 array->set_elements(*storage); | 10615 array->set_length(length); |
10610 return *array; | 10616 array->set_elements(*storage); |
| 10617 return *array; |
| 10618 } |
| 10619 // In case of failure, fall through. |
10611 } | 10620 } |
10612 | 10621 |
10613 Handle<FixedArray> storage; | 10622 Handle<FixedArray> storage; |
10614 if (fast_case) { | 10623 if (fast_case) { |
10615 // The backing storage array must have non-existing elements to preserve | 10624 // The backing storage array must have non-existing elements to preserve |
10616 // holes across concat operations. | 10625 // holes across concat operations. |
10617 storage = isolate->factory()->NewFixedArrayWithHoles( | 10626 storage = isolate->factory()->NewFixedArrayWithHoles( |
10618 estimate_result_length); | 10627 estimate_result_length); |
10619 } else { | 10628 } else { |
10620 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 10629 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
(...skipping 5009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15630 } | 15639 } |
15631 return NULL; | 15640 return NULL; |
15632 } | 15641 } |
15633 | 15642 |
15634 | 15643 |
15635 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15644 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15636 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15645 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15637 } | 15646 } |
15638 | 15647 |
15639 } } // namespace v8::internal | 15648 } } // namespace v8::internal |
OLD | NEW |