From b8ab82204080ea45d4560ce4a54061ae2c5fadf7 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Wed, 6 Aug 2014 09:31:10 +0000 Subject: [PATCH] Hydrogenize (and share) StoreField except heapobject (for now). BUG= R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/443873002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22909 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 111 +++++++++------------------------ src/arm64/stub-cache-arm64.cc | 113 +++++++++------------------------- src/code-stubs-hydrogen.cc | 38 ++++++++++++ src/code-stubs.h | 39 +++++++++--- src/field-index.h | 2 +- src/ia32/stub-cache-ia32.cc | 96 +++++++---------------------- src/ic.cc | 5 ++ src/x64/stub-cache-x64.cc | 87 +++++++------------------- 8 files changed, 182 insertions(+), 309 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index e37ff60b0f..f8dfe26e8c 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -598,82 +598,38 @@ void NamedStoreHandlerCompiler::GenerateStoreField( FieldIndex index = lookup->GetFieldIndex(); - Representation representation = lookup->representation(); - DCHECK(!representation.IsNone()); - if (representation.IsSmi()) { - __ JumpIfNotSmi(value_reg, miss_label); - } else if (representation.IsHeapObject()) { - __ JumpIfSmi(value_reg, miss_label); - HeapType* field_type = lookup->GetFieldType(); - HeapType::Iterator it = field_type->Classes(); - if (!it.Done()) { - __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); - Label do_store; - while (true) { - __ CompareMap(scratch1, it.Current(), &do_store); - it.Advance(); - if (it.Done()) { - __ b(ne, miss_label); - break; - } - __ b(eq, &do_store); + DCHECK(lookup->representation().IsHeapObject()); + __ JumpIfSmi(value_reg, miss_label); + HeapType* field_type = lookup->GetFieldType(); + HeapType::Iterator it = field_type->Classes(); + if (!it.Done()) { + __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); + Label do_store; + while (true) { + __ CompareMap(scratch1, it.Current(), &do_store); + it.Advance(); + if (it.Done()) { + __ b(ne, miss_label); + break; } - __ bind(&do_store); + __ b(eq, &do_store); } - } else if (representation.IsDouble()) { - // Load the double storage. - if (index.is_inobject()) { - __ ldr(scratch1, FieldMemOperand(receiver_reg, index.offset())); - } else { - __ ldr(scratch1, - FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); - __ ldr(scratch1, FieldMemOperand(scratch1, index.offset())); - } - - // Store the value into the storage. - Label do_store, heap_number; - __ JumpIfNotSmi(value_reg, &heap_number); - __ SmiUntag(scratch2, value_reg); - __ vmov(s0, scratch2); - __ vcvt_f64_s32(d0, s0); - __ jmp(&do_store); - - __ bind(&heap_number); - __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, - miss_label, DONT_DO_SMI_CHECK); - __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); - __ bind(&do_store); - __ vstr(d0, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); - // Return the value (register r0). - DCHECK(value_reg.is(r0)); - __ Ret(); - return; } - // TODO(verwaest): Share this code as a code stub. - SmiCheck smi_check = representation.IsTagged() - ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; if (index.is_inobject()) { // Set the property straight into the object. __ str(value_reg, FieldMemOperand(receiver_reg, index.offset())); - if (!representation.IsSmi()) { - // Skip updating write barrier if storing a smi. - __ JumpIfSmi(value_reg, &exit); + // Skip updating write barrier if storing a smi. + __ JumpIfSmi(value_reg, &exit); - // Update the write barrier for the array address. - // Pass the now unused name_reg as a scratch register. - __ mov(name_reg, value_reg); - __ RecordWriteField(receiver_reg, - index.offset(), - name_reg, - scratch1, - kLRHasNotBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Pass the now unused name_reg as a scratch register. + __ mov(name_reg, value_reg); + __ RecordWriteField(receiver_reg, index.offset(), name_reg, scratch1, + kLRHasNotBeenSaved, kDontSaveFPRegs, + EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } else { // Write to the properties array. // Get the properties array @@ -681,22 +637,15 @@ void NamedStoreHandlerCompiler::GenerateStoreField( FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); __ str(value_reg, FieldMemOperand(scratch1, index.offset())); - if (!representation.IsSmi()) { - // Skip updating write barrier if storing a smi. - __ JumpIfSmi(value_reg, &exit); + // Skip updating write barrier if storing a smi. + __ JumpIfSmi(value_reg, &exit); - // Update the write barrier for the array address. - // Ok to clobber receiver_reg and name_reg, since we return. - __ mov(name_reg, value_reg); - __ RecordWriteField(scratch1, - index.offset(), - name_reg, - receiver_reg, - kLRHasNotBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Ok to clobber receiver_reg and name_reg, since we return. + __ mov(name_reg, value_reg); + __ RecordWriteField(scratch1, index.offset(), name_reg, receiver_reg, + kLRHasNotBeenSaved, kDontSaveFPRegs, + EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } // Return the value (register r0). diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index 7ac68e79a5..92fbecf752 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -548,84 +548,38 @@ void NamedStoreHandlerCompiler::GenerateStoreField( FieldIndex index = lookup->GetFieldIndex(); - Representation representation = lookup->representation(); - DCHECK(!representation.IsNone()); - if (representation.IsSmi()) { - __ JumpIfNotSmi(value_reg, miss_label); - } else if (representation.IsHeapObject()) { - __ JumpIfSmi(value_reg, miss_label); - HeapType* field_type = lookup->GetFieldType(); - HeapType::Iterator it = field_type->Classes(); - if (!it.Done()) { - __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); - Label do_store; - while (true) { - __ CompareMap(scratch1, it.Current()); - it.Advance(); - if (it.Done()) { - __ B(ne, miss_label); - break; - } - __ B(eq, &do_store); + DCHECK(lookup->representation().IsHeapObject()); + __ JumpIfSmi(value_reg, miss_label); + HeapType* field_type = lookup->GetFieldType(); + HeapType::Iterator it = field_type->Classes(); + if (!it.Done()) { + __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); + Label do_store; + while (true) { + __ CompareMap(scratch1, it.Current()); + it.Advance(); + if (it.Done()) { + __ B(ne, miss_label); + break; } - __ Bind(&do_store); + __ B(eq, &do_store); } - } else if (representation.IsDouble()) { - UseScratchRegisterScope temps(masm()); - DoubleRegister temp_double = temps.AcquireD(); - - __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag); - - // Load the double storage. - if (index.is_inobject()) { - __ Ldr(scratch1, FieldMemOperand(receiver_reg, index.offset())); - } else { - __ Ldr(scratch1, - FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); - __ Ldr(scratch1, FieldMemOperand(scratch1, index.offset())); - } - - // Store the value into the storage. - Label do_store, heap_number; - - __ JumpIfSmi(value_reg, &do_store); - - __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, - miss_label, DONT_DO_SMI_CHECK); - __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); - __ Bind(&do_store); - __ Str(temp_double, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); - - // Return the value (register x0). - DCHECK(value_reg.is(x0)); - __ Ret(); - return; } - // TODO(verwaest): Share this code as a code stub. - SmiCheck smi_check = representation.IsTagged() - ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; if (index.is_inobject()) { // Set the property straight into the object. __ Str(value_reg, FieldMemOperand(receiver_reg, index.offset())); - if (!representation.IsSmi()) { - // Skip updating write barrier if storing a smi. - __ JumpIfSmi(value_reg, &exit); + // Skip updating write barrier if storing a smi. + __ JumpIfSmi(value_reg, &exit); - // Update the write barrier for the array address. - // Pass the now unused name_reg as a scratch register. - __ Mov(name_reg, value_reg); - __ RecordWriteField(receiver_reg, - index.offset(), - name_reg, - scratch1, - kLRHasNotBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Pass the now unused name_reg as a scratch register. + __ Mov(name_reg, value_reg); + __ RecordWriteField(receiver_reg, index.offset(), name_reg, scratch1, + kLRHasNotBeenSaved, kDontSaveFPRegs, + EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } else { // Write to the properties array. // Get the properties array @@ -633,22 +587,15 @@ void NamedStoreHandlerCompiler::GenerateStoreField( FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); __ Str(value_reg, FieldMemOperand(scratch1, index.offset())); - if (!representation.IsSmi()) { - // Skip updating write barrier if storing a smi. - __ JumpIfSmi(value_reg, &exit); + // Skip updating write barrier if storing a smi. + __ JumpIfSmi(value_reg, &exit); - // Update the write barrier for the array address. - // Ok to clobber receiver_reg and name_reg, since we return. - __ Mov(name_reg, value_reg); - __ RecordWriteField(scratch1, - index.offset(), - name_reg, - receiver_reg, - kLRHasNotBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Ok to clobber receiver_reg and name_reg, since we return. + __ Mov(name_reg, value_reg); + __ RecordWriteField(scratch1, index.offset(), name_reg, receiver_reg, + kLRHasNotBeenSaved, kDontSaveFPRegs, + EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } __ Bind(&exit); diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 2306da6db7..ba647bab84 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -62,6 +62,8 @@ class CodeStubGraphBuilderBase : public HGraphBuilder { HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index); + void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, + Representation representation); enum ArgumentClass { NONE, @@ -607,6 +609,42 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { Handle LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } +void CodeStubGraphBuilderBase::BuildStoreNamedField( + HValue* object, HValue* value, FieldIndex index, + Representation representation) { + DCHECK(!index.is_double() || representation.IsDouble()); + int offset = index.offset(); + HObjectAccess access = + index.is_inobject() + ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) + : HObjectAccess::ForBackingStoreOffset(offset, representation); + + if (representation.IsDouble()) { + // Load the heap number. + object = Add( + object, static_cast(NULL), + access.WithRepresentation(Representation::Tagged())); + // Store the double value into it. + access = HObjectAccess::ForHeapNumberValue(); + } else if (representation.IsHeapObject()) { + BuildCheckHeapObject(value); + } + + Add(object, access, value, STORE_TO_INITIALIZED_ENTRY); +} + + +template <> +HValue* CodeStubGraphBuilder::BuildCodeStub() { + BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(), + casted_stub()->representation()); + return GetParameter(2); +} + + +Handle StoreFieldStub::GenerateCode() { return DoGenerateCode(this); } + + template <> HValue* CodeStubGraphBuilder::BuildCodeStub() { HValue* string = BuildLoadNamedField(GetParameter(0), diff --git a/src/code-stubs.h b/src/code-stubs.h index 01f83ed54f..e9378de5bb 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -76,6 +76,7 @@ namespace internal { V(CallApiGetter) \ /* IC Handler stubs */ \ V(LoadField) \ + V(StoreField) \ V(LoadConstant) \ V(StringLength) @@ -920,19 +921,13 @@ class LoadFieldStub: public HandlerStub { public: LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate), index_(index) { - int property_index_key = index_.GetLoadFieldStubKey(); + int property_index_key = index_.GetFieldAccessStubKey(); bit_field_ = EncodedLoadFieldByIndexBits::encode(property_index_key); } virtual Handle GenerateCode() V8_OVERRIDE; - Representation representation() { - if (unboxed_double()) return Representation::Double(); - return Representation::Tagged(); - } - FieldIndex index() const { return index_; } - bool unboxed_double() { return index_.is_double(); } protected: explicit LoadFieldStub(Isolate* isolate); @@ -980,6 +975,36 @@ class StringLengthStub: public HandlerStub { }; +class StoreFieldStub : public HandlerStub { + public: + StoreFieldStub(Isolate* isolate, FieldIndex index, + Representation representation) + : HandlerStub(isolate), index_(index), representation_(representation) { + int property_index_key = index_.GetFieldAccessStubKey(); + bit_field_ = EncodedStoreFieldByIndexBits::encode(property_index_key) | + RepresentationBits::encode( + PropertyDetails::EncodeRepresentation(representation)); + } + + virtual Handle GenerateCode() V8_OVERRIDE; + + FieldIndex index() const { return index_; } + Representation representation() { return representation_; } + + protected: + explicit StoreFieldStub(Isolate* isolate); + virtual Code::Kind kind() const { return Code::STORE_IC; } + virtual Code::StubType GetStubType() { return Code::FAST; } + + private: + class EncodedStoreFieldByIndexBits : public BitField {}; + class RepresentationBits : public BitField {}; + virtual CodeStub::Major MajorKey() const { return StoreField; } + FieldIndex index_; + Representation representation_; +}; + + class StoreGlobalStub : public HandlerStub { public: StoreGlobalStub(Isolate* isolate, bool is_constant, bool check_global) diff --git a/src/field-index.h b/src/field-index.h index 56df7ec758..8650c8fb8f 100644 --- a/src/field-index.h +++ b/src/field-index.h @@ -65,7 +65,7 @@ class FieldIndex V8_FINAL { int GetKeyedLookupCacheIndex() const; - int GetLoadFieldStubKey() const { + int GetFieldAccessStubKey() const { return bit_field_ & (IsInObjectBits::kMask | IsDoubleBits::kMask | IndexBits::kMask); } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 0d74009a8b..2720711e2b 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -579,94 +579,44 @@ void NamedStoreHandlerCompiler::GenerateStoreField( DCHECK(!object->IsJSGlobalProxy()); FieldIndex index = lookup->GetFieldIndex(); - - Representation representation = lookup->representation(); - DCHECK(!representation.IsNone()); - if (representation.IsSmi()) { - __ JumpIfNotSmi(value_reg, miss_label); - } else if (representation.IsHeapObject()) { - __ JumpIfSmi(value_reg, miss_label); - HeapType* field_type = lookup->GetFieldType(); - HeapType::Iterator it = field_type->Classes(); - if (!it.Done()) { - Label do_store; - while (true) { - __ CompareMap(value_reg, it.Current()); - it.Advance(); - if (it.Done()) { - __ j(not_equal, miss_label); - break; - } - __ j(equal, &do_store, Label::kNear); + DCHECK(lookup->representation().IsHeapObject()); + __ JumpIfSmi(value_reg, miss_label); + HeapType* field_type = lookup->GetFieldType(); + HeapType::Iterator it = field_type->Classes(); + if (!it.Done()) { + Label do_store; + while (true) { + __ CompareMap(value_reg, it.Current()); + it.Advance(); + if (it.Done()) { + __ j(not_equal, miss_label); + break; } - __ bind(&do_store); + __ j(equal, &do_store, Label::kNear); } - } else if (representation.IsDouble()) { - // Load the double storage. - if (index.is_inobject()) { - __ mov(scratch1, FieldOperand(receiver_reg, index.offset())); - } else { - __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); - __ mov(scratch1, FieldOperand(scratch1, index.offset())); - } - - // Store the value into the storage. - Label do_store, heap_number; - __ JumpIfNotSmi(value_reg, &heap_number); - __ SmiUntag(value_reg); - __ Cvtsi2sd(xmm0, value_reg); - __ SmiTag(value_reg); - __ jmp(&do_store); - __ bind(&heap_number); - __ CheckMap(value_reg, 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); - // Return the value (register eax). - DCHECK(value_reg.is(eax)); - __ ret(0); - return; } - DCHECK(!representation.IsDouble()); - // TODO(verwaest): Share this code as a code stub. - SmiCheck smi_check = representation.IsTagged() - ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; if (index.is_inobject()) { // Set the property straight into the object. __ mov(FieldOperand(receiver_reg, index.offset()), value_reg); - if (!representation.IsSmi()) { - // Update the write barrier for the array address. - // Pass the value being stored in the now unused name_reg. - __ mov(name_reg, value_reg); - __ RecordWriteField(receiver_reg, - index.offset(), - name_reg, - scratch1, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Pass the value being stored in the now unused name_reg. + __ mov(name_reg, value_reg); + __ RecordWriteField(receiver_reg, index.offset(), name_reg, scratch1, + kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } else { // Write to the properties array. // Get the properties array (optimistically). __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); __ mov(FieldOperand(scratch1, index.offset()), value_reg); - if (!representation.IsSmi()) { - // Update the write barrier for the array address. - // Pass the value being stored in the now unused name_reg. - __ mov(name_reg, value_reg); - __ RecordWriteField(scratch1, - index.offset(), - name_reg, - receiver_reg, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - smi_check); - } + // Update the write barrier for the array address. + // Pass the value being stored in the now unused name_reg. + __ mov(name_reg, value_reg); + __ RecordWriteField(scratch1, index.offset(), name_reg, receiver_reg, + kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } // Return the value (register eax). diff --git a/src/ic.cc b/src/ic.cc index bd8db3e01a..05b235c794 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1474,6 +1474,11 @@ Handle StoreIC::CompileStoreHandler(LookupResult* lookup, } else { switch (lookup->type()) { case FIELD: + if (!lookup->representation().IsHeapObject()) { + StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), + lookup->representation()); + return stub.GetCode(); + } return compiler.CompileStoreField(lookup, name); case NORMAL: if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) { diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 0bf542e95a..7d6dbd20b2 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -528,85 +528,44 @@ void NamedStoreHandlerCompiler::GenerateStoreField( FieldIndex index = lookup->GetFieldIndex(); - Representation representation = lookup->representation(); - DCHECK(!representation.IsNone()); - if (representation.IsSmi()) { - __ JumpIfNotSmi(value_reg, miss_label); - } else if (representation.IsHeapObject()) { - __ JumpIfSmi(value_reg, miss_label); - HeapType* field_type = lookup->GetFieldType(); - HeapType::Iterator it = field_type->Classes(); - if (!it.Done()) { - Label do_store; - while (true) { - __ CompareMap(value_reg, it.Current()); - it.Advance(); - if (it.Done()) { - __ j(not_equal, miss_label); - break; - } - __ j(equal, &do_store, Label::kNear); + DCHECK(lookup->representation().IsHeapObject()); + __ JumpIfSmi(value_reg, miss_label); + HeapType* field_type = lookup->GetFieldType(); + HeapType::Iterator it = field_type->Classes(); + if (!it.Done()) { + Label do_store; + while (true) { + __ CompareMap(value_reg, it.Current()); + it.Advance(); + if (it.Done()) { + __ j(not_equal, miss_label); + break; } - __ bind(&do_store); + __ j(equal, &do_store, Label::kNear); } - } 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. - Label do_store, heap_number; - __ JumpIfNotSmi(value_reg, &heap_number); - __ SmiToInteger32(scratch2, value_reg); - __ Cvtlsi2sd(xmm0, scratch2); - __ jmp(&do_store); - - __ bind(&heap_number); - __ CheckMap(value_reg, 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); - // Return the value (register rax). - DCHECK(value_reg.is(rax)); - __ ret(0); - return; } - // TODO(verwaest): Share this code as a code stub. - SmiCheck smi_check = representation.IsTagged() - ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; if (index.is_inobject()) { // Set the property straight into the object. __ movp(FieldOperand(receiver_reg, index.offset()), value_reg); - if (!representation.IsSmi()) { - // Update the write barrier for the array address. - // Pass the value being stored in the now unused name_reg. - __ movp(name_reg, value_reg); - __ RecordWriteField( - receiver_reg, index.offset(), name_reg, scratch1, kDontSaveFPRegs, - EMIT_REMEMBERED_SET, smi_check); - } + // Update the write barrier for the array address. + // Pass the value being stored in the now unused name_reg. + __ movp(name_reg, value_reg); + __ RecordWriteField(receiver_reg, index.offset(), name_reg, scratch1, + kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } else { // Write to the properties array. // Get the properties array (optimistically). __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); __ movp(FieldOperand(scratch1, index.offset()), value_reg); - if (!representation.IsSmi()) { - // Update the write barrier for the array address. - // Pass the value being stored in the now unused name_reg. - __ movp(name_reg, value_reg); - __ RecordWriteField( - scratch1, index.offset(), name_reg, receiver_reg, kDontSaveFPRegs, - EMIT_REMEMBERED_SET, smi_check); - } + // Update the write barrier for the array address. + // Pass the value being stored in the now unused name_reg. + __ movp(name_reg, value_reg); + __ RecordWriteField(scratch1, index.offset(), name_reg, receiver_reg, + kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); } // Return the value (register rax).