| Index: base/tracked_objects.cc
|
| ===================================================================
|
| --- base/tracked_objects.cc (revision 110116)
|
| +++ base/tracked_objects.cc (working copy)
|
| @@ -8,7 +8,6 @@
|
|
|
| #include "base/format_macros.h"
|
| #include "base/message_loop.h"
|
| -#include "base/string_util.h"
|
| #include "base/stringprintf.h"
|
| #include "base/threading/thread_restrictions.h"
|
| #include "build/build_config.h"
|
| @@ -54,18 +53,6 @@
|
| run_time_.AddData(other.run_time_);
|
| }
|
|
|
| -void DeathData::WriteHTML(std::string* output) const {
|
| - if (!count_)
|
| - return;
|
| - base::StringAppendF(output, "%s:%d, ",
|
| - (count_ == 1) ? "Life" : "Lives", count_);
|
| - output->append("Run:");
|
| - run_time_.WriteHTML(count_, output);
|
| -
|
| - output->append("Queue:");
|
| - queue_time_.WriteHTML(count_, output);
|
| -}
|
| -
|
| base::DictionaryValue* DeathData::ToValue() const {
|
| base::DictionaryValue* dictionary = new base::DictionaryValue;
|
| dictionary->Set("count", base::Value::CreateIntegerValue(count_));
|
| @@ -88,21 +75,6 @@
|
|
|
| //------------------------------------------------------------------------------
|
|
|
| -void DeathData::Data::WriteHTML(int count, std::string* output) const {
|
| - // Be careful to leave static_casts intact, as the type returned by
|
| - // InMilliseconds() may not always be an int, even if it can generally fit
|
| - // into an int.
|
| - base::StringAppendF(output, "%dms",
|
| - static_cast<int>(duration_));
|
| - if (count == 1) {
|
| - output->append(" ");
|
| - return;
|
| - }
|
| - base::StringAppendF(output, "(%dms/life,max:%dms) ",
|
| - static_cast<int>(AverageMsDuration(count)),
|
| - static_cast<int>(max_));
|
| -}
|
| -
|
| void DeathData::Data::AddData(const Data& other) {
|
| duration_ += other.duration_;
|
| if (max_ > other.max_)
|
| @@ -270,116 +242,6 @@
|
| }
|
|
|
| // static
|
| -void ThreadData::WriteHTML(const std::string& query, std::string* output) {
|
| - if (status_ == UNINITIALIZED)
|
| - return; // Not yet initialized.
|
| -
|
| - DataCollector collected_data; // Gather data.
|
| - collected_data.AddListOfLivingObjects(); // Add births that are still alive.
|
| -
|
| - // Data Gathering is complete. Now to sort/process/render.
|
| - DataCollector::Collection* collection = collected_data.collection();
|
| -
|
| - // Create filtering and sort comparison object.
|
| - Comparator comparator;
|
| - comparator.ParseQuery(query);
|
| -
|
| - // Filter out acceptable (matching) instances.
|
| - DataCollector::Collection match_array;
|
| - for (DataCollector::Collection::iterator it = collection->begin();
|
| - it != collection->end(); ++it) {
|
| - if (comparator.Acceptable(*it))
|
| - match_array.push_back(*it);
|
| - }
|
| -
|
| - comparator.Sort(&match_array);
|
| -
|
| - WriteHTMLTotalAndSubtotals(match_array, comparator, output);
|
| -
|
| - comparator.Clear(); // Delete tiebreaker_ instances.
|
| -
|
| - output->append("</pre>");
|
| -
|
| - const char* help_string = "The following are the keywords that can be used to"
|
| - " sort and aggregate the data, or to select data.<br><ul>"
|
| - "<li><b>Count</b> Number of instances seen."
|
| - "<li><b>Duration</b> Average duration in ms of Run() time."
|
| - "<li><b>TotalDuration</b> Summed durations in ms of Run() times."
|
| - "<li><b>MaxDuration</b> Largest duration in ms of Run() times."
|
| - "<li><b>AverageQueueDuration</b> Average duration in ms of queueing time."
|
| - "<li><b>TotalQueueDuration</b> Summed queuing durations in ms."
|
| - "<li><b>MaxQueueDuration</b> Largest duration in ms of queueing times."
|
| - "<li><b>Birth</b> Thread on which the task was constructed."
|
| - "<li><b>Death</b> Thread on which the task was run and deleted."
|
| - "<li><b>File</b> File in which the task was contructed."
|
| - "<li><b>Function</b> Function in which the task was constructed."
|
| - "<li><b>Line</b> Line number of the file in which the task was constructed."
|
| - "</ul><br>"
|
| - "As examples:<ul>"
|
| - "<li><b>about:tracking/file</b> would sort the above data by file, and"
|
| - " aggregate data on a per-file basis."
|
| - "<li><b>about:tracking/file=Dns</b> would only list data for tasks"
|
| - " constructed in a file containing the text |Dns|."
|
| - "<li><b>about:tracking/death/duration</b> would sort the data by death"
|
| - " thread(i.e., where tasks ran) and then by the average runtime for the"
|
| - " tasks. Form an aggregation group, one per thread, showing the results on"
|
| - " each thread."
|
| - "<li><b>about:tracking/birth/death</b> would sort the above list by birth"
|
| - " thread, and then by death thread, and would aggregate data for each pair"
|
| - " of lifetime events."
|
| - "</ul>"
|
| - " The data can be reset to zero (discarding all births, deaths, etc.) using"
|
| - " <b>about:tracking/reset</b>. The existing stats will be displayed, but"
|
| - " the internal stats will be set to zero, and start accumulating afresh."
|
| - " This option is very helpful if you only wish to consider tasks created"
|
| - " after some point in time.<br><br>"
|
| - "If you wish to monitor Renderer events, be sure to run in --single-process"
|
| - " mode.";
|
| - output->append(help_string);
|
| -}
|
| -
|
| -// static
|
| -void ThreadData::WriteHTMLTotalAndSubtotals(
|
| - const DataCollector::Collection& match_array,
|
| - const Comparator& comparator,
|
| - std::string* output) {
|
| - if (match_array.empty()) {
|
| - output->append("There were no tracked matches.");
|
| - return;
|
| - }
|
| - // Aggregate during printing
|
| - Aggregation totals;
|
| - for (size_t i = 0; i < match_array.size(); ++i) {
|
| - totals.AddDeathSnapshot(match_array[i]);
|
| - }
|
| - output->append("Aggregate Stats: ");
|
| - totals.WriteHTML(output);
|
| - output->append("<hr><hr>");
|
| -
|
| - Aggregation subtotals;
|
| - for (size_t i = 0; i < match_array.size(); ++i) {
|
| - if (0 == i || !comparator.Equivalent(match_array[i - 1],
|
| - match_array[i])) {
|
| - // Print group's defining characteristics.
|
| - comparator.WriteSortGrouping(match_array[i], output);
|
| - output->append("<br><br>");
|
| - }
|
| - comparator.WriteSnapshotHTML(match_array[i], output);
|
| - output->append("<br>");
|
| - subtotals.AddDeathSnapshot(match_array[i]);
|
| - if (i + 1 >= match_array.size() ||
|
| - !comparator.Equivalent(match_array[i],
|
| - match_array[i + 1])) {
|
| - // Print aggregate stats for the group.
|
| - output->append("<br>");
|
| - subtotals.WriteHTML(output);
|
| - output->append("<br><hr><br>");
|
| - subtotals.Clear();
|
| - }
|
| - }
|
| -}
|
| -
|
| -// static
|
| base::DictionaryValue* ThreadData::ToValue() {
|
| DataCollector collected_data; // Gather data.
|
| collected_data.AddListOfLivingObjects(); // Add births that are still alive.
|
| @@ -535,8 +397,6 @@
|
| current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
|
| }
|
|
|
| -
|
| -
|
| // static
|
| ThreadData* ThreadData::first() {
|
| base::AutoLock lock(*list_lock_.Pointer());
|
| @@ -708,14 +568,6 @@
|
| return "Still_Alive";
|
| }
|
|
|
| -void Snapshot::WriteHTML(std::string* output) const {
|
| - death_data_.WriteHTML(output);
|
| - base::StringAppendF(output, "%s->%s ",
|
| - birth_->birth_thread()->thread_name().c_str(),
|
| - DeathThreadName().c_str());
|
| - birth_->location().Write(true, true, output);
|
| -}
|
| -
|
| base::DictionaryValue* Snapshot::ToValue() const {
|
| base::DictionaryValue* dictionary = new base::DictionaryValue;
|
| dictionary->Set("death_data", death_data_.ToValue());
|
| @@ -792,471 +644,4 @@
|
| return list;
|
| }
|
|
|
| -//------------------------------------------------------------------------------
|
| -// Aggregation
|
| -
|
| -Aggregation::Aggregation()
|
| - : birth_count_(0) {
|
| -}
|
| -
|
| -Aggregation::~Aggregation() {
|
| -}
|
| -
|
| -void Aggregation::AddDeathSnapshot(const Snapshot& snapshot) {
|
| - AddBirth(snapshot.birth());
|
| - death_threads_[snapshot.death_thread()]++;
|
| - AddDeathData(snapshot.death_data());
|
| -}
|
| -
|
| -void Aggregation::AddBirths(const Births& births) {
|
| - AddBirth(births);
|
| - birth_count_ += births.birth_count();
|
| -}
|
| -void Aggregation::AddBirth(const BirthOnThread& birth) {
|
| - AddBirthPlace(birth.location());
|
| - birth_threads_[birth.birth_thread()]++;
|
| -}
|
| -
|
| -void Aggregation::AddBirthPlace(const Location& location) {
|
| - locations_[location]++;
|
| - birth_files_[location.file_name()]++;
|
| -}
|
| -
|
| -void Aggregation::WriteHTML(std::string* output) const {
|
| - if (locations_.size() == 1) {
|
| - locations_.begin()->first.Write(true, true, output);
|
| - } else {
|
| - base::StringAppendF(output, "%" PRIuS " Locations. ", locations_.size());
|
| - if (birth_files_.size() > 1) {
|
| - base::StringAppendF(output, "%" PRIuS " Files. ", birth_files_.size());
|
| - } else {
|
| - base::StringAppendF(output, "All born in %s. ",
|
| - birth_files_.begin()->first.c_str());
|
| - }
|
| - }
|
| -
|
| - if (birth_threads_.size() > 1) {
|
| - base::StringAppendF(output, "%" PRIuS " BirthingThreads. ",
|
| - birth_threads_.size());
|
| - } else {
|
| - base::StringAppendF(output, "All born on %s. ",
|
| - birth_threads_.begin()->first->thread_name().c_str());
|
| - }
|
| -
|
| - if (death_threads_.size() > 1) {
|
| - base::StringAppendF(output, "%" PRIuS " DeathThreads. ",
|
| - death_threads_.size());
|
| - } else {
|
| - if (death_threads_.begin()->first) {
|
| - base::StringAppendF(output, "All deleted on %s. ",
|
| - death_threads_.begin()->first->thread_name().c_str());
|
| - } else {
|
| - output->append("All these objects are still alive.");
|
| - }
|
| - }
|
| -
|
| - if (birth_count_ > 1)
|
| - base::StringAppendF(output, "Births=%d ", birth_count_);
|
| -
|
| - DeathData::WriteHTML(output);
|
| -}
|
| -
|
| -void Aggregation::Clear() {
|
| - birth_count_ = 0;
|
| - birth_files_.clear();
|
| - locations_.clear();
|
| - birth_threads_.clear();
|
| - DeathData::Clear();
|
| - death_threads_.clear();
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Comparison object for sorting.
|
| -
|
| -Comparator::Comparator()
|
| - : selector_(NIL),
|
| - tiebreaker_(NULL),
|
| - combined_selectors_(0),
|
| - use_tiebreaker_for_sort_only_(false) {}
|
| -
|
| -void Comparator::Clear() {
|
| - if (tiebreaker_) {
|
| - tiebreaker_->Clear();
|
| - delete tiebreaker_;
|
| - tiebreaker_ = NULL;
|
| - }
|
| - use_tiebreaker_for_sort_only_ = false;
|
| - selector_ = NIL;
|
| -}
|
| -
|
| -// static
|
| -Comparator::Selector Comparator::FindSelector(const std::string& keyword) {
|
| - // Sorting and aggretation keywords, which specify how to sort the data, or
|
| - // can specify a required match from the specified field in the record.
|
| - if (0 == keyword.compare("count"))
|
| - return COUNT;
|
| - if (0 == keyword.compare("totalduration"))
|
| - return TOTAL_RUN_DURATION;
|
| - if (0 == keyword.compare("duration"))
|
| - return AVERAGE_RUN_DURATION;
|
| - if (0 == keyword.compare("maxduration"))
|
| - return MAX_RUN_DURATION;
|
| - if (0 == keyword.compare("totalqueueduration"))
|
| - return TOTAL_QUEUE_DURATION;
|
| - if (0 == keyword.compare("averagequeueduration"))
|
| - return AVERAGE_QUEUE_DURATION;
|
| - if (0 == keyword.compare("maxqueueduration"))
|
| - return MAX_QUEUE_DURATION;
|
| - if (0 == keyword.compare("birth"))
|
| - return BIRTH_THREAD;
|
| - if (0 == keyword.compare("death"))
|
| - return DEATH_THREAD;
|
| - if (0 == keyword.compare("file"))
|
| - return BIRTH_FILE;
|
| - if (0 == keyword.compare("function"))
|
| - return BIRTH_FUNCTION;
|
| - if (0 == keyword.compare("line"))
|
| - return BIRTH_LINE;
|
| - if (0 == keyword.compare("reset"))
|
| - return RESET_ALL_DATA;
|
| - return UNKNOWN_KEYWORD;
|
| -}
|
| -
|
| -bool Comparator::operator()(const Snapshot& left,
|
| - const Snapshot& right) const {
|
| - switch (selector_) {
|
| - case BIRTH_THREAD:
|
| - if (left.birth_thread() != right.birth_thread() &&
|
| - left.birth_thread()->thread_name() !=
|
| - right.birth_thread()->thread_name())
|
| - return left.birth_thread()->thread_name() <
|
| - right.birth_thread()->thread_name();
|
| - break;
|
| -
|
| - case DEATH_THREAD:
|
| - if (left.death_thread() != right.death_thread() &&
|
| - left.DeathThreadName() !=
|
| - right.DeathThreadName()) {
|
| - if (!left.death_thread())
|
| - return true;
|
| - if (!right.death_thread())
|
| - return false;
|
| - return left.DeathThreadName() <
|
| - right.DeathThreadName();
|
| - }
|
| - break;
|
| -
|
| - case BIRTH_FILE:
|
| - if (left.location().file_name() != right.location().file_name()) {
|
| - int comp = strcmp(left.location().file_name(),
|
| - right.location().file_name());
|
| - if (comp)
|
| - return 0 > comp;
|
| - }
|
| - break;
|
| -
|
| - case BIRTH_FUNCTION:
|
| - if (left.location().function_name() != right.location().function_name()) {
|
| - int comp = strcmp(left.location().function_name(),
|
| - right.location().function_name());
|
| - if (comp)
|
| - return 0 > comp;
|
| - }
|
| - break;
|
| -
|
| - case BIRTH_LINE:
|
| - if (left.location().line_number() != right.location().line_number())
|
| - return left.location().line_number() <
|
| - right.location().line_number();
|
| - break;
|
| -
|
| - case COUNT:
|
| - if (left.count() != right.count())
|
| - return left.count() > right.count(); // Sort large at front of vector.
|
| - break;
|
| -
|
| - case AVERAGE_RUN_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.AverageMsRunDuration() != right.AverageMsRunDuration())
|
| - return left.AverageMsRunDuration() > right.AverageMsRunDuration();
|
| - break;
|
| -
|
| - case TOTAL_RUN_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.run_duration() != right.run_duration())
|
| - return left.run_duration() > right.run_duration();
|
| - break;
|
| -
|
| - case MAX_RUN_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.run_duration_max() != right.run_duration_max())
|
| - return left.run_duration_max() > right.run_duration_max();
|
| - break;
|
| -
|
| - case AVERAGE_QUEUE_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.AverageMsQueueDuration() != right.AverageMsQueueDuration())
|
| - return left.AverageMsQueueDuration() > right.AverageMsQueueDuration();
|
| - break;
|
| -
|
| - case TOTAL_QUEUE_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.queue_duration() != right.queue_duration())
|
| - return left.queue_duration() > right.queue_duration();
|
| - break;
|
| -
|
| - case MAX_QUEUE_DURATION:
|
| - if (!left.count() || !right.count())
|
| - break;
|
| - if (left.queue_duration_max() != right.queue_duration_max())
|
| - return left.queue_duration_max() > right.queue_duration_max();
|
| - break;
|
| -
|
| - default:
|
| - break;
|
| - }
|
| - if (tiebreaker_)
|
| - return tiebreaker_->operator()(left, right);
|
| - return false;
|
| -}
|
| -
|
| -void Comparator::Sort(DataCollector::Collection* collection) const {
|
| - std::sort(collection->begin(), collection->end(), *this);
|
| -}
|
| -
|
| -bool Comparator::Equivalent(const Snapshot& left,
|
| - const Snapshot& right) const {
|
| - switch (selector_) {
|
| - case BIRTH_THREAD:
|
| - if (left.birth_thread() != right.birth_thread() &&
|
| - left.birth_thread()->thread_name() !=
|
| - right.birth_thread()->thread_name())
|
| - return false;
|
| - break;
|
| -
|
| - case DEATH_THREAD:
|
| - if (left.death_thread() != right.death_thread() &&
|
| - left.DeathThreadName() != right.DeathThreadName())
|
| - return false;
|
| - break;
|
| -
|
| - case BIRTH_FILE:
|
| - if (!required_.empty())
|
| - break; // No reason to aggregate when we've filtered out some.
|
| - if (left.location().file_name() != right.location().file_name()) {
|
| - int comp = strcmp(left.location().file_name(),
|
| - right.location().file_name());
|
| - if (comp)
|
| - return false;
|
| - }
|
| - break;
|
| -
|
| - case BIRTH_FUNCTION:
|
| - if (!required_.empty())
|
| - break; // No reason to aggregate when we've filtered out some.
|
| - if (left.location().function_name() != right.location().function_name()) {
|
| - int comp = strcmp(left.location().function_name(),
|
| - right.location().function_name());
|
| - if (comp)
|
| - return false;
|
| - }
|
| - break;
|
| -
|
| - case COUNT:
|
| - case AVERAGE_RUN_DURATION:
|
| - case TOTAL_RUN_DURATION:
|
| - case MAX_RUN_DURATION:
|
| - case AVERAGE_QUEUE_DURATION:
|
| - case TOTAL_QUEUE_DURATION:
|
| - case MAX_QUEUE_DURATION:
|
| - // We don't produce separate aggretation when only counts or times differ.
|
| - break;
|
| -
|
| - default:
|
| - break;
|
| - }
|
| - if (tiebreaker_ && !use_tiebreaker_for_sort_only_)
|
| - return tiebreaker_->Equivalent(left, right);
|
| - return true;
|
| -}
|
| -
|
| -bool Comparator::Acceptable(const Snapshot& sample) const {
|
| - if (required_.size()) {
|
| - switch (selector_) {
|
| - case BIRTH_THREAD:
|
| - if (sample.birth_thread()->thread_name().find(required_) ==
|
| - std::string::npos)
|
| - return false;
|
| - break;
|
| -
|
| - case DEATH_THREAD:
|
| - if (sample.DeathThreadName().find(required_) == std::string::npos)
|
| - return false;
|
| - break;
|
| -
|
| - case BIRTH_FILE:
|
| - if (!strstr(sample.location().file_name(), required_.c_str()))
|
| - return false;
|
| - break;
|
| -
|
| - case BIRTH_FUNCTION:
|
| - if (!strstr(sample.location().function_name(), required_.c_str()))
|
| - return false;
|
| - break;
|
| -
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| - if (tiebreaker_ && !use_tiebreaker_for_sort_only_)
|
| - return tiebreaker_->Acceptable(sample);
|
| - return true;
|
| -}
|
| -
|
| -void Comparator::SetTiebreaker(Selector selector, const std::string& required) {
|
| - if (selector == selector_ || NIL == selector)
|
| - return;
|
| - combined_selectors_ |= selector;
|
| - if (NIL == selector_) {
|
| - selector_ = selector;
|
| - if (required.size())
|
| - required_ = required;
|
| - return;
|
| - }
|
| - if (tiebreaker_) {
|
| - if (use_tiebreaker_for_sort_only_) {
|
| - Comparator* temp = new Comparator;
|
| - temp->tiebreaker_ = tiebreaker_;
|
| - tiebreaker_ = temp;
|
| - }
|
| - } else {
|
| - tiebreaker_ = new Comparator;
|
| - DCHECK(!use_tiebreaker_for_sort_only_);
|
| - }
|
| - tiebreaker_->SetTiebreaker(selector, required);
|
| -}
|
| -
|
| -bool Comparator::IsGroupedBy(Selector selector) const {
|
| - return 0 != (selector & combined_selectors_);
|
| -}
|
| -
|
| -void Comparator::SetSubgroupTiebreaker(Selector selector) {
|
| - if (selector == selector_ || NIL == selector)
|
| - return;
|
| - if (!tiebreaker_) {
|
| - use_tiebreaker_for_sort_only_ = true;
|
| - tiebreaker_ = new Comparator;
|
| - tiebreaker_->SetTiebreaker(selector, "");
|
| - } else {
|
| - tiebreaker_->SetSubgroupTiebreaker(selector);
|
| - }
|
| -}
|
| -
|
| -void Comparator::ParseKeyphrase(const std::string& key_phrase) {
|
| - std::string required;
|
| - // Watch for: "sort_key=value" as we parse.
|
| - size_t equal_offset = key_phrase.find('=', 0);
|
| - if (key_phrase.npos != equal_offset) {
|
| - // There is a value that must be matched for the data to display.
|
| - required = key_phrase.substr(equal_offset + 1, key_phrase.npos);
|
| - }
|
| - std::string keyword(key_phrase.substr(0, equal_offset));
|
| - keyword = StringToLowerASCII(keyword);
|
| - Selector selector = FindSelector(keyword);
|
| - if (selector == UNKNOWN_KEYWORD)
|
| - return;
|
| - if (selector == RESET_ALL_DATA) {
|
| - ThreadData::ResetAllThreadData();
|
| - return;
|
| - }
|
| - SetTiebreaker(selector, required);
|
| -}
|
| -
|
| -bool Comparator::ParseQuery(const std::string& query) {
|
| - // Parse each keyphrase between consecutive slashes.
|
| - for (size_t i = 0; i < query.size();) {
|
| - size_t slash_offset = query.find('/', i);
|
| - ParseKeyphrase(query.substr(i, slash_offset - i));
|
| - if (query.npos == slash_offset)
|
| - break;
|
| - i = slash_offset + 1;
|
| - }
|
| -
|
| - // Select subgroup ordering (if we want to display the subgroup)
|
| - SetSubgroupTiebreaker(COUNT);
|
| - SetSubgroupTiebreaker(AVERAGE_RUN_DURATION);
|
| - SetSubgroupTiebreaker(TOTAL_RUN_DURATION);
|
| - SetSubgroupTiebreaker(MAX_RUN_DURATION);
|
| - SetSubgroupTiebreaker(AVERAGE_QUEUE_DURATION);
|
| - SetSubgroupTiebreaker(TOTAL_QUEUE_DURATION);
|
| - SetSubgroupTiebreaker(MAX_QUEUE_DURATION);
|
| - SetSubgroupTiebreaker(BIRTH_THREAD);
|
| - SetSubgroupTiebreaker(DEATH_THREAD);
|
| - SetSubgroupTiebreaker(BIRTH_FUNCTION);
|
| - SetSubgroupTiebreaker(BIRTH_FILE);
|
| - SetSubgroupTiebreaker(BIRTH_LINE);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Comparator::WriteSortGrouping(const Snapshot& sample,
|
| - std::string* output) const {
|
| - bool wrote_data = false;
|
| - switch (selector_) {
|
| - case BIRTH_THREAD:
|
| - base::StringAppendF(output, "All new on %s ",
|
| - sample.birth_thread()->thread_name().c_str());
|
| - wrote_data = true;
|
| - break;
|
| -
|
| - case DEATH_THREAD:
|
| - if (sample.death_thread()) {
|
| - base::StringAppendF(output, "All deleted on %s ",
|
| - sample.DeathThreadName().c_str());
|
| - } else {
|
| - output->append("All still alive ");
|
| - }
|
| - wrote_data = true;
|
| - break;
|
| -
|
| - case BIRTH_FILE:
|
| - base::StringAppendF(output, "All born in %s ",
|
| - sample.location().file_name());
|
| - break;
|
| -
|
| - case BIRTH_FUNCTION:
|
| - output->append("All born in ");
|
| - sample.location().WriteFunctionName(output);
|
| - output->push_back(' ');
|
| - break;
|
| -
|
| - default:
|
| - break;
|
| - }
|
| - if (tiebreaker_ && !use_tiebreaker_for_sort_only_) {
|
| - wrote_data |= tiebreaker_->WriteSortGrouping(sample, output);
|
| - }
|
| - return wrote_data;
|
| -}
|
| -
|
| -void Comparator::WriteSnapshotHTML(const Snapshot& sample,
|
| - std::string* output) const {
|
| - sample.death_data().WriteHTML(output);
|
| - if (!(combined_selectors_ & BIRTH_THREAD) ||
|
| - !(combined_selectors_ & DEATH_THREAD))
|
| - base::StringAppendF(output, "%s->%s ",
|
| - (combined_selectors_ & BIRTH_THREAD) ? "*" :
|
| - sample.birth().birth_thread()->thread_name().c_str(),
|
| - (combined_selectors_ & DEATH_THREAD) ? "*" :
|
| - sample.DeathThreadName().c_str());
|
| - sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE),
|
| - !(combined_selectors_ & BIRTH_FUNCTION),
|
| - output);
|
| -}
|
| -
|
| } // namespace tracked_objects
|
|
|