// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/instruction-stream.h"

#include "src/builtins/builtins.h"
#include "src/objects-inl.h"
#include "src/snapshot/snapshot.h"

namespace v8 {
namespace internal {

// static
bool InstructionStream::PcIsOffHeap(Isolate* isolate, Address pc) {
  if (FLAG_embedded_builtins) {
    const Address start = reinterpret_cast<Address>(isolate->embedded_blob());
    return start <= pc && pc < start + isolate->embedded_blob_size();
  } else {
    return false;
  }
}

// static
Code* InstructionStream::TryLookupCode(Isolate* isolate, Address address) {
  if (!PcIsOffHeap(isolate, address)) return nullptr;

  EmbeddedData d = EmbeddedData::FromBlob();

  int l = 0, r = Builtins::builtin_count;
  while (l < r) {
    const int mid = (l + r) / 2;
    Address start = d.InstructionStartOfBuiltin(mid);
    Address end = start + d.InstructionSizeOfBuiltin(mid);

    if (address < start) {
      r = mid;
    } else if (address >= end) {
      l = mid + 1;
    } else {
      return isolate->builtins()->builtin(mid);
    }
  }

  UNREACHABLE();
}

// static
void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
                                                       uint8_t** data,
                                                       uint32_t* size) {
  EmbeddedData d = EmbeddedData::FromIsolate(isolate);

  const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize());
  const uint32_t allocated_size = RoundUp(d.size(), page_size);

  uint8_t* allocated_bytes = static_cast<uint8_t*>(
      AllocatePages(GetRandomMmapAddr(), allocated_size, page_size,
                    PageAllocator::kReadWrite));
  CHECK_NOT_NULL(allocated_bytes);

  std::memcpy(allocated_bytes, d.data(), d.size());
  CHECK(SetPermissions(allocated_bytes, allocated_size,
                       PageAllocator::kReadExecute));

  *data = allocated_bytes;
  *size = d.size();

  d.Dispose();
}

// static
void InstructionStream::FreeOffHeapInstructionStream(uint8_t* data,
                                                     uint32_t size) {
  const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize());
  CHECK(FreePages(data, RoundUp(size, page_size)));
}

}  // namespace internal
}  // namespace v8
