Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: src/runtime.cc

Issue 468863003: Correctly handle holes when concat()ing double arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-403409.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-403409.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698