Commit baf927ff authored by loislo's avatar loislo Committed by Commit bot

CpuProfiler: public API for deopt info in cpu profiler.

BUG=chromium:452067
LOG=n

Review URL: https://codereview.chromium.org/1045753002

Cr-Commit-Position: refs/heads/master@{#27626}
parent 8e723e98
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_V8_PROFILER_H_ #ifndef V8_V8_PROFILER_H_
#define V8_V8_PROFILER_H_ #define V8_V8_PROFILER_H_
#include <vector>
#include "v8.h" #include "v8.h"
/** /**
...@@ -17,6 +18,18 @@ struct HeapStatsUpdate; ...@@ -17,6 +18,18 @@ struct HeapStatsUpdate;
typedef uint32_t SnapshotObjectId; typedef uint32_t SnapshotObjectId;
struct V8_EXPORT CpuProfileDeoptInfo {
struct Frame {
int script_id;
size_t position;
};
/** A pointer to a static string owned by v8. */
const char* deopt_reason;
std::vector<Frame> stack;
};
/** /**
* CpuProfileNode represents a node in a call graph. * CpuProfileNode represents a node in a call graph.
*/ */
...@@ -85,6 +98,9 @@ class V8_EXPORT CpuProfileNode { ...@@ -85,6 +98,9 @@ class V8_EXPORT CpuProfileNode {
/** Retrieves a child node by index. */ /** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const; const CpuProfileNode* GetChild(int index) const;
/** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo; static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
}; };
......
...@@ -7535,6 +7535,12 @@ const CpuProfileNode* CpuProfileNode::GetChild(int index) const { ...@@ -7535,6 +7535,12 @@ const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
} }
const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
return node->deopt_infos();
}
void CpuProfile::Delete() { void CpuProfile::Delete() {
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
i::CpuProfiler* profiler = isolate->cpu_profiler(); i::CpuProfiler* profiler = isolate->cpu_profiler();
......
...@@ -112,15 +112,14 @@ void CodeEntry::FillFunctionInfo(SharedFunctionInfo* shared) { ...@@ -112,15 +112,14 @@ void CodeEntry::FillFunctionInfo(SharedFunctionInfo* shared) {
} }
DeoptInfo CodeEntry::GetDeoptInfo() { CpuProfileDeoptInfo CodeEntry::GetDeoptInfo() {
DCHECK(has_deopt_info()); DCHECK(has_deopt_info());
DeoptInfo info; CpuProfileDeoptInfo info;
info.deopt_reason = deopt_reason_; info.deopt_reason = deopt_reason_;
if (inlined_function_infos_.empty()) { if (inlined_function_infos_.empty()) {
info.stack.push_back(DeoptInfo::Frame( info.stack.push_back(CpuProfileDeoptInfo::Frame(
{script_id_, {script_id_, position_ + deopt_position_.position()}));
static_cast<int>(position_ + deopt_position_.position())}));
return info; return info;
} }
// Copy the only branch from the inlining tree where the deopt happened. // Copy the only branch from the inlining tree where the deopt happened.
...@@ -136,9 +135,9 @@ DeoptInfo CodeEntry::GetDeoptInfo() { ...@@ -136,9 +135,9 @@ DeoptInfo CodeEntry::GetDeoptInfo() {
} }
while (inlining_id != InlinedFunctionInfo::kNoParentId) { while (inlining_id != InlinedFunctionInfo::kNoParentId) {
InlinedFunctionInfo& inlined_info = inlined_function_infos_.at(inlining_id); InlinedFunctionInfo& inlined_info = inlined_function_infos_.at(inlining_id);
info.stack.push_back(DeoptInfo::Frame( info.stack.push_back(CpuProfileDeoptInfo::Frame(
{inlined_info.script_id, {inlined_info.script_id,
static_cast<int>(inlined_info.start_position + position.raw())})); inlined_info.start_position + position.raw()}));
position = inlined_info.inline_position; position = inlined_info.inline_position;
inlining_id = inlined_info.parent_id; inlining_id = inlined_info.parent_id;
} }
...@@ -216,7 +215,7 @@ void ProfileNode::Print(int indent) { ...@@ -216,7 +215,7 @@ void ProfileNode::Print(int indent) {
base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number()); base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number());
base::OS::Print("\n"); base::OS::Print("\n");
for (size_t i = 0; i < deopt_infos_.size(); ++i) { for (size_t i = 0; i < deopt_infos_.size(); ++i) {
DeoptInfo& info = deopt_infos_[i]; CpuProfileDeoptInfo& info = deopt_infos_[i];
base::OS::Print( base::OS::Print(
"%*s;;; deopted at script_id: %d position: %d with reason '%s'.\n", "%*s;;; deopted at script_id: %d position: %d with reason '%s'.\n",
indent + 10, "", info.stack[0].script_id, info.stack[0].position, indent + 10, "", info.stack[0].script_id, info.stack[0].position,
......
...@@ -37,16 +37,6 @@ class JITLineInfoTable : public Malloced { ...@@ -37,16 +37,6 @@ class JITLineInfoTable : public Malloced {
}; };
struct DeoptInfo {
const char* deopt_reason;
struct Frame {
int script_id;
int position;
};
std::vector<Frame> stack;
};
class CodeEntry { class CodeEntry {
public: public:
// CodeEntry doesn't own name strings, just references them. // CodeEntry doesn't own name strings, just references them.
...@@ -83,7 +73,7 @@ class CodeEntry { ...@@ -83,7 +73,7 @@ class CodeEntry {
deopt_position_ = position; deopt_position_ = position;
pc_offset_ = pc_offset; pc_offset_ = pc_offset;
} }
DeoptInfo GetDeoptInfo(); CpuProfileDeoptInfo GetDeoptInfo();
const char* deopt_reason() const { return deopt_reason_; } const char* deopt_reason() const { return deopt_reason_; }
SourcePosition deopt_position() const { return deopt_position_; } SourcePosition deopt_position() const { return deopt_position_; }
bool has_deopt_info() const { return !deopt_position_.IsUnknown(); } bool has_deopt_info() const { return !deopt_position_.IsUnknown(); }
...@@ -173,7 +163,9 @@ class ProfileNode { ...@@ -173,7 +163,9 @@ class ProfileNode {
bool GetLineTicks(v8::CpuProfileNode::LineTick* entries, bool GetLineTicks(v8::CpuProfileNode::LineTick* entries,
unsigned int length) const; unsigned int length) const;
void CollectDeoptInfo(CodeEntry* entry); void CollectDeoptInfo(CodeEntry* entry);
const std::vector<DeoptInfo>& deopt_infos() const { return deopt_infos_; } const std::vector<CpuProfileDeoptInfo>& deopt_infos() const {
return deopt_infos_;
}
void Print(int indent); void Print(int indent);
...@@ -196,7 +188,7 @@ class ProfileNode { ...@@ -196,7 +188,7 @@ class ProfileNode {
unsigned id_; unsigned id_;
HashMap line_ticks_; HashMap line_ticks_;
std::vector<DeoptInfo> deopt_infos_; std::vector<CpuProfileDeoptInfo> deopt_infos_;
DISALLOW_COPY_AND_ASSIGN(ProfileNode); DISALLOW_COPY_AND_ASSIGN(ProfileNode);
}; };
......
...@@ -56,8 +56,10 @@ static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) { ...@@ -56,8 +56,10 @@ static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) {
} }
static int offset(const char* src, const char* substring) { static size_t offset(const char* src, const char* substring) {
return static_cast<int>(strstr(src, substring) - src); const char* it = strstr(src, substring);
CHECK(it);
return static_cast<size_t>(it - src);
} }
...@@ -1898,10 +1900,11 @@ TEST(DeoptAtFirstLevelInlinedSource) { ...@@ -1898,10 +1900,11 @@ TEST(DeoptAtFirstLevelInlinedSource) {
const char* branch[] = {"", "test"}; const char* branch[] = {"", "test"};
const ProfileNode* itest_node = const ProfileNode* itest_node =
GetSimpleBranch(profile, branch, arraysize(branch)); GetSimpleBranch(profile, branch, arraysize(branch));
const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos(); const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos =
itest_node->deopt_infos();
CHECK_EQ(1, deopt_infos.size()); CHECK_EQ(1, deopt_infos.size());
const i::DeoptInfo& info = deopt_infos[0]; const v8::CpuProfileDeoptInfo& info = deopt_infos[0];
CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason); CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
CHECK_EQ(2, info.stack.size()); CHECK_EQ(2, info.stack.size());
CHECK_EQ(inlined_script_id, info.stack[0].script_id); CHECK_EQ(inlined_script_id, info.stack[0].script_id);
...@@ -1970,10 +1973,11 @@ TEST(DeoptAtSecondLevelInlinedSource) { ...@@ -1970,10 +1973,11 @@ TEST(DeoptAtSecondLevelInlinedSource) {
const char* branch[] = {"", "test1"}; const char* branch[] = {"", "test1"};
const ProfileNode* itest_node = const ProfileNode* itest_node =
GetSimpleBranch(profile, branch, arraysize(branch)); GetSimpleBranch(profile, branch, arraysize(branch));
const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos(); const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos =
itest_node->deopt_infos();
CHECK_EQ(1, deopt_infos.size()); CHECK_EQ(1, deopt_infos.size());
const i::DeoptInfo info = deopt_infos[0]; const v8::CpuProfileDeoptInfo info = deopt_infos[0];
CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason); CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
CHECK_EQ(3, info.stack.size()); CHECK_EQ(3, info.stack.size());
CHECK_EQ(inlined_script_id, info.stack[0].script_id); CHECK_EQ(inlined_script_id, info.stack[0].script_id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment