From: jarin@chromium.org Date: Thu, 24 Apr 2014 05:29:00 +0000 (+0000) Subject: Fix C++ type of Factory::NewFixedDoubleArray. X-Git-Tag: upstream/4.7.83~9475 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8c57b45042e2b458f831f514b0f17a24dc351fc9;p=platform%2Fupstream%2Fv8.git Fix C++ type of Factory::NewFixedDoubleArray. The change fixes the C++ type of Factory::NewFixedDoubleArray to reflect the empty array case, where we return an empty FixedArray (rather than FixedDoubleArray). R=mvstanton@chromium.org BUG= Review URL: https://codereview.chromium.org/249593002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20918 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/builtins.cc b/src/builtins.cc index f4ce991..c4ac278 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -470,7 +470,10 @@ BUILTIN(ArrayPush) { if (new_length > elms_len) { // New backing storage is needed. int capacity = new_length + (new_length >> 1) + 16; - new_elms = isolate->factory()->NewFixedDoubleArray(capacity); + // Create new backing store; since capacity > 0, we can + // safely cast to FixedDoubleArray. + new_elms = Handle::cast( + isolate->factory()->NewFixedDoubleArray(capacity)); ElementsAccessor* accessor = array->GetElementsAccessor(); accessor->CopyElements( diff --git a/src/factory.cc b/src/factory.cc index 2f5d1bd..2e405bc 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -88,23 +88,27 @@ Handle Factory::NewUninitializedFixedArray(int size) { } -Handle Factory::NewFixedDoubleArray(int size, +Handle Factory::NewFixedDoubleArray(int size, PretenureFlag pretenure) { ASSERT(0 <= size); CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), - FixedDoubleArray); + FixedArrayBase); } -Handle Factory::NewFixedDoubleArrayWithHoles( +Handle Factory::NewFixedDoubleArrayWithHoles( int size, PretenureFlag pretenure) { ASSERT(0 <= size); - Handle array = NewFixedDoubleArray(size, pretenure); - for (int i = 0; i < size; ++i) { - array->set_the_hole(i); + Handle array = NewFixedDoubleArray(size, pretenure); + if (size > 0) { + Handle double_array = + Handle::cast(array); + for (int i = 0; i < size; ++i) { + double_array->set_the_hole(i); + } } return array; } diff --git a/src/factory.h b/src/factory.h index a19f297..caabac8 100644 --- a/src/factory.h +++ b/src/factory.h @@ -33,12 +33,14 @@ class Factory V8_FINAL { Handle NewUninitializedFixedArray(int size); // Allocate a new uninitialized fixed double array. - Handle NewFixedDoubleArray( + // The function returns a pre-allocated empty fixed array for capacity = 0, + // so the return type must be the general fixed array class. + Handle NewFixedDoubleArray( int size, PretenureFlag pretenure = NOT_TENURED); // Allocate a new fixed double array with hole values. - Handle NewFixedDoubleArrayWithHoles( + Handle NewFixedDoubleArrayWithHoles( int size, PretenureFlag pretenure = NOT_TENURED); diff --git a/src/runtime.cc b/src/runtime.cc index ef7a748..b45f6e3 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -10484,12 +10484,13 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) { // dictionary. bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; - Handle storage; - if (fast_case) { - if (kind == FAST_DOUBLE_ELEMENTS) { + if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { + Handle storage = + isolate->factory()->NewFixedDoubleArray(estimate_result_length); + int j = 0; + if (estimate_result_length > 0) { Handle double_storage = - isolate->factory()->NewFixedDoubleArray(estimate_result_length); - int j = 0; + Handle::cast(storage); bool failure = false; for (int i = 0; i < argument_count; i++) { Handle obj(elements->get(i), isolate); @@ -10545,15 +10546,19 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) { } if (failure) break; } - Handle array = isolate->factory()->NewJSArray(0); - Smi* length = Smi::FromInt(j); - Handle map; - map = JSObject::GetElementsTransitionMap(array, kind); - array->set_map(*map); - array->set_length(length); - array->set_elements(*double_storage); - return *array; } + Handle array = isolate->factory()->NewJSArray(0); + Smi* length = Smi::FromInt(j); + Handle map; + map = JSObject::GetElementsTransitionMap(array, kind); + array->set_map(*map); + array->set_length(length); + array->set_elements(*storage); + return *array; + } + + Handle storage; + if (fast_case) { // The backing storage array must have non-existing elements to preserve // holes across concat operations. storage = isolate->factory()->NewFixedArrayWithHoles( diff --git a/test/mjsunit/regress/regress-empty-fixed-double-array.js b/test/mjsunit/regress/regress-empty-fixed-double-array.js new file mode 100644 index 0000000..1db9e2b --- /dev/null +++ b/test/mjsunit/regress/regress-empty-fixed-double-array.js @@ -0,0 +1,15 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --enable-slow-asserts + +function f(a, x) { + a.shift(); + a[0] = x; +} + +f([1], 1.1); +f([1], 1.1); +%OptimizeFunctionOnNextCall(f); +f([1], 1.1);