// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_BASE_H_
#define RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_BASE_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "platform/assert.h"
#include "platform/unaligned.h"
#include "vm/allocation.h"
#include "vm/compiler/assembler/object_pool_builder.h"
#include "vm/compiler/runtime_api.h"
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/hash_map.h"

namespace dart {

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
    defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
DECLARE_FLAG(bool, use_far_branches);
#endif

class MemoryRegion;
class Slot;

namespace compiler {

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
// On ARM and ARM64 branch-link family of instructions puts return address
// into a dedicated register (LR), which called code will then preserve
// manually if needed. To ensure that LR is not clobbered accidentally we
// discourage direct use of the register and instead require users to wrap
// their code in one of the macroses below, which would verify that it is
// safe to modify LR.
// We use RELEASE_ASSERT instead of ASSERT because we use LR state (tracked
// by the assembler) to generate different code sequences for write barriers
// so we would like to ensure that incorrect code will trigger an assertion
// instead of producing incorrect code.

// Class representing the state of LR register. In addition to tracking
// whether LR currently contain return address or not it also tracks
// entered frames - and whether they preserved a return address or not.
class LRState {
 public:
  LRState(const LRState&) = default;
  LRState& operator=(const LRState&) = default;

  bool LRContainsReturnAddress() const {
    RELEASE_ASSERT(!IsUnknown());
    return (state_ & kLRContainsReturnAddressMask) != 0;
  }

  LRState SetLRContainsReturnAddress(bool v) const {
    RELEASE_ASSERT(!IsUnknown());
    return LRState(frames_, v ? (state_ | 1) : (state_ & ~1));
  }

  // Returns a |LRState| representing a state after pushing current value
  // of LR on the stack. LR is assumed clobberable in the new state.
  LRState EnterFrame() const {
    RELEASE_ASSERT(!IsUnknown());
    // 1 bit is used for LR state the rest for frame states.
    constexpr auto kMaxFrames = (sizeof(state_) * kBitsPerByte) - 1;
    RELEASE_ASSERT(frames_ < kMaxFrames);
    // LSB will be clear after the shift meaning that LR can be clobbered.
    return LRState(frames_ + 1, state_ << 1);
  }

  // Returns a |LRState| representing a state after popping  LR from the stack.
  // Note that for inner frames LR would usually be assumed cloberrable
  // even after leaving a frame. Only outerframe would restore return address
  // into LR.
  LRState LeaveFrame() const {
    RELEASE_ASSERT(!IsUnknown());
    RELEASE_ASSERT(frames_ > 0);
    return LRState(frames_ - 1, state_ >> 1);
  }

  bool IsUnknown() const { return *this == Unknown(); }

  static LRState Unknown() { return LRState(kUnknownMarker, kUnknownMarker); }

  static LRState OnEntry() { return LRState(0, 1); }

  static LRState Clobbered() { return LRState(0, 0); }

  bool operator==(const LRState& other) const {
    return frames_ == other.frames_ && state_ == other.state_;
  }

 private:
  LRState(uint8_t frames, uint8_t state) : frames_(frames), state_(state) {}

  // LR state is encoded in the LSB of state_ bitvector.
  static constexpr uint8_t kLRContainsReturnAddressMask = 1;

  static constexpr uint8_t kUnknownMarker = 0xFF;

  // Number of frames on the stack or kUnknownMarker when representing
  // Unknown state.
  uint8_t frames_ = 0;

  // Bit vector with frames_ + 1 bits: LSB represents LR state, other bits
  // represent state of LR in each entered frame. Normally this value would
  // just be (1 << frames_).
  uint8_t state_ = 1;
};

// READS_RETURN_ADDRESS_FROM_LR(...) macro verifies that LR contains return
// address before allowing to use it.
#define READS_RETURN_ADDRESS_FROM_LR(block)                                    \
  do {                                                                         \
    RELEASE_ASSERT(__ lr_state().LRContainsReturnAddress());                   \
    constexpr Register LR = LR_DO_NOT_USE_DIRECTLY;                            \
    USE(LR);                                                                   \
    block;                                                                     \
  } while (0)

// WRITES_RETURN_ADDRESS_TO_LR(...) macro verifies that LR contains return
// address before allowing to write into it. LR is considered to still
// contain return address after this operation.
#define WRITES_RETURN_ADDRESS_TO_LR(block) READS_RETURN_ADDRESS_FROM_LR(block)

// CLOBBERS_LR(...) checks that LR does *not* contain return address and it is
// safe to clobber it.
#define CLOBBERS_LR(block)                                                     \
  do {                                                                         \
    RELEASE_ASSERT(!(__ lr_state().LRContainsReturnAddress()));                \
    constexpr Register LR = LR_DO_NOT_USE_DIRECTLY;                            \
    USE(LR);                                                                   \
    block;                                                                     \
  } while (0)

// SPILLS_RETURN_ADDRESS_FROM_LR_TO_REGISTER(...) checks that LR contains return
// address, executes |block| and marks that LR can be safely clobbered
// afterwards (assuming that |block| moved LR value onto into another register).
#define SPILLS_RETURN_ADDRESS_FROM_LR_TO_REGISTER(block)                       \
  do {                                                                         \
    READS_RETURN_ADDRESS_FROM_LR(block);                                       \
    __ set_lr_state(__ lr_state().SetLRContainsReturnAddress(false));          \
  } while (0)

// RESTORES_RETURN_ADDRESS_FROM_REGISTER_TO_LR(...) checks that LR does not
// contain return address, executes |block| and marks LR as containing return
// address (assuming that |block| restored LR value from another register).
#define RESTORES_RETURN_ADDRESS_FROM_REGISTER_TO_LR(block)                     \
  do {                                                                         \
    CLOBBERS_LR(block);                                                        \
    __ set_lr_state(__ lr_state().SetLRContainsReturnAddress(true));           \
  } while (0)

// SPILLS_LR_TO_FRAME(...) executes |block| and updates tracked LR state to
// record that we entered a frame which preserved LR. LR can be clobbered
// afterwards.
#define SPILLS_LR_TO_FRAME(block)                                              \
  do {                                                                         \
    constexpr Register LR = LR_DO_NOT_USE_DIRECTLY;                            \
    USE(LR);                                                                   \
    block;                                                                     \
    __ set_lr_state(__ lr_state().EnterFrame());                               \
  } while (0)

// RESTORE_LR(...) checks that LR does not contain return address, executes
// |block| and updates tracked LR state to record that we exited a frame.
// Whether LR contains return address or not after this operation depends on
// the frame state (only the outermost frame usually restores LR).
#define RESTORES_LR_FROM_FRAME(block)                                          \
  do {                                                                         \
    CLOBBERS_LR(block);                                                        \
    __ set_lr_state(__ lr_state().LeaveFrame());                               \
  } while (0)
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)

enum OperandSize {
  // Architecture-independent constants.
  kByte,
  kUnsignedByte,
  kTwoBytes,  // Halfword (ARM), w(ord) (Intel)
  kUnsignedTwoBytes,
  kFourBytes,  // Word (ARM), l(ong) (Intel)
  kUnsignedFourBytes,
  kEightBytes,  // DoubleWord (ARM), q(uadword) (Intel)
  // ARM-specific constants.
  kSWord,
  kDWord,
  // 32-bit ARM specific constants.
  kWordPair,
  kRegList,
  // 64-bit ARM specific constants.
  kQWord,

#if defined(HAS_SMI_63_BITS)
  kObjectBytes = kEightBytes,
#else
  kObjectBytes = kFourBytes,
#endif
};

// For declaring default sizes in AssemblerBase.
#if defined(TARGET_ARCH_IS_64_BIT)
constexpr OperandSize kWordBytes = kEightBytes;
#else
constexpr OperandSize kWordBytes = kFourBytes;
#endif

// Forward declarations.
class Assembler;
class AssemblerFixup;
class AssemblerBuffer;
class Address;
class FieldAddress;

#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
class Label : public ZoneAllocated {
 public:
  Label() {}
  ~Label() {
    // Assert if label is being destroyed with unresolved branches pending.
    ASSERT(!IsLinked());
  }

