| 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 |