Use type propagation to eliminate store barriers.

Review URL: https://chromiumcodereview.appspot.com//10876072

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@11357 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
srdjan@google.com 2012-08-25 00:27:07 +00:00
parent 89b1f5ec12
commit 3d8e3c169a
4 changed files with 52 additions and 34 deletions

View file

@ -292,6 +292,15 @@ bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const {
} }
bool Value::NeedsStoreBuffer() const {
const intptr_t cid = ResultCid();
if ((cid == kSmiCid) || (cid == kBoolCid) || (cid == kNullCid)) {
return false;
}
return !BindsToConstant();
}
RawAbstractType* PhiInstr::CompileType() const { RawAbstractType* PhiInstr::CompileType() const {
ASSERT(!HasPropagatedType()); ASSERT(!HasPropagatedType());
// Since type propagation has not yet occured, we are reaching this phi via a // Since type propagation has not yet occured, we are reaching this phi via a
@ -1432,8 +1441,13 @@ void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
Register dest_reg = locs()->in(1).reg(); Register dest_reg = locs()->in(1).reg();
ASSERT(value_reg == locs()->out().reg()); ASSERT(value_reg == locs()->out().reg());
__ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), if (value()->NeedsStoreBuffer()) {
value_reg); __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
value_reg);
} else {
__ StoreIntoObjectNoBarrier(
dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
}
} }

View file

@ -361,6 +361,10 @@ FOR_EACH_VALUE(DECLARE_PREDICATE)
// specific than any type. // specific than any type.
bool CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const; bool CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const;
// Compile time constants, Bool, Smi and Nulls do not need to update
// the store buffer.
bool NeedsStoreBuffer() const;
virtual bool Equals(Value* other) const = 0; virtual bool Equals(Value* other) const = 0;
virtual Value* CopyValue() = 0; virtual Value* CopyValue() = 0;

View file

@ -901,12 +901,12 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
__ j(ABOVE_EQUAL, deopt); __ j(ABOVE_EQUAL, deopt);
// Note that index is Smi, i.e, times 2. // Note that index is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1); ASSERT(kSmiTagShift == 1);
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space. __ StoreIntoObject(receiver,
__ movl(FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)), FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)),
value); value);
} else { } else {
__ StoreIntoObject(receiver, __ StoreIntoObjectNoBarrier(receiver,
FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)), FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)),
value); value);
} }
@ -919,12 +919,12 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
__ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
// Note that index is Smi, i.e, times 2. // Note that index is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1); ASSERT(kSmiTagShift == 1);
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space. __ StoreIntoObject(temp,
__ movl(FieldAddress(temp, index, TIMES_2, sizeof(RawArray)), FieldAddress(temp, index, TIMES_2, sizeof(RawArray)),
value); value);
} else { } else {
__ StoreIntoObject(temp, __ StoreIntoObjectNoBarrier(temp,
FieldAddress(temp, index, TIMES_2, sizeof(RawArray)), FieldAddress(temp, index, TIMES_2, sizeof(RawArray)),
value); value);
} }
@ -998,12 +998,12 @@ void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(ic_data() != NULL); ASSERT(ic_data() != NULL);
compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt);
} }
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space.
__ movl(FieldAddress(instance_reg, field().Offset()), value_reg);
} else {
__ StoreIntoObject(instance_reg, __ StoreIntoObject(instance_reg,
FieldAddress(instance_reg, field().Offset()), value_reg); FieldAddress(instance_reg, field().Offset()), value_reg);
} else {
__ StoreIntoObjectNoBarrier(instance_reg,
FieldAddress(instance_reg, field().Offset()), value_reg);
} }
} }
@ -1037,11 +1037,11 @@ void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(locs()->out().reg() == value); ASSERT(locs()->out().reg() == value);
__ LoadObject(temp, field()); __ LoadObject(temp, field());
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space.
__ movl(FieldAddress(temp, Field::value_offset()), value);
} else {
__ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
} else {
__ StoreIntoObjectNoBarrier(
temp, FieldAddress(temp, Field::value_offset()), value);
} }
} }

View file

@ -920,12 +920,12 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
__ j(ABOVE_EQUAL, deopt); __ j(ABOVE_EQUAL, deopt);
// Note that index is Smi, i.e, times 4. // Note that index is Smi, i.e, times 4.
ASSERT(kSmiTagShift == 1); ASSERT(kSmiTagShift == 1);
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space. __ StoreIntoObject(receiver,
__ movq(FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)),
value); value);
} else { } else {
__ StoreIntoObject(receiver, __ StoreIntoObjectNoBarrier(receiver,
FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)),
value); value);
} }
@ -939,12 +939,12 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
__ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
// Note that index is Smi, i.e, times 4. // Note that index is Smi, i.e, times 4.
ASSERT(kSmiTagShift == 1); ASSERT(kSmiTagShift == 1);
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space. __ StoreIntoObject(temp,
__ movq(FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), FieldAddress(temp, index, TIMES_4, sizeof(RawArray)),
value); value);
} else { } else {
__ StoreIntoObject(temp, __ StoreIntoObjectNoBarrier(temp,
FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), FieldAddress(temp, index, TIMES_4, sizeof(RawArray)),
value); value);
} }
@ -1018,12 +1018,12 @@ void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(ic_data() != NULL); ASSERT(ic_data() != NULL);
compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt); compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, temp_reg, deopt);
} }
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space.
__ movq(FieldAddress(instance_reg, field().Offset()), value_reg);
} else {
__ StoreIntoObject(instance_reg, __ StoreIntoObject(instance_reg,
FieldAddress(instance_reg, field().Offset()), value_reg); FieldAddress(instance_reg, field().Offset()), value_reg);
} else {
__ StoreIntoObjectNoBarrier(instance_reg,
FieldAddress(instance_reg, field().Offset()), value_reg);
} }
} }
@ -1057,11 +1057,11 @@ void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(locs()->out().reg() == value); ASSERT(locs()->out().reg() == value);
__ LoadObject(temp, field()); __ LoadObject(temp, field());
if (this->value()->BindsToConstant()) { if (this->value()->NeedsStoreBuffer()) {
// Compile time constants are Smi or allocated in the old space.
__ movq(FieldAddress(temp, Field::value_offset()), value);
} else {
__ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
} else {
__ StoreIntoObjectNoBarrier(
temp, FieldAddress(temp, Field::value_offset()), value);
} }
} }