Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Unified Diff: src/x64/codegen-x64.cc

Issue 8383002: Handle COW-arrays correctly when converting smi->double fast elements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | test/mjsunit/elements-transition.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/codegen-x64.cc
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index ee40c6ef254ca124c689502cdd3c6cf40e9334ac..10eda7606e2a92f164e9a62f5a964618af3ef6de 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -182,6 +182,25 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
// -- rsp[0] : return address
// -----------------------------------
// The fail label is not actually used since we do not allocate.
+ Label allocated, cow_array;
+
+ // Check backing store for COW-ness. If the negative case, we do not have to
+ // allocate a new array, since FixedArray and FixedDoubleArray do not differ
+ // in size.
+ __ movq(r8, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
+ __ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset),
+ Heap::kFixedCOWArrayMapRootIndex);
+ __ j(equal, &cow_array);
+ __ movq(r14, r8); // Destination array equals source array.
+
+ __ bind(&allocated);
+ // r8 : source FixedArray
+ // r9 : elements array length
+ // r14: destination FixedDoubleArray
+ // Set backing store's map
+ __ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
+ __ movq(FieldOperand(r14, HeapObject::kMapOffset), rdi);
// Set transitioned map.
__ movq(FieldOperand(rdx, HeapObject::kMapOffset), rbx);
@@ -192,22 +211,38 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
kDontSaveFPRegs,
EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- // Set backing store's map
- __ movq(r8, FieldOperand(rdx, JSObject::kElementsOffset));
- __ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
- __ movq(FieldOperand(r8, HeapObject::kMapOffset), rdi);
- // Convert smis to doubles and holes to hole NaNs. Since FixedArray and
- // FixedDoubleArray do not differ in size, we do not allocate a new array.
+ // Convert smis to doubles and holes to hole NaNs. In the non-COW case the
+ // length does not have to be set since we still use the exact same field
danno 2011/10/24 15:01:47 Or even simpler: NaNs. The Array's length remains
+ // for length.
STATIC_ASSERT(FixedDoubleArray::kLengthOffset == FixedArray::kLengthOffset);
STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
- __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
- // r8 : elements array
- // r9 : elements array length
+
Label loop, entry, convert_hole;
__ movq(r15, BitCast<int64_t, uint64_t>(kHoleNanInt64), RelocInfo::NONE);
// r15: the-hole NaN
__ jmp(&entry);
+
+ // Allocate new array if the source array is a COW array.
+ __ bind(&cow_array);
+ __ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
+ __ AllocateInNewSpace(rdi, r14, r11, r15, fail, TAG_OBJECT);
+ // Set receiver's backing store.
+ __ movq(FieldOperand(rdx, JSObject::kElementsOffset), r14);
+ __ movq(r11, r14);
+ __ RecordWriteField(rdx,
+ JSObject::kElementsOffset,
+ r11,
+ r15,
+ kDontSaveFPRegs,
+ EMIT_REMEMBERED_SET,
+ OMIT_SMI_CHECK);
+ // Set backing store's length.
+ __ Integer32ToSmi(r11, r9);
+ __ movq(FieldOperand(r14, FixedDoubleArray::kLengthOffset), r11);
+ __ jmp(&allocated);
+
+ // Conversion loop.
__ bind(&loop);
__ decq(r9);
__ movq(rbx,
@@ -217,11 +252,11 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
__ JumpIfNotSmi(rbx, &convert_hole);
__ SmiToInteger32(rbx, rbx);
__ cvtlsi2sd(xmm0, rbx);
- __ movsd(FieldOperand(r8, r9, times_8, FixedDoubleArray::kHeaderSize),
+ __ movsd(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize),
xmm0);
__ jmp(&entry);
__ bind(&convert_hole);
- __ movq(FieldOperand(r8, r9, times_8, FixedDoubleArray::kHeaderSize), r15);
+ __ movq(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize), r15);
__ bind(&entry);
__ testq(r9, r9);
__ j(not_zero, &loop);
@@ -245,12 +280,12 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
// r8 : source FixedDoubleArray
// r9 : number of elements
__ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize));
- __ AllocateInNewSpace(rdi, rax, r14, r15, &gc_required, TAG_OBJECT);
- // rax: destination FixedArray
+ __ AllocateInNewSpace(rdi, r11, r14, r15, &gc_required, TAG_OBJECT);
+ // r11: destination FixedArray
__ LoadRoot(rdi, Heap::kFixedArrayMapRootIndex);
- __ movq(FieldOperand(rax, HeapObject::kMapOffset), rdi);
+ __ movq(FieldOperand(r11, HeapObject::kMapOffset), rdi);
__ Integer32ToSmi(r14, r9);
- __ movq(FieldOperand(rax, FixedArray::kLengthOffset), r14);
+ __ movq(FieldOperand(r11, FixedArray::kLengthOffset), r14);
// Prepare for conversion loop.
__ movq(rsi, BitCast<int64_t, uint64_t>(kHoleNanInt64), RelocInfo::NONE);
@@ -278,17 +313,17 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ j(equal, &convert_hole);
// Non-hole double, copy value into a heap number.
- __ AllocateHeapNumber(r11, r15, &gc_required);
- // r11: new heap number
- __ movq(FieldOperand(r11, HeapNumber::kValueOffset), r14);
- __ movq(FieldOperand(rax,
+ __ AllocateHeapNumber(rax, r15, &gc_required);
+ // rax: new heap number
+ __ movq(FieldOperand(rax, HeapNumber::kValueOffset), r14);
+ __ movq(FieldOperand(r11,
r9,
times_pointer_size,
FixedArray::kHeaderSize),
- r11);
+ rax);
__ movq(r15, r9);
- __ RecordWriteArray(rax,
- r11,
+ __ RecordWriteArray(r11,
+ rax,
r15,
kDontSaveFPRegs,
EMIT_REMEMBERED_SET,
@@ -297,7 +332,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
// Replace the-hole NaN with the-hole pointer.
__ bind(&convert_hole);
- __ movq(FieldOperand(rax,
+ __ movq(FieldOperand(r11,
r9,
times_pointer_size,
FixedArray::kHeaderSize),
@@ -317,11 +352,11 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
// Replace receiver's backing store with newly created and filled FixedArray.
- __ movq(FieldOperand(rdx, JSObject::kElementsOffset), rax);
+ __ movq(FieldOperand(rdx, JSObject::kElementsOffset), r11);
__ RecordWriteField(rdx,
JSObject::kElementsOffset,
- rax,
- rdi,
+ r11,
+ r15,
kDontSaveFPRegs,
EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | test/mjsunit/elements-transition.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698