// 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/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler-inl.h"
#include "src/execution/simulator.h"
#include "src/handles/handles-inl.h"
#include "test/cctest/cctest.h"
#include "test/common/assembler-tester.h"

namespace v8 {
namespace internal {
namespace test_icache {

using F0 = int(int);

#define __ masm.

static constexpr int kNumInstr = 100;
static constexpr int kNumIterations = 5;
static constexpr int kBufferSize = 8 * KB;

static void FloodWithInc(Isolate* isolate, TestingAssemblerBuffer* buffer) {
  MacroAssembler masm(isolate, CodeObjectRequired::kYes, buffer->CreateView());
#if V8_TARGET_ARCH_IA32
  __ mov(eax, Operand(esp, kSystemPointerSize));
  for (int i = 0; i < kNumInstr; ++i) {
    __ add(eax, Immediate(1));
  }
#elif V8_TARGET_ARCH_X64
  __ movl(rax, arg_reg_1);
  for (int i = 0; i < kNumInstr; ++i) {
    __ addl(rax, Immediate(1));
  }
#elif V8_TARGET_ARCH_ARM64
  for (int i = 0; i < kNumInstr; ++i) {
    __ Add(x0, x0, Operand(1));
  }
#elif V8_TARGET_ARCH_ARM
  for (int i = 0; i < kNumInstr; ++i) {
    __ add(r0, r0, Operand(1));
  }
#elif V8_TARGET_ARCH_MIPS
  __ mov(v0, a0);
  for (int i = 0; i < kNumInstr; ++i) {
    __ Addu(v0, v0, Operand(1));
  }
#elif V8_TARGET_ARCH_MIPS64
  __ mov(v0, a0);
  for (int i = 0; i < kNumInstr; ++i) {
    __ Addu(v0, v0, Operand(1));
  }
#elif V8_TARGET_ARCH_PPC
  for (int i = 0; i < kNumInstr; ++i) {
    __ addi(r3, r3, Operand(1));
  }
#elif V8_TARGET_ARCH_S390
  for (int i = 0; i < kNumInstr; ++i) {
    __ agfi(r2, Operand(1));
  }
#else
#error Unsupported architecture
#endif
  __ Ret();
  CodeDesc desc;
  masm.GetCode(isolate, &desc);
}

static void FloodWithNop(Isolate* isolate, TestingAssemblerBuffer* buffer) {
  MacroAssembler masm(isolate, CodeObjectRequired::kYes, buffer->CreateView());
#if V8_TARGET_ARCH_IA32
  __ mov(eax, Operand(esp, kSystemPointerSize));
#elif V8_TARGET_ARCH_X64
  __ movl(rax, arg_reg_1);
#elif V8_TARGET_ARCH_MIPS
  __ mov(v0, a0);
#elif V8_TARGET_ARCH_MIPS64
  __ mov(v0, a0);
#endif
  for (int i = 0; i < kNumInstr; ++i) {
    __ nop();
  }
  __ Ret();
  CodeDesc desc;
  masm.GetCode(isolate, &desc);
}

// Order of operation for this test case:
//   exec -> perm(RW) -> patch -> flush -> perm(RX) -> exec
TEST(TestFlushICacheOfWritable) {
  Isolate* isolate = CcTest::i_isolate();
  HandleScope handles(isolate);

  for (int i = 0; i < kNumIterations; ++i) {
    auto buffer = AllocateAssemblerBuffer(kBufferSize);

    // Allow calling the function from C++.
    auto f = GeneratedCode<F0>::FromBuffer(isolate, buffer->start());

    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadWrite));
    FloodWithInc(isolate, buffer.get());
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadExecute));
    CHECK_EQ(23 + kNumInstr, f.Call(23));  // Call into generated code.
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadWrite));
    FloodWithNop(isolate, buffer.get());
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadExecute));
    CHECK_EQ(23, f.Call(23));  // Call into generated code.
  }
}

#if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64
// Note that this order of operations is not supported on ARM32/64 because on
// some older ARM32/64 kernels there is a bug which causes an access error on
// cache flush instructions to trigger access error on non-writable memory.
// See https://bugs.chromium.org/p/v8/issues/detail?id=8157
//
// Also note that this requires {kBufferSize == 8 * KB} to reproduce.
//
// The order of operations in V8 is akin to {TestFlushICacheOfWritable} above.
// It is hence OK to disable the below test on some architectures. Only the
// above test case should remain enabled on all architectures.
#define CONDITIONAL_TEST DISABLED_TEST
#else
#define CONDITIONAL_TEST TEST
#endif

// Order of operation for this test case:
//   exec -> perm(RW) -> patch -> perm(RX) -> flush -> exec
CONDITIONAL_TEST(TestFlushICacheOfExecutable) {
  Isolate* isolate = CcTest::i_isolate();
  HandleScope handles(isolate);

  for (int i = 0; i < kNumIterations; ++i) {
    auto buffer = AllocateAssemblerBuffer(kBufferSize);

    // Allow calling the function from C++.
    auto f = GeneratedCode<F0>::FromBuffer(isolate, buffer->start());

    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadWrite));
    FloodWithInc(isolate, buffer.get());
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadExecute));
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK_EQ(23 + kNumInstr, f.Call(23));  // Call into generated code.
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadWrite));
    FloodWithNop(isolate, buffer.get());
    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadExecute));
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK_EQ(23, f.Call(23));  // Call into generated code.
  }
}

#undef CONDITIONAL_TEST

// Order of operation for this test case:
//   perm(RWX) -> exec -> patch -> flush -> exec
TEST(TestFlushICacheOfWritableAndExecutable) {
  Isolate* isolate = CcTest::i_isolate();
  HandleScope handles(isolate);

  for (int i = 0; i < kNumIterations; ++i) {
    auto buffer = AllocateAssemblerBuffer(kBufferSize);

    // Allow calling the function from C++.
    auto f = GeneratedCode<F0>::FromBuffer(isolate, buffer->start());

    CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
                         buffer->size(), v8::PageAllocator::kReadWriteExecute));
    FloodWithInc(isolate, buffer.get());
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK_EQ(23 + kNumInstr, f.Call(23));  // Call into generated code.
    FloodWithNop(isolate, buffer.get());
    FlushInstructionCache(buffer->start(), buffer->size());
    CHECK_EQ(23, f.Call(23));  // Call into generated code.
  }
}

#undef __

}  // namespace test_icache
}  // namespace internal
}  // namespace v8
