Fix a bug in the x64 elements transition code.
1. The write barrier (RecordWriteStub) expects that pointer stored points to an initialized object. Specifically, the map must be set before it is stored. 2. The backing store for smi-only elements can only be reused for double elements if it is in new-space. Otherwise, we need to allocate a fresh one because the old one is in pointer-space and the new one has to be in data-space. BUG=117037 Review URL: https://chromiumcodereview.appspot.com/9633017 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10968 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
7d20d0b1d8
commit
068c6e5014
@ -228,7 +228,7 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
|
|||||||
// -- rsp[0] : return address
|
// -- rsp[0] : return address
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// The fail label is not actually used since we do not allocate.
|
// The fail label is not actually used since we do not allocate.
|
||||||
Label allocated, cow_array, only_change_map, done;
|
Label allocated, new_backing_store, only_change_map, done;
|
||||||
|
|
||||||
// Check for empty arrays, which only require a map transition and no changes
|
// Check for empty arrays, which only require a map transition and no changes
|
||||||
// to the backing store.
|
// to the backing store.
|
||||||
@ -236,16 +236,20 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
|
|||||||
__ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex);
|
__ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex);
|
||||||
__ j(equal, &only_change_map);
|
__ j(equal, &only_change_map);
|
||||||
|
|
||||||
// Check backing store for COW-ness. If the negative case, we do not have to
|
// Check backing store for COW-ness. For COW arrays we have to
|
||||||
// allocate a new array, since FixedArray and FixedDoubleArray do not differ
|
// allocate a new backing store.
|
||||||
// in size.
|
|
||||||
__ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
|
__ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
|
||||||
__ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset),
|
__ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset),
|
||||||
Heap::kFixedCOWArrayMapRootIndex);
|
Heap::kFixedCOWArrayMapRootIndex);
|
||||||
__ j(equal, &cow_array);
|
__ j(equal, &new_backing_store);
|
||||||
|
// Check if the backing store is in new-space. If not, we need to allocate
|
||||||
|
// a new one since the old one is in pointer-space.
|
||||||
|
// If in new space, we can reuse the old backing store because it is
|
||||||
|
// the same size.
|
||||||
|
__ JumpIfNotInNewSpace(r8, rdi, &new_backing_store);
|
||||||
|
|
||||||
__ movq(r14, r8); // Destination array equals source array.
|
__ movq(r14, r8); // Destination array equals source array.
|
||||||
|
|
||||||
__ bind(&allocated);
|
|
||||||
// r8 : source FixedArray
|
// r8 : source FixedArray
|
||||||
// r9 : elements array length
|
// r9 : elements array length
|
||||||
// r14: destination FixedDoubleArray
|
// r14: destination FixedDoubleArray
|
||||||
@ -253,6 +257,7 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
|
|||||||
__ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
|
__ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
|
||||||
__ movq(FieldOperand(r14, HeapObject::kMapOffset), rdi);
|
__ movq(FieldOperand(r14, HeapObject::kMapOffset), rdi);
|
||||||
|
|
||||||
|
__ bind(&allocated);
|
||||||
// Set transitioned map.
|
// Set transitioned map.
|
||||||
__ movq(FieldOperand(rdx, HeapObject::kMapOffset), rbx);
|
__ movq(FieldOperand(rdx, HeapObject::kMapOffset), rbx);
|
||||||
__ RecordWriteField(rdx,
|
__ RecordWriteField(rdx,
|
||||||
@ -273,10 +278,13 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
|
|||||||
// r15: the-hole NaN
|
// r15: the-hole NaN
|
||||||
__ jmp(&entry);
|
__ jmp(&entry);
|
||||||
|
|
||||||
// Allocate new array if the source array is a COW array.
|
// Allocate new backing store.
|
||||||
__ bind(&cow_array);
|
__ bind(&new_backing_store);
|
||||||
__ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
|
__ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
|
||||||
__ AllocateInNewSpace(rdi, r14, r11, r15, fail, TAG_OBJECT);
|
__ AllocateInNewSpace(rdi, r14, r11, r15, fail, TAG_OBJECT);
|
||||||
|
// Set backing store's map
|
||||||
|
__ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
|
||||||
|
__ movq(FieldOperand(r14, HeapObject::kMapOffset), rdi);
|
||||||
// Set receiver's backing store.
|
// Set receiver's backing store.
|
||||||
__ movq(FieldOperand(rdx, JSObject::kElementsOffset), r14);
|
__ movq(FieldOperand(rdx, JSObject::kElementsOffset), r14);
|
||||||
__ movq(r11, r14);
|
__ movq(r11, r14);
|
||||||
|
Loading…
Reference in New Issue
Block a user