  intptr_t Position() const {
    ASSERT(IsBound());
    return position_;
  }

  bool IsBound() const { return position_ != -1; }
  bool IsUnused() const { return !IsBound() && !IsLinked(); }
  bool IsLinked() const {
    return unresolved_cb_ != -1 || unresolved_cj_ != -1 ||
           unresolved_b_ != -1 || unresolved_j_ != -1 || unresolved_far_ != -1;
  }

 private:
  int32_t position_ = -1;
  void BindTo(intptr_t position) {
    ASSERT(!IsBound());
    ASSERT(!IsLinked());
    position_ = position;
    ASSERT(IsBound());
  }

  // Linked lists of unresolved forward branches, threaded through the branch
  // instructions. The offset encoded in each unresolved branch the delta to the
  // next instruction in the list, terminated with 0 delta. Each branch class
  // has a separate list because the offset range of each is different.
#define DEFINE_BRANCH_CLASS(name)                                              \
  int32_t unresolved_##name##_ = -1;                                           \
  int32_t link_##name(int32_t position) {                                      \
    ASSERT(position > unresolved_##name##_);                                   \
    int32_t offset;                                                            \
    if (unresolved_##name##_ == -1) {                                          \
      offset = 0;                                                              \
    } else {                                                                   \
      offset = position - unresolved_##name##_;                                \
      ASSERT(offset > 0);                                                      \
    }                                                                          \
    unresolved_##name##_ = position;                                           \
    return offset;                                                             \
  }
  DEFINE_BRANCH_CLASS(cb);
  DEFINE_BRANCH_CLASS(cj);
  DEFINE_BRANCH_CLASS(b);
  DEFINE_BRANCH_CLASS(j);
  DEFINE_BRANCH_CLASS(far);

  friend class MicroAssembler;
  DISALLOW_COPY_AND_ASSIGN(Label);
};
#else
class Label : public ZoneAllocated {
 public:
  Label() : position_(0), unresolved_(0) {
#ifdef DEBUG
    for (int i = 0; i < kMaxUnresolvedBranches; i++) {
      unresolved_near_positions_[i] = -1;
    }
#endif  // DEBUG
  }

  ~Label() {
    // Assert if label is being destroyed with unresolved branches pending.
    ASSERT(!IsLinked());
    ASSERT(!HasNear());
  }

  // Returns the position for bound and linked labels. Cannot be used
  // for unused labels.
  intptr_t Position() const {
    ASSERT(!IsUnused());
    return IsBound() ? -position_ - kBias : position_ - kBias;
  }

  intptr_t LinkPosition() const {
    ASSERT(IsLinked());
    return position_ - kBias;
  }

  intptr_t NearPosition() {
    ASSERT(HasNear());
    return unresolved_near_positions_[--unresolved_];
  }

  bool IsBound() const { return position_ < 0; }
  bool IsUnused() const { return position_ == 0 && unresolved_ == 0; }
  bool IsLinked() const { return position_ > 0; }
  bool HasNear() const { return unresolved_ != 0; }

 private:
#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
  static constexpr int kMaxUnresolvedBranches = 20;
#else
  static constexpr int kMaxUnresolvedBranches = 1;  // Unused on non-Intel.
#endif
  // Zero position_ means unused (neither bound nor linked to).
  // Thus we offset actual positions by the given bias to prevent zero
  // positions from occurring.
  // Note: we use target::kWordSize as a bias because on ARM
  // there are assertions that check that distance is aligned.
  static constexpr int kBias = 4;

  intptr_t position_;
  intptr_t unresolved_;
  intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  // On ARM/ARM64 we track LR state: whether it contains return address or
  // whether it can be clobbered. To make sure that our tracking it correct
  // for non linear code sequences we additionally verify at labels that
  // incoming states are compatible.
  LRState lr_state_ = LRState::Unknown();

  void UpdateLRState(LRState new_state) {
    if (lr_state_.IsUnknown()) {
      lr_state_ = new_state;
    } else {
      RELEASE_ASSERT(lr_state_ == new_state);
    }
  }
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)

