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