// Copyright 2017, VIXL authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of ARM Limited nor the names of its contributors may be
//     used to endorse or promote products derived from this software without
//     specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "test-pool-manager.h"

#include <stdio.h>

#include "pool-manager-impl.h"
#include "pool-manager.h"
#include "test-runner.h"

#define TEST(Name) TEST_(POOL_MANAGER_##Name)

#define IF_VERBOSE(exp) \
  if (Test::verbose()) exp

#define BUFFER_ALIGNMENT 16

using namespace vixl;

static int Random() { return static_cast<int>(std::abs(mrand48())); }

static int RandomObjectID(size_t num_objects) { return Random() % num_objects; }

static int RandomObjectSize() { return 1 + Random() % 256; }

static int RandomObjectAlignment(int size) {
  const int limit = static_cast<int>(floor(log2(BUFFER_ALIGNMENT)));
  int log2Size = static_cast<int>(floor(log2(size)));
  // Restrict alignment due to buffer alignment.
  log2Size = std::min(log2Size, limit);
  return (1 << (Random() % (1 + log2Size)));
}

// The size of the instruction.
static int RandomReferenceSize() { return (Random() % 2) ? 2 : 4; }

// The alignment of an instruction is either 2 or 4.
static int RandomInstructionAlignment() { return (Random() % 2) ? 2 : 4; }

static int32_t RandomMinOffset() {
  const int N = 3;
  static const int offsets[N] = {0, 2, 4};
  return offsets[Random() % N];
}

static int32_t RandomMaxOffset() {
  const int N = 5;
  static const int offsets[N] = {255, 1020, 1024, 4096, 16384};
  return offsets[Random() % N];
}

static int32_t RandomBranchMaxOffset() {
  const int N = 10;
  // The maximum offsets used for testing are taken from A32 and T32.
  static const int offsets[N] =
      {126, 254, 255, 1020, 1024, 2046, 4095, 1048574, 16777214, 33554428};
  return offsets[Random() % N];
}

static int RandomPCIncrement() {
  // A multiple of two.
  return 2 * (Random() % 4 + 1);
}

class TestObject : public LocationBase<int32_t> {
 public:
  TestObject(int size, int alignment, int id = 0)
      : LocationBase(0 /*type*/, size, alignment), id_(id) {}

  void EmitPoolObject(MacroAssemblerInterface *masm) VIXL_OVERRIDE {
    USE(masm);
  }

  bool ShouldDeletePoolObjectOnPlacement() const VIXL_OVERRIDE { return true; }

  // Update the references to this object.
  void ResolveReferences(internal::AssemblerBase *assembler) VIXL_OVERRIDE {
    int32_t location = GetLocation();
    USE(assembler);
    for (std::vector<ForwardReference<int32_t> *>::iterator iter =
             references_.begin();
         iter != references_.end();) {
      ForwardReference<int32_t> *ref = *iter;
      VIXL_ASSERT(ref->LocationIsEncodable(location));
      delete ref;
      iter = references_.erase(iter);
    }
    IF_VERBOSE(printf("Placed object %d at location: 0x%x (%u)\n",
                      id_,
                      location,
                      location));
  }

  void AddReference(ForwardReference<int32_t> *ref) {
    references_.push_back(ref);
  }

  int GetID() { return id_; }

  static TestObject *CreateRandom(int id) {
    int size = RandomObjectSize();
    int alignment = RandomObjectAlignment(size);
    IF_VERBOSE(printf("Object %d -> size = %d, alignment = %d\n",
                      id,
                      size,
                      alignment));
    return new TestObject(size, alignment, id);
  }

 private:
  // Store pointers to ForwardReference objects - TestObject is responsible
  // for deleting them.
  std::vector<ForwardReference<int32_t> *> references_;
  // Object id used for debugging.
  int id_;
};

class TestBranchObject : public LocationBase<int32_t> {
 public:
  TestBranchObject(int size, int alignment, int id = 0)
      : LocationBase(1 /* type */, size, alignment), id_(id) {}

