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()) { |