Create stub and runtime function for x64 full-codegen array literal element initializ...
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 8 Nov 2011 10:10:24 +0000 (10:10 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 8 Nov 2011 10:10:24 +0000 (10:10 +0000)
R=svenpanne@chromium.org
BUG=none
TEST=none

Review URL: http://codereview.chromium.org/8493024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9903 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/x64/code-stubs-x64.cc
src/x64/full-codegen-x64.cc

index 8a00b898741fcb65d008cae326c450e9f7b203ac..672be58db3643cf872b5e93a0f6b981b3adfc93e 100644 (file)
@@ -5702,6 +5702,8 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
   { rdx, r11, r15, EMIT_REMEMBERED_SET},
   // ElementsTransitionGenerator::GenerateDoubleToObject
   { r11, rax, r15, EMIT_REMEMBERED_SET},
+  // StoreArrayLiteralElementStub::Generate
+  { rbx, rax, rcx, EMIT_REMEMBERED_SET},
   // Null termination.
   { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET}
 };
@@ -5949,6 +5951,87 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
   // Fall through when we need to inform the incremental marker.
 }
 
+
+void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : element value to store
+  //  -- rbx    : array literal
+  //  -- rdi    : map of array literal
+  //  -- rcx    : element index as smi
+  //  -- rdx    : array literal index in function
+  //  -- rsp[0] : return address
+  // -----------------------------------
+
+  Label element_done;
+  Label double_elements;
+  Label smi_element;
+  Label slow_elements;
+  Label fast_elements;
+
+  if (!FLAG_trace_elements_transitions) {
+    __ CheckFastElements(rdi, &double_elements);
+
+    // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS
+    __ JumpIfSmi(rax, &smi_element);
+    __ CheckFastSmiOnlyElements(rdi, &fast_elements);
+
+    // Store into the array literal requires a elements transition. Call into
+    // the runtime.
+  }
+
+  __ bind(&slow_elements);
+  __ pop(rdi);  // Pop return address and remember to put back later for tail
+                // call.
+  __ push(rbx);
+  __ push(rcx);
+  __ push(rax);
+  __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+  __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
+  __ push(rdx);
+  __ push(rdi);  // Return return address so that tail call returns to right
+                 // place.
+  __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
+
+  if (!FLAG_trace_elements_transitions) {
+    // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
+    __ bind(&double_elements);
+
+    __ movq(r9, FieldOperand(rbx, JSObject::kElementsOffset));
+    __ SmiToInteger32(r10, rcx);
+    __ StoreNumberToDoubleElements(rax,
+                                   r9,
+                                   r10,
+                                   xmm0,
+                                   &slow_elements);
+    __ jmp(&element_done);
+
+    // Array literal has ElementsKind of FAST_ELEMENTS and value is an object.
+    __ bind(&fast_elements);
+    __ SmiToInteger32(r10, rcx);
+    __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
+    __ lea(rcx, FieldOperand(rbx, r10, times_pointer_size,
+                             FixedArrayBase::kHeaderSize));
+    __ movq(Operand(rcx, 0), rax);
+    // Update the write barrier for the array store.
+    __ RecordWrite(rbx, rcx, rax,
+                   kDontSaveFPRegs,
+                   EMIT_REMEMBERED_SET,
+                   OMIT_SMI_CHECK);
+    __ jmp(&element_done);
+
+    // Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or
+    // FAST_ELEMENTS, and value is Smi.
+    __ bind(&smi_element);
+    __ SmiToInteger32(r10, rcx);
+    __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
+    __ movq(FieldOperand(rbx, r10, times_pointer_size,
+                        FixedArrayBase::kHeaderSize), rax);
+    // Fall through
+    __ bind(&element_done);
+    __ ret(0);
+  }
+}
+
 #undef __
 
 } }  // namespace v8::internal
index a80a8b792e8dd8fe66d17c9846472bf15aad7e60..55c70d425aa800705c8dba04cce4211ab218163b 100644 (file)
@@ -1493,60 +1493,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
     VisitForAccumulatorValue(subexpr);
 
     // Store the subexpression value in the array's elements.
-    __ movq(r8, Operand(rsp, 0));  // Copy of array literal.
-    __ movq(rdi, FieldOperand(r8, JSObject::kMapOffset));
-    __ movq(rbx, FieldOperand(r8, JSObject::kElementsOffset));
-    int offset = FixedArray::kHeaderSize + (i * kPointerSize);
-
-    Label element_done;
-    Label double_elements;
-    Label smi_element;
-    Label slow_elements;
-    Label fast_elements;
-    __ CheckFastElements(rdi, &double_elements);
-
-    // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS
-    __ JumpIfSmi(result_register(), &smi_element);
-    __ CheckFastSmiOnlyElements(rdi, &fast_elements);
-
-    // Store into the array literal requires a elements transition. Call into
-    // the runtime.
-    __ bind(&slow_elements);
-    __ push(r8);  // Copy of array literal.
-    __ Push(Smi::FromInt(i));
-    __ push(result_register());
-    __ Push(Smi::FromInt(NONE));  // PropertyAttributes
-    __ Push(Smi::FromInt(strict_mode_flag()));  // Strict mode.
-    __ CallRuntime(Runtime::kSetProperty, 5);
-    __ jmp(&element_done);
-
-    // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
-    __ bind(&double_elements);
-    __ movq(rcx, Immediate(i));
-    __ StoreNumberToDoubleElements(result_register(),
-                                   rbx,
-                                   rcx,
-                                   xmm0,
-                                   &slow_elements);
-    __ jmp(&element_done);
-
-    // Array literal has ElementsKind of FAST_ELEMENTS and value is an object.
-    __ bind(&fast_elements);
-    __ movq(FieldOperand(rbx, offset), result_register());
-    // Update the write barrier for the array store.
-    __ RecordWriteField(rbx, offset, result_register(), rcx,
-                        kDontSaveFPRegs,
-                        EMIT_REMEMBERED_SET,
-                        OMIT_SMI_CHECK);
-    __ jmp(&element_done);
-
-    // Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or
-    // FAST_ELEMENTS, and value is Smi.
-    __ bind(&smi_element);
-    __ movq(FieldOperand(rbx, offset), result_register());
-    // Fall through
-
-    __ bind(&element_done);
+    __ movq(rbx, Operand(rsp, 0));  // Copy of array literal.
+    __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
+    __ Move(rcx, Smi::FromInt(i));
+    __ movq(rdx, Immediate(expr->literal_index()));
+    StoreArrayLiteralElementStub stub;
+    __ CallStub(&stub);
 
     PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
   }