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 |