  void Reinitialize() { position_ = 0; }

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  void BindTo(intptr_t position, LRState lr_state)
#else
  void BindTo(intptr_t position)
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  {
    ASSERT(!IsBound());
    ASSERT(!HasNear());
    position_ = -position - kBias;
    ASSERT(IsBound());
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
    UpdateLRState(lr_state);
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  }

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  void LinkTo(intptr_t position, LRState lr_state)
#else
  void LinkTo(intptr_t position)
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  {
    ASSERT(!IsBound());
    position_ = position + kBias;
    ASSERT(IsLinked());
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
    UpdateLRState(lr_state);
#endif  // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
  }

  void NearLinkTo(intptr_t position) {
    ASSERT(!IsBound());
    ASSERT(unresolved_ < kMaxUnresolvedBranches);
    unresolved_near_positions_[unresolved_++] = position;
  }

  friend class Assembler;
  DISALLOW_COPY_AND_ASSIGN(Label);
};
#endif

// External labels keep a function pointer to allow them
// to be called from code generated by the assembler.
class ExternalLabel : public ValueObject {
 public:
  explicit ExternalLabel(uword address) : address_(address) {}

  bool is_resolved() const { return address_ != 0; }
  uword address() const {
    ASSERT(is_resolved());
    return address_;
  }

 private:
  const uword address_;
};

// Assembler fixups are positions in generated code that hold relocation
// information that needs to be processed before finalizing the code
// into executable memory.
class AssemblerFixup : public ZoneAllocated {
 public:
  virtual void Process(const MemoryRegion& region, intptr_t position) = 0;

  virtual bool IsPointerOffset() const = 0;

  // It would be ideal if the destructor method could be made private,
  // but the g++ compiler complains when this is subclassed.
  virtual ~AssemblerFixup() { UNREACHABLE(); }

 private:
  AssemblerFixup* previous_;
  intptr_t position_;

  AssemblerFixup* previous() const { return previous_; }
  void set_previous(AssemblerFixup* previous) { previous_ = previous; }

  intptr_t position() const { return position_; }
  void set_position(intptr_t position) { position_ = position; }

  friend class AssemblerBuffer;
};

// Assembler buffers are used to emit binary code. They grow on demand.
class AssemblerBuffer : public ValueObject {
 public:
  AssemblerBuffer();
  ~AssemblerBuffer();

  // Basic support for emitting, loading, and storing.
  template <typename T>
  void Emit(T value) {
    ASSERT(HasEnsuredCapacity());
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
    // Variable-length instructions in ia32/x64 have unaligned immediates.
    // Instruction parcels in RISC-V are only 2-byte aligned.
    StoreUnaligned(reinterpret_cast<T*>(cursor_), value);
#else
    // Other architecture have aligned, fixed-length instructions.
    *reinterpret_cast<T*>(cursor_) = value;
#endif
    cursor_ += sizeof(T);
  }

  template <typename T>
  void Remit() {
    ASSERT(Size() >= static_cast<intptr_t>(sizeof(T)));
    cursor_ -= sizeof(T);
  }

  // Return address to code at |position| bytes.
  uword Address(intptr_t position) { return contents_ + position; }

  template <typename T>
  T Load(intptr_t position) {
    ASSERT(position >= 0 &&
           position <= (Size() - static_cast<intptr_t>(sizeof(T))));
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
    // Variable-length instructions in ia32/x64 have unaligned immediates.
    // Instruction parcels in RISC-V are only 2-byte aligned.
    return LoadUnaligned(reinterpret_cast<T*>(contents_ + position));
#else
    // Other architecture have aligned, fixed-length instructions.
    return *reinterpret_cast<T*>(contents_ + position);
#endif
  }

  template <typename T>
  void Store(intptr_t position, T value) {
    ASSERT(position >= 0 &&
           position <= (Size() - static_cast<intptr_t>(sizeof(T))));
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) ||                   \
    defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
    // Variable-length instructions in ia32/x64 have unaligned immediates.
    // Instruction parcels in RISC-V are only 2-byte aligned.
    StoreUnaligned(reinterpret_cast<T*>(contents_ + position), value);
#else
    // Other architecture have aligned, fixed-length instructions.
    *reinterpret_cast<T*>(contents_ + position) = value;
#endif
  }

  const ZoneGrowableArray<intptr_t>& pointer_offsets() const {
#if defined(DEBUG)
    ASSERT(fixups_processed_);
#endif
    return *pointer_offsets_;
  }

#if defined(TARGET_ARCH_IA32)
  // Emit an object pointer directly in the code.
  void EmitObject(const Object& object);
#endif

  // Emit a fixup at the current location.
  void EmitFixup(AssemblerFixup* fixup) {
    fixup->set_previous(fixup_);
    fixup->set_position(Size());
    fixup_ = fixup;
  }

  // Count the fixups that produce a pointer offset, without processing
  // the fixups.
  intptr_t CountPointerOffsets() const;

  // Get the size of the emitted code.
  intptr_t Size() const { return cursor_ - contents_; }
  uword contents() const { return contents_; }

  // Copy the assembled instructions into the specified memory block
  // and apply all fixups.
  void FinalizeInstructions(const MemoryRegion& region);

  // To emit an instruction to the assembler buffer, the EnsureCapacity helper
  // must be used to guarantee that the underlying data area is big enough to
  // hold the emitted instruction. Usage:
  //
  //     AssemblerBuffer buffer;
  //     AssemblerBuffer::EnsureCapacity ensured(&buffer);
  //     ... emit bytes for single instruction ...

#if defined(DEBUG)
  class EnsureCapacity : public ValueObject {
   public:
    explicit EnsureCapacity(AssemblerBuffer* buffer);
    ~EnsureCapacity();

   private:
    AssemblerBuffer* buffer_;
    intptr_t gap_;

    intptr_t ComputeGap() { return buffer_->Capacity() - buffer_->Size(); }
  };

  bool has_ensured_capacity_;
  bool HasEnsuredCapacity() const { return has_ensured_capacity_; }
#else
  class EnsureCapacity : public ValueObject {
   public:
    explicit EnsureCapacity(AssemblerBuffer* buffer) {
      if (buffer->cursor() >= buffer->limit()) buffer->ExtendCapacity();
    }
  };

  // When building the C++ tests, assertion code is enabled. To allow
  // asserting that the user of the assembler buffer has ensured the
  // capacity needed for emitting, we add a dummy method in non-debug mode.
  bool HasEnsuredCapacity() const { return true; }
