Revision: 9411
Author:   [email protected]
Date:     Fri Sep 23 02:31:20 2011
Log:      Porting r9392 to arm (smi-only arrays).

Review URL: http://codereview.chromium.org/7995002
http://code.google.com/p/v8/source/detail?r=9411

Modified:
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/arm/ic-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.h
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Sep 21 07:46:54 2011 +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Sep 23 02:31:20 2011
@@ -1504,15 +1504,25 @@
     VisitForAccumulatorValue(subexpr);

     // Store the subexpression value in the array's elements.
-    __ ldr(r1, MemOperand(sp));  // Copy of array literal.
-    __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
+    __ ldr(r6, MemOperand(sp));  // Copy of array literal.
+    __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset));
     int offset = FixedArray::kHeaderSize + (i * kPointerSize);
     __ str(result_register(), FieldMemOperand(r1, offset));

+    Label no_map_change;
+    __ JumpIfSmi(result_register(), &no_map_change);
     // Update the write barrier for the array store with r0 as the scratch
     // register.
     __ RecordWriteField(
- r1, offset, result_register(), r2, kLRHasBeenSaved, kDontSaveFPRegs); + r1, offset, result_register(), r2, kLRHasBeenSaved, kDontSaveFPRegs,
+        EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+    if (FLAG_smi_only_arrays) {
+      __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+      __ CheckFastSmiOnlyElements(r3, r2, &no_map_change);
+      __ push(r6);  // Copy of array literal.
+      __ CallRuntime(Runtime::kNonSmiElementStored, 1);
+    }
+    __ bind(&no_map_change);

     PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
   }
=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc   Mon Sep 19 11:36:47 2011
+++ /branches/bleeding_edge/src/arm/ic-arm.cc   Fri Sep 23 02:31:20 2011
@@ -1360,6 +1360,20 @@
   __ bind(&fast);
   Register scratch_value = r4;
   Register address = r5;
+  if (FLAG_smi_only_arrays) {
+    Label not_smi_only;
+    // Make sure the elements are smi-only.
+ __ ldr(scratch_value, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ CheckFastSmiOnlyElements(scratch_value, scratch_value, &not_smi_only);
+    // Non-smis need to call into the runtime if the array is smi only.
+    __ JumpIfNotSmi(value, &slow);
+    __ add(address, elements,
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+    __ str(value, MemOperand(address));
+    __ Ret();
+    __ bind(&not_smi_only);
+  }
   // Fast case, store the value to the elements backing store.
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Sep 22 04:30:04 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Sep 23 02:31:20 2011
@@ -1865,6 +1865,29 @@
   cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
   b(hi, fail);
 }
+
+
+void MacroAssembler::CheckFastObjectElements(Register map,
+                                             Register scratch,
+                                             Label* fail) {
+  STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
+  STATIC_ASSERT(FAST_ELEMENTS == 1);
+  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  cmp(scratch, Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
+  b(ls, fail);
+  cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
+  b(hi, fail);
+}
+
+
+void MacroAssembler::CheckFastSmiOnlyElements(Register map,
+                                              Register scratch,
+                                              Label* fail) {
+  STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
+  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  cmp(scratch, Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
+  b(hi, fail);
+}


 void MacroAssembler::CheckMap(Register obj,
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue Sep 20 06:32:27 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Fri Sep 23 02:31:20 2011
@@ -700,6 +700,18 @@
                          Register scratch,
                          Label* fail);

+ // Check if a map for a JSObject indicates that the object can have both smi
+  // and HeapObject elements.  Jump to the specified label if it does not.
+  void CheckFastObjectElements(Register map,
+                               Register scratch,
+                               Label* fail);
+
+ // Check if a map for a JSObject indicates that the object has fast smi only
+  // elements.  Jump to the specified label if it does not.
+  void CheckFastSmiOnlyElements(Register map,
+                                Register scratch,
+                                Label* fail);
+
   // Check if the map of an object is equal to a specified map (either
   // given directly or as an index into the root list) and branch to
   // label if not. Skip the smi check if not required (object is known
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Sep 22 04:30:04 2011 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Sep 23 02:31:20 2011
@@ -1580,7 +1580,7 @@
                 DONT_DO_SMI_CHECK);

     if (argc == 1) {  // Otherwise fall through to call the builtin.
-      Label exit, attempt_to_grow_elements;
+      Label attempt_to_grow_elements;

       // Get the array's length into r0 and calculate new length.
       __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
@@ -1595,11 +1595,15 @@
       __ cmp(r0, r4);
       __ b(gt, &attempt_to_grow_elements);

+      // Check if value is a smi.
+      Label with_write_barrier;
+      __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
+      __ JumpIfNotSmi(r4, &with_write_barrier);
+
       // Save new length.
       __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));

       // Push the element.
-      __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
       // We may need a register containing the address end_elements below,
       // so write back the value in end_elements.
       __ add(end_elements, elements,
@@ -1609,13 +1613,26 @@
       __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));

       // Check for a smi.
