Revision: 6214
Author: [email protected]
Date: Thu Jan  6 23:33:46 2011
Log: ARM implementations of LoadElements, LoadKeyedFastElement, StoreNamedField, StoreKeyedFastElement.

BUG=none
TEST=none

Patch by Martyn Capewell from ARM Ltd.

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

http://code.google.com/p/v8/source/detail?r=6214

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Jan  6 07:25:03 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Jan  6 23:33:46 2011
@@ -1924,7 +1924,7 @@


 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
-  bool needs_write_barrier = !instr->value()->type().IsSmi();
+  bool needs_write_barrier = instr->NeedsWriteBarrier();

   LOperand* obj = needs_write_barrier
       ? UseTempRegister(instr->object())
@@ -1934,17 +1934,11 @@
       ? UseTempRegister(instr->value())
       : UseRegister(instr->value());

-  // We only need a scratch register if we have a write barrier or we
-  // have a store into the properties array (not in-object-property).
-  LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
-      ? TempRegister() : NULL;
-
   return new LStoreNamedField(obj,
                               instr->name(),
                               val,
                               instr->is_in_object(),
                               instr->offset(),
-                              temp,
                               needs_write_barrier,
                               instr->transition());
 }
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Thu Jan  6 08:20:45 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Thu Jan  6 23:33:46 2011
@@ -1563,13 +1563,11 @@
                    LOperand* val,
                    bool in_object,
                    int offset,
-                   LOperand* temp,
                    bool needs_write_barrier,
                    Handle<Map> transition)
       : LStoreNamed(obj, name, val),
         is_in_object_(in_object),
         offset_(offset),
-        temp_(temp),
         needs_write_barrier_(needs_write_barrier),
         transition_(transition) { }

@@ -1577,7 +1575,6 @@

   bool is_in_object() { return is_in_object_; }
   int offset() { return offset_; }
-  LOperand* temp() { return temp_; }
   bool needs_write_barrier() { return needs_write_barrier_; }
   Handle<Map> transition() const { return transition_; }
   void set_transition(Handle<Map> map) { transition_ = map; }
@@ -1585,7 +1582,6 @@
  private:
   bool is_in_object_;
   int offset_;
-  LOperand* temp_;
   bool needs_write_barrier_;
   Handle<Map> transition_;
 };
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jan 6 07:25:03 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jan 6 23:33:46 2011
@@ -1583,7 +1583,22 @@


 void LCodeGen::DoLoadElements(LLoadElements* instr) {
-  Abort("DoLoadElements unimplemented.");
+  ASSERT(instr->result()->Equals(instr->input()));
+  Register reg = ToRegister(instr->input());
+  Register scratch = scratch0();
+
+  __ ldr(reg, FieldMemOperand(reg, JSObject::kElementsOffset));
+  if (FLAG_debug_code) {
+    Label done;
+    __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
+    __ cmp(scratch, ip);
+    __ b(eq, &done);
+    __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
+    __ cmp(scratch, ip);
+    __ Check(eq, "Check for fast elements failed.");
+    __ bind(&done);
+  }
 }


@@ -1606,7 +1621,38 @@


 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
-  Abort("DoLoadKeyedFastElement unimplemented.");
+  Register elements = ToRegister(instr->elements());
+  Register key = EmitLoadRegister(instr->key(), scratch0());
+  Register result;
+  Register scratch = scratch0();
+
+  if (instr->load_result() != NULL) {
+    result = ToRegister(instr->load_result());
+  } else {
+    result = ToRegister(instr->result());
+    ASSERT(result.is(elements));
+  }
+
+  // Load the result.
+  __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+  __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+
+  Representation r = instr->hydrogen()->representation();
+  if (r.IsInteger32()) {
+    // Untag and check for smi.
+    __ SmiUntag(result);
+    DeoptimizeIf(cs, instr->environment());
+  } else if (r.IsDouble()) {
+    EmitNumberUntagD(result,
+                     ToDoubleRegister(instr->result()),
+                     instr->environment());
+  } else {
+    // Check for the hole value.
+    ASSERT(r.IsTagged());
+    __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, scratch);
+    DeoptimizeIf(eq, instr->environment());
+  }
 }


@@ -1821,7 +1867,34 @@


 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
-  Abort("DoStoreNamedField unimplemented.");
+  Register object = ToRegister(instr->object());
+  Register value = ToRegister(instr->value());
+  Register scratch = scratch0();
+  int offset = instr->offset();
+
+  ASSERT(!object.is(value));
+
+  if (!instr->transition().is_null()) {
+    __ mov(scratch, Operand(instr->transition()));
+    __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  }
+
+  // Do the store.
+  if (instr->is_in_object()) {
+    __ str(value, FieldMemOperand(object, offset));
+    if (instr->needs_write_barrier()) {
+      // Update the write barrier for the object for in-object properties.
+      __ RecordWrite(object, Operand(offset), value, scratch);
+    }
+  } else {
+    __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    __ str(value, FieldMemOperand(scratch, offset));
+    if (instr->needs_write_barrier()) {
+      // Update the write barrier for the properties array.
+      // object is used as a scratch register.
+      __ RecordWrite(scratch, Operand(offset), value, object);
+    }
+  }
 }


@@ -1843,7 +1916,28 @@


 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
-  Abort("DoStoreKeyedFastElement unimplemented.");
+  Register value = ToRegister(instr->value());
+  Register elements = ToRegister(instr->object());
+ Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
+  Register scratch = scratch0();
+
+  // Do the store.
+  if (instr->key()->IsConstantOperand()) {
+    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
+    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+    int offset =
+ ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
+    __ str(value, FieldMemOperand(elements, offset));
+  } else {
+    __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+    __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+  }
+
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    // Compute address of modified element and store it into key register.
+    __ add(key, scratch, Operand(FixedArray::kHeaderSize));
+    __ RecordWrite(elements, key, value);
+  }
 }


=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Jan 5 23:28:51 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Jan 6 23:33:46 2011
@@ -2638,7 +2638,6 @@
            value);
   }

- // Update the write barrier unless we're certain that we're storing a smi.
   if (instr->hydrogen()->NeedsWriteBarrier()) {
     // Compute address of modified element and store it into key register.
__ lea(key, FieldOperand(elements, key, times_4, FixedArray::kHeaderSize));

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

Reply via email to