| Index: runtime/vm/assembler_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_ia32.cc (revision 41779)
|
| +++ 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,29 @@
|
| }
|
|
|
|
|
| +void Assembler::VerifyHeapWord(const Address& address) {
|
| + if (VerifiedMemory::enabled()) {
|
| + Register addr_reg = EDX;
|
| + Register value = EBX;
|
| + // Preserve registers.
|
| + pushl(addr_reg);
|
| + pushl(value);
|
| + leal(addr_reg, address);
|
| + // ASSERT(*address == *(address + offset))
|
| + movl(value, Address(addr_reg, 0));
|
| + cmpl(value, Address(addr_reg, VerifiedMemory::offset()));
|
| + Label ok;
|
| + j(EQUAL, &ok, Assembler::kNearJump);
|
| + Stop("Write barrier verification failed");
|
| + Bind(&ok);
|
| + popl(value);
|
| + popl(addr_reg);
|
| + }
|
| +}
|
| +
|
| +
|
| void Assembler::VerifiedWrite(const Address& dest, Register value) {
|
| - // TODO(koda): Verify previous value.
|
| + VerifyHeapWord(dest);
|
| movl(dest, value);
|
| if (VerifiedMemory::enabled()) {
|
| Register temp = (value == EDX) ? ECX : EDX;
|
| @@ -2271,8 +2298,8 @@
|
| void Assembler::StoreIntoObjectNoBarrier(Register object,
|
| const Address& dest,
|
| const Object& value) {
|
| + VerifyHeapWord(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 +2336,9 @@
|
|
|
|
|
| void Assembler::ZeroSmiField(const Address& dest) {
|
| + // TODO(koda): Add VerifySmi once we distinguish initalization.
|
| + VerifyHeapWord(dest);
|
| Immediate zero(Smi::RawValue(0));
|
| - // TODO(koda): Verify previous value.
|
| movl(dest, zero);
|
| if (VerifiedMemory::enabled()) {
|
| Register temp = ECX;
|
| @@ -2325,8 +2353,8 @@
|
| 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.
|
| + // TODO(koda): Add VerifySmi once we distinguish initalization.
|
| + VerifyHeapWord(dest);
|
| Immediate inc_imm(Smi::RawValue(increment));
|
| addl(dest, inc_imm);
|
| if (VerifiedMemory::enabled()) {
|
|
|