Revision: 22931
Author: [email protected]
Date: Wed Aug 6 13:18:36 2014 UTC
Log: Always use the StoreFieldStub to do the actual storing.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/443963002
http://code.google.com/p/v8/source/detail?r=22931
Modified:
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/arm64/stub-cache-arm64.cc
/branches/bleeding_edge/src/code-stubs.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/isolate.cc
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Aug 6 09:31:10
2014 UTC
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Aug 6 13:18:36
2014 UTC
@@ -581,77 +581,28 @@
}
-// Generate StoreField code, value is passed in r0 register.
-// When leaving generated code after success, the receiver_reg and name_reg
-// may be clobbered. Upon branch to miss_label, the receiver and name
-// registers have their original values.
-void NamedStoreHandlerCompiler::GenerateStoreField(
- Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
- Register name_reg, Register value_reg, Register scratch1, Register
scratch2,
- Label* miss_label) {
- // r0 : value
- Label exit;
-
- // Stub never generated for objects that require access checks.
- DCHECK(!object->IsAccessCheckNeeded());
- DCHECK(!object->IsJSGlobalProxy());
-
- FieldIndex index = lookup->GetFieldIndex();
-
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupResult* lookup,
+ Register value_reg,
+ Label* miss_label) {
DCHECK(lookup->representation().IsHeapObject());
__ JumpIfSmi(value_reg, miss_label);
- HeapType* field_type = lookup->GetFieldType();
- HeapType::Iterator<Map> 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);
+ HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+ __ 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);
}
+ __ bind(&do_store);
- if (index.is_inobject()) {
- // Set the property straight into the object.
- __ str(value_reg, FieldMemOperand(receiver_reg, index.offset()));
-
- // 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, OMIT_SMI_CHECK);
- } else {
- // Write to the properties array.
- // Get the properties array
- __ ldr(scratch1,
- FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ str(value_reg, FieldMemOperand(scratch1, index.offset()));
-
- // 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, OMIT_SMI_CHECK);
- }
-
- // Return the value (register r0).
- DCHECK(value_reg.is(r0));
- __ bind(&exit);
- __ Ret();
+ StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+ lookup->representation());
+ GenerateTailCall(masm(), stub.GetCode());
}
=======================================
--- /branches/bleeding_edge/src/arm64/stub-cache-arm64.cc Wed Aug 6
09:31:10 2014 UTC
+++ /branches/bleeding_edge/src/arm64/stub-cache-arm64.cc Wed Aug 6
13:18:36 2014 UTC
@@ -531,77 +531,28 @@
}
-// Generate StoreField code, value is passed in x0 register.
-// When leaving generated code after success, the receiver_reg and
name_reg may
-// be clobbered. Upon branch to miss_label, the receiver and name
registers have
-// their original values.
-void NamedStoreHandlerCompiler::GenerateStoreField(
- Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
- Register name_reg, Register value_reg, Register scratch1, Register
scratch2,
- Label* miss_label) {
- // x0 : value
- Label exit;
-
- // Stub never generated for objects that require access checks.
- DCHECK(!object->IsAccessCheckNeeded());
- DCHECK(!object->IsJSGlobalProxy());
-
- FieldIndex index = lookup->GetFieldIndex();
-
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupResult* lookup,
+ Register value_reg,
+ Label* miss_label) {
DCHECK(lookup->representation().IsHeapObject());
__ JumpIfSmi(value_reg, miss_label);
- HeapType* field_type = lookup->GetFieldType();
- HeapType::Iterator<Map> 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);
+ HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+ __ 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);
}
+ __ Bind(&do_store);
- if (index.is_inobject()) {
- // Set the property straight into the object.
- __ Str(value_reg, FieldMemOperand(receiver_reg, index.offset()));
-
- // 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, OMIT_SMI_CHECK);
- } else {
- // Write to the properties array.
- // Get the properties array
- __ Ldr(scratch1,
- FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
- __ Str(value_reg, FieldMemOperand(scratch1, index.offset()));
-
- // 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, OMIT_SMI_CHECK);
- }
-
- __ Bind(&exit);
- // Return the value (register x0).
- DCHECK(value_reg.is(x0));
- __ Ret();
+ StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+ lookup->representation());
+ GenerateTailCall(masm(), stub.GetCode());
}
=======================================
--- /branches/bleeding_edge/src/code-stubs.cc Wed Aug 6 08:02:21 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.cc Wed Aug 6 13:18:36 2014 UTC
@@ -935,6 +935,14 @@
KeyedLoadGenericStub stub(isolate);
InstallDescriptor(isolate, &stub);
}
+
+
+// static
+void StoreFieldStub::InstallDescriptors(Isolate* isolate) {
+ StoreFieldStub stub(isolate, FieldIndex::ForInObjectOffset(0),
+ Representation::None());
+ InstallDescriptor(isolate, &stub);
+}
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Wed Aug 6 09:31:10 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Wed Aug 6 13:18:36 2014 UTC
@@ -990,6 +990,7 @@
FieldIndex index() const { return index_; }
Representation representation() { return representation_; }
+ static void InstallDescriptors(Isolate* isolate);
protected:
explicit StoreFieldStub(Isolate* isolate);
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed Aug 6 09:31:10
2014 UTC
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed Aug 6 13:18:36
2014 UTC
@@ -568,60 +568,27 @@
}
-// Both name_reg and receiver_reg are preserved on jumps to miss_label,
-// but may be destroyed if store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreField(
- Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
- Register name_reg, Register value_reg, Register scratch1, Register
scratch2,
- Label* miss_label) {
- // Stub never generated for objects that require access checks.
- DCHECK(!object->IsAccessCheckNeeded());
- DCHECK(!object->IsJSGlobalProxy());
-
- FieldIndex index = lookup->GetFieldIndex();
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupResult* lookup,
+ Register value_reg,
+ Label* miss_label) {
DCHECK(lookup->representation().IsHeapObject());
__ JumpIfSmi(value_reg, miss_label);
- HeapType* field_type = lookup->GetFieldType();
- HeapType::Iterator<Map> 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);
+ HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+ 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);
}
+ __ bind(&do_store);
- if (index.is_inobject()) {
- // Set the property straight into the object.
- __ mov(FieldOperand(receiver_reg, index.offset()), value_reg);
-
- // 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);
-
- // 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).
- DCHECK(value_reg.is(eax));
- __ ret(0);
+ StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+ lookup->representation());
+ GenerateTailCall(masm(), stub.GetCode());
}
=======================================
--- /branches/bleeding_edge/src/ic.cc Wed Aug 6 09:31:10 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Wed Aug 6 13:18:36 2014 UTC
@@ -1473,13 +1473,21 @@
}
} else {
switch (lookup->type()) {
- case FIELD:
- if (!lookup->representation().IsHeapObject()) {
+ case FIELD: {
+ bool use_stub = true;
+ if (lookup->representation().IsHeapObject()) {
+ // Only use a generic stub if no types need to be tracked.
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ use_stub = it.Done();
+ }
+ if (use_stub) {
StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
lookup->representation());
return stub.GetCode();
}
return compiler.CompileStoreField(lookup, name);
+ }
case NORMAL:
if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value
directly
=======================================
--- /branches/bleeding_edge/src/isolate.cc Wed Aug 6 09:41:52 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc Wed Aug 6 13:18:36 2014 UTC
@@ -2003,6 +2003,7 @@
StringAddStub::InstallDescriptors(this);
RegExpConstructResultStub::InstallDescriptors(this);
KeyedLoadGenericStub::InstallDescriptors(this);
+ StoreFieldStub::InstallDescriptors(this);
}
CallDescriptors::InitializeForIsolate(this);
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Wed Aug 6 08:02:21 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Wed Aug 6 13:18:36 2014 UTC
@@ -995,14 +995,7 @@
Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult*
lookup,
Handle<Name>
name) {
Label miss;
-
- FrontendHeader(receiver(), name, &miss);
-
- // Generate store field code.
- GenerateStoreField(holder(), lookup, receiver(), this->name(), value(),
- scratch1(), scratch2(), &miss);
-
- // Handle store cache miss.
+ GenerateStoreField(lookup, value(), &miss);
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
return GetCode(kind(), Code::FAST, name);
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Wed Aug 6 08:02:21 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.h Wed Aug 6 13:18:36 2014 UTC
@@ -589,10 +589,8 @@
Register scratch2, Register scratch3,
Label* miss_label, Label* slow);
- void GenerateStoreField(Handle<JSObject> object, LookupResult* lookup,
- Register receiver_reg, Register name_reg,
- Register value_reg, Register scratch1,
- Register scratch2, Label* miss_label);
+ void GenerateStoreField(LookupResult* lookup, Register value_reg,
+ Label* miss_label);
static Builtins::Name SlowBuiltin(Code::Kind kind) {
switch (kind) {
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Aug 6 09:31:10
2014 UTC
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Aug 6 13:18:36
2014 UTC
@@ -516,61 +516,27 @@
}
-// Both name_reg and receiver_reg are preserved on jumps to miss_label,
-// but may be destroyed if store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreField(
- Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
- Register name_reg, Register value_reg, Register scratch1, Register
scratch2,
- Label* miss_label) {
- // Stub never generated for objects that require access checks.
- DCHECK(!object->IsAccessCheckNeeded());
- DCHECK(!object->IsJSGlobalProxy());
-
- FieldIndex index = lookup->GetFieldIndex();
-
+void NamedStoreHandlerCompiler::GenerateStoreField(LookupResult* lookup,
+ Register value_reg,
+ Label* miss_label) {
DCHECK(lookup->representation().IsHeapObject());
__ JumpIfSmi(value_reg, miss_label);
- HeapType* field_type = lookup->GetFieldType();
- HeapType::Iterator<Map> 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);
+ HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
+ 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);
}
+ __ bind(&do_store);
- if (index.is_inobject()) {
- // Set the property straight into the object.
- __ movp(FieldOperand(receiver_reg, index.offset()), value_reg);
-
- // 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);
-
- // 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).
- DCHECK(value_reg.is(rax));
- __ ret(0);
+ StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
+ lookup->representation());
+ GenerateTailCall(masm(), stub.GetCode());
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.