#endif

  // Returns the position in the instruction stream.
  intptr_t GetPosition() const { return cursor_ - contents_; }

  void Reset() { cursor_ = contents_; }

 private:
  // The limit is set to kMinimumGap bytes before the end of the data area.
  // This leaves enough space for the longest possible instruction and allows
  // for a single, fast space check per instruction.
  static constexpr intptr_t kMinimumGap = 32;

  uword contents_;
  uword cursor_;
  uword limit_;
  AssemblerFixup* fixup_;
  ZoneGrowableArray<intptr_t>* pointer_offsets_;
#if defined(DEBUG)
  bool fixups_processed_;
#endif

  uword cursor() const { return cursor_; }
  uword limit() const { return limit_; }
  intptr_t Capacity() const {
    ASSERT(limit_ >= contents_);
    return (limit_ - contents_) + kMinimumGap;
  }

  // Process the fixup chain.
  void ProcessFixups(const MemoryRegion& region);

  // Compute the limit based on the data area and the capacity. See
  // description of kMinimumGap for the reasoning behind the value.
  static uword ComputeLimit(uword data, intptr_t capacity) {
    return data + capacity - kMinimumGap;
  }

  void ExtendCapacity();

  friend class AssemblerFixup;
};

class AssemblerBase : public StackResource {
 public:
  explicit AssemblerBase(ObjectPoolBuilder* object_pool_builder)
      : StackResource(ThreadState::Current()),
        object_pool_builder_(object_pool_builder) {}
  virtual ~AssemblerBase();

  // Used for near/far jumps on IA32/X64, ignored for ARM.
  enum JumpDistance : bool {
    kFarJump = false,
    kNearJump = true,
  };

  intptr_t CodeSize() const { return buffer_.Size(); }

  uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }

  bool HasObjectPoolBuilder() const { return object_pool_builder_ != nullptr; }
  ObjectPoolBuilder& object_pool_builder() { return *object_pool_builder_; }

  intptr_t prologue_offset() const { return prologue_offset_; }
  bool has_monomorphic_entry() const { return has_monomorphic_entry_; }

  // Tracks if the resulting code should be aligned by kPreferredLoopAlignment
  // boundary.
  void mark_should_be_aligned() { should_be_aligned_ = true; }
  bool should_be_aligned() const { return should_be_aligned_; }

  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
  static bool EmittingComments();

  virtual void Breakpoint() = 0;

  virtual void SmiTag(Register r) = 0;

  virtual void Bind(Label* label) = 0;

  // If Smis are compressed and the Smi value in dst is non-negative, ensures
  // the upper bits are cleared. If Smis are not compressed, is a no-op.
  //
  // Since this operation only affects the unused upper bits when Smis are
  // compressed, it can be used on registers not allocated as writable.
  //
  // The behavior on the upper bits of signed compressed Smis is undefined.
#if defined(DART_COMPRESSED_POINTERS)
  virtual void ExtendNonNegativeSmi(Register dst) {
    // Default to sign extension and allow architecture-specific assemblers
    // where an alternative like zero-extension is preferred to override this.
    ExtendValue(dst, dst, kObjectBytes);
  }
#else
  void ExtendNonNegativeSmi(Register dst) {}
