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

Unified Diff: runtime/vm/profiler_service.cc

Issue 2748403002: Added page to Observatory to display native memory allocation information. (Closed)
Patch Set: Added tests to verify sample tries inclusive/exclusive allocations. Element now displays memory con… Created 3 years, 9 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
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/profiler_service.cc
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index e750b2c573ed036de4a197b2490653a12a83d956..939ecdeb0851f9f8046a68efb68730898b1f6a9e 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -146,9 +146,11 @@ bool ProfileFunction::is_visible() const {
void ProfileFunction::Tick(bool exclusive,
intptr_t inclusive_serial,
- TokenPosition token_position) {
+ TokenPosition token_position,
+ ProcessedSample* sample) {
if (exclusive) {
exclusive_ticks_++;
+ AccumulateAllocation(sample->native_allocation_size_bytes(), true);
TickSourcePosition(token_position, exclusive);
}
// Fall through and tick inclusive count too.
@@ -158,6 +160,7 @@ void ProfileFunction::Tick(bool exclusive,
}
inclusive_serial_ = inclusive_serial;
inclusive_ticks_++;
+ AccumulateAllocation(sample->native_allocation_size_bytes(), false);
TickSourcePosition(token_position, false);
}
@@ -199,6 +202,42 @@ void ProfileFunction::TickSourcePosition(TokenPosition token_position,
}
+static intptr_t SumAllocations(const AllocationHashMap& map) {
+ uintptr_t sum = 0;
+ AllocationHashMap::Iterator iter = map.GetIterator();
+ AllocationKeyValueTrait::Pair* pair = iter.Next();
+
+ while (pair != NULL) {
+ sum += pair->value * pair->key;
+ pair = iter.Next();
+ }
+
+ return sum;
+}
+
+
+static void AccumulateAllocationHelper(AllocationHashMap* map,
Cutch 2017/03/16 20:38:16 I don't see why this code is necessary?
bkonyi 2017/03/16 20:48:40 So, currently, I'm tracking the inclusive/exclusiv
bkonyi 2017/03/21 01:53:23 Removed.
+ intptr_t allocation_size) {
+ ASSERT(map != NULL);
+ AllocationKeyValueTrait::Pair* allocation = map->Lookup(allocation_size);
+ if (allocation == NULL) {
+ map->Insert(AllocationKeyValueTrait::Pair(allocation_size, 1));
+ return;
+ }
+ ++allocation->value;
+}
+
+
+void ProfileFunction::AccumulateAllocation(intptr_t allocation_size,
+ bool exclusive) {
+ if (exclusive) {
+ AccumulateAllocationHelper(&exclusive_native_allocations_, allocation_size);
+ } else {
+ AccumulateAllocationHelper(&inclusive_native_allocations_, allocation_size);
+ }
+}
+
+
const char* ProfileFunction::KindToCString(Kind kind) {
switch (kind) {
case kDartFunction:
@@ -230,6 +269,12 @@ void ProfileFunction::PrintToJSONArray(JSONArray* functions) {
obj.AddProperty("kind", KindToCString(kind()));
obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+
+ obj.AddPropertyF("inclusiveNativeAllocations", "%" Pd "",
+ SumAllocations(inclusive_native_allocations_));
+ obj.AddPropertyF("exclusiveNativeAllocations", "%" Pd "",
+ SumAllocations(exclusive_native_allocations_));
+
if (kind() == kDartFunction) {
ASSERT(!function_.IsNull());
obj.AddProperty("function", function_);
@@ -344,10 +389,14 @@ void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
}
-void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) {
+void ProfileCode::Tick(uword pc,
+ bool exclusive,
+ intptr_t serial,
+ ProcessedSample* sample) {
// If exclusive is set, tick it.
if (exclusive) {
exclusive_ticks_++;
+ AccumulateAllocation(sample->native_allocation_size_bytes(), true);
TickAddress(pc, true);
}
// Fall through and tick inclusive count too.
@@ -355,6 +404,9 @@ void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) {
// Already gave inclusive tick for this sample.
return;
}
+
+ AccumulateAllocation(sample->native_allocation_size_bytes(), false);
+
inclusive_serial_ = serial;
inclusive_ticks_++;
TickAddress(pc, false);
@@ -392,6 +444,16 @@ void ProfileCode::TickAddress(uword pc, bool exclusive) {
}
+void ProfileCode::AccumulateAllocation(intptr_t allocation_size,
+ bool exclusive) {
+ if (exclusive) {
+ AccumulateAllocationHelper(&exclusive_native_allocations_, allocation_size);
+ } else {
+ AccumulateAllocationHelper(&inclusive_native_allocations_, allocation_size);
+ }
+}
+
+
void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) {
ASSERT(kind() == kNativeCode);
JSONObject obj(profile_code_obj, "code");
@@ -487,6 +549,10 @@ void ProfileCode::PrintToJSONArray(JSONArray* codes) {
obj.AddProperty("kind", ProfileCode::KindToCString(kind()));
obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+ obj.AddPropertyF("inclusiveNativeAllocations", "%" Pd "",
+ SumAllocations(inclusive_native_allocations_));
+ obj.AddPropertyF("exclusiveNativeAllocations", "%" Pd "",
+ SumAllocations(exclusive_native_allocations_));
if (kind() == kDartCode) {
ASSERT(!code_.IsNull());
obj.AddProperty("code", code_);
@@ -863,7 +929,12 @@ class ProfileCodeTable : public ZoneAllocated {
ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
- : table_index_(table_index), count_(0), children_(0), frame_id_(-1) {
+ : table_index_(table_index),
+ count_(0),
+ exclusive_allocations_(0),
+ inclusive_allocations_(0),
+ children_(0),
+ frame_id_(-1) {
ASSERT(table_index_ >= 0);
}
@@ -904,6 +975,10 @@ class ProfileCodeTrieNode : public ProfileTrieNode {
// Write number of children.
intptr_t child_count = NumChildren();
array->AddValue(child_count);
+ // Write inclusive allocations.
+ array->AddValue64(inclusive_allocations_);
+ // Write exclusive allocations.
+ array->AddValue64(exclusive_allocations_);
// Recurse.
for (intptr_t i = 0; i < child_count; i++) {
children_[i]->PrintToJSONArray(array);
@@ -965,6 +1040,10 @@ class ProfileFunctionTrieNode : public ProfileTrieNode {
array->AddValue(table_index());
// Write count.
array->AddValue(count());
+ // Write inclusive allocations.
+ array->AddValue64(inclusive_allocations_);
+ // Write exclusive allocations.
+ array->AddValue64(exclusive_allocations_);
// Write number of code objects.
intptr_t code_count = code_objects_.length();
array->AddValue(code_count);
@@ -1320,10 +1399,11 @@ class ProfileBuilder : public ValueObject {
ASSERT(pc != 0);
ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp);
ASSERT(code != NULL);
- code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
+ code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index,
+ sample);
}
- TickExitFrame(sample->vm_tag(), sample_index);
+ TickExitFrame(sample->vm_tag(), sample_index, sample);
}
SanitizeMinMaxTimes();
}
@@ -1410,15 +1490,18 @@ class ProfileBuilder : public ValueObject {
// Tick the root.
ProfileCodeTrieNode* current = root;
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
Cutch 2017/03/16 20:38:16 Refactor this so it follows the pattern you set el
bkonyi 2017/03/21 01:53:24 Done.
+ false);
// VM & User tags.
- current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ current =
+ AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
ResetKind();
// Truncated tag.
if (sample->truncated()) {
- current = AppendTruncatedTag(current);
+ current = AppendTruncatedTag(current, sample);
}
// Walk the sampled PCs.
@@ -1433,13 +1516,15 @@ class ProfileBuilder : public ValueObject {
GetProfileCode(sample->At(frame_index), sample->timestamp());
ASSERT(profile_code->code_table_index() == index);
code ^= profile_code->code();
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
current = current->GetChild(index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
Cutch 2017/03/16 20:38:16 ditto
bkonyi 2017/03/21 01:53:23 Done.
+ (frame_index == 0));
}
if (!sample->first_frame_executing()) {
- current = AppendExitFrame(sample->vm_tag(), current);
+ current = AppendExitFrame(sample->vm_tag(), current, sample);
}
}
}
@@ -1454,14 +1539,16 @@ class ProfileBuilder : public ValueObject {
// Tick the root.
ProfileCodeTrieNode* current = root;
current->Tick();
-
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
Cutch 2017/03/16 20:38:16 ditto
bkonyi 2017/03/21 01:53:23 Done.
+ false);
// VM & User tags.
- current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ current =
+ AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
ResetKind();
if (!sample->first_frame_executing()) {
- current = AppendExitFrame(sample->vm_tag(), current);
+ current = AppendExitFrame(sample->vm_tag(), current, sample);
}
// Walk the sampled PCs.
@@ -1479,12 +1566,14 @@ class ProfileBuilder : public ValueObject {
current = current->GetChild(index);
if (ShouldTickNode(sample, frame_index)) {
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
Cutch 2017/03/16 20:38:16 ditto
bkonyi 2017/03/21 01:53:24 Done.
+ (frame_index == 0));
}
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
}
// Truncated tag.
if (sample->truncated()) {
- current = AppendTruncatedTag(current);
+ current = AppendTruncatedTag(current, sample);
}
}
}
@@ -1516,13 +1605,15 @@ class ProfileBuilder : public ValueObject {
// Tick the root.
ProfileFunctionTrieNode* current = root;
current->Tick();
-
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
// VM & User tags.
- current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ current =
+ AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
// Truncated tag.
if (sample->truncated()) {
- current = AppendTruncatedTag(current);
+ current = AppendTruncatedTag(current, sample);
}
// Walk the sampled PCs.
@@ -1533,7 +1624,7 @@ class ProfileBuilder : public ValueObject {
}
if (!sample->first_frame_executing()) {
- current = AppendExitFrame(sample->vm_tag(), current);
+ current = AppendExitFrame(sample->vm_tag(), current, sample);
}
sample->set_timeline_trie(current);
@@ -1551,14 +1642,16 @@ class ProfileBuilder : public ValueObject {
// Tick the root.
ProfileFunctionTrieNode* current = root;
current->Tick();
-
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
// VM & User tags.
- current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+ current =
+ AppendTags(sample->vm_tag(), sample->user_tag(), current, sample);
ResetKind();
if (!sample->first_frame_executing()) {
- current = AppendExitFrame(sample->vm_tag(), current);
+ current = AppendExitFrame(sample->vm_tag(), current, sample);
}
// Walk the sampled PCs.
@@ -1568,12 +1661,12 @@ class ProfileBuilder : public ValueObject {
current = ProcessFrame(current, sample_index, sample, frame_index);
}
- TickExitFrameFunction(sample->vm_tag(), sample_index);
+ TickExitFrameFunction(sample->vm_tag(), sample_index, sample);
// Truncated tag.
if (sample->truncated()) {
- current = AppendTruncatedTag(current);
- InclusiveTickTruncatedTag();
+ current = AppendTruncatedTag(current, sample);
+ InclusiveTickTruncatedTag(sample);
}
}
}
@@ -1611,16 +1704,17 @@ class ProfileBuilder : public ValueObject {
(inlined_functions->length() <= 1)) {
// No inlined functions.
if (inclusive_tree_) {
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
}
current = ProcessFunction(current, sample_index, sample, frame_index,
function, token_position, code_index);
if (!inclusive_tree_) {
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
}
return current;
}
+ // TODO(bkonyi) deal with this
bkonyi 2017/03/16 19:50:57 What needs to be done here again John?
Cutch 2017/03/16 20:38:16 You should figure out why the assumption that the
bkonyi 2017/03/21 01:53:24 Acknowledged.
ASSERT(code.is_optimized());
if (inclusive_tree_) {
@@ -1631,19 +1725,19 @@ class ProfileBuilder : public ValueObject {
TokenPosition inlined_token_position = (*inlined_token_positions)[i];
const bool inliner = i == 0;
if (inliner) {
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
}
current = ProcessInlinedFunction(current, sample_index, sample,
frame_index, inlined_function,
inlined_token_position, code_index);
if (inliner) {
- current = AppendKind(kInlineStart, current);
+ current = AppendKind(kInlineStart, current, sample);
}
}
- current = AppendKind(kInlineFinish, current);
+ current = AppendKind(kInlineFinish, current, sample);
} else {
// Append the inlined children.
- current = AppendKind(kInlineFinish, current);
+ current = AppendKind(kInlineFinish, current, sample);
for (intptr_t i = inlined_functions->length() - 1; i >= 0; i--) {
const Function* inlined_function = (*inlined_functions)[i];
ASSERT(inlined_function != NULL);
@@ -1651,13 +1745,13 @@ class ProfileBuilder : public ValueObject {
TokenPosition inlined_token_position = (*inlined_token_positions)[i];
const bool inliner = i == 0;
if (inliner) {
- current = AppendKind(kInlineStart, current);
+ current = AppendKind(kInlineStart, current, sample);
}
current = ProcessInlinedFunction(current, sample_index, sample,
frame_index + i, inlined_function,
inlined_token_position, code_index);
if (inliner) {
- current = AppendKind(code, current);
+ current = AppendKind(code, current, sample);
}
}
}
@@ -1707,19 +1801,21 @@ class ProfileBuilder : public ValueObject {
sample->At(frame_index));
}
function->Tick(IsExecutingFrame(sample, frame_index), sample_index,
- token_position);
+ token_position, sample);
}
function->AddProfileCode(code_index);
current = current->GetChild(function->table_index());
if (ShouldTickNode(sample, frame_index)) {
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ (frame_index == 0));
}
current->AddCodeObjectIndex(code_index);
return current;
}
// Tick the truncated tag's inclusive tick count.
- void InclusiveTickTruncatedTag() {
+ void InclusiveTickTruncatedTag(ProcessedSample* sample) {
ProfileCodeTable* tag_table = profile_->tag_code_;
intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
ASSERT(index >= 0);
@@ -1728,6 +1824,10 @@ class ProfileBuilder : public ValueObject {
ASSERT(code != NULL);
ProfileFunction* function = code->function();
function->IncInclusiveTicks();
+
+ code->AccumulateAllocation(sample->native_allocation_size_bytes(), false);
+ function->AccumulateAllocation(sample->native_allocation_size_bytes(),
+ false);
}
@@ -1736,25 +1836,32 @@ class ProfileBuilder : public ValueObject {
// ProfileCodeTrieNode
ProfileCodeTrieNode* AppendUserTag(uword user_tag,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag);
if (user_tag_index >= 0) {
current = current->GetChild(user_tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
- ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
intptr_t truncated_tag_index =
GetProfileCodeTagIndex(VMTag::kTruncatedTagId);
ASSERT(truncated_tag_index >= 0);
current = current->GetChild(truncated_tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
- ProfileCodeTrieNode* AppendVMTag(uword vm_tag, ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* AppendVMTag(uword vm_tag,
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
if (VMTag::IsNativeEntryTag(vm_tag)) {
// Insert a dummy kNativeTagId node.
intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId);
@@ -1773,12 +1880,14 @@ class ProfileBuilder : public ValueObject {
// Give the tag a tick.
current->Tick();
}
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
uword vm_tag,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
// Only Native and Runtime entries have a second VM tag.
if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) {
return current;
@@ -1787,6 +1896,7 @@ class ProfileBuilder : public ValueObject {
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
@@ -1811,7 +1921,8 @@ class ProfileBuilder : public ValueObject {
}
ProfileCodeTrieNode* AppendKind(ProfileInfoKind kind,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
// Only emit if debug tags are requested.
return current;
@@ -1822,29 +1933,33 @@ class ProfileBuilder : public ValueObject {
ASSERT(tag_index >= 0);
current = current->GetChild(tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
ProfileCodeTrieNode* AppendKind(const Code& code,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
if (code.IsNull()) {
- return AppendKind(kNone, current);
+ return AppendKind(kNone, current, sample);
} else if (code.is_optimized()) {
- return AppendKind(kOptimized, current);
+ return AppendKind(kOptimized, current, sample);
} else {
- return AppendKind(kUnoptimized, current);
+ return AppendKind(kUnoptimized, current, sample);
}
}
ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
- ProfileCodeTrieNode* current) {
- current = AppendVMTag(vm_tag, current);
- current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
+ current = AppendVMTag(vm_tag, current, sample);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
return current;
}
- void TickExitFrame(uword vm_tag, intptr_t serial) {
+ void TickExitFrame(uword vm_tag, intptr_t serial, ProcessedSample* sample) {
if (FLAG_profile_vm) {
return;
}
@@ -1854,10 +1969,12 @@ class ProfileBuilder : public ValueObject {
ProfileCodeTable* tag_table = profile_->tag_code_;
ProfileCode* code = tag_table->FindCodeForPC(vm_tag);
ASSERT(code != NULL);
- code->Tick(vm_tag, true, serial);
+ code->Tick(vm_tag, true, serial, sample);
}
- void TickExitFrameFunction(uword vm_tag, intptr_t serial) {
+ void TickExitFrameFunction(uword vm_tag,
+ intptr_t serial,
+ ProcessedSample* sample) {
if (FLAG_profile_vm) {
return;
}
@@ -1869,11 +1986,12 @@ class ProfileBuilder : public ValueObject {
ASSERT(code != NULL);
ProfileFunction* function = code->function();
ASSERT(function != NULL);
- function->Tick(true, serial, TokenPosition::kNoSource);
+ function->Tick(true, serial, TokenPosition::kNoSource, sample);
}
ProfileCodeTrieNode* AppendExitFrame(uword vm_tag,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
if (FLAG_profile_vm) {
return current;
}
@@ -1883,19 +2001,22 @@ class ProfileBuilder : public ValueObject {
}
if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) {
- current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
} else {
intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
ProfileCodeTrieNode* AppendTags(uword vm_tag,
uword user_tag,
- ProfileCodeTrieNode* current) {
+ ProfileCodeTrieNode* current,
+ ProcessedSample* sample) {
if (FLAG_profile_vm) {
// None.
if (tag_order() == Profile::kNoTags) {
@@ -1904,36 +2025,37 @@ class ProfileBuilder : public ValueObject {
// User first.
if ((tag_order() == Profile::kUserVM) ||
(tag_order() == Profile::kUser)) {
- current = AppendUserTag(user_tag, current);
+ current = AppendUserTag(user_tag, current, sample);
// Only user.
if (tag_order() == Profile::kUser) {
return current;
}
- return AppendVMTags(vm_tag, current);
+ return AppendVMTags(vm_tag, current, sample);
}
// VM first.
ASSERT((tag_order() == Profile::kVMUser) ||
(tag_order() == Profile::kVM));
- current = AppendVMTags(vm_tag, current);
+ current = AppendVMTags(vm_tag, current, sample);
// Only VM.
if (tag_order() == Profile::kVM) {
return current;
}
- return AppendUserTag(user_tag, current);
+ return AppendUserTag(user_tag, current, sample);
}
if (tag_order() == Profile::kNoTags) {
return current;
}
- return AppendUserTag(user_tag, current);
+ return AppendUserTag(user_tag, current, sample);
}
// ProfileFunctionTrieNode
void ResetKind() { info_kind_ = kNone; }
ProfileFunctionTrieNode* AppendKind(ProfileInfoKind kind,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
if (!TagsEnabled(ProfilerService::kCodeTransitionTagsBit)) {
// Only emit if debug tags are requested.
return current;
@@ -1945,43 +2067,51 @@ class ProfileBuilder : public ValueObject {
ASSERT(tag_index >= 0);
current = current->GetChild(tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
ProfileFunctionTrieNode* AppendKind(const Code& code,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
if (code.IsNull()) {
- return AppendKind(kNone, current);
+ return AppendKind(kNone, current, sample);
} else if (code.is_optimized()) {
- return AppendKind(kOptimized, current);
+ return AppendKind(kOptimized, current, sample);
} else {
- return AppendKind(kUnoptimized, current);
+ return AppendKind(kUnoptimized, current, sample);
}
}
ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
if (user_tag_index >= 0) {
current = current->GetChild(user_tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
- ProfileFunctionTrieNode* AppendTruncatedTag(
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* AppendTruncatedTag(ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
intptr_t truncated_tag_index =
GetProfileFunctionTagIndex(VMTag::kTruncatedTagId);
ASSERT(truncated_tag_index >= 0);
current = current->GetChild(truncated_tag_index);
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
ProfileFunctionTrieNode* AppendVMTag(uword vm_tag,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
if (VMTag::IsNativeEntryTag(vm_tag)) {
// Insert a dummy kNativeTagId node.
intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId);
@@ -2000,12 +2130,14 @@ class ProfileBuilder : public ValueObject {
// Give the tag a tick.
current->Tick();
}
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
uword vm_tag,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
// Only Native and Runtime entries have a second VM tag.
if (!VMTag::IsNativeEntryTag(vm_tag) && !VMTag::IsRuntimeEntryTag(vm_tag)) {
return current;
@@ -2014,18 +2146,21 @@ class ProfileBuilder : public ValueObject {
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(), false);
return current;
}
ProfileFunctionTrieNode* AppendVMTags(uword vm_tag,
- ProfileFunctionTrieNode* current) {
- current = AppendVMTag(vm_tag, current);
- current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
+ current = AppendVMTag(vm_tag, current, sample);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
return current;
}
ProfileFunctionTrieNode* AppendExitFrame(uword vm_tag,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
if (FLAG_profile_vm) {
return current;
}
@@ -2034,19 +2169,22 @@ class ProfileBuilder : public ValueObject {
return current;
}
if (VMTag::IsNativeEntryTag(vm_tag) || VMTag::IsRuntimeEntryTag(vm_tag)) {
- current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current, sample);
} else {
intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
+ current->IncrementAllocation(sample->native_allocation_size_bytes(),
+ false);
}
return current;
}
ProfileFunctionTrieNode* AppendTags(uword vm_tag,
uword user_tag,
- ProfileFunctionTrieNode* current) {
+ ProfileFunctionTrieNode* current,
+ ProcessedSample* sample) {
if (FLAG_profile_vm) {
// None.
if (tag_order() == Profile::kNoTags) {
@@ -2055,29 +2193,29 @@ class ProfileBuilder : public ValueObject {
// User first.
if ((tag_order() == Profile::kUserVM) ||
(tag_order() == Profile::kUser)) {
- current = AppendUserTag(user_tag, current);
+ current = AppendUserTag(user_tag, current, sample);
// Only user.
if (tag_order() == Profile::kUser) {
return current;
}
- return AppendVMTags(vm_tag, current);
+ return AppendVMTags(vm_tag, current, sample);
}
// VM first.
ASSERT((tag_order() == Profile::kVMUser) ||
(tag_order() == Profile::kVM));
- current = AppendVMTags(vm_tag, current);
+ current = AppendVMTags(vm_tag, current, sample);
// Only VM.
if (tag_order() == Profile::kVM) {
return current;
}
- return AppendUserTag(user_tag, current);
+ return AppendUserTag(user_tag, current, sample);
}
if (tag_order() == Profile::kNoTags) {
return current;
}
- return AppendUserTag(user_tag, current);
+ return AppendUserTag(user_tag, current, sample);
}
intptr_t GetProfileCodeTagIndex(uword tag) {
@@ -2727,15 +2865,15 @@ class ClassAllocationSampleFilter : public SampleFilter {
class NativeAllocationSampleFilter : public SampleFilter {
public:
- NativeAllocationSampleFilter(intptr_t thread_task_mask,
- int64_t time_origin_micros,
+ NativeAllocationSampleFilter(int64_t time_origin_micros,
int64_t time_extent_micros)
: SampleFilter(ILLEGAL_PORT,
- thread_task_mask,
+ SampleFilter::kNoTaskFilter,
time_origin_micros,
time_extent_micros) {}
bool FilterSample(Sample* sample) {
- return sample->is_native_allocation_sample();
+ return sample->is_native_allocation_sample() &&
+ !sample->NativeAllocationFreed();
}
};
@@ -2760,11 +2898,7 @@ void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream,
int64_t time_origin_micros,
int64_t time_extent_micros) {
Thread* thread = Thread::Current();
- const intptr_t thread_task_mask = Thread::kMutatorTask |
- Thread::kCompilerTask |
- Thread::kSweeperTask | Thread::kMarkerTask;
- NativeAllocationSampleFilter filter(thread_task_mask, time_origin_micros,
- time_extent_micros);
+ NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros);
const bool as_timeline = false;
PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
}
« runtime/vm/profiler_service.h ('K') | « runtime/vm/profiler_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698