Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1139)

Unified Diff: src/profiler/profile-generator.cc

Issue 2396733002: [profiler] Tracing-based CPU profiler. (Closed)
Patch Set: Addressing comments + moving traced-value back to src/tracing Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profiler/profile-generator.h ('k') | src/profiler/profile-generator-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profiler/profile-generator.cc
diff --git a/src/profiler/profile-generator.cc b/src/profiler/profile-generator.cc
index 583ef0f4e381e17f4c06452e4401ba6be0f8f82c..a670729b794961da40ef3668a326cb11cf851f90 100644
--- a/src/profiler/profile-generator.cc
+++ b/src/profiler/profile-generator.cc
@@ -10,6 +10,8 @@
#include "src/global-handles.h"
#include "src/profiler/cpu-profiler.h"
#include "src/profiler/profile-generator-inl.h"
+#include "src/tracing/trace-event.h"
+#include "src/tracing/traced-value.h"
#include "src/unicode.h"
namespace v8 {
@@ -214,9 +216,8 @@ ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) {
base::HashMap::Entry* map_entry =
children_.LookupOrInsert(entry, CodeEntryHash(entry));
ProfileNode* node = reinterpret_cast<ProfileNode*>(map_entry->value);
- if (node == NULL) {
- // New node added.
- node = new ProfileNode(tree_, entry);
+ if (!node) {
+ node = new ProfileNode(tree_, entry, this);
map_entry->value = node;
children_list_.Add(node);
}
@@ -305,7 +306,7 @@ class DeleteNodesCallback {
ProfileTree::ProfileTree(Isolate* isolate)
: root_entry_(CodeEventListener::FUNCTION_TAG, "(root)"),
next_node_id_(1),
- root_(new ProfileNode(this, &root_entry_)),
+ root_(new ProfileNode(this, &root_entry_, nullptr)),
isolate_(isolate),
next_function_id_(1),
function_ids_(ProfileNode::CodeEntriesMatch) {}
@@ -397,13 +398,22 @@ void ProfileTree::TraverseDepthFirst(Callback* callback) {
}
}
+using v8::tracing::TracedValue;
+
CpuProfile::CpuProfile(CpuProfiler* profiler, const char* title,
bool record_samples)
: title_(title),
record_samples_(record_samples),
start_time_(base::TimeTicks::HighResolutionNow()),
top_down_(profiler->isolate()),
- profiler_(profiler) {}
+ profiler_(profiler),
+ streaming_next_sample_(0) {
+ auto value = TracedValue::Create();
+ value->SetDouble("startTime",
+ (start_time_ - base::TimeTicks()).InMicroseconds());
+ TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"),
+ "CpuProfile", this, "data", std::move(value));
+}
void CpuProfile::AddPath(base::TimeTicks timestamp,
const std::vector<CodeEntry*>& path, int src_line,
@@ -414,10 +424,91 @@ void CpuProfile::AddPath(base::TimeTicks timestamp,
timestamps_.Add(timestamp);
samples_.Add(top_frame_node);
}
+ const int kSamplesFlushCount = 100;
+ const int kNodesFlushCount = 10;
+ if (samples_.length() - streaming_next_sample_ >= kSamplesFlushCount ||
+ top_down_.pending_nodes_count() >= kNodesFlushCount) {
+ StreamPendingTraceEvents();
+ }
+}
+
+namespace {
+
+void BuildNodeValue(const ProfileNode* node, TracedValue* value) {
+ const CodeEntry* entry = node->entry();
+ value->BeginDictionary("callFrame");
+ value->SetString("functionName", entry->name());
+ if (*entry->resource_name()) {
+ value->SetString("url", entry->resource_name());
+ }
+ value->SetInteger("scriptId", entry->script_id());
+ if (entry->line_number()) {
+ value->SetInteger("lineNumber", entry->line_number() - 1);
+ }
+ if (entry->column_number()) {
+ value->SetInteger("columnNumber", entry->column_number() - 1);
+ }
+ value->EndDictionary();
+ value->SetInteger("id", node->id());
+ if (node->parent()) {
+ value->SetInteger("parent", node->parent()->id());
+ }
+ const char* deopt_reason = entry->bailout_reason();
+ if (deopt_reason && deopt_reason[0] && strcmp(deopt_reason, "no reason")) {
+ value->SetString("deoptReason", deopt_reason);
+ }
+}
+
+} // namespace
+
+void CpuProfile::StreamPendingTraceEvents() {
+ std::vector<const ProfileNode*> pending_nodes = top_down_.TakePendingNodes();
+ if (pending_nodes.empty() && !samples_.length()) return;
+ auto value = TracedValue::Create();
+
+ if (!pending_nodes.empty()) {
+ value->BeginArray("nodes");
+ for (auto node : pending_nodes) {
+ value->BeginDictionary();
+ BuildNodeValue(node, value.get());
+ value->EndDictionary();
+ }
+ value->EndArray();
+ }
+
+ if (streaming_next_sample_ != samples_.length()) {
+ value->BeginArray("samples");
+ for (int i = streaming_next_sample_; i < samples_.length(); ++i) {
+ value->AppendInteger(samples_[i]->id());
+ }
+ value->EndArray();
+ value->BeginArray("timeDeltas");
+ base::TimeTicks lastTimestamp =
+ streaming_next_sample_ ? timestamps_[streaming_next_sample_ - 1]
+ : start_time();
+ for (int i = streaming_next_sample_; i < timestamps_.length(); ++i) {
+ value->AppendInteger(
+ static_cast<int>((timestamps_[i] - lastTimestamp).InMicroseconds()));
+ lastTimestamp = timestamps_[i];
+ }
+ value->EndArray();
+ DCHECK(samples_.length() == timestamps_.length());
+ streaming_next_sample_ = samples_.length();
+ }
+
+ TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"),
+ "CpuProfileChunk", this, "data",
+ std::move(value));
}
-void CpuProfile::CalculateTotalTicksAndSamplingRate() {
+void CpuProfile::FinishProfile() {
end_time_ = base::TimeTicks::HighResolutionNow();
+ StreamPendingTraceEvents();
+ auto value = TracedValue::Create();
+ value->SetDouble("endTime", (end_time_ - base::TimeTicks()).InMicroseconds());
+ TRACE_EVENT_SAMPLE_WITH_ID1(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"),
+ "CpuProfileChunk", this, "data",
+ std::move(value));
}
void CpuProfile::Print() {
@@ -504,7 +595,7 @@ bool CpuProfilesCollection::StartProfiling(const char* title,
CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
const int title_len = StrLength(title);
- CpuProfile* profile = NULL;
+ CpuProfile* profile = nullptr;
current_profiles_semaphore_.Wait();
for (int i = current_profiles_.length() - 1; i >= 0; --i) {
if (title_len == 0 || strcmp(current_profiles_[i]->title(), title) == 0) {
@@ -514,8 +605,8 @@ CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
}
current_profiles_semaphore_.Signal();
- if (profile == NULL) return NULL;
- profile->CalculateTotalTicksAndSamplingRate();
+ if (!profile) return nullptr;
+ profile->FinishProfile();
finished_profiles_.Add(profile);
return profile;
}
« no previous file with comments | « src/profiler/profile-generator.h ('k') | src/profiler/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698