  bool UsePoolObjectEmissionMargin() const VIXL_OVERRIDE { return true; }
  int32_t GetPoolObjectEmissionMargin() const VIXL_OVERRIDE {
    return 1 * KBytes;
  }

  // Do nothing for now.
  void EmitPoolObject(MacroAssemblerInterface *masm) VIXL_OVERRIDE {
    USE(masm);
  }

  bool ShouldDeletePoolObjectOnPlacement() const VIXL_OVERRIDE { return false; }

  virtual void UpdatePoolObject(PoolObject<int32_t> *object) VIXL_OVERRIDE {
    // Reference from the last emitted veneer:
    int32_t min = location_ + min_offset_;
    int32_t max = location_ + max_offset_;
    // The alignment that the new "veneer" requires of the label.
    int reference_alignment = RandomInstructionAlignment();
    reference_alignment =
        std::max(reference_alignment, GetPoolObjectAlignment());
    ForwardReference<int32_t> *ref =
        new ForwardReference<int32_t>(location_,
                                      4 /*size*/,
                                      min,
                                      max,
                                      reference_alignment);
    AddReference(ref);
    object->Update(min, max, reference_alignment);
  }

  // Update the references to this object.
  void ResolveReferences(internal::AssemblerBase *assembler) VIXL_OVERRIDE {
    int32_t location = GetLocation();
    USE(assembler);
    for (std::vector<ForwardReference<int32_t> *>::iterator iter =
             references_.begin();
         iter != references_.end();) {
      ForwardReference<int32_t> *ref = *iter;
      VIXL_ASSERT(ref->LocationIsEncodable(location));
      delete ref;
      iter = references_.erase(iter);
    }
    IF_VERBOSE(printf("Veneer %d placed at location: 0x%x (%u)\n",
                      id_,
                      location,
                      location));
  }

  void AddReference(ForwardReference<int32_t> *ref) {
    references_.push_back(ref);
  }

  virtual int GetMaxAlignment() const VIXL_OVERRIDE {
    int max_alignment = GetPoolObjectAlignment();
    for (std::vector<ForwardReference<int32_t> *>::const_iterator iter =
             references_.begin();
         iter != references_.end();
         ++iter) {
      const ForwardReference<int32_t> *ref = *iter;
      if (ref->GetAlignment() > max_alignment)
        max_alignment = ref->GetAlignment();
    }
    return max_alignment;
  }
  virtual int32_t GetMinLocation() const VIXL_OVERRIDE {
    int32_t min_location = 0;
    for (std::vector<ForwardReference<int32_t> *>::const_iterator iter =
             references_.begin();
         iter != references_.end();
         ++iter) {
      const ForwardReference<int32_t> *ref = *iter;
      if (ref->GetMinLocation() > min_location)
        min_location = ref->GetMinLocation();
    }
    return min_location;
  }

  int GetID() { return id_; }

  static TestBranchObject *CreateRandom(int id) {
    int size = RandomReferenceSize();
    int alignment = size;
    IF_VERBOSE(printf("Object %d -> size = %d, alignment = %d\n",
                      id,
                      size,
                      alignment));
    return new TestBranchObject(size, alignment, id);
  }

 private:
  // Store pointers to ForwardReference objects - TestBranchObject is
  // responsible for deleting them.
  std::vector<ForwardReference<int32_t> *> references_;
  // Object id used for debugging.
  int id_;

  // These are the min and max offsets of the type of branch used for the
  // veneer.
  static const int32_t min_offset_ = 0;
  static const int32_t max_offset_ = 16 * 1024 * 1024;
};

// MacroAssembler implementation that does nothing but print in verbose mode.
class TestMacroAssembler : public MacroAssemblerInterface {
 public:
  TestMacroAssembler() : assembler_(128) {}

