| Index: test/cctest/test-log-ia32.cc
|
| diff --git a/test/cctest/test-log-ia32.cc b/test/cctest/test-log-ia32.cc
|
| deleted file mode 100644
|
| index a40a800ee3a55c070eddafcf5ee7c05b8b9d6cfd..0000000000000000000000000000000000000000
|
| --- a/test/cctest/test-log-ia32.cc
|
| +++ /dev/null
|
| @@ -1,370 +0,0 @@
|
| -// Copyright 2006-2009 the V8 project authors. All rights reserved.
|
| -//
|
| -// Tests of profiler-related functions from log.h
|
| -
|
| -#ifdef ENABLE_LOGGING_AND_PROFILING
|
| -
|
| -#include <stdlib.h>
|
| -
|
| -#include "v8.h"
|
| -
|
| -#include "codegen.h"
|
| -#include "log.h"
|
| -#include "top.h"
|
| -#include "cctest.h"
|
| -#include "disassembler.h"
|
| -#include "register-allocator-inl.h"
|
| -
|
| -using v8::Function;
|
| -using v8::Local;
|
| -using v8::Object;
|
| -using v8::Script;
|
| -using v8::String;
|
| -using v8::Value;
|
| -
|
| -using v8::internal::byte;
|
| -using v8::internal::Address;
|
| -using v8::internal::Handle;
|
| -using v8::internal::JSFunction;
|
| -using v8::internal::StackTracer;
|
| -using v8::internal::TickSample;
|
| -using v8::internal::Top;
|
| -
|
| -namespace i = v8::internal;
|
| -
|
| -
|
| -static v8::Persistent<v8::Context> env;
|
| -
|
| -
|
| -static struct {
|
| - TickSample* sample;
|
| -} trace_env = { NULL };
|
| -
|
| -
|
| -static void InitTraceEnv(TickSample* sample) {
|
| - trace_env.sample = sample;
|
| -}
|
| -
|
| -
|
| -static void DoTrace(Address fp) {
|
| - trace_env.sample->fp = reinterpret_cast<uintptr_t>(fp);
|
| - // sp is only used to define stack high bound
|
| - trace_env.sample->sp =
|
| - reinterpret_cast<unsigned int>(trace_env.sample) - 10240;
|
| - StackTracer::Trace(trace_env.sample);
|
| -}
|
| -
|
| -
|
| -// Hide c_entry_fp to emulate situation when sampling is done while
|
| -// pure JS code is being executed
|
| -static void DoTraceHideCEntryFPAddress(Address fp) {
|
| - v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
|
| - CHECK(saved_c_frame_fp);
|
| - *(Top::c_entry_fp_address()) = 0;
|
| - DoTrace(fp);
|
| - *(Top::c_entry_fp_address()) = saved_c_frame_fp;
|
| -}
|
| -
|
| -
|
| -static void CheckRetAddrIsInFunction(const char* func_name,
|
| - Address ret_addr,
|
| - Address func_start_addr,
|
| - unsigned int func_len) {
|
| - printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n",
|
| - func_name, func_start_addr, ret_addr, func_start_addr + func_len);
|
| - CHECK_GE(ret_addr, func_start_addr);
|
| - CHECK_GE(func_start_addr + func_len, ret_addr);
|
| -}
|
| -
|
| -
|
| -static void CheckRetAddrIsInJSFunction(const char* func_name,
|
| - Address ret_addr,
|
| - Handle<JSFunction> func) {
|
| - v8::internal::Code* func_code = func->code();
|
| - CheckRetAddrIsInFunction(
|
| - func_name, ret_addr,
|
| - func_code->instruction_start(),
|
| - func_code->ExecutableSize());
|
| -}
|
| -
|
| -
|
| -// --- T r a c e E x t e n s i o n ---
|
| -
|
| -class TraceExtension : public v8::Extension {
|
| - public:
|
| - TraceExtension() : v8::Extension("v8/trace", kSource) { }
|
| - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
|
| - v8::Handle<String> name);
|
| - static v8::Handle<v8::Value> Trace(const v8::Arguments& args);
|
| - static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args);
|
| - static v8::Handle<v8::Value> JSEntrySP(const v8::Arguments& args);
|
| - static v8::Handle<v8::Value> JSEntrySPLevel2(const v8::Arguments& args);
|
| - private:
|
| - static Address GetFP(const v8::Arguments& args);
|
| - static const char* kSource;
|
| -};
|
| -
|
| -
|
| -const char* TraceExtension::kSource =
|
| - "native function trace();"
|
| - "native function js_trace();"
|
| - "native function js_entry_sp();"
|
| - "native function js_entry_sp_level2();";
|
| -
|
| -v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
|
| - v8::Handle<String> name) {
|
| - if (name->Equals(String::New("trace"))) {
|
| - return v8::FunctionTemplate::New(TraceExtension::Trace);
|
| - } else if (name->Equals(String::New("js_trace"))) {
|
| - return v8::FunctionTemplate::New(TraceExtension::JSTrace);
|
| - } else if (name->Equals(String::New("js_entry_sp"))) {
|
| - return v8::FunctionTemplate::New(TraceExtension::JSEntrySP);
|
| - } else if (name->Equals(String::New("js_entry_sp_level2"))) {
|
| - return v8::FunctionTemplate::New(TraceExtension::JSEntrySPLevel2);
|
| - } else {
|
| - CHECK(false);
|
| - return v8::Handle<v8::FunctionTemplate>();
|
| - }
|
| -}
|
| -
|
| -
|
| -Address TraceExtension::GetFP(const v8::Arguments& args) {
|
| - CHECK_EQ(1, args.Length());
|
| - Address fp = reinterpret_cast<Address>(args[0]->Int32Value() << 2);
|
| - printf("Trace: %p\n", fp);
|
| - return fp;
|
| -}
|
| -
|
| -
|
| -v8::Handle<v8::Value> TraceExtension::Trace(const v8::Arguments& args) {
|
| - DoTrace(GetFP(args));
|
| - return v8::Undefined();
|
| -}
|
| -
|
| -
|
| -v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
|
| - DoTraceHideCEntryFPAddress(GetFP(args));
|
| - return v8::Undefined();
|
| -}
|
| -
|
| -
|
| -static Address GetJsEntrySp() {
|
| - CHECK_NE(NULL, Top::GetCurrentThread());
|
| - return Top::js_entry_sp(Top::GetCurrentThread());
|
| -}
|
| -
|
| -
|
| -v8::Handle<v8::Value> TraceExtension::JSEntrySP(const v8::Arguments& args) {
|
| - CHECK_NE(0, GetJsEntrySp());
|
| - return v8::Undefined();
|
| -}
|
| -
|
| -
|
| -static void CompileRun(const char* source) {
|
| - Script::Compile(String::New(source))->Run();
|
| -}
|
| -
|
| -
|
| -v8::Handle<v8::Value> TraceExtension::JSEntrySPLevel2(
|
| - const v8::Arguments& args) {
|
| - v8::HandleScope scope;
|
| - const Address js_entry_sp = GetJsEntrySp();
|
| - CHECK_NE(0, js_entry_sp);
|
| - CompileRun("js_entry_sp();");
|
| - CHECK_EQ(js_entry_sp, GetJsEntrySp());
|
| - return v8::Undefined();
|
| -}
|
| -
|
| -
|
| -static TraceExtension kTraceExtension;
|
| -v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);
|
| -
|
| -
|
| -static void InitializeVM() {
|
| - if (env.IsEmpty()) {
|
| - v8::HandleScope scope;
|
| - const char* extensions[] = { "v8/trace" };
|
| - v8::ExtensionConfiguration config(1, extensions);
|
| - env = v8::Context::New(&config);
|
| - }
|
| - v8::HandleScope scope;
|
| - env->Enter();
|
| -}
|
| -
|
| -
|
| -static Handle<JSFunction> CompileFunction(const char* source) {
|
| - return v8::Utils::OpenHandle(*Script::Compile(String::New(source)));
|
| -}
|
| -
|
| -
|
| -static Local<Value> GetGlobalProperty(const char* name) {
|
| - return env->Global()->Get(String::New(name));
|
| -}
|
| -
|
| -
|
| -static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
|
| - Handle<JSFunction> js_func(JSFunction::cast(
|
| - *(v8::Utils::OpenHandle(
|
| - *GetGlobalProperty(name)))));
|
| - return js_func;
|
| -}
|
| -
|
| -
|
| -static void CheckRetAddrIsInJSFunction(const char* func_name,
|
| - Address ret_addr) {
|
| - CheckRetAddrIsInJSFunction(func_name, ret_addr,
|
| - GetGlobalJSFunction(func_name));
|
| -}
|
| -
|
| -
|
| -static void SetGlobalProperty(const char* name, Local<Value> value) {
|
| - env->Global()->Set(String::New(name), value);
|
| -}
|
| -
|
| -
|
| -static Handle<v8::internal::String> NewString(const char* s) {
|
| - return i::Factory::NewStringFromAscii(i::CStrVector(s));
|
| -}
|
| -
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -class CodeGeneratorPatcher {
|
| - public:
|
| - CodeGeneratorPatcher() {
|
| - CodeGenerator::InlineRuntimeLUT genGetFramePointer =
|
| - {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer"};
|
| - // _FastCharCodeAt is not used in our tests.
|
| - bool result = CodeGenerator::PatchInlineRuntimeEntry(
|
| - NewString("_FastCharCodeAt"),
|
| - genGetFramePointer, &oldInlineEntry);
|
| - CHECK(result);
|
| - }
|
| -
|
| - ~CodeGeneratorPatcher() {
|
| - CHECK(CodeGenerator::PatchInlineRuntimeEntry(
|
| - NewString("_GetFramePointer"),
|
| - oldInlineEntry, NULL));
|
| - }
|
| -
|
| - private:
|
| - CodeGenerator::InlineRuntimeLUT oldInlineEntry;
|
| -};
|
| -
|
| -} } // namespace v8::internal
|
| -
|
| -
|
| -// Creates a global function named 'func_name' that calls the tracing
|
| -// function 'trace_func_name' with an actual EBP register value,
|
| -// shifted right to be presented as Smi.
|
| -static void CreateTraceCallerFunction(const char* func_name,
|
| - const char* trace_func_name) {
|
| - i::EmbeddedVector<char, 256> trace_call_buf;
|
| - i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name);
|
| -
|
| - // Compile the script.
|
| - i::CodeGeneratorPatcher patcher;
|
| - bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
|
| - i::FLAG_allow_natives_syntax = true;
|
| - Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
|
| - CHECK(!func.is_null());
|
| - i::FLAG_allow_natives_syntax = allow_natives_syntax;
|
| -
|
| -#ifdef DEBUG
|
| - v8::internal::Code* func_code = func->code();
|
| - CHECK(func_code->IsCode());
|
| - func_code->Print();
|
| -#endif
|
| -
|
| - SetGlobalProperty(func_name, v8::ToApi<Value>(func));
|
| -}
|
| -
|
| -
|
| -TEST(CFromJSStackTrace) {
|
| - TickSample sample;
|
| - InitTraceEnv(&sample);
|
| -
|
| - InitializeVM();
|
| - v8::HandleScope scope;
|
| - CreateTraceCallerFunction("JSFuncDoTrace", "trace");
|
| - CompileRun(
|
| - "function JSTrace() {"
|
| - " JSFuncDoTrace();"
|
| - "};\n"
|
| - "JSTrace();");
|
| - CHECK_GT(sample.frames_count, 1);
|
| - // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace"
|
| - CheckRetAddrIsInJSFunction("JSFuncDoTrace",
|
| - sample.stack[0]);
|
| - CheckRetAddrIsInJSFunction("JSTrace",
|
| - sample.stack[1]);
|
| -}
|
| -
|
| -
|
| -TEST(PureJSStackTrace) {
|
| - TickSample sample;
|
| - InitTraceEnv(&sample);
|
| -
|
| - InitializeVM();
|
| - v8::HandleScope scope;
|
| - CreateTraceCallerFunction("JSFuncDoTrace", "js_trace");
|
| - CompileRun(
|
| - "function JSTrace() {"
|
| - " JSFuncDoTrace();"
|
| - "};\n"
|
| - "function OuterJSTrace() {"
|
| - " JSTrace();"
|
| - "};\n"
|
| - "OuterJSTrace();");
|
| - CHECK_GT(sample.frames_count, 1);
|
| - // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
|
| - CheckRetAddrIsInJSFunction("JSTrace",
|
| - sample.stack[0]);
|
| - CheckRetAddrIsInJSFunction("OuterJSTrace",
|
| - sample.stack[1]);
|
| -}
|
| -
|
| -
|
| -static void CFuncDoTrace() {
|
| - Address fp;
|
| -#ifdef __GNUC__
|
| - fp = reinterpret_cast<Address>(__builtin_frame_address(0));
|
| -#elif defined _MSC_VER
|
| - __asm mov [fp], ebp // NOLINT
|
| -#endif
|
| - DoTrace(fp);
|
| -}
|
| -
|
| -
|
| -static int CFunc(int depth) {
|
| - if (depth <= 0) {
|
| - CFuncDoTrace();
|
| - return 0;
|
| - } else {
|
| - return CFunc(depth - 1) + 1;
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST(PureCStackTrace) {
|
| - TickSample sample;
|
| - InitTraceEnv(&sample);
|
| - // Check that sampler doesn't crash
|
| - CHECK_EQ(10, CFunc(10));
|
| -}
|
| -
|
| -
|
| -TEST(JsEntrySp) {
|
| - InitializeVM();
|
| - v8::HandleScope scope;
|
| - CHECK_EQ(0, GetJsEntrySp());
|
| - CompileRun("a = 1; b = a + 1;");
|
| - CHECK_EQ(0, GetJsEntrySp());
|
| - CompileRun("js_entry_sp();");
|
| - CHECK_EQ(0, GetJsEntrySp());
|
| - CompileRun("js_entry_sp_level2();");
|
| - CHECK_EQ(0, GetJsEntrySp());
|
| -}
|
| -
|
| -#endif // ENABLE_LOGGING_AND_PROFILING
|
|
|