Chromium Code Reviews| Index: runtime/vm/assembler_ia32.cc |
| diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc |
| index 9a6c5112f8c1b073b161dd32c56c0e8dfcc3c4a7..7c700b48a27ed4bc25b779fb7cfc536e052ca1c5 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"); |
| @@ -1364,8 +1366,54 @@ 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 |
|
cshapiro
2012/06/12 21:41:01
Apparently, this store is not legal since it is an
|
| + CallRuntime(kStoreBufferRuntimeEntry); |
| + 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); |
| + // No store buffer update. |
| +#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 |
| +} |
| + |
| + |
| +void Assembler::StoreIntoObjectNoBarrier(Register object, |
| + const FieldAddress& dest, |
| + const Immediate& value) { |
| + movl(dest, value); |
|
srdjan
2012/06/12 06:57:08
I do not think this works as the inlined value is
cshapiro
2012/06/12 21:41:01
Thanks. I have changed the code to use EmitObject
|
| + // No store buffer update. |
| + int addr = value.value(); |
| + bool is_smi = ((addr & kHeapObjectTag) == 0); |
| + bool is_old = ((addr & (kOldObjectAlignmentOffset | kHeapObjectTag)) == 1); |
| + ASSERT(is_smi || is_old); |
| } |