A64: Improve constraints for StoreNamedField

Improve register constraints for cases that don't need write barriers, and
remove TODOs.

BUG=
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/189373006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19807 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 797c75e7
...@@ -2236,17 +2236,29 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { ...@@ -2236,17 +2236,29 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
// TODO(jbramley): Optimize register usage in this instruction. For now, it
// allocates everything that it might need because it keeps changing in the
// merge and keeping it valid is time-consuming.
// TODO(jbramley): It might be beneficial to allow value to be a constant in // TODO(jbramley): It might be beneficial to allow value to be a constant in
// some cases. x64 makes use of this with FLAG_track_fields, for example. // some cases. x64 makes use of this with FLAG_track_fields, for example.
LOperand* object = UseRegister(instr->object()); LOperand* object = UseRegister(instr->object());
LOperand* value = UseRegisterAndClobber(instr->value()); LOperand* value;
LOperand* temp0 = TempRegister(); LOperand* temp0 = NULL;
LOperand* temp1 = TempRegister(); LOperand* temp1 = NULL;
if (instr->access().IsExternalMemory() ||
instr->field_representation().IsDouble()) {
value = UseRegister(instr->value());
} else if (instr->NeedsWriteBarrier()) {
value = UseRegisterAndClobber(instr->value());
temp0 = TempRegister();
temp1 = TempRegister();
} else if (instr->NeedsWriteBarrierForMap()) {
value = UseRegister(instr->value());
temp0 = TempRegister();
temp1 = TempRegister();
} else {
value = UseRegister(instr->value());
temp0 = TempRegister();
}
LStoreNamedField* result = LStoreNamedField* result =
new(zone()) LStoreNamedField(object, value, temp0, temp1); new(zone()) LStoreNamedField(object, value, temp0, temp1);
......
...@@ -5172,48 +5172,45 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { ...@@ -5172,48 +5172,45 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
} }
// TODO(jbramley): Once the merge is done and we're tracking bleeding_edge, try
// to tidy up this function.
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
Representation representation = instr->representation(); Representation representation = instr->representation();
Register object = ToRegister(instr->object()); Register object = ToRegister(instr->object());
Register temp0 = ToRegister(instr->temp0());
Register temp1 = ToRegister(instr->temp1());
HObjectAccess access = instr->hydrogen()->access(); HObjectAccess access = instr->hydrogen()->access();
Handle<Map> transition = instr->transition();
int offset = access.offset(); int offset = access.offset();
if (access.IsExternalMemory()) { if (access.IsExternalMemory()) {
ASSERT(transition.is_null());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
Register value = ToRegister(instr->value()); Register value = ToRegister(instr->value());
__ Store(value, MemOperand(object, offset), representation); __ Store(value, MemOperand(object, offset), representation);
return; return;
} else if (representation.IsDouble()) {
ASSERT(transition.is_null());
ASSERT(access.IsInobject());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
FPRegister value = ToDoubleRegister(instr->value());
__ Str(value, FieldMemOperand(object, offset));
return;
} }
Handle<Map> transition = instr->transition(); Register value = ToRegister(instr->value());
SmiCheck check_needed =
instr->hydrogen()->value()->IsHeapObject() SmiCheck check_needed = instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK; ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
if (representation.IsHeapObject()) { if (representation.IsHeapObject() &&
Register value = ToRegister(instr->value()); !instr->hydrogen()->value()->type().IsHeapObject()) {
if (!instr->hydrogen()->value()->type().IsHeapObject()) {
DeoptimizeIfSmi(value, instr->environment()); DeoptimizeIfSmi(value, instr->environment());
// We know that value is a smi now, so we can omit the check below. // We know that value is a smi now, so we can omit the check below.
check_needed = OMIT_SMI_CHECK; check_needed = OMIT_SMI_CHECK;
} }
} else if (representation.IsDouble()) {
ASSERT(transition.is_null());
ASSERT(access.IsInobject());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
FPRegister value = ToDoubleRegister(instr->value());
__ Str(value, FieldMemOperand(object, offset));
return;
}
if (!transition.is_null()) { if (!transition.is_null()) {
// Store the new map value. // Store the new map value.
Register new_map_value = temp0; Register new_map_value = ToRegister(instr->temp0());
__ Mov(new_map_value, Operand(transition)); __ Mov(new_map_value, Operand(transition));
__ Str(new_map_value, FieldMemOperand(object, HeapObject::kMapOffset)); __ Str(new_map_value, FieldMemOperand(object, HeapObject::kMapOffset));
if (instr->hydrogen()->NeedsWriteBarrierForMap()) { if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
...@@ -5221,7 +5218,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { ...@@ -5221,7 +5218,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ RecordWriteField(object, __ RecordWriteField(object,
HeapObject::kMapOffset, HeapObject::kMapOffset,
new_map_value, new_map_value,
temp1, ToRegister(instr->temp1()),
GetLinkRegisterState(), GetLinkRegisterState(),
kSaveFPRegs, kSaveFPRegs,
OMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET,
...@@ -5230,11 +5227,11 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { ...@@ -5230,11 +5227,11 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
} }
// Do the store. // Do the store.
Register value = ToRegister(instr->value());
Register destination; Register destination;
if (access.IsInobject()) { if (access.IsInobject()) {
destination = object; destination = object;
} else { } else {
Register temp0 = ToRegister(instr->temp0());
__ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset)); __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset));
destination = temp0; destination = temp0;
} }
...@@ -5243,8 +5240,15 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { ...@@ -5243,8 +5240,15 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
instr->hydrogen()->value()->representation().IsInteger32()) { instr->hydrogen()->value()->representation().IsInteger32()) {
ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
#ifdef DEBUG #ifdef DEBUG
__ Ldr(temp1, FieldMemOperand(destination, offset)); Register temp0 = ToRegister(instr->temp0());
__ AssertSmi(temp1); __ Ldr(temp0, FieldMemOperand(destination, offset));
__ AssertSmi(temp0);
// If destination aliased temp0, restore it to the address calculated
// earlier.
if (destination.Is(temp0)) {
ASSERT(!access.IsInobject());
__ Ldr(destination, FieldMemOperand(object, JSObject::kPropertiesOffset));
}
#endif #endif
STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0); STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0);
__ Store(value, UntagSmiFieldMemOperand(destination, offset), __ Store(value, UntagSmiFieldMemOperand(destination, offset),
...@@ -5256,7 +5260,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { ...@@ -5256,7 +5260,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ RecordWriteField(destination, __ RecordWriteField(destination,
offset, offset,
value, // Clobbered. value, // Clobbered.
temp1, // Clobbered. ToRegister(instr->temp1()), // Clobbered.
GetLinkRegisterState(), GetLinkRegisterState(),
kSaveFPRegs, kSaveFPRegs,
EMIT_REMEMBERED_SET, EMIT_REMEMBERED_SET,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment