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 JSObject::AllowsSetElementsLength() {
|
||||||
bool result = elements()->IsFixedArray() ||
|
bool result = elements()->IsFixedArray();
|
||||||
elements()->IsFixedDoubleArray();
|
|
||||||
ASSERT(result == !HasExternalArrayElements());
|
ASSERT(result == !HasExternalArrayElements());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3207,7 +3207,7 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
|||||||
case FAST_DOUBLE_ELEMENTS: {
|
case FAST_DOUBLE_ELEMENTS: {
|
||||||
int length = IsJSArray()
|
int length = IsJSArray()
|
||||||
? Smi::cast(JSArray::cast(this)->length())->value()
|
? Smi::cast(JSArray::cast(this)->length())->value()
|
||||||
: FixedDoubleArray::cast(elements())->length();
|
: FixedArray::cast(elements())->length();
|
||||||
if (index < static_cast<uint32_t>(length)) {
|
if (index < static_cast<uint32_t>(length)) {
|
||||||
FixedDoubleArray::cast(elements())->set_the_hole(index);
|
FixedDoubleArray::cast(elements())->set_the_hole(index);
|
||||||
}
|
}
|
||||||
@ -7628,55 +7628,32 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
|
|||||||
const int value = Smi::cast(smi_length)->value();
|
const int value = Smi::cast(smi_length)->value();
|
||||||
if (value < 0) return ArrayLengthRangeError(GetHeap());
|
if (value < 0) return ArrayLengthRangeError(GetHeap());
|
||||||
switch (GetElementsKind()) {
|
switch (GetElementsKind()) {
|
||||||
case FAST_ELEMENTS:
|
case FAST_ELEMENTS: {
|
||||||
case FAST_DOUBLE_ELEMENTS: {
|
int old_capacity = FixedArray::cast(elements())->length();
|
||||||
int old_capacity = FixedArrayBase::cast(elements())->length();
|
|
||||||
if (value <= old_capacity) {
|
if (value <= old_capacity) {
|
||||||
if (IsJSArray()) {
|
if (IsJSArray()) {
|
||||||
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;
|
Object* obj;
|
||||||
{ MaybeObject* maybe_obj = EnsureWritableFastElements();
|
{ MaybeObject* maybe_obj = EnsureWritableFastElements();
|
||||||
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
||||||
}
|
}
|
||||||
FixedArray* fast_elements = FixedArray::cast(elements());
|
FixedArray* fast_elements = FixedArray::cast(elements());
|
||||||
fast_elements->set_length(value);
|
if (2 * value <= old_capacity) {
|
||||||
filler_start = fast_elements->address() +
|
// If more than half the elements won't be used, trim the array.
|
||||||
FixedArray::OffsetOfElementAt(value);
|
if (value == 0) {
|
||||||
filler_size = (old_capacity - value) * kPointerSize;
|
initialize_elements();
|
||||||
} else {
|
} else {
|
||||||
ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
|
fast_elements->set_length(value);
|
||||||
FixedDoubleArray* fast_double_elements =
|
Address filler_start = fast_elements->address() +
|
||||||
FixedDoubleArray::cast(elements());
|
FixedArray::OffsetOfElementAt(value);
|
||||||
fast_double_elements->set_length(value);
|
int filler_size = (old_capacity - value) * kPointerSize;
|
||||||
filler_start = fast_double_elements->address() +
|
|
||||||
FixedDoubleArray::OffsetOfElementAt(value);
|
|
||||||
filler_size = (old_capacity - value) * kDoubleSize;
|
|
||||||
}
|
|
||||||
GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
|
GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, fill the unused tail with holes.
|
// Otherwise, fill the unused tail with holes.
|
||||||
int old_length = FastD2I(JSArray::cast(this)->length()->Number());
|
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++) {
|
for (int i = value; i < old_length; i++) {
|
||||||
fast_elements->set_the_hole(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));
|
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;
|
int new_capacity = value > min ? value : min;
|
||||||
if (new_capacity <= kMaxFastElementsLength ||
|
if (new_capacity <= kMaxFastElementsLength ||
|
||||||
!ShouldConvertToSlowElements(new_capacity)) {
|
!ShouldConvertToSlowElements(new_capacity)) {
|
||||||
MaybeObject* result;
|
MaybeObject* result =
|
||||||
if (GetElementsKind() == FAST_ELEMENTS) {
|
SetFastElementsCapacityAndLength(new_capacity, value);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (result->IsFailure()) return result;
|
if (result->IsFailure()) return result;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -7733,6 +7700,7 @@ MaybeObject* JSObject::SetElementsLength(Object* len) {
|
|||||||
case EXTERNAL_FLOAT_ELEMENTS:
|
case EXTERNAL_FLOAT_ELEMENTS:
|
||||||
case EXTERNAL_DOUBLE_ELEMENTS:
|
case EXTERNAL_DOUBLE_ELEMENTS:
|
||||||
case EXTERNAL_PIXEL_ELEMENTS:
|
case EXTERNAL_PIXEL_ELEMENTS:
|
||||||
|
case FAST_DOUBLE_ELEMENTS:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2169,9 +2169,6 @@ class FixedDoubleArray: public FixedArrayBase {
|
|||||||
return kHeaderSize + length * kDoubleSize;
|
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 bool is_the_hole_nan(double value);
|
||||||
inline static double hole_nan_as_double();
|
inline static double hole_nan_as_double();
|
||||||
inline static double canonical_not_the_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
|
// Test dictionary -> double elements -> dictionary elements round trip
|
||||||
|
|
||||||
// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
|
// Flags: --allow-natives-syntax --unbox-double-arrays --expose-gc
|
||||||
var large_array_size = 100000;
|
var large_array_size = 500000;
|
||||||
var approx_dict_to_elements_threshold = 75000;
|
var approx_dict_to_elements_threshold = 69000;
|
||||||
|
|
||||||
var name = 0;
|
var name = 0;
|
||||||
|
|
||||||
@ -42,21 +42,14 @@ function expected_array_value(i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function force_to_fast_double_array(a) {
|
function force_to_fast_double_array(a) {
|
||||||
a[large_array_size - 2] = 1;
|
|
||||||
for (var i= 0; i < approx_dict_to_elements_threshold; ++i ) {
|
for (var i= 0; i < approx_dict_to_elements_threshold; ++i ) {
|
||||||
a[i] = expected_array_value(i);
|
a[i] = expected_array_value(i);
|
||||||
}
|
}
|
||||||
assertTrue(%HasFastDoubleElements(a));
|
assertTrue(%HasFastDoubleElements(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_object_like_array(size) {
|
|
||||||
obj = new Object();
|
|
||||||
obj.length = size;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
function testOneArrayType(allocator) {
|
function testOneArrayType(allocator) {
|
||||||
var large_array = new allocator(large_array_size);
|
var large_array = new allocator(500000);
|
||||||
force_to_fast_double_array(large_array);
|
force_to_fast_double_array(large_array);
|
||||||
var six = 6;
|
var six = 6;
|
||||||
|
|
||||||
@ -326,94 +319,35 @@ function testOneArrayType(allocator) {
|
|||||||
|
|
||||||
// Make sure that we haven't converted from fast double.
|
// Make sure that we haven't converted from fast double.
|
||||||
assertTrue(%HasFastDoubleElements(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[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);
|
// Test dictionary -> double elements -> fast elements.
|
||||||
testOneArrayType(Array);
|
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);
|
// Convert back to fast elements and make sure the contents of the array are
|
||||||
force_to_fast_double_array(large_array);
|
// unchanged.
|
||||||
assertTrue(%HasFastDoubleElements(large_array));
|
large_array2[25] = new Object();
|
||||||
|
assertTrue(%HasFastElements(large_array2));
|
||||||
// Cause the array to grow beyond it's JSArray length. This will double the
|
for (var i= 0; i < approx_dict_to_elements_threshold; i += 500 ) {
|
||||||
// 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) {
|
if (i != 25 && i != 5) {
|
||||||
assertEquals(expected_array_value(i), large_array2[i]);
|
assertEquals(expected_array_value(i), large_array2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals(undefined, large_array2[5]);
|
assertEquals(undefined, large_array2[5])
|
||||||
assertEquals(undefined, large_array2[large_array_size-1]);
|
assertEquals(undefined, large_array2[large_array_size-1])
|
||||||
assertEquals(undefined, large_array2[-1]);
|
assertEquals(undefined, large_array2[-1])
|
||||||
assertEquals(large_array_size, large_array2.length);
|
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;
|
testOneArrayType(Array);
|
||||||
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();
|
|
||||||
|
Loading…
Reference in New Issue
Block a user