CPU profiler: increase the max number of captured frames.
LOG=N R=jkummerow@chromium.org, loislo@chromium.org, yurys@chromium.org Review URL: https://codereview.chromium.org/357443003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21986 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
80e1bf42e5
commit
65e585fa38
@ -1715,7 +1715,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) {
|
||||
if (overflow) {
|
||||
msg.Append(",overflow");
|
||||
}
|
||||
for (int i = 0; i < sample->frames_count; ++i) {
|
||||
for (unsigned i = 0; i < sample->frames_count; ++i) {
|
||||
msg.Append(',');
|
||||
msg.AppendAddress(sample->stack[i]);
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
|
||||
|
||||
SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
|
||||
top_frame_type = it.top_frame_type();
|
||||
int i = 0;
|
||||
unsigned i = 0;
|
||||
while (!it.done() && i < TickSample::kMaxFramesCount) {
|
||||
stack[i++] = it.frame()->pc();
|
||||
it.Advance();
|
||||
|
@ -44,10 +44,11 @@ struct TickSample {
|
||||
Address tos; // Top stack value (*sp).
|
||||
Address external_callback;
|
||||
};
|
||||
static const int kMaxFramesCount = 64;
|
||||
static const unsigned kMaxFramesCountLog2 = 8;
|
||||
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
|
||||
Address stack[kMaxFramesCount]; // Call stack.
|
||||
TimeTicks timestamp;
|
||||
int frames_count : 8; // Number of captured frames.
|
||||
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
|
||||
bool has_external_callback : 1;
|
||||
StackFrame::Type top_frame_type : 4;
|
||||
};
|
||||
|
@ -283,7 +283,7 @@ TEST(Issue1398) {
|
||||
sample->pc = code->address();
|
||||
sample->tos = 0;
|
||||
sample->frames_count = i::TickSample::kMaxFramesCount;
|
||||
for (int i = 0; i < sample->frames_count; ++i) {
|
||||
for (unsigned i = 0; i < sample->frames_count; ++i) {
|
||||
sample->stack[i] = code->address();
|
||||
}
|
||||
processor->FinishTickSample();
|
||||
@ -1248,6 +1248,72 @@ TEST(FunctionApplySample) {
|
||||
}
|
||||
|
||||
|
||||
static const char* cpu_profiler_deep_stack_test_source =
|
||||
"function foo(n) {\n"
|
||||
" if (n)\n"
|
||||
" foo(n - 1);\n"
|
||||
" else\n"
|
||||
" startProfiling('my_profile');\n"
|
||||
"}\n"
|
||||
"function start() {\n"
|
||||
" foo(250);\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
// Check a deep stack
|
||||
//
|
||||
// [Top down]:
|
||||
// 0 (root) 0 #1
|
||||
// 2 (program) 0 #2
|
||||
// 0 start 21 #3 no reason
|
||||
// 0 foo 21 #4 no reason
|
||||
// 0 foo 21 #5 no reason
|
||||
// ....
|
||||
// 0 foo 21 #253 no reason
|
||||
// 1 startProfiling 0 #254
|
||||
TEST(CpuProfileDeepStack) {
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
|
||||
v8::Context::Scope context_scope(env);
|
||||
|
||||
v8::Script::Compile(v8::String::NewFromUtf8(
|
||||
env->GetIsolate(), cpu_profiler_deep_stack_test_source))->Run();
|
||||
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
|
||||
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
|
||||
|
||||
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
|
||||
v8::Local<v8::String> profile_name =
|
||||
v8::String::NewFromUtf8(env->GetIsolate(), "my_profile");
|
||||
function->Call(env->Global(), 0, NULL);
|
||||
v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
|
||||
CHECK_NE(NULL, profile);
|
||||
// Dump collected profile to have a better diagnostic in case of failure.
|
||||
reinterpret_cast<i::CpuProfile*>(profile)->Print();
|
||||
|
||||
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
|
||||
{
|
||||
ScopedVector<v8::Handle<v8::String> > names(3);
|
||||
names[0] = v8::String::NewFromUtf8(
|
||||
env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName);
|
||||
names[1] = v8::String::NewFromUtf8(env->GetIsolate(),
|
||||
ProfileGenerator::kProgramEntryName);
|
||||
names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start");
|
||||
CheckChildrenNames(root, names);
|
||||
}
|
||||
|
||||
const v8::CpuProfileNode* node =
|
||||
GetChild(env->GetIsolate(), root, "start");
|
||||
for (int i = 0; i < 250; ++i) {
|
||||
node = GetChild(env->GetIsolate(), node, "foo");
|
||||
}
|
||||
// TODO(alph):
|
||||
// In theory there must be one more 'foo' and a 'startProfiling' nodes,
|
||||
// but due to unstable top frame extraction these might be missing.
|
||||
|
||||
profile->Delete();
|
||||
}
|
||||
|
||||
|
||||
static const char* js_native_js_test_source =
|
||||
"var is_profiling = false;\n"
|
||||
"function foo(iterations) {\n"
|
||||
|
@ -172,7 +172,7 @@ TEST(CFromJSStackTrace) {
|
||||
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;
|
||||
unsigned base = 0;
|
||||
CHECK_GT(sample.frames_count, base + 1);
|
||||
|
||||
CHECK(IsAddressWithinFuncCode(
|
||||
@ -225,7 +225,7 @@ TEST(PureJSStackTrace) {
|
||||
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;
|
||||
unsigned base = 0;
|
||||
CHECK_GT(sample.frames_count, base + 1);
|
||||
CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 0]));
|
||||
CHECK(IsAddressWithinFuncCode(
|
||||
|
Loading…
Reference in New Issue
Block a user