Chromium Code Reviews| 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); |