Chromium Code Reviews| Index: runtime/vm/assembler_x64.cc |
| =================================================================== |
| --- runtime/vm/assembler_x64.cc (revision 41724) |
| +++ runtime/vm/assembler_x64.cc (working copy) |
| @@ -2384,6 +2384,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; |
| @@ -2436,6 +2439,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; |
| @@ -2871,12 +2877,44 @@ |
| } |
| +void Assembler::Verify(const Address& dest) { |
|
Ivan Posva
2014/11/14 22:16:06
ditto about the name.
koda
2014/11/17 17:08:59
Done, matching ia32.
|
| + if (VerifiedMemory::enabled()) { |
| + Register dest_addr = RDX; |
| + Register old_value = RBX; |
| + pushq(dest_addr); |
| + pushq(old_value); |
| + leaq(dest_addr, dest); |
| + movq(old_value, Address(dest_addr, 0)); |
| + cmpq(old_value, Address(dest_addr, VerifiedMemory::offset())); |
| + Label ok; |
| + j(EQUAL, &ok, Assembler::kNearJump); |
|
Ivan Posva
2014/11/14 22:16:07
Will be a forced far jump.
koda
2014/11/17 17:09:00
Good point; removed hint.
|
| + Stop("Write barrier verification failed"); |
| + Bind(&ok); |
| + popq(old_value); |
| + popq(dest_addr); |
| + } |
| +} |
| + |
| + |
| +void Assembler::VerifiedWrite(const Address& dest, Register value) { |
| + Verify(dest); |
| + movq(dest, value); |
| + if (VerifiedMemory::enabled()) { |
| + Register temp = (value == RDX) ? RCX : RDX; |
| + pushq(temp); |
| + leaq(temp, dest); |
| + movq(Address(temp, VerifiedMemory::offset()), value); |
| + popq(temp); |
| + } |
| +} |
| + |
| + |
| void Assembler::StoreIntoObject(Register object, |
| const Address& dest, |
| Register value, |
| bool can_value_be_smi) { |
| ASSERT(object != value); |
| - movq(dest, value); |
| + VerifiedWrite(dest, value); |
| Label done; |
| if (can_value_be_smi) { |
| StoreIntoObjectFilter(object, value, &done); |
| @@ -2898,7 +2936,7 @@ |
| void Assembler::StoreIntoObjectNoBarrier(Register object, |
| const Address& dest, |
| Register value) { |
| - movq(dest, value); |
| + VerifiedWrite(dest, value); |
| #if defined(DEBUG) |
| Label done; |
| pushq(value); |
| @@ -2911,6 +2949,48 @@ |
| } |
| +void Assembler::StoreIntoSmiField(const Address& dest, Register value) { |
| + VerifiedWrite(dest, value); |
| +#if defined(DEBUG) |
| + Label done; |
| + testq(value, Immediate(kHeapObjectTag)); |
| + j(ZERO, &done); |
| + Stop("Smi expected"); |
| + Bind(&done); |
| +#endif // defined(DEBUG) |
| +} |
| + |
| + |
| +void Assembler::ZeroSmiField(const Address& dest) { |
| + Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization. |
| + Immediate zero(Smi::RawValue(0)); |
| + movq(dest, zero); |
| + if (VerifiedMemory::enabled()) { |
| + Register temp = RCX; |
| + pushq(temp); |
| + leaq(temp, dest); |
| + movq(Address(temp, VerifiedMemory::offset()), zero); |
| + popq(temp); |
| + } |
| +} |
| + |
| + |
| +void Assembler::IncrementSmiField(const Address& dest, int64_t increment) { |
| + // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on |
| + // the length of this instruction sequence. |
| + Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization. |
| + Immediate inc_imm(Smi::RawValue(increment)); |
| + addq(dest, inc_imm); |
| + if (VerifiedMemory::enabled()) { |
| + Register temp = RCX; |
| + pushq(temp); |
| + leaq(temp, dest); |
| + addq(Address(temp, VerifiedMemory::offset()), inc_imm); |
| + popq(temp); |
| + } |
| +} |
| + |
| + |
| void Assembler::DoubleNegate(XmmRegister d) { |
| static const struct ALIGN16 { |
| uint64_t a; |