| Index: runtime/vm/assembler_x64.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_x64.cc (revision 41785)
|
| +++ 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,46 @@
|
| }
|
|
|
|
|
| +void Assembler::VerifyHeapWord(const Address& address) {
|
| + if (VerifiedMemory::enabled()) {
|
| + Register addr_reg = RDX;
|
| + Register value = RBX;
|
| + // Preserve registers.
|
| + pushq(addr_reg);
|
| + pushq(value);
|
| + leaq(addr_reg, address);
|
| + // ASSERT(*address == *(address + offset))
|
| + movq(value, Address(addr_reg, 0));
|
| + cmpq(value, Address(addr_reg, VerifiedMemory::offset()));
|
| + Label ok;
|
| + j(EQUAL, &ok);
|
| + Stop("Write barrier verification failed");
|
| + Bind(&ok);
|
| + popq(value);
|
| + popq(addr_reg);
|
| + }
|
| +}
|
| +
|
| +
|
| +void Assembler::VerifiedWrite(const Address& dest, Register value) {
|
| + VerifyHeapWord(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 +2938,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 +2951,50 @@
|
| }
|
|
|
|
|
| +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) {
|
| + // TODO(koda): Add VerifySmi once we distinguish initalization.
|
| + VerifyHeapWord(dest);
|
| + 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.
|
| + // TODO(koda): Add VerifySmi once we distinguish initalization.
|
| + VerifyHeapWord(dest);
|
| + 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;
|
|
|