Chromium Code Reviews| Index: runtime/vm/assembler_ia32.cc |
| diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc |
| index 72bd938eb74664c3e0133b0228d395cd6284556c..04534c7814e9ef0521c587c1ff7c2272c388574e 100644 |
| --- a/runtime/vm/assembler_ia32.cc |
| +++ b/runtime/vm/assembler_ia32.cc |
| @@ -13,6 +13,8 @@ |
| namespace dart { |
| +DECLARE_RUNTIME_ENTRY(StoreBuffer); |
| + |
| DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| DEFINE_FLAG(bool, code_comments, false, |
| "Include comments into code and disassembly"); |
| @@ -1365,8 +1367,58 @@ void Assembler::CompareObject(Register reg, const Object& object) { |
| void Assembler::StoreIntoObject(Register object, |
| const FieldAddress& dest, |
| Register value) { |
| - // TODO(iposva): Add write barrier. |
| movl(dest, value); |
| + Label done; |
| + // Check that 'value' is a new object. Store buffer updates are not |
| + // required when storing a smi or an old object. |
| + testl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); |
| + j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + // Check that 'object' is an old object. A store buffer update is |
| + // not required when storing into a new object. |
| + testl(object, Immediate(kOldObjectAlignmentOffset | kHeapObjectTag)); |
| + j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + // A store buffer update is required. |
| + pushl(object); // Save 'object' register |
| + pushl(value); // Save 'value' register |
| + pushl(dest); // Push argument |
| + CallRuntime(kStoreBufferRuntimeEntry); |
|
srdjan
2012/06/15 21:12:08
I'd rather have a CallLeafRuntime which would stor
cshapiro
2012/06/15 23:17:32
Per our off-line discussion, I have added a pushal
|
| + popl(value); // Pop argument |
| + popl(value); // Restore 'value' register |
| + popl(object); // Restore 'object' register |
| + Bind(&done); |
| +} |
| + |
| + |
| +void Assembler::StoreIntoObjectNoBarrier(Register object, |
| + const FieldAddress& dest, |
| + Register value) { |
| + movl(dest, value); |
| +#if defined(DEBUG) |
| + Label done; |
| + testl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag)); |
| + j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + testl(object, Immediate(kOldObjectAlignmentOffset | kHeapObjectTag)); |
| + j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + Stop("Store buffer update is required"); |
| + Bind(&done); |
| +#endif |
| + // No store buffer update. |
| +} |
| + |
| + |
| +void Assembler::StoreIntoObjectNoBarrier(Register object, |
| + const FieldAddress& dest, |
| + const Object& value) { |
| + if (value.IsSmi()) { |
| + movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw()))); |
| + } else { |
| + ASSERT(value.IsOld()); |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + EmitUint8(0xC7); |
| + EmitOperand(0, dest); |
| + buffer_.EmitObject(value); |
| + } |
| + // No store buffer update. |
| } |