#endif

  // Extends a value of size sz in src to a value of size kWordBytes in dst.
  // That is, bits in the source register that are not part of the sz-sized
  // value are ignored, and if sz is signed, then the value is sign extended.
  //
  // Produces no instructions if dst and src are the same and sz is kWordBytes.
  virtual void ExtendValue(Register dst, Register src, OperandSize sz) = 0;

  // Extends a value of size sz in src to a tagged Smi value in dst.
  // That is, bits in the source register that are not part of the sz-sized
  // value are ignored, and if sz is signed, then the value is sign extended.
  virtual void ExtendAndSmiTagValue(Register dst,
                                    Register src,
                                    OperandSize sz) {
    ExtendValue(dst, src, sz);
    SmiTag(dst);
  }

  // Move the contents of src into dst.
  //
  // Produces no instructions if dst and src are the same.
  virtual void MoveRegister(Register dst, Register src) {
    ExtendValue(dst, src, kWordBytes);
  }

  // Move the contents of src into dst and tag the value in dst as a Smi.
  virtual void MoveAndSmiTagRegister(Register dst, Register src) {
    ExtendAndSmiTagValue(dst, src, kWordBytes);
  }

  // Inlined allocation in new space of an instance of an object whose instance
  // size is known at compile time with class ID 'cid'. The generated code has
  // no runtime calls. Jump to 'failure' if the instance cannot be allocated
  // here and should be done via runtime call instead.
  //
  // ObjectPtr to allocated instance is returned in 'instance_reg'.
  //
  // WARNING: The caller is responsible for initializing all GC-visible fields
  // of the object other than the tags field, which is initialized here.
  virtual void TryAllocateObject(intptr_t cid,
                                 intptr_t instance_size,
                                 Label* failure,
                                 JumpDistance distance,
                                 Register instance_reg,
                                 Register temp) = 0;

  // An alternative version of TryAllocateObject that takes a Class object
  // and passes the class id and instance size to TryAllocateObject along with
  // the other arguments.
  void TryAllocate(const Class& cls,
                   Label* failure,
                   JumpDistance distance,
                   Register instance_reg,
                   Register temp) {
    TryAllocateObject(target::Class::GetId(cls),
                      target::Class::GetInstanceSize(cls), failure, distance,
                      instance_reg, temp);
  }

  virtual void BranchIfSmi(Register reg,
                           Label* label,
                           JumpDistance distance = kFarJump) = 0;

  // [reg] = [reg] << [shift]
  virtual void LslImmediate(Register reg,
                            int32_t shift,
                            OperandSize sz = kWordBytes) = 0;

  // [dst] = [src] << [shift]
  virtual void LslImmediate(Register dst,
                            Register src,
                            int32_t shift,
                            OperandSize sz = kWordBytes) = 0;

  // [reg] = [reg] >>> [shift]
  //
  // Assumes [sz] is a signed OperandSize.
  virtual void ArithmeticShiftRightImmediate(Register reg,
                                             int32_t shift,
                                             OperandSize sz = kWordBytes) = 0;

  // [dst] = [src] >>> [shift]
  //
  // Assumes [sz] is a signed OperandSize.
  virtual void ArithmeticShiftRightImmediate(Register dst,
                                             Register src,
                                             int32_t shift,
                                             OperandSize sz = kWordBytes) = 0;
  virtual void CompareWords(Register reg1,
                            Register reg2,
                            intptr_t offset,
                            Register count,
                            Register temp,
                            Label* equals) = 0;

  void UnrolledMemCopy(Register dst_base,
                       intptr_t dst_offset,
                       Register src_base,
                       intptr_t src_offset,
                       intptr_t size,
                       Register temp);
  enum CanBeSmi {
    kValueCanBeSmi,
    kValueIsNotSmi,
  };

  enum MemoryOrder {
    // All previous writes to memory in this thread must be visible to other
    // threads. Currently, only used for lazily populating hash indices in
    // shared const maps and sets.
    kRelease,
    kAcquire,

    // All other stores.
    kRelaxedNonAtomic,
  };

  virtual void LoadFieldAddressForOffset(Register reg,
                                         Register base,
                                         int32_t offset) = 0;
  virtual void LoadFieldAddressForRegOffset(
      Register address,
      Register instance,
      Register offset_in_words_as_smi) = 0;

  virtual void LoadAcquire(Register dst,
                           const Address& address,
                           OperandSize size = kWordBytes) = 0;
  virtual void StoreRelease(Register src,
                            const Address& address,
                            OperandSize size = kWordBytes) = 0;

  virtual void Load(Register dst,
                    const Address& address,
                    OperandSize sz = kWordBytes) = 0;
  // Does not use write barriers, use StoreIntoObject instead for boxed fields.
  virtual void Store(Register src,
                     const Address& address,
                     OperandSize sz = kWordBytes) = 0;

  // When emitting the write barrier code on IA32, either the caller must
  // allocate a scratch register or the implementation chooses a register to
  // save and restore and uses that as a scratch register internally.
  // Thus, the scratch register is an additional optional argument to
  // StoreIntoObject, StoreIntoArray, StoreIntoObjectOffset, and StoreBarrier
  // that defaults to TMP on other architectures. (TMP is kNoRegister on IA32,
  // so the default value invokes the correct behavior.)

  // Store into a heap object and applies the appropriate write barriers.
  // (See StoreBarrier for which are applied on a given architecture.)
  //
  // All stores into heap objects must pass through this function or,
  // if the value can be proven either Smi or old-and-premarked, its NoBarrier
  // variant. Preserves the [object] and [value] registers.
  void StoreIntoObject(Register object,         // Object being stored into.
                       const Address& address,  // Offset into object.
                       Register value,          // Value being stored.
                       CanBeSmi can_be_smi = kValueCanBeSmi,
                       MemoryOrder memory_order = kRelaxedNonAtomic,
                       Register scratch = TMP,
                       OperandSize size = kWordBytes);

  void StoreIntoObjectNoBarrier(Register object,  // Object being stored into.
                                const Address& address,  // Offset into object.
                                Register value,          // Value being stored.
                                MemoryOrder memory_order = kRelaxedNonAtomic,
                                OperandSize size = kWordBytes);
  virtual void StoreObjectIntoObjectNoBarrier(
      Register object,         // Object being stored into.
      const Address& address,  // Offset into object.
      const Object& value,     // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic,
      OperandSize size = kWordBytes) = 0;

  virtual void LoadIndexedPayload(Register dst,
                                  Register base,
                                  int32_t offset,
                                  Register index,
                                  ScaleFactor scale,
                                  OperandSize sz = kWordBytes) = 0;

  // For virtual XOffset methods, the base method implementation creates an
  // appropriate address from the base register and offset and calls the
  // corresponding address-taking method. These should be overridden for
  // architectures where offsets should not be converted to addresses without
  // additional precautions, for when the ARM-specific Assembler needs
  // to override with an overloaded version for the Condition argument,
  // or for when the IA32-specific Assembler needs to override with an
  // overloaded version for adding a scratch register argument.

  void LoadAcquireFromOffset(Register dst,
                             Register base,
                             int32_t offset = 0,
                             OperandSize size = kWordBytes);
  void StoreReleaseToOffset(Register src,
                            Register base,
                            int32_t offset = 0,
                            OperandSize size = kWordBytes);

  virtual void LoadFromOffset(Register dst,
                              Register base,
                              int32_t offset,
                              OperandSize sz = kWordBytes);
  // Does not use write barriers, use StoreIntoObject instead for boxed fields.
  virtual void StoreToOffset(Register src,
                             Register base,
                             int32_t offset,
                             OperandSize sz = kWordBytes);

  virtual void StoreIntoObjectOffset(
      Register object,  // Object being stored into.
      int32_t offset,   // Offset into object.
      Register value,   // Value being stored.
      CanBeSmi can_be_smi = kValueCanBeSmi,
      MemoryOrder memory_order = kRelaxedNonAtomic,
      Register scratch = TMP,
      OperandSize size = kWordBytes);
  virtual void StoreIntoObjectOffsetNoBarrier(
      Register object,  // Object being stored into.
      int32_t offset,   // Offset into object.
      Register value,   // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic,
      OperandSize size = kWordBytes);
  void StoreObjectIntoObjectOffsetNoBarrier(
      Register object,      // Object being stored into.
      int32_t offset,       // Offset into object.
      const Object& value,  // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic,
      OperandSize size = kWordBytes);

  void LoadField(Register dst,
                 const FieldAddress& address,
                 OperandSize sz = kWordBytes);
  virtual void LoadFieldFromOffset(Register dst,
                                   Register base,
                                   int32_t offset,
                                   OperandSize sz = kWordBytes);

  // Does not use write barriers, use StoreIntoObjectOffset instead for
  // boxed fields.
  virtual void StoreFieldToOffset(Register src,
                                  Register base,
                                  int32_t offset,
                                  OperandSize sz = kWordBytes);

  // Loads a Smi. In DEBUG mode, also checks that the loaded value is a Smi and
  // halts if not.
  void LoadSmi(Register dst, const Address& address) {
    Load(dst, address);
    DEBUG_ONLY(VerifySmi(dst));
  }

  // Loads a Smi field from a Dart object. In DEBUG mode, also checks that the
  // loaded value is a Smi and halts if not.
  void LoadSmiField(Register dst, const FieldAddress& address);

  // Loads a Smi. In DEBUG mode, also checks that the loaded value is a Smi and
  // halts if not.
  void LoadSmiFromOffset(Register dst, Register base, int32_t offset);

  // Loads a Smi field from a Dart object. In DEBUG mode, also checks that the
  // loaded value is a Smi and halts if not.
  void LoadSmiFieldFromOffset(Register dst, Register base, int32_t offset);

#if defined(DART_COMPRESSED_POINTERS)
  // These are the base methods that all other compressed methods delegate to.
  //
  // For the virtual methods, they are only virtual when using compressed
  // pointers, so the overriding definitions must be guarded with an #ifdef.

  virtual void LoadCompressedFieldAddressForRegOffset(
      Register address,
      Register instance,
      Register offset_in_words_as_smi) = 0;

  virtual void LoadAcquireCompressed(Register dst, const Address& address) = 0;

  virtual void LoadCompressed(Register dst, const Address& address) = 0;

  virtual void LoadIndexedCompressed(Register dst,
                                     Register base,
                                     int32_t offset,
                                     Register index) = 0;

  // Loads a compressed Smi. In DEBUG mode, also checks that the loaded value is
  // a Smi and halts if not.
  void LoadCompressedSmi(Register dst, const Address& address) {
    Load(dst, address, kUnsignedFourBytes);  // Zero extension.
    DEBUG_ONLY(VerifySmi(dst);)
  }
#else
  // These are the base methods that all other compressed methods delegate to.
  //
  // The methods are non-virtual and forward to the uncompressed versions.

  void LoadCompressedFieldAddressForRegOffset(Register address,
                                              Register instance,
                                              Register offset_in_words_as_smi) {
    LoadFieldAddressForRegOffset(address, instance, offset_in_words_as_smi);
  }

  void LoadAcquireCompressed(Register dst, const Address& address) {
    LoadAcquire(dst, address);
  }

  void LoadCompressed(Register dst, const Address& address) {
    Load(dst, address);
  }

  void LoadIndexedCompressed(Register dst,
                             Register base,
                             int32_t offset,
                             Register index) {
    LoadIndexedPayload(dst, base, offset, index, TIMES_WORD_SIZE, kWordBytes);
  }

  // Loads a compressed Smi. In DEBUG mode, also checks that the loaded value is
  // a Smi and halts if not.
  void LoadCompressedSmi(Register dst, const Address& address) {
    LoadSmi(dst, address);
  }
#endif  // defined(DART_COMPRESSED_POINTERS)

  // Compressed store methods are implemented in AssemblerBase, as the only
  // difference is whether the entire word is stored or just the low bits.

  void StoreReleaseCompressed(Register src, const Address& address) {
    StoreRelease(src, address, kObjectBytes);
  }
  void StoreReleaseCompressedToOffset(Register src,
                                      Register base,
                                      int32_t offset = 0) {
    StoreReleaseToOffset(src, base, offset, kObjectBytes);
  }

  void StoreCompressedIntoObject(
      Register object,         // Object being stored into.
      const Address& address,  // Address to store the value at.
      Register value,          // Value being stored.
      CanBeSmi can_be_smi = kValueCanBeSmi,
      MemoryOrder memory_order = kRelaxedNonAtomic,
      Register scratch = TMP) {
    StoreIntoObject(object, address, value, can_be_smi, memory_order, TMP,
                    kObjectBytes);
  }
  void StoreCompressedIntoObjectNoBarrier(
      Register object,         // Object being stored into.
      const Address& address,  // Address to store the value at.
      Register value,          // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic) {
    StoreIntoObjectNoBarrier(object, address, value, memory_order,
                             kObjectBytes);
  }
  virtual void StoreCompressedObjectIntoObjectNoBarrier(
      Register object,         // Object being stored into.
      const Address& address,  // Address to store the value at.
      const Object& value,     // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic) {
    StoreObjectIntoObjectNoBarrier(object, address, value, memory_order,
                                   kObjectBytes);
  }

  void StoreCompressedIntoObjectOffset(
      Register object,  // Object being stored into.
      int32_t offset,   // Offset into object.
      Register value,   // Value being stored.
      CanBeSmi can_be_smi = kValueCanBeSmi,
      MemoryOrder memory_order = kRelaxedNonAtomic,
      Register scratch = TMP) {
    StoreIntoObjectOffset(object, offset, value, can_be_smi, memory_order, TMP,
                          kObjectBytes);
  }
  void StoreCompressedIntoObjectOffsetNoBarrier(
      Register object,  // Object being stored into.
      int32_t offset,   // Offset into object.
      Register value,   // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic) {
    StoreIntoObjectOffsetNoBarrier(object, offset, value, memory_order,
                                   kObjectBytes);
  }
  void StoreCompressedObjectIntoObjectOffsetNoBarrier(
      Register object,      // Object being stored into.
      int32_t offset,       // Offset into object.
      const Object& value,  // Value being stored.
      MemoryOrder memory_order = kRelaxedNonAtomic) {
    StoreObjectIntoObjectOffsetNoBarrier(object, offset, value, memory_order,
                                         kObjectBytes);
  }

  void StoreIntoArray(Register object,
                      Register slot,
                      Register value,
                      CanBeSmi can_value_be_smi = kValueCanBeSmi,
                      Register scratch = TMP,
                      OperandSize size = kWordBytes);
  void StoreCompressedIntoArray(Register object,
                                Register slot,
                                Register value,
                                CanBeSmi can_value_be_smi = kValueCanBeSmi,
                                Register scratch = TMP) {
    StoreIntoArray(object, slot, value, can_value_be_smi, scratch,
                   kObjectBytes);
  }

  // These methods just delegate to the non-Field classes, either passing
  // along a FieldAddress as the Address or adjusting the offset appropriately.

  void LoadAcquireCompressedFromOffset(Register dst,
                                       Register base,
                                       int32_t offset);
  void LoadAcquireCompressedFieldFromOffset(Register dst,
                                            Register base,
                                            int32_t offset);
  void LoadCompressedField(Register dst, const FieldAddress& address);
  void LoadCompressedFromOffset(Register dst, Register base, int32_t offset);
  void LoadCompressedFieldFromOffset(Register dst,
                                     Register base,
                                     int32_t offset);
  void LoadCompressedSmiField(Register dst, const FieldAddress& address);
  void LoadCompressedSmiFromOffset(Register dst, Register base, int32_t offset);
  void LoadCompressedSmiFieldFromOffset(Register dst,
                                        Register base,
                                        int32_t offset);

  // There are no StoreCompressedField methods because only Dart objects contain
  // compressed pointers and compressed pointers may require write barriers, so
  // StoreCompressedIntoObject should be used instead.

  void LoadFromSlot(Register dst,
                    Register base,
                    const Slot& slot,
                    MemoryOrder memory_order = kRelaxedNonAtomic);
  void StoreToSlot(Register src,
                   Register base,
                   const Slot& slot,
                   CanBeSmi can_be_smi,
                   MemoryOrder memory_order = kRelaxedNonAtomic,
                   Register scratch = TMP);
  void StoreToSlotNoBarrier(Register src,
                            Register base,
                            const Slot& slot,
                            MemoryOrder memory_order = kRelaxedNonAtomic);
  // Uses the type information of the Slot to determine whether the field
  // can be a Smi or not.
  void StoreToSlot(Register src,
                   Register base,
                   const Slot& slot,
                   MemoryOrder memory_order = kRelaxedNonAtomic,
                   Register scratch = TMP);

  // Truncates upper bits.
  virtual void LoadInt32FromBoxOrSmi(Register result, Register value) = 0;

