// Copyright 2011 the V8 project 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 Google Inc. 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 AND 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.
//
// Tests of profiler-related functions from log.h

#include <stdlib.h>

#include "include/v8-profiler.h"
#include "src/api/api-inl.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames.h"
#include "src/execution/isolate.h"
#include "src/execution/vm-state-inl.h"
#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/trace-extension.h"

namespace v8 {
namespace internal {

static bool IsAddressWithinFuncCode(JSFunction function, void* addr) {
  i::AbstractCode code = function.abstract_code();
  return code.contains(reinterpret_cast<Address>(addr));
}

static bool IsAddressWithinFuncCode(v8::Local<v8::Context> context,
                                    const char* func_name, void* addr) {
  v8::Local<v8::Value> func =
      context->Global()->Get(context, v8_str(func_name)).ToLocalChecked();
  CHECK(func->IsFunction());
  JSFunction js_func = JSFunction::cast(*v8::Utils::OpenHandle(*func));
  return IsAddressWithinFuncCode(js_func, addr);
}


// This C++ function is called as a constructor, to grab the frame pointer
// from the calling function.  When this function runs, the stack contains
// a C_Entry frame and a Construct frame above the calling function's frame.
static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) {
  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
  i::StackFrameIterator frame_iterator(isolate);
  CHECK(frame_iterator.frame()->is_exit() ||
        frame_iterator.frame()->is_builtin_exit());
  frame_iterator.Advance();
  CHECK(frame_iterator.frame()->is_construct());
  frame_iterator.Advance();
  if (frame_iterator.frame()->type() == i::StackFrame::STUB) {
    // Skip over bytecode handler frame.
    frame_iterator.Advance();
  }
  i::StackFrame* calling_frame = frame_iterator.frame();
  CHECK(calling_frame->is_java_script());

  v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
#if defined(V8_HOST_ARCH_32_BIT)
  int32_t low_bits = static_cast<int32_t>(calling_frame->fp());
  args.This()
      ->Set(context, v8_str("low_bits"), v8_num(low_bits >> 1))
      .FromJust();
#elif defined(V8_HOST_ARCH_64_BIT)
  Address fp = calling_frame->fp();
  uint64_t kSmiValueMask =
      (static_cast<uintptr_t>(1) << (kSmiValueSize - 1)) - 1;
  int32_t low_bits = static_cast<int32_t>(fp & kSmiValueMask);
  fp >>= kSmiValueSize - 1;
  int32_t high_bits = static_cast<int32_t>(fp & kSmiValueMask);
  fp >>= kSmiValueSize - 1;
  CHECK_EQ(fp, 0);  // Ensure all the bits are successfully encoded.
  args.This()->Set(context, v8_str("low_bits"), v8_int(low_bits)).FromJust();
  args.This()->Set(context, v8_str("high_bits"), v8_int(high_bits)).FromJust();
#else
#error Host architecture is neither 32-bit nor 64-bit.
#endif
  args.GetReturnValue().Set(args.This());
}


// Use the API to create a JSFunction object that calls the above C++ function.
void CreateFramePointerGrabberConstructor(v8::Local<v8::Context> context,
                                          const char* constructor_name) {
    Local<v8::FunctionTemplate> constructor_template =
        v8::FunctionTemplate::New(context->GetIsolate(), construct_call);
    constructor_template->SetClassName(v8_str("FPGrabber"));
    Local<Function> fun =
        constructor_template->GetFunction(context).ToLocalChecked();
    context->Global()->Set(context, v8_str(constructor_name), fun).FromJust();
}


// Creates a global function named 'func_name' that calls the tracing
// function 'trace_func_name' with an actual EBP register value,
// encoded as one or two Smis.
static void CreateTraceCallerFunction(v8::Local<v8::Context> context,
                                      const char* func_name,
                                      const char* trace_func_name) {
  i::EmbeddedVector<char, 256> trace_call_buf;
  i::SNPrintF(trace_call_buf,
              "function %s() {"
              "  fp = new FPGrabber();"
              "  %s(fp.low_bits, fp.high_bits);"
              "}",
              func_name, trace_func_name);

  // Create the FPGrabber function, which grabs the caller's frame pointer
  // when called as a constructor.
  CreateFramePointerGrabberConstructor(context, "FPGrabber");

  // Compile the script.
  CompileRun(trace_call_buf.begin());
}


// This test verifies that stack tracing works when called during
// execution of a native function called from JS code. In this case,
// TickSample::Trace uses Isolate::c_entry_fp as a starting point for stack
// walking.
TEST(CFromJSStackTrace) {
  // BUG(1303) Inlining of JSFuncDoTrace() in JSTrace below breaks this test.
  i::FLAG_turbo_inlining = false;

  TickSample sample;
  i::TraceExtension::InitTraceEnv(&sample);

  v8::HandleScope scope(CcTest::isolate());
  v8::Local<v8::Context> context = CcTest::NewContext({TRACE_EXTENSION_ID});
  v8::Context::Scope context_scope(context);

  // Create global function JSFuncDoTrace which calls
  // extension function trace() with the current frame pointer value.
  CreateTraceCallerFunction(context, "JSFuncDoTrace", "trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "JSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  // When stack tracer is invoked, the stack should look as follows:
  // script [JS]
  //   JSTrace() [JS]
  //     JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi]
  //       trace(EBP) [native (extension)]
  //         DoTrace(EBP) [native]
  //           TickSample::Trace

  CHECK(sample.has_external_callback);
  CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace),
           reinterpret_cast<Address>(sample.external_callback_entry));

  // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
  unsigned base = 0;
  CHECK_GT(sample.frames_count, base + 1);

  CHECK(IsAddressWithinFuncCode(
      context, "JSFuncDoTrace", sample.stack[base + 0]));
  CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 1]));
}


// This test verifies that stack tracing works when called during
// execution of JS code. However, as calling TickSample::Trace requires
// entering native code, we can only emulate pure JS by erasing
// Isolate::c_entry_fp value. In this case, TickSample::Trace uses passed frame
// pointer value as a starting point for stack walking.
TEST(PureJSStackTrace) {
  // This test does not pass with inlining enabled since inlined functions
  // don't appear in the stack trace.
  i::FLAG_turbo_inlining = false;

  TickSample sample;
  i::TraceExtension::InitTraceEnv(&sample);

  v8::HandleScope scope(CcTest::isolate());
  v8::Local<v8::Context> context = CcTest::NewContext({TRACE_EXTENSION_ID});
  v8::Context::Scope context_scope(context);

  // Create global function JSFuncDoTrace which calls
  // extension function js_trace() with the current frame pointer value.
  CreateTraceCallerFunction(context, "JSFuncDoTrace", "js_trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "function OuterJSTrace() {"
      "         JSTrace();"
      "};\n"
      "OuterJSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  // When stack tracer is invoked, the stack should look as follows:
  // script [JS]
  //   OuterJSTrace() [JS]
  //     JSTrace() [JS]
  //       JSFuncDoTrace() [JS]
  //         js_trace(EBP) [native (extension)]
  //           DoTraceHideCEntryFPAddress(EBP) [native]
  //             TickSample::Trace
  //

  CHECK(sample.has_external_callback);
  CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace),
           reinterpret_cast<Address>(sample.external_callback_entry));

  // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
  unsigned base = 0;
  CHECK_GT(sample.frames_count, base + 1);
  CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 0]));
  CHECK(IsAddressWithinFuncCode(
      context, "OuterJSTrace", sample.stack[base + 1]));
}

static void CFuncDoTrace(byte dummy_param) {
  Address fp;
#if V8_HAS_BUILTIN_FRAME_ADDRESS
  fp = reinterpret_cast<Address>(__builtin_frame_address(0));
#elif V8_CC_MSVC
  // Approximate a frame pointer address. We compile without base pointers,
  // so we can't trust ebp/rbp.
  fp = reinterpret_cast<Address>(&dummy_param) - 2 * sizeof(void*);  // NOLINT
#else
#error Unexpected platform.
#endif
  i::TraceExtension::DoTrace(fp);
}


static int CFunc(int depth) {
  if (depth <= 0) {
    CFuncDoTrace(0);
    return 0;
  } else {
    return CFunc(depth - 1) + 1;
  }
}


// This test verifies that stack tracing doesn't crash when called on
// pure native code. TickSample::Trace only unrolls JS code, so we can't
// get any meaningful info here.
TEST(PureCStackTrace) {
  TickSample sample;
  i::TraceExtension::InitTraceEnv(&sample);
  v8::HandleScope scope(CcTest::isolate());
  v8::Local<v8::Context> context = CcTest::NewContext({TRACE_EXTENSION_ID});
  v8::Context::Scope context_scope(context);
  // Check that sampler doesn't crash
  CHECK_EQ(10, CFunc(10));
}


TEST(JsEntrySp) {
  v8::HandleScope scope(CcTest::isolate());
  v8::Local<v8::Context> context = CcTest::NewContext({TRACE_EXTENSION_ID});
  v8::Context::Scope context_scope(context);
  CHECK(!i::TraceExtension::GetJsEntrySp());
  CompileRun("a = 1; b = a + 1;");
  CHECK(!i::TraceExtension::GetJsEntrySp());
  CompileRun("js_entry_sp();");
  CHECK(!i::TraceExtension::GetJsEntrySp());
  CompileRun("js_entry_sp_level2();");
  CHECK(!i::TraceExtension::GetJsEntrySp());
}

}  // namespace internal
}  // namespace v8
