Index: src/x64/stub-cache-x64.cc |
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc |
index 886d9ad9d71ec8a0b36190ab299e835559627b69..9b9b5f93ed13602e788a15c5d8aed931d21a1a56 100644 |
--- a/src/x64/stub-cache-x64.cc |
+++ b/src/x64/stub-cache-x64.cc |
@@ -488,8 +488,12 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
__ bind(&do_store); |
} |
} else if (representation.IsDouble()) { |
+ FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor); |
+ |
Label do_store, heap_number; |
- __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE); |
+ if (!FLAG_unbox_double_fields || !index.is_inobject()) { |
+ __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE); |
+ } |
__ JumpIfNotSmi(value_reg, &heap_number); |
__ SmiToInteger32(scratch1, value_reg); |
@@ -502,7 +506,9 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); |
__ bind(&do_store); |
- __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); |
+ if (!FLAG_unbox_double_fields || !index.is_inobject()) { |
+ __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); |
+ } |
} |
// Stub never generated for non-global objects that require access |
@@ -546,44 +552,38 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
return; |
} |
- int index = transition->instance_descriptors()->GetFieldIndex( |
- transition->LastAdded()); |
- |
- // Adjust for the number of properties stored in the object. Even in the |
- // face of a transition we can use the old map here because the size of the |
- // object and the number of in-object properties is not going to change. |
- index -= object->map()->inobject_properties(); |
+ FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor); |
Toon Verwaest
2014/07/29 15:02:09
Nice cleanup. What about porting this to other pla
Igor Sheludko
2014/10/30 14:23:44
Done.
|
// TODO(verwaest): Share this code as a code stub. |
SmiCheck smi_check = representation.IsTagged() |
? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
- if (index < 0) { |
+ if (index.is_inobject()) { |
// Set the property straight into the object. |
- int offset = object->map()->instance_size() + (index * kPointerSize); |
- if (representation.IsDouble()) { |
- __ movp(FieldOperand(receiver_reg, offset), storage_reg); |
+ if (FLAG_unbox_double_fields && representation.IsDouble()) { |
+ __ movsd(FieldOperand(receiver_reg, index.offset()), xmm0); |
+ } else if (representation.IsDouble()) { |
+ __ movp(FieldOperand(receiver_reg, index.offset()), storage_reg); |
} else { |
- __ movp(FieldOperand(receiver_reg, offset), value_reg); |
+ __ movp(FieldOperand(receiver_reg, index.offset()), value_reg); |
} |
- if (!representation.IsSmi()) { |
+ if ((!FLAG_unbox_double_fields || !representation.IsDouble()) && |
+ !representation.IsSmi()) { |
// Update the write barrier for the array address. |
if (!representation.IsDouble()) { |
__ movp(storage_reg, value_reg); |
} |
- __ RecordWriteField( |
- receiver_reg, offset, storage_reg, scratch1, kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, smi_check); |
+ __ RecordWriteField(receiver_reg, index.offset(), storage_reg, scratch1, |
+ kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); |
} |
} else { |
// Write to the properties array. |
- int offset = index * kPointerSize + FixedArray::kHeaderSize; |
// Get the properties array (optimistically). |
__ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
if (representation.IsDouble()) { |
- __ movp(FieldOperand(scratch1, offset), storage_reg); |
+ __ movp(FieldOperand(scratch1, index.offset()), storage_reg); |
} else { |
- __ movp(FieldOperand(scratch1, offset), value_reg); |
+ __ movp(FieldOperand(scratch1, index.offset()), value_reg); |
} |
if (!representation.IsSmi()) { |
@@ -591,9 +591,8 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, |
if (!representation.IsDouble()) { |
__ movp(storage_reg, value_reg); |
} |
- __ RecordWriteField( |
- scratch1, offset, storage_reg, receiver_reg, kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, smi_check); |
+ __ RecordWriteField(scratch1, index.offset(), storage_reg, receiver_reg, |
+ kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check); |
} |
} |
@@ -642,28 +641,33 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, |
__ bind(&do_store); |
} |
} else if (representation.IsDouble()) { |
- // Load the double storage. |
- if (index.is_inobject()) { |
- __ movp(scratch1, FieldOperand(receiver_reg, index.offset())); |
- } else { |
- __ movp(scratch1, |
- FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
- __ movp(scratch1, FieldOperand(scratch1, index.offset())); |
- } |
- |
- // Store the value into the storage. |
+ // Prepare value for storing. |
Label do_store, heap_number; |
__ JumpIfNotSmi(value_reg, &heap_number); |
- __ SmiToInteger32(scratch2, value_reg); |
- __ Cvtlsi2sd(xmm0, scratch2); |
+ __ SmiToInteger32(scratch1, value_reg); |
+ __ Cvtlsi2sd(xmm0, scratch1); |
__ jmp(&do_store); |
__ bind(&heap_number); |
__ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
miss_label, DONT_DO_SMI_CHECK); |
__ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); |
+ |
__ bind(&do_store); |
- __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); |
+ // Store it either to respective mutable box or directly to in-object field. |
+ Operand operand = FieldOperand(scratch1, HeapNumber::kValueOffset); |
Toon Verwaest
2014/07/29 15:02:09
Arg this code is confusing. Can you please just se
Igor Sheludko
2014/10/30 14:23:44
Done.
|
+ if (index.is_inobject()) { |
+ if (FLAG_unbox_double_fields) { |
+ operand = FieldOperand(receiver_reg, index.offset()); |
+ } else { |
+ __ movp(scratch1, FieldOperand(receiver_reg, index.offset())); |
+ } |
+ } else { |
+ __ movp(scratch1, |
+ FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
+ __ movp(scratch1, FieldOperand(scratch1, index.offset())); |
+ } |
+ __ movsd(operand, xmm0); |
// Return the value (register rax). |
ASSERT(value_reg.is(rax)); |
__ ret(0); |