Chromium Code Reviews| Index: runtime/vm/assembler_ia32.cc |
| =================================================================== |
| --- runtime/vm/assembler_ia32.cc (revision 41700) |
| +++ runtime/vm/assembler_ia32.cc (working copy) |
| @@ -1945,6 +1945,9 @@ |
| void Assembler::j(Condition condition, Label* label, bool near) { |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + if (VerifiedMemory::enabled()) { |
| + near = Assembler::kFarJump; |
| + } |
| if (label->IsBound()) { |
| static const int kShortSize = 2; |
| static const int kLongSize = 6; |
| @@ -1987,6 +1990,9 @@ |
| void Assembler::jmp(Label* label, bool near) { |
| AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + if (VerifiedMemory::enabled()) { |
| + near = Assembler::kFarJump; |
| + } |
| if (label->IsBound()) { |
| static const int kShortSize = 2; |
| static const int kLongSize = 5; |
| @@ -2199,8 +2205,27 @@ |
| } |
| +void Assembler::Verify(const Address& dest) { |
|
Ivan Posva
2014/11/14 22:09:11
Verify is a bit too generic a name for this functi
koda
2014/11/17 16:17:11
Renamed to VerifyHeapWord.
|
| + if (VerifiedMemory::enabled()) { |
| + Register dest_addr = EDX; |
| + Register old_value = EBX; |
| + pushl(dest_addr); |
|
Ivan Posva
2014/11/14 22:09:11
Some comments explaining what is going on here wou
koda
2014/11/17 16:17:11
Done. Also improved naming of vars/params.
|
| + pushl(old_value); |
| + leal(dest_addr, dest); |
| + movl(old_value, Address(dest_addr, 0)); |
| + cmpl(old_value, Address(dest_addr, VerifiedMemory::offset())); |
| + Label ok; |
| + j(EQUAL, &ok, Assembler::kNearJump); |
| + Stop("Write barrier verification failed"); |
| + Bind(&ok); |
| + popl(old_value); |
| + popl(dest_addr); |
| + } |
| +} |
| + |
| + |
| void Assembler::VerifiedWrite(const Address& dest, Register value) { |
| - // TODO(koda): Verify previous value. |
| + Verify(dest); |
| movl(dest, value); |
| if (VerifiedMemory::enabled()) { |
| Register temp = (value == EDX) ? ECX : EDX; |
| @@ -2271,8 +2296,8 @@ |
| void Assembler::StoreIntoObjectNoBarrier(Register object, |
| const Address& dest, |
| const Object& value) { |
| + Verify(dest); |
| if (value.IsSmi() || value.InVMHeap()) { |
| - // TODO(koda): Verify previous value. |
| Immediate imm_value(reinterpret_cast<int32_t>(value.raw())); |
| movl(dest, imm_value); |
| if (VerifiedMemory::enabled()) { |
| @@ -2309,8 +2334,8 @@ |
| void Assembler::ZeroSmiField(const Address& dest) { |
| + Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization. |
| Immediate zero(Smi::RawValue(0)); |
| - // TODO(koda): Verify previous value. |
| movl(dest, zero); |
| if (VerifiedMemory::enabled()) { |
| Register temp = ECX; |
| @@ -2325,8 +2350,7 @@ |
| void Assembler::IncrementSmiField(const Address& dest, int32_t increment) { |
| // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on |
| // the length of this instruction sequence. |
| - // |
| - // TODO(koda): Implement testl for addresses and check that dest is a smi. |
| + Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization. |
| Immediate inc_imm(Smi::RawValue(increment)); |
| addl(dest, inc_imm); |
| if (VerifiedMemory::enabled()) { |