Index: test/cctest/test-log-ia32.cc |
=================================================================== |
--- test/cctest/test-log-ia32.cc (revision 1784) |
+++ test/cctest/test-log-ia32.cc (working copy) |
@@ -62,28 +62,6 @@ |
} |
-static void CheckRetAddrIsInFunction(const char* func_name, |
- unsigned int ret_addr, |
- unsigned int func_start_addr, |
- unsigned int func_len) { |
- printf("CheckRetAddrIsInFunction \"%s\": %08x %08x %08x\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, |
- unsigned int ret_addr, |
- Handle<JSFunction> func) { |
- v8::internal::Code* func_code = func->code(); |
- CheckRetAddrIsInFunction( |
- func_name, ret_addr, |
- reinterpret_cast<unsigned int>(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 { |
@@ -141,146 +119,6 @@ |
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 void CompileRun(const char* source) { |
- Script::Compile(String::New(source))->Run(); |
-} |
- |
- |
-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, |
- unsigned int 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 bool Patch(byte* from, |
- size_t num, |
- byte* original, |
- byte* patch, |
- size_t patch_len) { |
- byte* to = from + num; |
- do { |
- from = static_cast<byte*>(memchr(from, *original, to - from)); |
- CHECK(from != NULL); |
- if (memcmp(original, from, patch_len) == 0) { |
- memcpy(from, patch, patch_len); |
- return true; |
- } else { |
- from++; |
- } |
- } while (to - from > 0); |
- return false; |
-} |
- |
- |
-// 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) { |
- ::v8::internal::EmbeddedVector<char, 256> trace_call_buf; |
- ::v8::internal::OS::SNPrintF(trace_call_buf, "%s(0x6666);", trace_func_name); |
- Handle<JSFunction> func = CompileFunction(trace_call_buf.start()); |
- CHECK(!func.is_null()); |
- v8::internal::Code* func_code = func->code(); |
- CHECK(func_code->IsCode()); |
- |
- // push 0xcccc (= 0x6666 << 1) |
- byte original[] = { 0x68, 0xcc, 0xcc, 0x00, 0x00 }; |
- // mov eax,ebp; shr eax; push eax; |
- byte patch[] = { 0x89, 0xe8, 0xd1, 0xe8, 0x50 }; |
- // Patch generated code to replace pushing of a constant with |
- // pushing of ebp contents in a Smi |
- CHECK(Patch(func_code->instruction_start(), |
- func_code->instruction_size(), |
- original, patch, sizeof(patch))); |
- |
- SetGlobalProperty(func_name, v8::ToApi<Value>(func)); |
-} |
- |
- |
-TEST(CFromJSStackTrace) { |
- TickSample sample; |
- StackTracer tracer(reinterpret_cast<unsigned int>(&sample)); |
- InitTraceEnv(&tracer, &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", |
- reinterpret_cast<unsigned int>(sample.stack[0])); |
- CheckRetAddrIsInJSFunction("JSTrace", |
- reinterpret_cast<unsigned int>(sample.stack[1])); |
-} |
- |
- |
-TEST(PureJSStackTrace) { |
- TickSample sample; |
- StackTracer tracer(reinterpret_cast<unsigned int>(&sample)); |
- InitTraceEnv(&tracer, &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", |
- reinterpret_cast<unsigned int>(sample.stack[0])); |
- CheckRetAddrIsInJSFunction("OuterJSTrace", |
- reinterpret_cast<unsigned int>(sample.stack[1])); |
-} |
- |
- |
static void CFuncDoTrace() { |
unsigned int fp; |
#ifdef __GNUC__ |