| Index: src/profile-generator.h
|
| diff --git a/src/profile-generator.h b/src/profile-generator.h
|
| index 1fb2a464b3159be02dc9bdf30c3f0e17b700a23e..18edeec28bb4543ad751f3d721ef2c5f90216b02 100644
|
| --- a/src/profile-generator.h
|
| +++ b/src/profile-generator.h
|
| @@ -5,6 +5,7 @@
|
| #ifndef V8_PROFILE_GENERATOR_H_
|
| #define V8_PROFILE_GENERATOR_H_
|
|
|
| +#include <map>
|
| #include "include/v8-profiler.h"
|
| #include "src/allocation.h"
|
| #include "src/hashmap.h"
|
| @@ -45,6 +46,36 @@ class StringsStorage {
|
| };
|
|
|
|
|
| +// Provides a mapping from the offsets within generated code to
|
| +// the source line.
|
| +class JITLineInfoTable : public Malloced {
|
| + public:
|
| + JITLineInfoTable() {}
|
| + ~JITLineInfoTable() {}
|
| +
|
| + void SetPosition(int pc_offset, int line) {
|
| + ASSERT(pc_offset >= 0);
|
| + ASSERT(line > 0); // The 1-based number of the source line.
|
| + pc_offset_map_.insert(std::make_pair(pc_offset, line));
|
| + }
|
| +
|
| + int GetSourceLineNumber(int pc_offset) const {
|
| + PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset);
|
| + if (it == pc_offset_map_.end()) {
|
| + return v8::CpuProfileNode::kNoLineNumberInfo;
|
| + }
|
| + return it->second;
|
| + }
|
| +
|
| + bool Empty() const { return pc_offset_map_.empty(); }
|
| +
|
| + private:
|
| + // pc_offset -> source line
|
| + typedef std::map<int, int> PcOffsetMap;
|
| + PcOffsetMap pc_offset_map_;
|
| + DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable);
|
| +};
|
| +
|
| class CodeEntry {
|
| public:
|
| // CodeEntry doesn't own name strings, just references them.
|
| @@ -53,7 +84,8 @@ class CodeEntry {
|
| const char* name_prefix = CodeEntry::kEmptyNamePrefix,
|
| const char* resource_name = CodeEntry::kEmptyResourceName,
|
| int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
|
| - int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
|
| + int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
|
| + JITLineInfoTable* line_info = NULL);
|
| ~CodeEntry();
|
|
|
| bool is_js_function() const { return is_js_function_tag(tag_); }
|
| @@ -63,6 +95,7 @@ class CodeEntry {
|
| const char* resource_name() const { return resource_name_; }
|
| int line_number() const { return line_number_; }
|
| int column_number() const { return column_number_; }
|
| + const JITLineInfoTable* line_info() const { return line_info_; }
|
| void set_shared_id(int shared_id) { shared_id_ = shared_id; }
|
| int script_id() const { return script_id_; }
|
| void set_script_id(int script_id) { script_id_ = script_id; }
|
| @@ -84,6 +117,8 @@ class CodeEntry {
|
| uint32_t GetCallUid() const;
|
| bool IsSameAs(CodeEntry* entry) const;
|
|
|
| + int GetSourceLine(int pc_offset) const;
|
| +
|
| static const char* const kEmptyNamePrefix;
|
| static const char* const kEmptyResourceName;
|
| static const char* const kEmptyBailoutReason;
|
| @@ -100,6 +135,7 @@ class CodeEntry {
|
| int script_id_;
|
| List<OffsetRange>* no_frame_ranges_;
|
| const char* bailout_reason_;
|
| + JITLineInfoTable* line_info_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(CodeEntry);
|
| };
|
| @@ -115,11 +151,15 @@ class ProfileNode {
|
| ProfileNode* FindOrAddChild(CodeEntry* entry);
|
| void IncrementSelfTicks() { ++self_ticks_; }
|
| void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; }
|
| + void IncrementLineTicks(int src_line);
|
|
|
| CodeEntry* entry() const { return entry_; }
|
| unsigned self_ticks() const { return self_ticks_; }
|
| const List<ProfileNode*>* children() const { return &children_list_; }
|
| unsigned id() const { return id_; }
|
| + unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); }
|
| + bool GetLineTicks(v8::CpuProfileNode::LineTick* entries,
|
| + unsigned int length) const;
|
|
|
| void Print(int indent);
|
|
|
| @@ -140,6 +180,7 @@ class ProfileNode {
|
| HashMap children_;
|
| List<ProfileNode*> children_list_;
|
| unsigned id_;
|
| + HashMap line_ticks_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ProfileNode);
|
| };
|
| @@ -150,8 +191,11 @@ class ProfileTree {
|
| ProfileTree();
|
| ~ProfileTree();
|
|
|
| - ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
|
| - void AddPathFromStart(const Vector<CodeEntry*>& path);
|
| + ProfileNode* AddPathFromEnd(
|
| + const Vector<CodeEntry*>& path,
|
| + int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
|
| + void AddPathFromStart(const Vector<CodeEntry*>& path,
|
| + int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
|
| ProfileNode* root() const { return root_; }
|
| unsigned next_node_id() { return next_node_id_++; }
|
|
|
| @@ -176,7 +220,9 @@ class CpuProfile {
|
| CpuProfile(const char* title, bool record_samples);
|
|
|
| // Add pc -> ... -> main() call path to the profile.
|
| - void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
|
| + void AddPath(base::TimeTicks timestamp,
|
| + const Vector<CodeEntry*>& path,
|
| + int src_line);
|
| void CalculateTotalTicksAndSamplingRate();
|
|
|
| const char* title() const { return title_; }
|
| @@ -283,11 +329,13 @@ class CpuProfilesCollection {
|
| const char* name_prefix = CodeEntry::kEmptyNamePrefix,
|
| const char* resource_name = CodeEntry::kEmptyResourceName,
|
| int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
|
| - int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
|
| + int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
|
| + JITLineInfoTable* line_info = NULL);
|
|
|
| // Called from profile generator thread.
|
| - void AddPathToCurrentProfiles(
|
| - base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
|
| + void AddPathToCurrentProfiles(base::TimeTicks timestamp,
|
| + const Vector<CodeEntry*>& path,
|
| + int src_line);
|
|
|
| // Limits the number of profiles that can be simultaneously collected.
|
| static const int kMaxSimultaneousProfiles = 100;
|
|
|