  void EmitPoolHeader() VIXL_OVERRIDE {
    IF_VERBOSE(printf("[MASM] Emitting pool header.\n"));
  }
  void EmitPoolFooter() VIXL_OVERRIDE {
    IF_VERBOSE(printf("[MASM] Emitting pool footer.\n"));
  }
  void EmitPaddingBytes(int n) VIXL_OVERRIDE {
    IF_VERBOSE(printf("[MASM] Added %d bytes of padding.\n", n));
  }
  void EmitNopBytes(int n) VIXL_OVERRIDE {
    IF_VERBOSE(printf("[MASM] Added %d bytes of NOPs.\n", n));
  }
  bool ArePoolsBlocked() const VIXL_OVERRIDE { return false; }
  bool AllowMacroInstructions() const VIXL_OVERRIDE { return false; }
  void SetAllowMacroInstructions(bool allow) VIXL_OVERRIDE { USE(allow); }

  void BlockPools() VIXL_OVERRIDE {}
  void ReleasePools() VIXL_OVERRIDE {}
  void EnsureEmitPoolsFor(size_t) VIXL_OVERRIDE {}
  internal::AssemblerBase *AsAssemblerBase() VIXL_OVERRIDE {
    return &assembler_;
  }

 private:
  internal::AssemblerBase assembler_;
};

// Used for debugging.
namespace vixl {
template <>
void PoolManager<int32_t>::DumpCurrentState(int32_t pc) const {
  IF_VERBOSE(
      printf("Number of objects: %d\n", static_cast<int>(objects_.size())));
  IF_VERBOSE(printf("Current pc = 0x%x (%d)\n", pc, pc));

  for (int i = 0; i < static_cast<int>(objects_.size()); ++i) {
    const PoolObject<int32_t> &object = objects_[i];
    IF_VERBOSE(
        printf("Object %d -> size = %d, alignment = %d, range = (%d,%d)\n",
               i,
               object.label_base_->GetPoolObjectSizeInBytes(),
               object.alignment_,
               object.min_location_,
               object.max_location_));
  }
}
}

// Basic test - checks that emitting a very simple pool works.
TEST(Basic) {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  TestObject object1(4 /*size*/, 4 /*alignment*/);
  TestObject object2(128 /*size*/, 4 /*alignment*/);
  ForwardReference<int32_t> *ref1_obj1 =
      new ForwardReference<int32_t>(0 /*location*/, 2 /*size*/, 0, 200);
  ForwardReference<int32_t> *ref2_obj1 =
      new ForwardReference<int32_t>(2 /*location*/, 2 /*size*/, 2, 202);
  ForwardReference<int32_t> *ref3_obj1 =
      new ForwardReference<int32_t>(4 /*location*/, 2 /*size*/, 4, 204);
  object1.AddReference(ref1_obj1);
  object1.AddReference(ref2_obj1);
  object1.AddReference(ref3_obj1);
  ForwardReference<int32_t> *ref1_obj2 =
      new ForwardReference<int32_t>(8 /*location*/, 2 /*size*/, 8, 500);
  ForwardReference<int32_t> *ref2_obj2 =
      new ForwardReference<int32_t>(12 /*location*/, 4 /*size*/, 12, 300);
  ForwardReference<int32_t> *ref3_obj2 =
      new ForwardReference<int32_t>(16 /*location*/, 4 /*size*/, 16, 400);
  object2.AddReference(ref1_obj2);
  object2.AddReference(ref2_obj2);
  object2.AddReference(ref3_obj2);

  pool_manager.AddObjectReference(ref1_obj1, &object1);
  pool_manager.AddObjectReference(ref2_obj1, &object1);
  pool_manager.AddObjectReference(ref3_obj1, &object1);
  pool_manager.AddObjectReference(ref1_obj2, &object2);
  pool_manager.AddObjectReference(ref2_obj2, &object2);
  pool_manager.AddObjectReference(ref3_obj2, &object2);

  pool_manager.Emit(&masm, 20);
}

static ForwardReference<int32_t> *CreateReference(int id,
                                                  int32_t pc,
                                                  int size,
                                                  int32_t min_offset,
                                                  int32_t max_offset,
                                                  int alignment) {
  IF_VERBOSE(printf(
      "About to add a new reference to object %d with min location = %d, max "
      "location = %d, alignment = %d, size = %d\n",
      id,
      min_offset + pc,
      max_offset + pc,
      alignment,
      size));
  return new ForwardReference<int32_t>(pc,
                                       size,
                                       min_offset + pc,
                                       max_offset + pc,
                                       alignment);
}

// Fuzz test that uses literal-like objects, that get deleted when they are
// placed.
TEST(FuzzObjectDeletedWhenPlaced) {
  TestMacroAssembler masm;
  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);

  const int kObjectNum = 100;
  std::vector<TestObject *> objects;

  // Create objects.
  for (int i = 0; i < kObjectNum; ++i) {
    objects.push_back(TestObject::CreateRandom(i));
  }

  int32_t pc = 0;
  for (int i = 0; !objects.empty(); ++i) {
    IF_VERBOSE(printf("PC = 0x%x (%d)\n", pc, pc));
    int32_t pc_increment = RandomPCIncrement();
    IF_VERBOSE(printf("Attempting to increment PC by %d\n", pc_increment));
    if (pool_manager.MustEmit(pc, pc_increment)) {
      pc = pool_manager.Emit(&masm, pc, pc_increment);
    }
    pc += pc_increment;
    // Pick an object, randomly.
    TestObject *object = objects[RandomObjectID(objects.size())];
    int32_t min_offset = RandomMinOffset();
    int32_t max_offset = RandomMaxOffset();
    int32_t size = RandomReferenceSize();
    int32_t alignment =
        RandomObjectAlignment(object->GetPoolObjectSizeInBytes());
    ForwardReference<int32_t> *ref = CreateReference(object->GetID(),
                                                     pc,
                                                     size,
                                                     min_offset,
                                                     max_offset,
                                                     alignment);
    if (pool_manager.MustEmit(pc, size, ref, object)) {
      pc = pool_manager.Emit(&masm, pc, size, ref, object);
      delete ref;
      // We must recreate the reference, the PC has changed, but only if
      // it still is a forward reference.
      if (!object->IsBound()) {
        ref = CreateReference(object->GetID(),
                              pc,
                              size,
                              min_offset,
                              max_offset,
                              alignment);
      }
    }
    IF_VERBOSE(printf("Incrementing PC by size of reference (%d).\n", size));
    pc += size;
    // We only need to track the reference if it's a forward reference.
    if (!object->IsBound()) {
      object->AddReference(ref);
      pool_manager.AddObjectReference(ref, object);
    }
    VIXL_ASSERT(!pool_manager.MustEmit(pc - 1));
    // Remove bound objects.
    for (std::vector<TestObject *>::iterator iter = objects.begin();
         iter != objects.end();) {
      TestObject *object = *iter;
      if (object->IsBound()) {
        delete object;
        iter = objects.erase(iter);
      } else {
        ++iter;
      }
    }
  }

  pool_manager.Emit(&masm, pc);
}

// Fuzz test that uses veneer-like objects, that get updated when they are
// placed and get deleted when they are bound by the user.
TEST(FuzzObjectUpdatedWhenPlaced) {
  TestMacroAssembler masm;
  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  const int kObjectNum = 1000;
  std::vector<TestBranchObject *> objects;

  // Create objects.
  for (int i = 0; i < kObjectNum; ++i) {
    objects.push_back(TestBranchObject::CreateRandom(i));
  }

  int32_t pc = 0;
  for (int i = 0; !objects.empty(); ++i) {
    IF_VERBOSE(printf("PC = 0x%x (%d)\n", pc, pc));

    int32_t pc_increment = RandomPCIncrement();
    IF_VERBOSE(printf("Attempting to increment PC by %d\n", pc_increment));

    if (pool_manager.MustEmit(pc, pc_increment)) {
      pc = pool_manager.Emit(&masm, pc, pc_increment);
    }
    pc += pc_increment;

    // Pick a random object.
    TestBranchObject *object = objects[RandomObjectID(objects.size())];
    int32_t min_offset = RandomMinOffset();
    int32_t max_offset = RandomBranchMaxOffset();
    int32_t size = RandomReferenceSize();
    int32_t alignment =
        RandomObjectAlignment(object->GetPoolObjectSizeInBytes());
    ForwardReference<int32_t> *ref = CreateReference(object->GetID(),
                                                     pc,
                                                     size,
                                                     min_offset,
                                                     max_offset,
                                                     alignment);
    if (pool_manager.MustEmit(pc, size, ref, object)) {
      pc = pool_manager.Emit(&masm, pc, size);
      delete ref;
      // We must recreate the reference, the PC has changed.
      ref = CreateReference(object->GetID(),
                            pc,
                            size,
                            min_offset,
                            max_offset,
                            alignment);
    }
    IF_VERBOSE(printf("Incrementing PC by size of reference (%d).\n", size));
    pc += size;
    object->AddReference(ref);
    pool_manager.AddObjectReference(ref, object);
    VIXL_ASSERT(!pool_manager.MustEmit(pc - 1));

    // Pick another random label to bind.
    const int kProbabilityToBind = 20;
    if ((Random() % 100) < kProbabilityToBind) {
      TestBranchObject *object = objects[RandomObjectID(objects.size())];
      // Binding can cause the pool emission, so check if we need to emit
      // the pools. The actual backends will know the max alignment we
      // might need here, so can simplify the check (won't need to check
      // the object references).
      int max_padding = object->GetMaxAlignment() - 1;
      if (pool_manager.MustEmit(pc, max_padding)) {
        pc = pool_manager.Emit(&masm, pc, max_padding);
      }
      pc = pool_manager.Bind(&masm, object, pc);
    }

    // Remove bound objects.
    for (std::vector<TestBranchObject *>::iterator iter = objects.begin();
         iter != objects.end();) {
      TestBranchObject *object = *iter;
      if (object->IsBound()) {
        delete object;
        iter = objects.erase(iter);
      } else {
        ++iter;
      }
    }
  }

  pool_manager.Emit(&masm, pc);
}

// Test that binding an unused label works.
TEST(BindUnusedLabel) {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  TestBranchObject *object = new TestBranchObject(4 /*size*/, 4 /*alignment*/);
  int32_t pc = 0;
  pool_manager.Bind(&masm, object, pc);
  delete object;
}

// Test that binding a label adds necessary padding.
TEST(BindLabelNeedsPadding) {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);

  // Label that needs padding because of the minimum location of the reference.
  TestBranchObject *object = new TestBranchObject(4 /*size*/, 2 /*alignment*/);
  ForwardReference<int32_t> *ref =
      new ForwardReference<int32_t>(0 /*location*/,
                                    2 /*size*/,
                                    4 /*min_location*/,
                                    500 /*max_location*/);
  object->AddReference(ref);
  pool_manager.AddObjectReference(ref, object);
  int32_t pc = 2;
  pc = pool_manager.Bind(&masm, object, pc);
  VIXL_ASSERT(pc == 4);
  delete object;

  // Label that needs padding because of the alignment of the object.
  object = new TestBranchObject(4 /*size*/, 4 /*alignment*/);
  ref = new ForwardReference<int32_t>(0 /*location*/,
                                      2 /*size*/,
                                      0 /*min_location*/,
                                      500 /*max_location*/);
  object->AddReference(ref);
  pool_manager.AddObjectReference(ref, object);

  pc = 2;
  pc = pool_manager.Bind(&masm, object, pc);
  VIXL_ASSERT(pc == 4);
  delete object;

  // Label that needs padding because of the alignment of the reference.
  object = new TestBranchObject(4 /*size*/, 1 /*alignment*/);
  ref = new ForwardReference<int32_t>(0 /*location*/,
                                      2 /*size*/,
                                      0 /*min_location*/,
                                      500 /*max_location*/,
                                      4 /*alignment*/);
  object->AddReference(ref);
  pool_manager.AddObjectReference(ref, object);

  pc = 2;
  pc = pool_manager.Bind(&masm, object, pc);
  VIXL_ASSERT(pc == 4);
  delete object;
}

// This test checks that when we omit the pool header, we insert any padding
// needed in order to meet the minimum location of the first object.
TEST(PoolWithoutHeaderMinLocation) {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  int object_size = 4;
  int object_alignment = 1;  // Do not restrict alignment for this test.
  int min_location = 4;      // We emit the pool at location 2, so need padding.
  int max_location = 500;
  TestObject object(object_size, object_alignment);
  ForwardReference<int32_t> *ref = new ForwardReference<int32_t>(0 /*location*/,
                                                                 2 /*size*/,
                                                                 min_location,
                                                                 max_location);
  object.AddReference(ref);
  pool_manager.AddObjectReference(ref, &object);

  int32_t new_pc = pool_manager.Emit(&masm,
                                     2,
                                     0, /* no new code added */
                                     NULL,
                                     NULL,
                                     PoolManager<int32_t>::kNoBranchRequired);
  USE(new_pc);
  VIXL_ASSERT(new_pc == min_location + object_size);
}

// This test checks that when we omit the pool header, we insert any padding
// needed in order to meet the alignment of the first object.
TEST(PoolWithoutHeaderAlignment) {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  int object_size = 4;
  int object_alignment = 4;  // We emit the pool at location 2, so need padding.
  int min_location = 0;      // Do not restrict this for this test.
  int max_location = 500;
  TestObject object(object_size, object_alignment);
  ForwardReference<int32_t> *ref = new ForwardReference<int32_t>(0 /*location*/,
                                                                 2 /*size*/,
                                                                 min_location,
                                                                 max_location);
  object.AddReference(ref);
  pool_manager.AddObjectReference(ref, &object);

  int32_t pc = 2;
  int32_t new_pc = pool_manager.Emit(&masm,
                                     pc,
                                     0, /* no new code added */
                                     NULL,
                                     NULL,
                                     PoolManager<int32_t>::kNoBranchRequired);
  USE(pc);
  USE(new_pc);
  VIXL_ASSERT(new_pc == AlignUp(pc, object_alignment) + object_size);
}

static int32_t AddNBranches(PoolManager<int32_t> *pool_manager,
                            int32_t pc,
                            TestBranchObject *labels[],
                            int num_branches,
                            int branch_size,
                            int veneer_size,
                            int veneer_alignment,
                            int branch_range) {
  for (int i = 0; i < num_branches; ++i) {
    labels[i] = new TestBranchObject(veneer_size, veneer_alignment);
    int32_t min_location = pc;
    int32_t max_location = pc + branch_range;
    ForwardReference<int32_t> *ref =
        new ForwardReference<int32_t>(pc,
                                      branch_size,
                                      min_location,
                                      max_location);
    labels[i]->AddReference(ref);
    // We have picked the object sizes so that we do not need to emit now.
    VIXL_ASSERT(!pool_manager->MustEmit(pc, branch_size, ref, labels[i]));
    pool_manager->AddObjectReference(ref, labels[i]);
    pc += branch_size;
  }
  return pc;
}

TEST(MustEmitNewReferenceDueToRange) {
  const int kHeaderSize = 4;
  const int kHeaderAlignment = 2;
  const int kNumBranches = 550;
  const int kBranchSize = 4;
  const int kVeneerSize = 4;
  const int kVeneerAlignment = 2;
  const int kBranchRange = 1 * MBytes;
  int32_t pc = 0;

  TestMacroAssembler masm;
  TestBranchObject *labels[kNumBranches];
  PoolManager<int32_t> pool_manager(kHeaderSize,
                                    kHeaderAlignment,
                                    BUFFER_ALIGNMENT);
  pc = AddNBranches(&pool_manager,
                    pc,
                    labels,
                    kNumBranches,
                    kBranchSize,
                    kVeneerSize,
                    kVeneerAlignment,
                    kBranchRange);

  // Increment PC to close to the checkpoint of the pools.
  TestPoolManager test(&pool_manager);
  pc = test.GetPoolCheckpoint() - 4;
  VIXL_ASSERT(!pool_manager.MustEmit(pc));

  // Now, attempt to add a reference that would make the problem impossible.
  // We need to emit the pool immediately after this new instruction, and
  // the current size of the pool is kVeneerSize * kNumBranches, so adding a
  // short-range (smaller than the pool size) reference should trigger pool
  // emission.
  const int kPoolSize = kVeneerSize * kNumBranches + kHeaderSize;

  const int kNewObjectSize = 2;
  TestObject new_object(kNewObjectSize, 1);

  ForwardReference<int32_t> temp_ref(pc,
                                     kBranchSize,
                                     pc,
                                     pc + kPoolSize + kBranchSize - 1);
  VIXL_ASSERT(pool_manager.MustEmit(pc, kBranchSize, &temp_ref, &new_object));

  // Before actually emitting the pool, try a few different references to make
  // sure that this works as expected.
  {
    // This reference has a large enough range, so should not force pool
    // emission.
    ForwardReference<int32_t> far_ref(pc,
                                      kBranchSize,
                                      pc,
                                      pc + kPoolSize + kBranchSize);
    VIXL_ASSERT(!pool_manager.MustEmit(pc, kBranchSize, &far_ref, &new_object));

    // This reference had a large enough range but will be restricted by
    // alignment so should force pool emission.
    int alignment = 16;
    VIXL_ASSERT((pc & (alignment - 1)) != 0);
    ForwardReference<int32_t> aligned_ref(pc,
                                          kBranchSize,
                                          pc,
                                          pc + kPoolSize + kBranchSize,
                                          alignment);
    VIXL_ASSERT(
        pool_manager.MustEmit(pc, kBranchSize, &aligned_ref, &new_object));
  }

  // Emit the pool and check its size.
  int32_t new_pc =
      pool_manager.Emit(&masm, pc, kBranchSize, &temp_ref, &new_object);
  VIXL_ASSERT(pc % kHeaderAlignment == 0);  // No need for padding.
  VIXL_ASSERT(new_pc == pc + kPoolSize);
  pc = new_pc;

  // Add the new reference, safely.
  ForwardReference<int32_t> *ref =
      new ForwardReference<int32_t>(pc, 4 /*size*/, pc, pc + kBranchRange);
  new_object.AddReference(ref);
  pool_manager.AddObjectReference(ref, &new_object);
  pc += 4;

  // Emit the pool again.
  new_pc = pool_manager.Emit(&masm, pc);
  VIXL_ASSERT(pc % kHeaderAlignment == 0);  // No need for padding.
  VIXL_ASSERT(new_pc == pc + kNewObjectSize + kHeaderSize);
  pc = new_pc;

  // Finally, bind the labels.
  for (int i = 0; i < kNumBranches; ++i) {
    pc = pool_manager.Bind(&masm, labels[i], pc);
    delete labels[i];
  }
}

TEST(MustEmitNewReferenceDueToSizeOfObject) {
  const int kHeaderSize = 4;
  const int kHeaderAlignment = 2;
  const int kNumBranches = 550;
  const int kBranchSize = 4;
  const int kVeneerSize = 4;
  const int kVeneerAlignment = 2;
  const int kBranchRange = 1 * MBytes;
  int32_t pc = 0;

  TestMacroAssembler masm;
  PoolManager<int32_t> pool_manager(kHeaderSize,
                                    kHeaderAlignment,
                                    BUFFER_ALIGNMENT);
  TestBranchObject *labels[kNumBranches];
  pc = AddNBranches(&pool_manager,
                    pc,
                    labels,
                    kNumBranches,
                    kBranchSize,
                    kVeneerSize,
                    kVeneerAlignment,
                    kBranchRange);


  // Increment PC to close to the checkpoint of the pools minus a known
  // thershold.
  const int kBigObjectSize = 1024;
  TestPoolManager test(&pool_manager);
  pc = test.GetPoolCheckpoint() - kBigObjectSize;
  VIXL_ASSERT(!pool_manager.MustEmit(pc));

  // Now, attempt to add a reference that would make the problem impossible.
  // If we add a short-range (smaller than the pool size) reference with a
  // large size (larger than the margin we have until pool emission), pool
  // emission should be triggered.
  const int kPoolSize = kVeneerSize * kNumBranches + kHeaderSize;

  TestObject new_object(kBigObjectSize, 1);
  ForwardReference<int32_t> temp_ref(pc, kBranchSize, pc, pc + kPoolSize);
  VIXL_ASSERT(pool_manager.MustEmit(pc, kBranchSize, &temp_ref, &new_object));

  // Before actually emitting the pool, try a few different references to make
  // sure that this works as expected.
  {
    // If the object is smaller, we can emit the reference.
    TestObject smaller_object(kBigObjectSize - 4, 1);
    ForwardReference<int32_t> temp_ref(pc, kBranchSize, pc, pc + kPoolSize);
    VIXL_ASSERT(
        !pool_manager.MustEmit(pc, kBranchSize, &temp_ref, &smaller_object));

    // If the reference is going to be added after the current objects in the
    // pool, we can still emit it.
    ForwardReference<int32_t> far_ref(pc, kBranchSize, pc, pc + kBranchRange);
    VIXL_ASSERT(!pool_manager.MustEmit(pc, kBranchSize, &far_ref, &new_object));
  }

  // Emit the pool and check its size.
  int32_t new_pc =
      pool_manager.Emit(&masm, pc, kBranchSize, &temp_ref, &new_object);
  VIXL_ASSERT(pc % kHeaderAlignment == 0);  // No need for padding.
  VIXL_ASSERT(new_pc == pc + kPoolSize);
  pc = new_pc;

  // Add the new reference, safely.
  ForwardReference<int32_t> *ref =
      new ForwardReference<int32_t>(pc, 4 /*size*/, pc, pc + kBranchRange);
  new_object.AddReference(ref);
  pool_manager.AddObjectReference(ref, &new_object);
  pc += 4;

  // Emit the pool again.
  new_pc = pool_manager.Emit(&masm, pc);
  VIXL_ASSERT(pc % kHeaderAlignment == 0);  // No need for padding.
  VIXL_ASSERT(new_pc == pc + kBigObjectSize + kHeaderSize);
  pc = new_pc;

  // Finally, bind the labels.
  for (int i = 0; i < kNumBranches; ++i) {
    pc = pool_manager.Bind(&masm, labels[i], pc);
    delete labels[i];
  }
}

template <typename ObjectType>
void ManagedLocationBaseTestHelper() {
  TestMacroAssembler masm;

  PoolManager<int32_t> pool_manager(4 /*header_size*/,
                                    2 /*header_alignment*/,
                                    BUFFER_ALIGNMENT);
  ObjectType *object1 = new ObjectType();
  ObjectType *object2 = new ObjectType();
  ForwardReference<int32_t> *ref_obj1 =
      new ForwardReference<int32_t>(0 /*location*/, 2 /*size*/, 0, 200);
  object1->AddReference(ref_obj1);
  ForwardReference<int32_t> *ref_obj2 =
      new ForwardReference<int32_t>(8 /*location*/, 2 /*size*/, 8, 500);
  object2->AddReference(ref_obj2);

  pool_manager.AddObjectReference(ref_obj1, object1);
  pool_manager.AddObjectReference(ref_obj2, object2);

  pool_manager.Emit(&masm, 20);
}

class TestObjectDeletedOnPlacement : public TestObject {
 public:
  TestObjectDeletedOnPlacement() : TestObject(4 /*size*/, 4 /*alignment*/) {}
  // After passing ownership of this type of object to the pool manager, it is
  // not safe to use it anymore.
  virtual bool ShouldBeDeletedOnPlacementByPoolManager() const VIXL_OVERRIDE {
    return true;
  }
};

TEST(DeleteLocationBaseOnPlacement) {
  ManagedLocationBaseTestHelper<TestObjectDeletedOnPlacement>();
}

class TestObjectDeletedOnPoolManagerDestruction : public TestObject {
 public:
  TestObjectDeletedOnPoolManagerDestruction()
      : TestObject(4 /*size*/, 4 /*alignment*/) {}
  // We can continue using this type of object after passing its ownership to
  // the pool manager, as it will be deleted only when the pool manager is
  // destroyed.
  virtual bool ShouldBeDeletedOnPoolManagerDestruction() const VIXL_OVERRIDE {
    return true;
  }
};


TEST(DeleteLocationBaseOnPoolManagerDestruction) {
  ManagedLocationBaseTestHelper<TestObjectDeletedOnPoolManagerDestruction>();
}
