Reviewers: Jakob, loislo, alph,
Description:
Revert r14252 as it broke --prof for some cases
R=jkummerow
BUG=v8:2642
Please review this at https://codereview.chromium.org/14367020/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/log.cc
M src/profile-generator.cc
M src/sampler.h
M src/sampler.cc
M test/cctest/test-cpu-profiler.cc
M test/cctest/test-log-stack-tracer.cc
M test/cctest/test-profile-generator.cc
M test/mjsunit/tools/tickprocessor-test-func-info.log
M test/mjsunit/tools/tickprocessor-test.log
M tools/tickprocessor.js
Index: src/log.cc
diff --git a/src/log.cc b/src/log.cc
index
55f5637d555b4bfc1ccb5f138e8b5ad995abdb78..57abdefbaba9ae5e850b53148bdffadefa99a28f
100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -1448,7 +1448,13 @@ void Logger::TickEvent(TickSample* sample, bool
overflow) {
msg.Append(',');
msg.AppendAddress(sample->sp);
msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_));
- msg.AppendAddress(sample->external_callback);
+ if (sample->has_external_callback) {
+ msg.Append(",1,");
+ msg.AppendAddress(sample->external_callback);
+ } else {
+ msg.Append(",0,");
+ msg.AppendAddress(sample->tos);
+ }
msg.Append(",%d", static_cast<int>(sample->state));
if (overflow) {
msg.Append(",overflow");
Index: src/profile-generator.cc
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index
eacabeff4f1ab8c882b10c038052d2335d973759..e4c750cb83c1dbc8b489f2a08779d3b43ccacb0d
100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -894,7 +894,7 @@ void ProfileGenerator::RecordTickSample(const
TickSample& sample) {
if (sample.pc != NULL) {
*entry++ = code_map_.FindEntry(sample.pc);
- if (sample.external_callback) {
+ if (sample.has_external_callback) {
// Don't use PC when in external callback code, as it can point
// inside callback's code, and we will erroneously report
// that a callback calls itself.
Index: src/sampler.cc
diff --git a/src/sampler.cc b/src/sampler.cc
index
948b0540736d629a1d861b9db6371c0711590a96..e271470bd2d01ee841eae39d4f51ee59e98061ba
100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -636,7 +636,16 @@ DISABLE_ASAN void TickSample::Trace(Isolate* isolate) {
return;
}
- external_callback = isolate->external_callback();
+ const Address callback = isolate->external_callback();
+ if (callback != NULL) {
+ external_callback = callback;
+ has_external_callback = true;
+ } else {
+ // Sample potential return address value for frameless invocation of
+ // stubs (we'll figure out later, if this value makes sense).
+ tos = Memory::Address_at(sp);
+ has_external_callback = false;
+ }
SafeStackTraceFrameIterator it(isolate, fp, sp, sp, js_entry_sp);
int i = 0;
Index: src/sampler.h
diff --git a/src/sampler.h b/src/sampler.h
index
a76d8b9a5785485d18389462e19a6dd22fbc4c8c..1d9ac8723bf0487ab6cd37ac4dc2af7b4d3c41c7
100644
--- a/src/sampler.h
+++ b/src/sampler.h
@@ -51,16 +51,21 @@ struct TickSample {
sp(NULL),
fp(NULL),
external_callback(NULL),
- frames_count(0) {}
+ frames_count(0),
+ has_external_callback(false) {}
void Trace(Isolate* isolate);
StateTag state; // The state of the VM.
Address pc; // Instruction pointer.
Address sp; // Stack pointer.
Address fp; // Frame pointer.
- Address external_callback;
+ union {
+ Address tos; // Top stack value (*sp).
+ Address external_callback;
+ };
static const int kMaxFramesCount = 64;
Address stack[kMaxFramesCount]; // Call stack.
int frames_count : 8; // Number of captured frames.
+ bool has_external_callback : 1;
};
class Sampler {
Index: test/cctest/test-cpu-profiler.cc
diff --git a/test/cctest/test-cpu-profiler.cc
b/test/cctest/test-cpu-profiler.cc
index
2eece46230eb565fd17c815980384457fc383ee3..40b5b79125a7f22fa0c2db853a2e9ec4b50820a6
100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -64,6 +64,7 @@ static void
EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
i::Address frame3 = NULL) {
i::TickSample* sample = proc->TickSampleEvent();
sample->pc = frame1;
+ sample->tos = frame1;
sample->frames_count = 0;
if (frame2 != NULL) {
sample->stack[0] = frame2;
@@ -238,6 +239,7 @@ TEST(Issue1398) {
i::TickSample* sample = processor.TickSampleEvent();
sample->pc = ToAddress(0x1200);
+ sample->tos = 0;
sample->frames_count = i::TickSample::kMaxFramesCount;
for (int i = 0; i < sample->frames_count; ++i) {
sample->stack[i] = ToAddress(0x1200);
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
5bfc1d36beef64ef3c34d6229d9b430dac54fa5a..ca6c7aea47bd11f76bc3e10e4f16f7c7174a8453
100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -286,7 +286,7 @@ TEST(CFromJSStackTrace) {
// DoTrace(EBP) [native]
// TickSample::Trace
- CHECK(sample.external_callback);
+ CHECK(sample.has_external_callback);
CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback);
// Stack tracing will start from the first JS function,
i.e. "JSFuncDoTrace"
@@ -336,7 +336,7 @@ TEST(PureJSStackTrace) {
// TickSample::Trace
//
- CHECK(sample.external_callback);
+ CHECK(sample.has_external_callback);
CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace),
sample.external_callback);
// Stack sampling will start from the caller of JSFuncDoTrace,
i.e. "JSTrace"
Index: test/cctest/test-profile-generator.cc
diff --git a/test/cctest/test-profile-generator.cc
b/test/cctest/test-profile-generator.cc
index
0682fbcdb164d57f3fde27858139d22c86340e57..56b1788a85132140bfeb0d7bea36479f0f0deb36
100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -624,11 +624,13 @@ TEST(RecordTickSample) {
// -> ccc -> aaa - sample3
TickSample sample1;
sample1.pc = ToAddress(0x1600);
+ sample1.tos = ToAddress(0x1500);
sample1.stack[0] = ToAddress(0x1510);
sample1.frames_count = 1;
generator.RecordTickSample(sample1);
TickSample sample2;
sample2.pc = ToAddress(0x1925);
+ sample2.tos = ToAddress(0x1900);
sample2.stack[0] = ToAddress(0x1780);
sample2.stack[1] = ToAddress(0x10000); // non-existent.
sample2.stack[2] = ToAddress(0x1620);
@@ -636,6 +638,7 @@ TEST(RecordTickSample) {
generator.RecordTickSample(sample2);
TickSample sample3;
sample3.pc = ToAddress(0x1510);
+ sample3.tos = ToAddress(0x1500);
sample3.stack[0] = ToAddress(0x1910);
sample3.stack[1] = ToAddress(0x1610);
sample3.frames_count = 2;
Index: test/mjsunit/tools/tickprocessor-test-func-info.log
diff --git a/test/mjsunit/tools/tickprocessor-test-func-info.log
b/test/mjsunit/tools/tickprocessor-test-func-info.log
index
fccd87e744feabd414dcd366f2ceebac1dc996ef..5e64dc09e31c60e11c605464ae59a83eb4cb6880
100644
--- a/test/mjsunit/tools/tickprocessor-test-func-info.log
+++ b/test/mjsunit/tools/tickprocessor-test-func-info.log
@@ -5,7 +5,7 @@ profiler,"begin",1
code-creation,Stub,0,0x424260,348,"CompareStub_GE"
code-creation,LazyCompile,0,0x2a8100,18535,"DrawQube
3d-cube.js:188",0xf43abcac,
code-creation,LazyCompile,0,0x480100,3908,"DrawLine
3d-cube.js:17",0xf43abc50,
-tick,0x424284,0xbfffeea0,0,0,0,0x480600,0x2aaaa5
-tick,0x42429f,0xbfffed88,0,0,0,0x480600,0x2aacb4
-tick,0x48063d,0xbfffec7c,0,0,0,0x2d0f7c,0x2aaec6
+tick,0x424284,0xbfffeea0,0,0,0x480600,0,0x2aaaa5
+tick,0x42429f,0xbfffed88,0,0,0x480600,0,0x2aacb4
+tick,0x48063d,0xbfffec7c,0,0,0x2d0f7c,0,0x2aaec6
profiler,"end"
Index: test/mjsunit/tools/tickprocessor-test.log
diff --git a/test/mjsunit/tools/tickprocessor-test.log
b/test/mjsunit/tools/tickprocessor-test.log
index
27335138467fd13b9c173964bc96ede3f05de65b..5ddad89a55d0382af6a33b0140f78b09eec8edb8
100644
--- a/test/mjsunit/tools/tickprocessor-test.log
+++ b/test/mjsunit/tools/tickprocessor-test.log
@@ -9,17 +9,17 @@ code-creation,LazyCompile,0,0xf541d120,145,"exp native
math.js:41"
function-creation,0xf441d280,0xf541d120
code-creation,LoadIC,0,0xf541d280,117,"j"
code-creation,LoadIC,0,0xf541d360,63,"i"
-tick,0x80f82d1,0xffdfe880,0,0,0,0xf541ce5c
-tick,0x80f89a1,0xffdfecf0,0,0,0,0xf541ce5c
-tick,0x8123b5c,0xffdff1a0,0,0,0,0xf541d1a1,0xf541ceea
-tick,0x8123b65,0xffdff1a0,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xf541d2be,0xffdff1e4,0,0,0
-tick,0xf541d320,0xffdff1dc,0,0,0
-tick,0xf541d384,0xffdff1d8,0,0,0
-tick,0xf7db94da,0xffdff0ec,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xf7db951c,0xffdff0f0,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xf7dbc508,0xffdff14c,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xf7dbff21,0xffdff198,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xf7edec90,0xffdff0ec,0,0,0,0xf541d1a1,0xf541ceea
-tick,0xffffe402,0xffdff488,0,0,0
+tick,0x80f82d1,0xffdfe880,0,0,0,0,0xf541ce5c
+tick,0x80f89a1,0xffdfecf0,0,0,0,0,0xf541ce5c
+tick,0x8123b5c,0xffdff1a0,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0x8123b65,0xffdff1a0,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xf541d2be,0xffdff1e4,0,0,0,0
+tick,0xf541d320,0xffdff1dc,0,0,0,0
+tick,0xf541d384,0xffdff1d8,0,0,0,0
+tick,0xf7db94da,0xffdff0ec,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xf7db951c,0xffdff0f0,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xf7dbc508,0xffdff14c,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xf7dbff21,0xffdff198,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xf7edec90,0xffdff0ec,0,0,0,0,0xf541d1a1,0xf541ceea
+tick,0xffffe402,0xffdff488,0,0,0,0
profiler,"end"
Index: tools/tickprocessor.js
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index
0ffe7342a998846fcb940308537b96bcb26a930f..c9ee1011f066abfc1aae9353ac589e65cce03fcd
100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -170,7 +170,7 @@ function TickProcessor(
processor: this.processSnapshotPosition },
'tick': {
parsers: [parseInt, parseInt, parseInt, parseInt,
- parseInt, 'var-args'],
+ parseInt, parseInt, 'var-args'],
processor: this.processTick },
'heap-sample-begin': { parsers: [null, null, parseInt],
processor: this.processHeapSampleBegin },
@@ -368,7 +368,8 @@ TickProcessor.prototype.includeTick = function(vmState)
{
TickProcessor.prototype.processTick = function(pc,
sp,
ns_since_start,
- external_callback,
+ is_external_callback,
+ tos_or_external_callback,
vmState,
stack) {
this.distortion += this.distortion_per_entry;
@@ -382,15 +383,23 @@ TickProcessor.prototype.processTick = function(pc,
this.ticks_.excluded++;
return;
}
- if (external_callback) {
+ if (is_external_callback) {
// Don't use PC when in external callback code, as it can point
// inside callback's code, and we will erroneously report
// that a callback calls itself. Instead we use
tos_or_external_callback,
// as simply resetting PC will produce unaccounted ticks.
- pc = 0;
- }
+ pc = tos_or_external_callback;
+ tos_or_external_callback = 0;
+ } else if (tos_or_external_callback) {
+ // Find out, if top of stack was pointing inside a JS function
+ // meaning that we have encountered a frameless invocation.
+ var funcEntry = this.profile_.findEntry(tos_or_external_callback);
+ if (!funcEntry || !funcEntry.isJSFunction |
| !funcEntry.isJSFunction()) {
+ tos_or_external_callback = 0;
+ }
+ }
- this.profile_.recordTick(this.processStack(pc, external_callback,
stack));
+ this.profile_.recordTick(this.processStack(pc, tos_or_external_callback,
stack));
};
--
--
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/groups/opt_out.