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

Unified Diff: runtime/vm/profiler_service.cc

Issue 1758653003: Add source position information to profile (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
Index: runtime/vm/profiler_service.cc
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 3de17c8009fd8fc55b28c77842ad24dd365761b1..474fa0c5938fc311a16f7c0ccc1960d7d0b82ea4 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -5,6 +5,7 @@
#include "vm/profiler_service.h"
#include "vm/growable_array.h"
+#include "vm/log.h"
#include "vm/native_symbol.h"
#include "vm/object.h"
#include "vm/os.h"
@@ -89,6 +90,23 @@ class DeoptimizedCodeSet : public ZoneAllocated {
};
+ProfileFunctionSourcePosition::ProfileFunctionSourcePosition(
+ TokenPosition token_pos)
+ : token_pos_(token_pos),
+ exclusive_ticks_(0),
+ inclusive_ticks_(0) {
+}
+
+
+void ProfileFunctionSourcePosition::Tick(bool exclusive) {
+ if (exclusive) {
+ exclusive_ticks_++;
+ } else {
+ inclusive_ticks_++;
+ }
+}
+
+
ProfileFunction::ProfileFunction(Kind kind,
const char* name,
const Function& function,
@@ -98,6 +116,7 @@ ProfileFunction::ProfileFunction(Kind kind,
function_(Function::ZoneHandle(function.raw())),
table_index_(table_index),
profile_codes_(0),
+ source_position_ticks_(0),
exclusive_ticks_(0),
inclusive_ticks_(0),
inclusive_serial_(-1) {
@@ -117,9 +136,13 @@ const char* ProfileFunction::Name() const {
return func_name.ToCString();
}
-void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) {
+
+void ProfileFunction::Tick(bool exclusive,
+ intptr_t inclusive_serial,
+ TokenPosition token_position) {
if (exclusive) {
exclusive_ticks_++;
+ TickSourcePosition(token_position, exclusive);
}
// Fall through and tick inclusive count too.
if (inclusive_serial_ == inclusive_serial) {
@@ -128,6 +151,24 @@ void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) {
}
inclusive_serial_ = inclusive_serial;
inclusive_ticks_++;
+ TickSourcePosition(token_position, false);
+}
+
+
+void ProfileFunction::TickSourcePosition(TokenPosition token_position,
+ bool exclusive) {
+ for (intptr_t i = 0; i < source_position_ticks_.length(); i++) {
+ ProfileFunctionSourcePosition& position = source_position_ticks_[i];
+ if (position.token_pos() == token_position) {
+ // Found existing position, tick it.
+ position.Tick(exclusive);
+ return;
+ }
+ }
+ // Add new one.
+ ProfileFunctionSourcePosition pfsp(token_position);
+ pfsp.Tick(exclusive);
+ source_position_ticks_.Add(pfsp);
}
@@ -189,6 +230,18 @@ void ProfileFunction::AddProfileCode(intptr_t code_table_index) {
}
+bool ProfileFunction::GetSinglePosition(ProfileFunctionSourcePosition* pfsp) {
+ if (pfsp == NULL) {
+ return false;
+ }
+ if (source_position_ticks_.length() != 1) {
+ return false;
+ }
+ *pfsp = source_position_ticks_[0];
+ return true;
+}
+
+
ProfileCodeAddress::ProfileCodeAddress(uword pc)
: pc_(pc),
exclusive_ticks_(0),
@@ -1388,14 +1441,40 @@ class ProfileBuilder : public ValueObject {
ASSERT(profile_code != NULL);
const Code& code = Code::ZoneHandle(profile_code->code());
GrowableArray<Function*> inlined_functions;
+ GrowableArray<TokenPosition> inlined_token_positions;
+ TokenPosition token_position = TokenPosition::kNoSource;
if (!code.IsNull()) {
intptr_t offset = pc - code.EntryPoint();
if (frame_index != 0) {
// The PC of frames below the top frame is a call's return address,
// which can belong to a different inlining interval than the call.
offset--;
+ } else if (sample->IsAllocationSample()) {
+ // Allocation samples skip the top frame, so the top frame's pc is
+ // also a call's return address.
+ offset--;
+ }
+ code.GetInlinedFunctionsAt(offset,
+ &inlined_functions,
+ &inlined_token_positions);
+ token_position = code.GetTokenPositionAt(offset);
+ if (inlined_functions.length() > 0) {
+ // The inlined token position table does not include the token position
+ // of the final call. Insert it at the beginning because the table.
+ // is reversed.
+ inlined_token_positions.InsertAt(0, token_position);
+ }
+ ASSERT(inlined_functions.length() <= inlined_token_positions.length());
+ if (FLAG_trace_profiler) {
+ for (intptr_t i = 0; i < inlined_functions.length(); i++) {
+ const String& name =
+ String::Handle(inlined_functions[i]->QualifiedScrubbedName());
+ THR_Print("InlinedFunction[%" Pd "] = {%s, %s}\n",
+ i,
+ name.ToCString(),
+ inlined_token_positions[i].ToCString());
+ }
}
- code.GetInlinedFunctionsAt(offset, &inlined_functions);
}
if (code.IsNull() || (inlined_functions.length() == 0)) {
// No inlined functions.
@@ -1407,6 +1486,7 @@ class ProfileBuilder : public ValueObject {
sample,
frame_index,
function,
+ token_position,
code_index);
if (!inclusive_tree_) {
current = AppendKind(code, current);
@@ -1421,6 +1501,7 @@ class ProfileBuilder : public ValueObject {
Function* inlined_function = inlined_functions[i];
ASSERT(inlined_function != NULL);
ASSERT(!inlined_function->IsNull());
+ TokenPosition inlined_token_position = inlined_token_positions[i];
const bool inliner = i == (inlined_functions.length() - 1);
if (inliner) {
current = AppendKind(code, current);
@@ -1430,6 +1511,7 @@ class ProfileBuilder : public ValueObject {
sample,
frame_index,
inlined_function,
+ inlined_token_position,
code_index);
if (inliner) {
current = AppendKind(kInlineStart, current);
@@ -1443,6 +1525,7 @@ class ProfileBuilder : public ValueObject {
Function* inlined_function = inlined_functions[i];
ASSERT(inlined_function != NULL);
ASSERT(!inlined_function->IsNull());
+ TokenPosition inlined_token_position = inlined_token_positions[i];
const bool inliner = i == (inlined_functions.length() - 1);
if (inliner) {
current = AppendKind(kInlineStart, current);
@@ -1452,6 +1535,7 @@ class ProfileBuilder : public ValueObject {
sample,
frame_index + i,
inlined_function,
+ inlined_token_position,
code_index);
if (inliner) {
current = AppendKind(code, current);
@@ -1468,6 +1552,7 @@ class ProfileBuilder : public ValueObject {
ProcessedSample* sample,
intptr_t frame_index,
Function* inlined_function,
+ TokenPosition inlined_token_position,
intptr_t code_index) {
ProfileFunctionTable* function_table = profile_->functions_;
ProfileFunction* function = function_table->LookupOrAdd(*inlined_function);
@@ -1477,6 +1562,7 @@ class ProfileBuilder : public ValueObject {
sample,
frame_index,
function,
+ inlined_token_position,
code_index);
}
@@ -1494,9 +1580,18 @@ class ProfileBuilder : public ValueObject {
ProcessedSample* sample,
intptr_t frame_index,
ProfileFunction* function,
+ TokenPosition token_position,
intptr_t code_index) {
+ if (FLAG_trace_profiler) {
+ THR_Print("S[%" Pd "]F[%" Pd "] %s %s\n",
+ sample_index,
+ frame_index,
+ function->Name(), token_position.ToCString());
+ }
if (tick_functions_) {
- function->Tick(IsExecutingFrame(sample, frame_index), sample_index);
+ function->Tick(IsExecutingFrame(sample, frame_index),
+ sample_index,
+ token_position);
}
function->AddProfileCode(code_index);
current = current->GetChild(function->table_index());
@@ -2244,6 +2339,50 @@ intptr_t ProfileTrieWalker::CurrentExclusiveTicks() {
}
+const char* ProfileTrieWalker::CurrentToken() {
+ if (current_ == NULL) {
+ return NULL;
+ }
+ if (code_trie_) {
+ return NULL;
+ }
+ ProfileFunction* func = profile_->GetFunction(current_->table_index());
+ const Function& function = Function::Handle(func->function());
+ if (function.IsNull()) {
+ // No function.
+ return NULL;
+ }
+ const Script& script = Script::Handle(function.script());
+ if (script.IsNull()) {
+ // No script.
+ return NULL;
+ }
+ const TokenStream& token_stream = TokenStream::Handle(script.tokens());
+ if (token_stream.IsNull()) {
+ // No token position.
+ return NULL;
+ }
+ ProfileFunctionSourcePosition pfsp(TokenPosition::kNoSource);
+ if (!func->GetSinglePosition(&pfsp)) {
+ // Not exactly one source position.
+ return NULL;
+ }
+ TokenPosition token_pos = pfsp.token_pos();
+ if (!token_pos.IsReal() && !token_pos.IsSynthetic()) {
+ // Not a location in a script.
+ return NULL;
+ }
+ if (token_pos.IsSynthetic()) {
+ token_pos = token_pos.FromSynthetic();
+ }
+ TokenStream::Iterator iterator(token_stream, token_pos);
+ const String& str = String::Handle(iterator.CurrentLiteral());
+ if (str.IsNull()) {
+ return NULL;
+ }
+ return str.ToCString();
+}
+
bool ProfileTrieWalker::Down() {
if ((current_ == NULL) || (current_->NumChildren() == 0)) {
return false;

Powered by Google App Engine
This is Rietveld 408576698