blob: 1865fd9b581dc572eafa592f1952c13911935ca7 [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/browser/memory_tracker/tool/memory_size_binner_tool.h"
#include <sstream>
#include <string>
#include <vector>
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "cobalt/base/c_val.h"
#include "cobalt/browser/memory_tracker/tool/util.h"
#include "nb/analytics/memory_tracker.h"
#include "nb/analytics/memory_tracker_helpers.h"
#include "starboard/log.h"
#include "starboard/types.h"
namespace cobalt {
namespace browser {
namespace memory_tracker {
namespace {
const nb::analytics::AllocationGroup* FindAllocationGroup(
const std::string& name,
nb::analytics::MemoryTracker* memory_tracker) {
std::vector<const nb::analytics::AllocationGroup*> groups;
memory_tracker->GetAllocationGroups(&groups);
// Find by exact string match.
for (size_t i = 0; i < groups.size(); ++i) {
const nb::analytics::AllocationGroup* group = groups[i];
if (group->name().compare(name) == 0) {
return group;
}
}
return NULL;
}
} // namespace.
MemorySizeBinnerTool::MemorySizeBinnerTool(const std::string& memory_scope_name)
: memory_scope_name_(memory_scope_name) {}
void MemorySizeBinnerTool::Run(Params* params) {
const nb::analytics::AllocationGroup* target_group = NULL;
while (!params->finished()) {
if (target_group == NULL && !memory_scope_name_.empty()) {
target_group =
FindAllocationGroup(memory_scope_name_, params->memory_tracker());
}
std::stringstream ss;
ss.precision(2);
if (target_group || memory_scope_name_.empty()) {
AllocationSizeBinner visitor_binner = AllocationSizeBinner(target_group);
params->memory_tracker()->Accept(&visitor_binner);
size_t min_size = 0;
size_t max_size = 0;
visitor_binner.GetLargestSizeRange(&min_size, &max_size);
FindTopSizes top_size_visitor =
FindTopSizes(min_size, max_size, target_group);
params->memory_tracker()->Accept(&top_size_visitor);
ss << kNewLine;
ss << "TimeNow " << params->TimeInMinutesString() << " (minutes):";
ss << kNewLine;
if (!memory_scope_name_.empty()) {
ss << "Tracking Memory Scope \"" << memory_scope_name_ << "\", ";
} else {
ss << "Tracking whole program, ";
}
ss << "first row is allocation size range, second row is number of "
<< kNewLine << "allocations in that range." << kNewLine;
ss << visitor_binner.ToCSVString();
ss << kNewLine;
ss << "Largest allocation range: \"" << min_size << "..." << max_size
<< "\"" << kNewLine;
ss << "Printing out top allocations from this range: " << kNewLine;
ss << top_size_visitor.ToString(5) << kNewLine;
} else {
ss << "No allocations for \"" << memory_scope_name_ << "\".";
}
params->logger()->Output(ss.str().c_str());
params->logger()->Flush();
// Sleep until the next sample.
base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
}
}
std::string MemorySizeBinnerTool::tool_name() const {
return "MemoryTrackerCompressedTimeSeries";
}
} // namespace memory_tracker
} // namespace browser
} // namespace cobalt