-      Label with_write_barrier;
-      __ JumpIfNotSmi(r4, &with_write_barrier);
-      __ bind(&exit);
       __ Drop(argc + 1);
       __ Ret();

       __ bind(&with_write_barrier);
+
+      if (FLAG_smi_only_arrays) {
+        __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset));
+        __ CheckFastSmiOnlyElements(r6, r6, &call_builtin);
+      }
+
+      // Save new length.
+      __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+
+      // Push the element.
+      // We may need a register containing the address end_elements below,
+      // so write back the value in end_elements.
+      __ add(end_elements, elements,
+             Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
+      __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
+
       __ RecordWrite(elements,
                      end_elements,
                      r4,
@@ -1633,6 +1650,17 @@
       if (!FLAG_inline_new) {
         __ b(&call_builtin);
       }
+
+      __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize));
+      if (FLAG_smi_only_arrays) {
+ // Growing elements that are SMI-only requires special handling in case
+        // the new element is non-Smi. For now, delegate to the builtin.
+        Label no_fast_elements_check;
+        __ JumpIfSmi(r2, &no_fast_elements_check);
+        __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset));
+        __ CheckFastObjectElements(r7, r7, &call_builtin);
+        __ bind(&no_fast_elements_check);
+      }

       Isolate* isolate = masm()->isolate();
       ExternalReference new_space_allocation_top =
@@ -1660,8 +1688,7 @@
       // Update new_space_allocation_top.
       __ str(r6, MemOperand(r7));
       // Push the argument.
-      __ ldr(r6, MemOperand(sp, (argc - 1) * kPointerSize));
-      __ str(r6, MemOperand(end_elements));
+      __ str(r2, MemOperand(end_elements));
       // Fill the rest with holes.
       __ LoadRoot(r6, Heap::kTheHoleValueRootIndex);
       for (int i = 1; i < kAllocationDelta; i++) {
@@ -4323,21 +4350,33 @@
   __ cmp(key_reg, scratch);
   __ b(hs, &miss_force_generic);

-  __ add(scratch,
-         elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-  STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
-  __ add(scratch,
-         scratch,
-         Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize));
-  __ str(value_reg, MemOperand(scratch));
-  __ mov(receiver_reg, value_reg);
-  ASSERT(elements_kind == FAST_ELEMENTS);
-  __ RecordWrite(elements_reg,  // Object.
-                 scratch,       // Address.
-                 receiver_reg,  // Value.
-                 kLRHasNotBeenSaved,
-                 kDontSaveFPRegs);
-
+  if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
+    __ JumpIfNotSmi(value_reg, &miss_force_generic);
+    __ add(scratch,
+           elements_reg,
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+    __ add(scratch,
+           scratch,
+           Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize));
+    __ str(value_reg, MemOperand(scratch));
+  } else {
+    ASSERT(elements_kind == FAST_ELEMENTS);
+    __ add(scratch,
+           elements_reg,
+           Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+    STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
+    __ add(scratch,
+           scratch,
+           Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize));
+    __ str(value_reg, MemOperand(scratch));
+    __ mov(receiver_reg, value_reg);
+    __ RecordWrite(elements_reg,  // Object.
+                   scratch,       // Address.
+                   receiver_reg,  // Value.
+                   kLRHasNotBeenSaved,
+                   kDontSaveFPRegs);
+  }
   // value_reg (r0) is preserved.
   // Done.
   __ Ret();

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to