case FAST_DOUBLE_ELEMENTS: {
int length = IsJSArray()
? Smi::cast(JSArray::cast(this)->length())->value()
- : FixedArray::cast(elements())->length();
+ : FixedDoubleArray::cast(elements())->length();
if (index < static_cast<uint32_t>(length)) {
FixedDoubleArray::cast(elements())->set_the_hole(index);
}
if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
const int value = Smi::cast(smi_length)->value();
if (value < 0) return ArrayLengthRangeError(GetHeap());
- switch (GetElementsKind()) {
- case FAST_ELEMENTS: {
- int old_capacity = FixedArray::cast(elements())->length();
+ JSObject::ElementsKind elements_kind = GetElementsKind();
+ switch (elements_kind) {
+ case FAST_ELEMENTS:
+ case FAST_DOUBLE_ELEMENTS: {
+ int old_capacity = FixedArrayBase::cast(elements())->length();
if (value <= old_capacity) {
if (IsJSArray()) {
Object* obj;
- { MaybeObject* maybe_obj = EnsureWritableFastElements();
+ if (elements_kind == FAST_ELEMENTS) {
+ MaybeObject* maybe_obj = EnsureWritableFastElements();
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
- FixedArray* fast_elements = FixedArray::cast(elements());
if (2 * value <= old_capacity) {
// If more than half the elements won't be used, trim the array.
if (value == 0) {
initialize_elements();
} else {
- fast_elements->set_length(value);
- Address filler_start = fast_elements->address() +
- FixedArray::OffsetOfElementAt(value);
- int filler_size = (old_capacity - value) * kPointerSize;
+ Address filler_start;
+ int filler_size;
+ if (GetElementsKind() == FAST_ELEMENTS) {
+ FixedArray* fast_elements = FixedArray::cast(elements());
+ fast_elements->set_length(value);
+ filler_start = fast_elements->address() +
+ FixedArray::OffsetOfElementAt(value);
+ filler_size = (old_capacity - value) * kPointerSize;
+ } else {
+ ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+ FixedDoubleArray* fast_double_elements =
+ FixedDoubleArray::cast(elements());
+ fast_double_elements->set_length(value);
+ filler_start = fast_double_elements->address() +
+ FixedDoubleArray::OffsetOfElementAt(value);
+ filler_size = (old_capacity - value) * kDoubleSize;
+ }
GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
}
} else {
// Otherwise, fill the unused tail with holes.
int old_length = FastD2I(JSArray::cast(this)->length()->Number());
- for (int i = value; i < old_length; i++) {
- fast_elements->set_the_hole(i);
+ if (GetElementsKind() == FAST_ELEMENTS) {
+ FixedArray* fast_elements = FixedArray::cast(elements());
+ for (int i = value; i < old_length; i++) {
+ fast_elements->set_the_hole(i);
+ }
+ } else {
+ ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+ FixedDoubleArray* fast_double_elements =
+ FixedDoubleArray::cast(elements());
+ for (int i = value; i < old_length; i++) {
+ fast_double_elements->set_the_hole(i);
+ }
}
}
JSArray::cast(this)->set_length(Smi::cast(smi_length));
int new_capacity = value > min ? value : min;
if (new_capacity <= kMaxFastElementsLength ||
!ShouldConvertToSlowElements(new_capacity)) {
- MaybeObject* result =
- SetFastElementsCapacityAndLength(new_capacity, value);
+ MaybeObject* result;
+ if (GetElementsKind() == FAST_ELEMENTS) {
+ result = SetFastElementsCapacityAndLength(new_capacity, value);
+ } else {
+ ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
+ result = SetFastDoubleElementsCapacityAndLength(new_capacity,
+ value);
+ }
if (result->IsFailure()) return result;
return this;
}
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
case EXTERNAL_PIXEL_ELEMENTS:
- case FAST_DOUBLE_ELEMENTS:
UNREACHABLE();
break;
}
// Test dictionary -> double elements -> dictionary elements round trip
// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
-var large_array_size = 500000;
-var approx_dict_to_elements_threshold = 69000;
+var large_array_size = 100000;
+var approx_dict_to_elements_threshold = 75000;
var name = 0;
}
function force_to_fast_double_array(a) {
+ a[large_array_size - 2] = 1;
for (var i= 0; i < approx_dict_to_elements_threshold; ++i ) {
a[i] = expected_array_value(i);
}
assertTrue(%HasFastDoubleElements(a));
}
+function make_object_like_array(size) {
+ obj = new Object();
+ obj.length = size;
+ return obj;
+}
+
function testOneArrayType(allocator) {
- var large_array = new allocator(500000);
+ var large_array = new allocator(large_array_size);
force_to_fast_double_array(large_array);
var six = 6;
// Make sure that we haven't converted from fast double.
assertTrue(%HasFastDoubleElements(large_array));
- // Cause the array to grow beyond it's JSArray length. This will double the
- // size of the capacity and force the array into "slow" dictionary case.
- large_array[large_array_size+1] = 50;
- assertTrue(%HasDictionaryElements(large_array));
- assertEquals(50, large_array[large_array_size+1]);
- assertEquals(large_array_size+2, large_array.length);
- assertEquals(Infinity, large_array[5]);
- assertEquals(undefined, large_array[large_array_size-1]);
- assertEquals(undefined, large_array[-1]);
- assertEquals(large_array_size+2, large_array.length);
-
- // Test dictionary -> double elements -> fast elements.
- var large_array2 = new allocator(large_array_size);
- force_to_fast_double_array(large_array2);
- delete large_array2[5];
-
- // Convert back to fast elements and make sure the contents of the array are
- // unchanged.
- large_array2[25] = new Object();
- assertTrue(%HasFastElements(large_array2));
- for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) {
- if (i != 25 && i != 5) {
- assertEquals(expected_array_value(i), large_array2[i]);
- }
- }
- assertEquals(undefined, large_array2[5])
- assertEquals(undefined, large_array2[large_array_size-1])
- assertEquals(undefined, large_array2[-1])
- assertEquals(large_array_size, large_array2.length);
}
+testOneArrayType(make_object_like_array);
testOneArrayType(Array);
+
+var large_array = new Array(large_array_size);
+force_to_fast_double_array(large_array);
+assertTrue(%HasFastDoubleElements(large_array));
+
+// Cause the array to grow beyond it's JSArray length. This will double the
+// size of the capacity and force the array into "slow" dictionary case.
+large_array[5] = Infinity;
+large_array[large_array_size+10001] = 50;
+assertTrue(%HasDictionaryElements(large_array));
+assertEquals(50, large_array[large_array_size+10001]);
+assertEquals(large_array_size+10002, large_array.length);
+assertEquals(Infinity, large_array[5]);
+assertEquals(undefined, large_array[large_array_size-1]);
+assertEquals(undefined, large_array[-1]);
+assertEquals(large_array_size+10002, large_array.length);
+
+// Test dictionary -> double elements -> fast elements.
+var large_array2 = new Array(large_array_size);
+force_to_fast_double_array(large_array2);
+delete large_array2[5];
+
+// Convert back to fast elements and make sure the contents of the array are
+// unchanged.
+large_array2[25] = new Object();
+assertTrue(%HasFastElements(large_array2));
+for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) {
+ if (i != 25 && i != 5) {
+ assertEquals(expected_array_value(i), large_array2[i]);
+ }
+}
+assertEquals(undefined, large_array2[5]);
+assertEquals(undefined, large_array2[large_array_size-1]);
+assertEquals(undefined, large_array2[-1]);
+assertEquals(large_array_size, large_array2.length);
+
+// Make sure it's possible to change the array's length and that array is still
+// intact after the resize.
+var large_array3 = new Array(large_array_size);
+force_to_fast_double_array(large_array3);
+large_array3.length = 60000;
+assertEquals(60000, large_array3.length);
+assertEquals(undefined, large_array3[60000]);
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(expected_array_value(large_array3.length-1),
+ large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();
+
+for (var i= 0; i < large_array3.length; i += 501 ) {
+ assertEquals(expected_array_value(i), large_array3[i]);
+}
+
+large_array3.length = 25;
+assertEquals(25, large_array3.length);
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(undefined, large_array3[25]);
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(expected_array_value(large_array3.length-1),
+ large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();
+
+for (var i= 0; i < large_array3.length; ++i) {
+ assertEquals(expected_array_value(i), large_array3[i]);
+}
+
+large_array3.length = 100;
+assertEquals(100, large_array3.length);
+large_array3[95] = 95;
+assertTrue(%HasFastDoubleElements(large_array3));
+assertEquals(undefined, large_array3[100]);
+assertEquals(95, large_array3[95]);
+assertEquals(expected_array_value(5), large_array3[5]);
+assertEquals(expected_array_value(6), large_array3[6]);
+assertEquals(expected_array_value(7), large_array3[7]);
+assertEquals(undefined, large_array3[large_array3.length-1]);
+assertEquals(undefined, large_array3[large_array_size-1]);
+assertEquals(undefined, large_array3[-1]);
+gc();