Rollback 8683: Implement setting the length property for FixedDoubleArrays
R=ager@chromium.org BUG=none TEST=none Review URL: http://codereview.chromium.org/7448002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8684 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
837d83ebf3
commit
a1e851e916
@ -4007,8 +4007,7 @@ bool JSObject::HasIndexedInterceptor() {
|
||||
|
||||
|
||||
bool JSObject::AllowsSetElementsLength() {
|
||||
bool result = elements()->IsFixedArray() ||
|
||||
elements()->IsFixedDoubleArray();
|
||||
bool result = elements()->IsFixedArray();
|
||||
ASSERT(result == !HasExternalArrayElements());
|
||||
return result;
|
||||
}
|
||||
|
@ -3207,7 +3207,7 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
||||
case FAST_DOUBLE_ELEMENTS: {
|
||||
int length = IsJSArray()
|
||||
? Smi::cast(JSArray::cast(this)->length())->value()
|
||||
: FixedDoubleArray::cast(elements())->length();
|
||||
: FixedArray::cast(elements())->length();
|
||||
if (index < static_cast<uint32_t>(length)) {
|
||||
FixedDoubleArray::cast(elements())->set_the_hole(index);
|
||||
}
|
||||
@ -7628,54 +7628,31 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
|
||||
const int value = Smi::cast(smi_length)->value();
|
||||
if (value < 0) return ArrayLengthRangeError(GetHeap());
|
||||
switch (GetElementsKind()) {
|
||||
case FAST_ELEMENTS:
|
||||
case FAST_DOUBLE_ELEMENTS: {
|
||||
int old_capacity = FixedArrayBase::cast(elements())->length();
|
||||
case FAST_ELEMENTS: {
|
||||
int old_capacity = FixedArray::cast(elements())->length();
|
||||
if (value <= old_capacity) {
|
||||
if (IsJSArray()) {
|
||||
Object* obj;
|
||||
{ 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 {
|
||||
Address filler_start;
|
||||
int filler_size;
|
||||
if (GetElementsKind() == FAST_ELEMENTS) {
|
||||
Object* obj;
|
||||
{ MaybeObject* maybe_obj = EnsureWritableFastElements();
|
||||
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
||||
}
|
||||
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;
|
||||
}
|
||||
fast_elements->set_length(value);
|
||||
Address filler_start = fast_elements->address() +
|
||||
FixedArray::OffsetOfElementAt(value);
|
||||
int filler_size = (old_capacity - value) * kPointerSize;
|
||||
GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, fill the unused tail with holes.
|
||||
int old_length = FastD2I(JSArray::cast(this)->length()->Number());
|
||||
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);
|
||||
}
|
||||
for (int i = value; i < old_length; i++) {
|
||||
fast_elements->set_the_hole(i);
|
||||
}
|
||||
}
|
||||
JSArray::cast(this)->set_length(Smi::cast(smi_length));
|
||||
@ -7686,18 +7663,8 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
|
||||
int new_capacity = value > min ? value : min;
|
||||
if (new_capacity <= kMaxFastElementsLength ||
|
||||
!ShouldConvertToSlowElements(new_capacity)) {
|
||||
MaybeObject* result;
|
||||
if (GetElementsKind() == FAST_ELEMENTS) {
|
||||
Object* obj;
|
||||
{ MaybeObject* maybe_obj = EnsureWritableFastElements();
|
||||
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
||||
}
|
||||
result = SetFastElementsCapacityAndLength(new_capacity, value);
|
||||
} else {
|
||||
ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
|
||||
result = SetFastDoubleElementsCapacityAndLength(new_capacity,
|
||||
value);
|
||||
}
|
||||
MaybeObject* result =
|
||||
SetFastElementsCapacityAndLength(new_capacity, value);
|
||||
if (result->IsFailure()) return result;
|
||||
return this;
|
||||
}
|
||||
@ -7733,6 +7700,7 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
|
||||
case EXTERNAL_FLOAT_ELEMENTS:
|
||||
case EXTERNAL_DOUBLE_ELEMENTS:
|
||||
case EXTERNAL_PIXEL_ELEMENTS:
|
||||
case FAST_DOUBLE_ELEMENTS:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
@ -2169,9 +2169,6 @@ class FixedDoubleArray: public FixedArrayBase {
|
||||
return kHeaderSize + length * kDoubleSize;
|
||||
}
|
||||
|
||||
// Code Generation support.
|
||||
static int OffsetOfElementAt(int index) { return SizeFor(index); }
|
||||
|
||||
inline static bool is_the_hole_nan(double value);
|
||||
inline static double hole_nan_as_double();
|
||||
inline static double canonical_not_the_hole_nan_as_double();
|
||||
|
@ -28,8 +28,8 @@
|
||||
// Test dictionary -> double elements -> dictionary elements round trip
|
||||
|
||||
// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
|
||||
var large_array_size = 100000;
|
||||
var approx_dict_to_elements_threshold = 75000;
|
||||
var large_array_size = 500000;
|
||||
var approx_dict_to_elements_threshold = 69000;
|
||||
|
||||
var name = 0;
|
||||
|
||||
@ -42,21 +42,14 @@ function expected_array_value(i) {
|
||||
}
|
||||
|
||||
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(large_array_size);
|
||||
var large_array = new allocator(500000);
|
||||
force_to_fast_double_array(large_array);
|
||||
var six = 6;
|
||||
|
||||
@ -326,94 +319,35 @@ function testOneArrayType(allocator) {
|
||||
|
||||
// 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);
|
||||
|
||||
testOneArrayType(make_object_like_array);
|
||||
testOneArrayType(Array);
|
||||
// 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];
|
||||
|
||||
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]);
|
||||
// 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]);
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
testOneArrayType(Array);
|
||||
|
Loading…
Reference in New Issue
Block a user