Revision: 24700
Author: [email protected]
Date: Fri Oct 17 15:44:02 2014 UTC
Log: Tick processor: Print C++ entry points
[email protected], [email protected], [email protected]
Review URL: https://codereview.chromium.org/638633002
https://code.google.com/p/v8/source/detail?r=24700
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/cpu-profiler.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/isolate.h
/branches/bleeding_edge/src/sampler.cc
/branches/bleeding_edge/src/sampler.h
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/test/cctest/trace-extension.cc
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
/branches/bleeding_edge/tools/codemap.js
/branches/bleeding_edge/tools/logreader.js
/branches/bleeding_edge/tools/profile.js
/branches/bleeding_edge/tools/tickprocessor.js
=======================================
--- /branches/bleeding_edge/src/api.cc Fri Oct 17 09:04:58 2014 UTC
+++ /branches/bleeding_edge/src/api.cc Fri Oct 17 15:44:02 2014 UTC
@@ -6657,8 +6657,8 @@
void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info)
{
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- i::TickSample::GetStackSample(isolate, state, frames, frames_limit,
- sample_info);
+ i::TickSample::GetStackSample(isolate, state,
i::TickSample::kSkipCEntryFrame,
+ frames, frames_limit, sample_info);
}
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Tue Oct 7 14:45:17 2014 UTC
+++ /branches/bleeding_edge/src/cpu-profiler.cc Fri Oct 17 15:44:02 2014 UTC
@@ -48,7 +48,7 @@
regs.fp = frame->fp();
regs.pc = frame->pc();
}
- record.sample.Init(isolate, regs);
+ record.sample.Init(isolate, regs, TickSample::kSkipCEntryFrame);
ticks_from_vm_buffer_.Enqueue(record);
}
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon Oct 13
14:41:33 2014 UTC
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Oct 17
15:44:02 2014 UTC
@@ -942,8 +942,10 @@
// Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress,
isolate());
ExternalReference context_address(Isolate::kContextAddress, isolate());
+ ExternalReference c_function_address(Isolate::kCFunctionAddress,
isolate());
mov(Operand::StaticVariable(c_entry_fp_address), ebp);
mov(Operand::StaticVariable(context_address), esi);
+ mov(Operand::StaticVariable(c_function_address), ebx);
}
=======================================
--- /branches/bleeding_edge/src/isolate.h Tue Oct 14 08:43:33 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h Fri Oct 17 15:44:02 2014 UTC
@@ -169,6 +169,7 @@
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C) \
C(Handler, handler) \
C(CEntryFP, c_entry_fp) \
+ C(CFunction, c_function) \
C(Context, context) \
C(PendingException, pending_exception) \
C(ExternalCaughtException, external_caught_exception) \
@@ -288,6 +289,7 @@
// Stack.
Address c_entry_fp_; // the frame pointer of the top c entry frame
Address handler_; // try-blocks are chained through the stack
+ Address c_function_; // C function that was called at c entry.
// Throwing an exception may cause a Promise rejection. For this purpose
// we keep track of a stack of nested promises and the corresponding
@@ -652,11 +654,15 @@
return thread->c_entry_fp_;
}
static Address handler(ThreadLocalTop* thread) { return
thread->handler_; }
+ Address c_function() { return thread_local_top_.c_function_; }
inline Address* c_entry_fp_address() {
return &thread_local_top_.c_entry_fp_;
}
inline Address* handler_address() { return &thread_local_top_.handler_; }
+ inline Address* c_function_address() {
+ return &thread_local_top_.c_function_;
+ }
// Bottom JS entry.
Address js_entry_sp() {
=======================================
--- /branches/bleeding_edge/src/sampler.cc Wed Oct 8 11:51:57 2014 UTC
+++ /branches/bleeding_edge/src/sampler.cc Fri Oct 17 15:44:02 2014 UTC
@@ -570,7 +570,8 @@
// StackTracer implementation
//
DISABLE_ASAN void TickSample::Init(Isolate* isolate,
- const v8::RegisterState& regs) {
+ const v8::RegisterState& regs,
+ RecordCEntryFrame record_c_entry_frame)
{
timestamp = base::TimeTicks::HighResolutionNow();
pc = reinterpret_cast<Address>(regs.pc);
state = isolate->current_vm_state();
@@ -601,13 +602,14 @@
top_frame_type = it.top_frame_type();
SampleInfo info;
- GetStackSample(isolate, regs, reinterpret_cast<void**>(&stack[0]),
- kMaxFramesCount, &info);
+ GetStackSample(isolate, regs, record_c_entry_frame,
+ reinterpret_cast<void**>(&stack[0]), kMaxFramesCount,
&info);
frames_count = static_cast<unsigned>(info.frames_count);
}
void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState&
regs,
+ RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info) {
sample_info->frames_count = 0;
@@ -620,6 +622,10 @@
SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
reinterpret_cast<Address>(regs.sp),
js_entry_sp);
size_t i = 0;
+ if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() &&
+ it.top_frame_type() == StackFrame::EXIT) {
+ frames[i++] = isolate->c_function();
+ }
while (!it.done() && i < frames_limit) {
frames[i++] = it.frame()->pc();
it.Advance();
@@ -696,7 +702,7 @@
TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
TickSample sample_obj;
if (sample == NULL) sample = &sample_obj;
- sample->Init(isolate_, state);
+ sample->Init(isolate_, state, TickSample::kIncludeCEntryFrame);
if (is_counting_samples_) {
if (sample->state == JS || sample->state == EXTERNAL) {
++js_and_external_sample_count_;
=======================================
--- /branches/bleeding_edge/src/sampler.h Mon Sep 29 12:59:54 2014 UTC
+++ /branches/bleeding_edge/src/sampler.h Fri Oct 17 15:44:02 2014 UTC
@@ -25,6 +25,11 @@
// TickSample captures the information collected for each sample.
struct TickSample {
+ // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
+ // include the runtime function we're calling. Externally exposed tick
+ // samples don't care.
+ enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
+
TickSample()
: state(OTHER),
pc(NULL),
@@ -32,8 +37,10 @@
frames_count(0),
has_external_callback(false),
top_frame_type(StackFrame::NONE) {}
- void Init(Isolate* isolate, const v8::RegisterState& state);
+ void Init(Isolate* isolate, const v8::RegisterState& state,
+ RecordCEntryFrame record_c_entry_frame);
static void GetStackSample(Isolate* isolate, const v8::RegisterState&
state,
+ RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info);
StateTag state; // The state of the VM.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Oct 17
04:18:38 2014 UTC
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Oct 17
15:44:02 2014 UTC
@@ -4093,6 +4093,7 @@
Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi);
+ Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx);
}
=======================================
--- /branches/bleeding_edge/test/cctest/trace-extension.cc Tue Jun 3
08:12:43 2014 UTC
+++ /branches/bleeding_edge/test/cctest/trace-extension.cc Fri Oct 17
15:44:02 2014 UTC
@@ -91,7 +91,8 @@
// 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);
+ trace_env.sample->Init(CcTest::i_isolate(), regs,
+ TickSample::kSkipCEntryFrame);
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
Mon Aug 4 09:13:58 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
Fri Oct 17 15:44:02 2014 UTC
@@ -24,6 +24,13 @@
4 30.8% Shared libraries
2 15.4% Unaccounted
+ [C++ entry points]:
+ ticks cpp total name
+ 2 40.0% 15.4%
v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+ 1 20.0% 7.7%
v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*,
v8::internal::LookupResult*)
+ 1 20.0% 7.7%
v8::internal::HashTable<v8::internal::StringDictionaryShape,
v8::internal::String*>::FindEntry(v8::internal::String*)
+ 1 20.0% 7.7% exp
+
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info
Mon Aug 4 09:13:58 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info
Fri Oct 17 15:44:02 2014 UTC
@@ -18,6 +18,9 @@
0 0.0% 0.0% GC
0 0.0% Shared libraries
+ [C++ entry points]:
+ ticks cpp total name
+
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
Mon Aug 4 09:13:58 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
Fri Oct 17 15:44:02 2014 UTC
@@ -16,6 +16,9 @@
0 0.0% 0.0% GC
0 0.0% Shared libraries
+ [C++ entry points]:
+ ticks cpp total name
+
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
=======================================
---
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
Mon Aug 4 09:13:58 2014 UTC
+++
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
Fri Oct 17 15:44:02 2014 UTC
@@ -23,6 +23,13 @@
0 0.0% 0.0% GC
4 36.4% Shared libraries
+ [C++ entry points]:
+ ticks cpp total name
+ 2 40.0% 18.2%
v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+ 1 20.0% 9.1%
v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*,
v8::internal::LookupResult*)
+ 1 20.0% 9.1%
v8::internal::HashTable<v8::internal::StringDictionaryShape,
v8::internal::String*>::FindEntry(v8::internal::String*)
+ 1 20.0% 9.1% exp
+
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
=======================================
---
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
Mon Aug 4 09:13:58 2014 UTC
+++
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
Fri Oct 17 15:44:02 2014 UTC
@@ -26,6 +26,13 @@
4 30.8% Shared libraries
2 15.4% Unaccounted
+ [C++ entry points]:
+ ticks cpp total name
+ 2 40.0% 15.4%
v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+ 1 20.0% 7.7%
v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*,
v8::internal::LookupResult*)
+ 1 20.0% 7.7%
v8::internal::HashTable<v8::internal::StringDictionaryShape,
v8::internal::String*>::FindEntry(v8::internal::String*)
+ 1 20.0% 7.7% exp
+
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
=======================================
--- /branches/bleeding_edge/tools/codemap.js Wed Sep 14 11:47:03 2011 UTC
+++ /branches/bleeding_edge/tools/codemap.js Fri Oct 17 15:44:02 2014 UTC
@@ -258,11 +258,13 @@
*
* @param {number} size Code entry size in bytes.
* @param {string} opt_name Code entry name.
+ * @param {string} opt_type Code entry type, e.g. SHARED_LIB, CPP.
* @constructor
*/
-CodeMap.CodeEntry = function(size, opt_name) {
+CodeMap.CodeEntry = function(size, opt_name, opt_type) {
this.size = size;
this.name = opt_name || '';
+ this.type = opt_type || '';
this.nameUpdated_ = false;
};
=======================================
--- /branches/bleeding_edge/tools/logreader.js Thu Sep 15 13:20:42 2011 UTC
+++ /branches/bleeding_edge/tools/logreader.js Fri Oct 17 15:44:02 2014 UTC
@@ -108,6 +108,8 @@
// Filter out possible 'overflow' string.
} else if (firstChar != 'o') {
fullStack.push(parseInt(frame, 16));
+ } else {
+ print("dropping: " + frame);
}
}
return fullStack;
=======================================
--- /branches/bleeding_edge/tools/profile.js Mon Sep 12 10:50:40 2011 UTC
+++ /branches/bleeding_edge/tools/profile.js Fri Oct 17 15:44:02 2014 UTC
@@ -36,6 +36,7 @@
this.codeMap_ = new CodeMap();
this.topDownTree_ = new CallTree();
this.bottomUpTree_ = new CallTree();
+ this.c_entries_ = {};
};
@@ -102,7 +103,7 @@
Profile.prototype.addLibrary = function(
name, startAddr, endAddr) {
var entry = new CodeMap.CodeEntry(
- endAddr - startAddr, name);
+ endAddr - startAddr, name, 'SHARED_LIB');
this.codeMap_.addLibrary(startAddr, entry);
return entry;
};
@@ -118,7 +119,7 @@
Profile.prototype.addStaticCode = function(
name, startAddr, endAddr) {
var entry = new CodeMap.CodeEntry(
- endAddr - startAddr, name);
+ endAddr - startAddr, name, 'CPP');
this.codeMap_.addStaticCode(startAddr, entry);
return entry;
};
@@ -250,10 +251,26 @@
*/
Profile.prototype.resolveAndFilterFuncs_ = function(stack) {
var result = [];
+ var last_seen_c_function = '';
+ var look_for_first_c_function = false;
for (var i = 0; i < stack.length; ++i) {
var entry = this.codeMap_.findEntry(stack[i]);
if (entry) {
var name = entry.getName();
+ if (i == 0 && (entry.type == 'CPP' || entry.type == 'SHARED_LIB')) {
+ look_for_first_c_function = true;
+ }
+ if (look_for_first_c_function) {
+ if (entry.type == 'CPP') {
+ last_seen_c_function = name;
+ } else if (i > 0 && last_seen_c_function != '') {
+ if (this.c_entries_[last_seen_c_function] === undefined) {
+ this.c_entries_[last_seen_c_function] = 0;
+ }
+ this.c_entries_[last_seen_c_function]++;
+ look_for_first_c_function = false; // Found it, we're done.
+ }
+ }
if (!this.skipThisFunction(name)) {
result.push(name);
}
@@ -381,6 +398,28 @@
};
+Profile.CEntryNode = function(name, ticks) {
+ this.name = name;
+ this.ticks = ticks;
+}
+
+
+Profile.prototype.getCEntryProfile = function() {
+ var result = [new Profile.CEntryNode("TOTAL", 0)];
+ var total_ticks = 0;
+ for (var f in this.c_entries_) {
+ var ticks = this.c_entries_[f];
+ total_ticks += ticks;
+ result.push(new Profile.CEntryNode(f, ticks));
+ }
+ result[0].ticks = total_ticks; // Sorting will keep this at index 0.
+ result.sort(function(n1, n2) {
+ return n2.ticks - n1.ticks || (n2.name < n1.name ? -1 : 1)
+ });
+ return result;
+}
+
+
/**
* Cleans up function entries that are not referenced by code entries.
*/
@@ -415,8 +454,7 @@
* @constructor
*/
Profile.DynamicCodeEntry = function(size, type, name) {
- CodeMap.CodeEntry.call(this, size, name);
- this.type = type;
+ CodeMap.CodeEntry.call(this, size, name, type);
};
@@ -456,8 +494,7 @@
* @constructor
*/
Profile.DynamicFuncCodeEntry = function(size, type, func, state) {
- CodeMap.CodeEntry.call(this, size);
- this.type = type;
+ CodeMap.CodeEntry.call(this, size, '', type);
this.func = func;
this.state = state;
};
=======================================
--- /branches/bleeding_edge/tools/tickprocessor.js Mon Aug 4 08:31:49 2014
UTC
+++ /branches/bleeding_edge/tools/tickprocessor.js Fri Oct 17 15:44:02 2014
UTC
@@ -484,6 +484,15 @@
this.printLine('Unaccounted', this.ticks_.unaccounted,
this.ticks_.total, null);
}
+
+ print('\n [C++ entry points]:');
+ print(' ticks cpp total name');
+ var c_entry_functions = this.profile_.getCEntryProfile();
+ var total_c_entry = c_entry_functions[0].ticks;
+ for (var i = 1; i < c_entry_functions.length; i++) {
+ c = c_entry_functions[i];
+ this.printLine(c.name, c.ticks, total_c_entry, totalTicks);
+ }
this.printHeavyProfHeader();
var heavyProfile = this.profile_.getBottomUpProfile();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.