Index: test/cctest/test-log-stack-tracer.cc |
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc |
index c3752ff1abe47614037b7353a6c3a89677bf331b..5b6858e553666ee500469ce1c70ff3b47ae5dab9 100644 |
--- a/test/cctest/test-log-stack-tracer.cc |
+++ b/test/cctest/test-log-stack-tracer.cc |
@@ -38,6 +38,7 @@ |
#include "isolate.h" |
#include "log.h" |
#include "sampler.h" |
+#include "trace-extension.h" |
#include "vm-state-inl.h" |
using v8::Function; |
@@ -52,137 +53,9 @@ using v8::internal::Address; |
using v8::internal::Handle; |
using v8::internal::Isolate; |
using v8::internal::JSFunction; |
-using v8::internal::RegisterState; |
using v8::internal::TickSample; |
-static struct { |
- TickSample* sample; |
-} trace_env = { NULL }; |
- |
- |
-static void InitTraceEnv(TickSample* sample) { |
- trace_env.sample = sample; |
-} |
- |
- |
-static void DoTrace(Address fp) { |
- RegisterState regs; |
- regs.fp = fp; |
- // sp is only used to define stack high bound |
- regs.sp = |
- reinterpret_cast<Address>(trace_env.sample) - 10240; |
- trace_env.sample->Init(CcTest::i_isolate(), regs); |
-} |
- |
- |
-// 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 = |
- *(CcTest::i_isolate()->c_entry_fp_address()); |
- CHECK(saved_c_frame_fp); |
- *(CcTest::i_isolate()->c_entry_fp_address()) = 0; |
- DoTrace(fp); |
- *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp; |
-} |
- |
- |
-// --- 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> GetNativeFunctionTemplate( |
- v8::Isolate* isolate, |
- v8::Handle<String> name); |
- static void Trace(const v8::FunctionCallbackInfo<v8::Value>& args); |
- static void JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args); |
- static void JSEntrySP(const v8::FunctionCallbackInfo<v8::Value>& args); |
- static void JSEntrySPLevel2(const v8::FunctionCallbackInfo<v8::Value>& args); |
- private: |
- static Address GetFP(const v8::FunctionCallbackInfo<v8::Value>& 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::GetNativeFunctionTemplate( |
- v8::Isolate* isolate, v8::Handle<String> name) { |
- if (name->Equals(String::NewFromUtf8(isolate, "trace"))) { |
- return v8::FunctionTemplate::New(isolate, TraceExtension::Trace); |
- } else if (name->Equals( |
- String::NewFromUtf8(isolate, "js_trace"))) { |
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace); |
- } else if (name->Equals(String::NewFromUtf8(isolate, "js_entry_sp"))) { |
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP); |
- } else if (name->Equals(String::NewFromUtf8(isolate, "js_entry_sp_level2"))) { |
- return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2); |
- } else { |
- CHECK(false); |
- return v8::Handle<v8::FunctionTemplate>(); |
- } |
-} |
- |
- |
-Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) { |
- // Convert frame pointer from encoding as smis in the arguments to a pointer. |
- CHECK_EQ(2, args.Length()); // Ignore second argument on 32-bit platform. |
-#if defined(V8_HOST_ARCH_32_BIT) |
- Address fp = *reinterpret_cast<Address*>(*args[0]); |
-#elif defined(V8_HOST_ARCH_64_BIT) |
- int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32; |
- int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]); |
- Address fp = reinterpret_cast<Address>(high_bits | low_bits); |
-#else |
-#error Host architecture is neither 32-bit nor 64-bit. |
-#endif |
- printf("Trace: %p\n", fp); |
- return fp; |
-} |
- |
- |
-void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) { |
- DoTrace(GetFP(args)); |
-} |
- |
- |
-void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) { |
- DoTraceHideCEntryFPAddress(GetFP(args)); |
-} |
- |
- |
-static Address GetJsEntrySp() { |
- CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top()); |
- return CcTest::i_isolate()->js_entry_sp(); |
-} |
- |
- |
-void TraceExtension::JSEntrySP( |
- const v8::FunctionCallbackInfo<v8::Value>& args) { |
- CHECK_NE(0, GetJsEntrySp()); |
-} |
- |
- |
-void TraceExtension::JSEntrySPLevel2( |
- const v8::FunctionCallbackInfo<v8::Value>& args) { |
- v8::HandleScope scope(args.GetIsolate()); |
- const Address js_entry_sp = GetJsEntrySp(); |
- CHECK_NE(0, js_entry_sp); |
- CompileRun("js_entry_sp();"); |
- CHECK_EQ(js_entry_sp, GetJsEntrySp()); |
-} |
- |
- |
-static TraceExtension kTraceExtension; |
-v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension); |
- |
- |
static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) { |
i::Code* code = function->code(); |
return code->contains(addr); |
@@ -271,7 +144,7 @@ TEST(CFromJSStackTrace) { |
i::FLAG_use_inlining = false; |
TickSample sample; |
- InitTraceEnv(&sample); |
+ i::TraceExtension::InitTraceEnv(&sample); |
v8::HandleScope scope(CcTest::isolate()); |
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); |
@@ -296,7 +169,7 @@ TEST(CFromJSStackTrace) { |
// TickSample::Trace |
CHECK(sample.has_external_callback); |
- CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback); |
+ CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::Trace), sample.external_callback); |
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace" |
int base = 0; |
@@ -319,7 +192,7 @@ TEST(PureJSStackTrace) { |
i::FLAG_use_inlining = false; |
TickSample sample; |
- InitTraceEnv(&sample); |
+ i::TraceExtension::InitTraceEnv(&sample); |
v8::HandleScope scope(CcTest::isolate()); |
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); |
@@ -349,7 +222,7 @@ TEST(PureJSStackTrace) { |
// |
CHECK(sample.has_external_callback); |
- CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback); |
+ CHECK_EQ(FUNCTION_ADDR(i::TraceExtension::JSTrace), sample.external_callback); |
// Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" |
int base = 0; |
@@ -371,7 +244,7 @@ static void CFuncDoTrace(byte dummy_parameter) { |
#else |
#error Unexpected platform. |
#endif |
- DoTrace(fp); |
+ i::TraceExtension::DoTrace(fp); |
} |
@@ -390,7 +263,7 @@ static int CFunc(int depth) { |
// get any meaningful info here. |
TEST(PureCStackTrace) { |
TickSample sample; |
- InitTraceEnv(&sample); |
+ i::TraceExtension::InitTraceEnv(&sample); |
v8::HandleScope scope(CcTest::isolate()); |
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); |
v8::Context::Scope context_scope(context); |
@@ -403,11 +276,11 @@ TEST(JsEntrySp) { |
v8::HandleScope scope(CcTest::isolate()); |
v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION); |
v8::Context::Scope context_scope(context); |
- CHECK_EQ(0, GetJsEntrySp()); |
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); |
CompileRun("a = 1; b = a + 1;"); |
- CHECK_EQ(0, GetJsEntrySp()); |
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); |
CompileRun("js_entry_sp();"); |
- CHECK_EQ(0, GetJsEntrySp()); |
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); |
CompileRun("js_entry_sp_level2();"); |
- CHECK_EQ(0, GetJsEntrySp()); |
+ CHECK_EQ(0, i::TraceExtension::GetJsEntrySp()); |
} |