#if !defined(TARGET_ARCH_IS_32_BIT)
  virtual void LoadInt64FromBoxOrSmi(Register result, Register value) = 0;
#endif

  // Truncates upper bits on 32 bit archs.
  void LoadWordFromBoxOrSmi(Register result, Register value) {
#if defined(TARGET_ARCH_IS_32_BIT)
    LoadInt32FromBoxOrSmi(result, value);
#else
    LoadInt64FromBoxOrSmi(result, value);
#endif
  }

  // Loads nullability from an AbstractType [type] to [dst].
  void LoadAbstractTypeNullability(Register dst, Register type);
  // Loads nullability from an AbstractType [type] and compares it
  // to [value]. Clobbers [scratch].
  void CompareAbstractTypeNullabilityWith(Register type,
                                          /*Nullability*/ int8_t value,
                                          Register scratch);

  // [dst] = [base] + ([index] << [scale]) + [disp].
  //
  // Base can be kNoRegister (or ZR if available), in which case
  //   [dst] = [index] << [scale] + [disp]
  // with a set of emitted instructions optimized for that case.
  virtual void AddScaled(Register dst,
                         Register base,
                         Register index,
                         ScaleFactor scale,
                         int32_t disp) = 0;

  virtual void LoadImmediate(Register dst, target::word imm) = 0;

  virtual void CompareImmediate(Register reg,
                                target::word imm,
                                OperandSize width = kWordBytes) = 0;

  virtual void CompareWithMemoryValue(Register value,
                                      Address address,
                                      OperandSize size = kWordBytes) = 0;

  // [reg] = [reg] & [imm]
  virtual void AndImmediate(Register reg,
                            target::word imm,
                            OperandSize sz = kWordBytes) = 0;

  // [dst] = [src] & [imm]
  virtual void AndImmediate(Register dst,
                            Register src,
                            target::word imm,
                            OperandSize sz = kWordBytes) = 0;

  virtual void LsrImmediate(Register dst, int32_t shift) = 0;

  virtual void MulImmediate(Register dst,
                            target::word imm,
                            OperandSize = kWordBytes) = 0;

  // If src2 == kNoRegister, dst = dst & src1, otherwise dst = src1 & src2.
  virtual void AndRegisters(Register dst,
                            Register src1,
                            Register src2 = kNoRegister) = 0;

  // dst = dst << shift. On some architectures, we must use a specific register
  // for the shift, so either the shift register must be that specific register
  // or the architecture must define a TMP register, which is clobbered.
  virtual void LslRegister(Register dst, Register shift) = 0;

  // Performs CombineHashes from runtime/vm/hash.h on the hashes contained in
  // dst and other. Puts the result in dst. Clobbers other.
  //
  // Note: Only uses the lower 32 bits of the hashes and returns a 32 bit hash.
  virtual void CombineHashes(Register dst, Register other) = 0;
  // Performs FinalizeHash from runtime/vm/hash.h on the hash contained in
  // dst. May clobber scratch if provided, otherwise may clobber TMP.
  //
  // Note: Only uses the lower 32 bits of the hash and returns a 32 bit hash.
  void FinalizeHash(Register hash, Register scratch = TMP) {
    return FinalizeHashForSize(/*bit_size=*/kBitsPerInt32, hash, scratch);
  }
  // Performs FinalizeHash from runtime/vm/hash.h on the hash contained in
  // dst and returns the result, masked to a maximum of [bit_size] bits.
  // May clobber scratch if provided, otherwise may clobber TMP.
  //
  // Note: Only uses the lower 32 bits of the hash. Since the underlying
  // algorithm produces 32-bit values, assumes 0 < [bit_size] <= 32.
  virtual void FinalizeHashForSize(intptr_t bit_size,
                                   Register hash,
                                   Register scratch = TMP) = 0;

  void LoadTypeClassId(Register dst, Register src);

  virtual void EnsureHasClassIdInDEBUG(intptr_t cid,
                                       Register src,
                                       Register scratch,
                                       bool can_be_null = false) = 0;

  intptr_t InsertAlignedRelocation(BSS::Relocation reloc);

  void MsanUnpoison(Register base, intptr_t length_in_bytes);
  void MsanUnpoison(Register base, Register length_in_bytes);

  void Unimplemented(const char* message);
  void Untested(const char* message);
  void Unreachable(const char* message);
  void Stop(const char* message);

  void FinalizeInstructions(const MemoryRegion& region) {
    buffer_.FinalizeInstructions(region);
  }

  // Count the fixups that produce a pointer offset, without processing
  // the fixups.
  intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); }

  const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
    return buffer_.pointer_offsets();
  }

  class CodeComment : public ZoneAllocated {
   public:
    CodeComment(intptr_t pc_offset, const String& comment)
        : pc_offset_(pc_offset), comment_(comment) {}

    intptr_t pc_offset() const { return pc_offset_; }
    const String& comment() const { return comment_; }

   private:
    intptr_t pc_offset_;
    const String& comment_;

    DISALLOW_COPY_AND_ASSIGN(CodeComment);
  };

  const GrowableArray<CodeComment*>& comments() const { return comments_; }

  void BindUncheckedEntryPoint() {
    ASSERT(unchecked_entry_offset_ == 0);
    unchecked_entry_offset_ = CodeSize();
  }

  // Returns the offset (from the very beginning of the instructions) to the
  // unchecked entry point (incl. prologue/frame setup, etc.).
  intptr_t UncheckedEntryOffset() const { return unchecked_entry_offset_; }

  enum RangeCheckCondition {
    kIfNotInRange = 0,
    kIfInRange = 1,
  };

  // Jumps to [target] if [condition] is satisfied.
  //
  // [low] and [high] are inclusive.
  // If [temp] is kNoRegister, then [value] is overwritten.
  // Note: Using a valid [temp] register generates an additional
  //       instruction on x64/ia32.
  virtual void RangeCheck(Register value,
                          Register temp,
                          intptr_t low,
                          intptr_t high,
                          RangeCheckCondition condition,
                          Label* target) = 0;

  // Checks [dst] for a Smi, halting if it does not contain one.
  void VerifySmi(Register dst) {
    Label done;
    BranchIfSmi(dst, &done, kNearJump);
    Stop("Expected Smi");
    Bind(&done);
  }

  static inline intptr_t OperandSizeInBits(OperandSize os) {
    switch (os) {
      case kByte:
      case kUnsignedByte:
        return kBitsPerInt8;
      case kTwoBytes:
      case kUnsignedTwoBytes:
        return kBitsPerInt16;
      case kFourBytes:
      case kUnsignedFourBytes:
        return kBitsPerInt32;
      case kEightBytes:
        return kBitsPerInt64;
      default:
        UNREACHABLE();
        return kBitsPerInt64;
    }
  }

  static inline bool IsSignedOperand(OperandSize os) {
    switch (os) {
      case kByte:
      case kTwoBytes:
      case kFourBytes:
      case kEightBytes:
        return true;
      case kUnsignedByte:
      case kUnsignedTwoBytes:
      case kUnsignedFourBytes:
      case kSWord:
      case kDWord:
      case kQWord:
        return false;
      default:
        UNREACHABLE();
        break;
    }
    return false;
  }

  static inline bool NeedsSignExtension(OperandSize os) {
    if (!IsSignedOperand(os)) return false;
    switch (os) {
      case kByte:
      case kTwoBytes:
        return true;
      case kFourBytes:
#if defined(TARGET_ARCH_IS_32_BIT)
        return false;
#else
        return true;
#endif
#if defined(TARGET_ARCH_IS_64_BIT)
      case kEightBytes:
        return false;
#endif
      default:
        UNREACHABLE();
        return false;
    }
  }

 protected:
  AssemblerBuffer buffer_;  // Contains position independent code.
  int32_t prologue_offset_ = -1;
  bool has_monomorphic_entry_ = false;
  bool should_be_aligned_ = false;

  intptr_t unchecked_entry_offset_ = 0;

 private:
  // Apply the generational write barrier on all architectures and incremental
  // write barrier on non-IA32 architectures.
  //
  // On IA32, since the incremental write barrier is not applied,
  // concurrent marking cannot be enabled.
  virtual void StoreBarrier(Register object,  // Object being stored into.
                            Register value,   // Value being stored.
                            CanBeSmi can_be_smi,
                            Register scratch) = 0;

  // Apply the generational write barrier on all architectures and incremental
  // write barrier on non-IA32 architectures when storing into an array.
  //
  // On IA32, since the incremental write barrier is not applied,
  // concurrent marking cannot be enabled.
  virtual void ArrayStoreBarrier(Register object,  // Object being stored into.
                                 Register slot,    // Slot being stored into.
                                 Register value,   // Value being stored.
                                 CanBeSmi can_be_smi,
                                 Register scratch) = 0;

  // Checks that storing [value] into [object] does not require a write barrier.
  virtual void VerifyStoreNeedsNoWriteBarrier(Register object,
                                              Register value) = 0;

  GrowableArray<CodeComment*> comments_;
  ObjectPoolBuilder* object_pool_builder_;
};

// For leaf runtime calls. For non-leaf runtime calls, use
// Assembler::CallRuntime.
class LeafRuntimeScope : public ValueObject {
 public:
  // Enters a frame, saves registers, and aligns the stack according to the C
  // ABI.
  //
  // If [preserve_registers] is false, only registers normally preserved at a
  // Dart call will be preserved (SP, FP, THR, PP, CODE_REG, RA). Suitable for
  // use in IL instructions marked with LocationSummary::kCall.
  // If [preserve registers] is true, all registers allocatable by Dart (roughly
  // everything but TMP, TMP2) will be preserved. Suitable for non-call IL
  // instructions like the write barrier.
  LeafRuntimeScope(Assembler* assembler,
                   intptr_t frame_size,
                   bool preserve_registers);

  // Restores registers and leaves the frame.
  ~LeafRuntimeScope();

  // Sets the current tag, calls the runtime function, and restores the current
  // tag.
  void Call(const RuntimeEntry& entry, intptr_t argument_count);

 private:
  Assembler* const assembler_;
  const bool preserve_registers_;
};

}  // namespace compiler

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_BASE_H_
