Remove chrome huge pages mapping deducer
This functionality is now implemented by both perf and quipper on CrOS devices.
PiperOrigin-RevId: 175088452
diff --git a/Makefile b/Makefile
index f798dea..bcd9352 100644
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@
QUIPPER_LIBRARY_SOURCES := \
$(QUIPPER_LIBRARY_SOURCES:%=${CWP}/%)
CONVERTER_LIBRARY_SOURCES = perf_data_converter.cc perf_data_handler.cc \
- builder.cc chrome_huge_pages_mapping_deducer.cc
+ builder.cc
LIBRARY_SOURCES = $(QUIPPER_LIBRARY_SOURCES) $(CONVERTER_LIBRARY_SOURCES)
QUIPPER_PROTOS = perf_data.proto perf_stat.proto
@@ -76,7 +76,7 @@
COMMON_OBJECTS = $(COMMON_SOURCES:.cc=.o)
TEST_SOURCES = intervalmap_test.cc perf_data_converter_test.cc \
- perf_data_handler_test.cc chrome_huge_pages_mapping_deducer_test.cc
+ perf_data_handler_test.cc
TEST_BINARIES = $(TEST_SOURCES:.cc=)
TEST_OBJECTS = $(TEST_SOURCES:.cc=.o)
diff --git a/chrome_huge_pages_mapping_deducer.cc b/chrome_huge_pages_mapping_deducer.cc
deleted file mode 100644
index 0e9386c..0000000
--- a/chrome_huge_pages_mapping_deducer.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2016, Google Inc.
- * All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <stddef.h>
-
-#include "chrome_huge_pages_mapping_deducer.h"
-
-namespace perftools {
-
-namespace {
-
-using quipper::PerfDataProto_MMapEvent;
-
-// Name of Chrome binary.
-const char kChromeFilename[] = "/opt/google/chrome/chrome";
-// Filename of Chrome huge pages mapping.
-const char kHugePagesFilename[] = "//anon";
-// Size in bytes of a huge page. A huge pages mapping could be a multiple of
-// this value.
-const size_t kHugePageSize = 2 * 1024 * 1024;
-
-} // namespace
-
-ChromeHugePagesMappingDeducer::ChromeHugePagesMappingDeducer()
- : state_(BASE_STATE) {}
-
-void ChromeHugePagesMappingDeducer::ProcessMmap(
- const PerfDataProto_MMapEvent& mmap) {
- switch (state_) {
- case BASE_STATE:
- case SECOND_CHROME_MMAP: // After the second Chrome mapping been processed,
- // a new huge pages mapping could come up
- // immediately. Otherwise, reset.
- if (IsFirstChromeMmap(mmap)) {
- combined_mapping_ = mmap;
- state_ = FIRST_CHROME_MMAP;
- } else if (IsHugePagesMmap(mmap)) {
- // This could be a hugepage mapping following a non-hugepage mapping.
- // Because it is contiguous, assume it is part of that same mapping by
- // extending the length.
- if (IsContiguousWithCombinedMapping(mmap)) {
- combined_mapping_.set_len(combined_mapping_.len() + mmap.len());
- } else {
- combined_mapping_ = mmap;
- }
-
- // Skipping the first Chrome mapping so fill in the name manually.
- combined_mapping_.set_filename(kChromeFilename);
- state_ = HUGE_PAGES_MMAP;
- } else {
- Reset();
- }
- break;
- case FIRST_CHROME_MMAP:
- // This is the case where there is already a Chrome mapping, so make sure
- // that the new mapping is contiguous.
- if (IsHugePagesMmap(mmap) && IsContiguousWithCombinedMapping(mmap)) {
- combined_mapping_.set_len(combined_mapping_.len() + mmap.len());
- state_ = HUGE_PAGES_MMAP;
- } else {
- Reset();
- }
- break;
- case HUGE_PAGES_MMAP:
- if (IsSecondChromeMmap(mmap)) {
- combined_mapping_.set_pgoff(mmap.pgoff() - combined_mapping_.len());
- combined_mapping_.set_len(combined_mapping_.len() + mmap.len());
- state_ = SECOND_CHROME_MMAP;
- } else {
- Reset();
- }
- break;
- default:
- Reset();
- }
-}
-
-void ChromeHugePagesMappingDeducer::Reset() {
- state_ = BASE_STATE;
- combined_mapping_.Clear();
-}
-
-bool ChromeHugePagesMappingDeducer::IsFirstChromeMmap(
- const PerfDataProto_MMapEvent& mmap) const {
- return mmap.filename() == kChromeFilename && mmap.pgoff() == 0;
-}
-
-bool ChromeHugePagesMappingDeducer::IsHugePagesMmap(
- const PerfDataProto_MMapEvent& mmap) const {
- if (mmap.filename() != kHugePagesFilename) {
- return false;
- }
- // Even though the original mapping is huge-page aligned, the perf data could
- // have been post-processed to the point where it is no longer aligned.
- return mmap.len() % kHugePageSize == 0 && mmap.pgoff() == 0;
-}
-
-bool ChromeHugePagesMappingDeducer::IsSecondChromeMmap(
- const PerfDataProto_MMapEvent& mmap) const {
- if (mmap.filename() != kChromeFilename) {
- return false;
- }
- // The second Chrome mapping's pgoff must be equal to the sum of the size of
- // the previous two mappings. The first Chrome mapping could be missing so the
- // pgoff could be larger than the total mapping size so far.
- return mmap.pgoff() >= combined_mapping_.pgoff() &&
- combined_mapping_.start() + combined_mapping_.len() == mmap.start();
-}
-
-bool ChromeHugePagesMappingDeducer::IsContiguousWithCombinedMapping(
- const PerfDataProto_MMapEvent& mmap) const {
- if (state_ == BASE_STATE) {
- return false;
- }
-
- return !combined_mapping_.has_len() ||
- combined_mapping_.start() + combined_mapping_.len() == mmap.start();
-}
-
-} // namespace perftools
diff --git a/chrome_huge_pages_mapping_deducer.h b/chrome_huge_pages_mapping_deducer.h
deleted file mode 100644
index 1a01b53..0000000
--- a/chrome_huge_pages_mapping_deducer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2016, Google Inc.
- * All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef PERFTOOLS_CHROME_HUGE_PAGES_MAPPING_DEDUCER_H_
-#define PERFTOOLS_CHROME_HUGE_PAGES_MAPPING_DEDUCER_H_
-
-#include "base/macros.h"
-#include "quipper/perf_data.proto.h"
-
-namespace perftools {
-// A state machine that tracks the order of split-up Chrome MMAPs it has seen.
-// It deduces that there was a Chrome binary that was split into multiple MMAPs,
-// including a huge pages mapping in the middle. The split is as follows:
-// - First Chrome MMAP (optional): start=A len=X pgoff=0
-// - Huge pages MMAP: start=A+X len=Y pgoff=0 name="//anon"
-// - Second Chrome MMAP: start=A+X+Y len=Z pgoff=X+Y
-// Here, Y=|kHugePagesSize|.
-//
-class ChromeHugePagesMappingDeducer {
- public:
- ChromeHugePagesMappingDeducer();
-
- // Pass the next MMAP into the deducer state machine.
- void ProcessMmap(const quipper::PerfDataProto_MMapEvent& mmap);
-
- bool CombinedMappingAvailable() const { return state_ == SECOND_CHROME_MMAP; }
-
- const quipper::PerfDataProto_MMapEvent& combined_mapping() const {
- return combined_mapping_;
- }
-
- private:
- // Resets the state machine.
- void Reset();
-
- // Functions used to determine whether a mapping falls into a particular part
- // of the split-mapped sequence.
- bool IsFirstChromeMmap(const quipper::PerfDataProto_MMapEvent& mmap) const;
- bool IsHugePagesMmap(const quipper::PerfDataProto_MMapEvent& mmap) const;
- bool IsSecondChromeMmap(const quipper::PerfDataProto_MMapEvent& mmap) const;
-
- // Checks that the mapping is contiguous with the existing |combined_mapping|,
- // if it has already been initialized.
- bool IsContiguousWithCombinedMapping(
- const quipper::PerfDataProto_MMapEvent& mmap) const;
-
- // States of the state machine.
- enum State {
- // No huge pages Chrome mapping encountered.
- BASE_STATE,
- // Encountered first Chrome mapping. The first Chrome mapping may not exist,
- // so this stage can be skipped if necessary.
- FIRST_CHROME_MMAP,
- // Encountered the huge pages mapping.
- HUGE_PAGES_MMAP,
- // Encountered the second Chrome mapping, after the huge pages mapping.
- SECOND_CHROME_MMAP,
- } state_;
-
- // A single mapping combined from the split Chrome mappings. Gets updated as
- // new mappings are processed.
- quipper::PerfDataProto_MMapEvent combined_mapping_;
-
- DISALLOW_COPY_AND_ASSIGN(ChromeHugePagesMappingDeducer);
-};
-
-} // namespace perftools
-
-#endif // PERFTOOLS_CHROME_HUGE_PAGES_MAPPING_DEDUCER_H_
diff --git a/chrome_huge_pages_mapping_deducer_test.cc b/chrome_huge_pages_mapping_deducer_test.cc
deleted file mode 100644
index 38041d2..0000000
--- a/chrome_huge_pages_mapping_deducer_test.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2016, Google Inc.
- * All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-// Tests converting split hugepages mapping into a single mapping.
-
-#include "chrome_huge_pages_mapping_deducer.h"
-
-#include <cstdint>
-#include <string>
-
-#include "quipper/perf_data.proto.h"
-#include "compat/test_compat.h"
-
-namespace perftools {
-
-namespace {
-
-using MMap = quipper::PerfDataProto_MMapEvent;
-
-// Determines whether a MMap protobuf is uninitialized. The MMap protobuf uses
-// the lite message format, which has no Empty() function. Instead, serialize to
-// a string and compare against the serialized string of an uninitialized
-// protobuf.
-bool IsUninitialized(const MMap& mmap) {
- return mmap.SerializeAsString() == MMap().SerializeAsString();
-}
-
-class TestDeducer : public ChromeHugePagesMappingDeducer {
- public:
- // Wrapper around ChromeHugePagesMappingDeducer::ProcessMmap() that lets the
- // caller pass in the mapping parameters without having to first create a MMap
- // protobuf.
- void ProcessMmap(const std::string& filename, uint64_t start, uint64_t length,
- uint64_t file_offset, uint32_t pid) {
- MMap mmap;
- mmap.set_filename(filename);
- mmap.set_start(start);
- mmap.set_len(length);
- mmap.set_pgoff(file_offset);
- mmap.set_pid(pid);
-
- ChromeHugePagesMappingDeducer::ProcessMmap(mmap);
- }
-};
-
-} // namespace
-
-TEST(ChromeHugePagesMappingDeducerTest, InitialState) {
- TestDeducer deducer;
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, NonHugePagesMappings) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("foo", 0x1000, 0x1000, 0, 1);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("bar", 0x2000, 0x10000, 0, 2);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("goo", 0x12000, 0x4000, 0, 3);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("baz", 0x16000, 0xa000, 0, 4);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 5);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, SingleHugePagesMapping) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 123);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("//anon", 0x28000, 0x1e00000, 0, 123);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e28000, 0x10000,
- 0x1e08000, 123);
- EXPECT_TRUE(deducer.CombinedMappingAvailable());
-
- const auto& combined_mapping = deducer.combined_mapping();
- EXPECT_EQ("/opt/google/chrome/chrome", combined_mapping.filename());
- EXPECT_EQ(0x20000, combined_mapping.start());
- EXPECT_EQ(0x1e18000, combined_mapping.len());
- EXPECT_EQ(0U, combined_mapping.pgoff());
- EXPECT_EQ(123U, combined_mapping.pid());
-
- // Add another mapping to the end to reset the deducer.
- deducer.ProcessMmap("foo", 0x1e38000, 0x10000, 0, 123);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, MultipleHugepageMappings) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("//anon", 0x200000, 0x400000, 0, 123);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x600000, 0x800000, 0x400000,
- 123);
- deducer.ProcessMmap("//anon", 0xe00000, 0x1c00000, 0, 123);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x2a00000, 0x10000,
- 0x2800000, 123);
- ASSERT_TRUE(deducer.CombinedMappingAvailable());
-
- const auto& combined_mapping = deducer.combined_mapping();
- EXPECT_EQ("/opt/google/chrome/chrome", combined_mapping.filename());
- EXPECT_EQ(0x200000, combined_mapping.start());
- EXPECT_EQ(0x2810000, combined_mapping.len());
- EXPECT_EQ(0U, combined_mapping.pgoff());
- EXPECT_EQ(123U, combined_mapping.pid());
-}
-
-TEST(ChromeHugePagesMappingDeducerTest,
- SingleHugePagesMappingWithoutFirstMapping) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("//anon", 0x28000, 0x1e00000, 0, 123);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e28000, 0x10000,
- 0x1e08000, 123);
- EXPECT_TRUE(deducer.CombinedMappingAvailable());
-
- const auto& combined_mapping = deducer.combined_mapping();
- EXPECT_EQ("/opt/google/chrome/chrome", combined_mapping.filename());
- EXPECT_EQ(0x28000, combined_mapping.start());
- EXPECT_EQ(0x1e10000, combined_mapping.len());
- EXPECT_EQ(0x8000, combined_mapping.pgoff());
- EXPECT_EQ(123U, combined_mapping.pid());
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, IncorrectHugePageSize) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 456);
- deducer.ProcessMmap("//anon", 0x28000, 0x1e80000, 0, 456);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e28000, 0x10000,
- 0x1e08000, 456);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, IncorrectFileName) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 456);
- deducer.ProcessMmap("//anonymous", 0x28000, 0x1e00000, 0, 456);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e28000, 0x10000,
- 0x1e08000, 456);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-
- deducer.ProcessMmap("//anon", 0x28000, 0x1e00000, 0, 456);
- deducer.ProcessMmap("/opt/google/chrome/bogus", 0x1e28000, 0x10000, 0x1e08000,
- 456);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, NoncontiguousMappings) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 456);
- deducer.ProcessMmap("//anon", 0x29000, 0x1e00000, 0, 456);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e29000, 0x10000,
- 0x1e08000, 456);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-
- deducer.ProcessMmap("//anon", 0x28000, 0x1e00000, 0, 456);
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e29000, 0x10000,
- 0x1e08000, 456);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- EXPECT_TRUE(IsUninitialized(deducer.combined_mapping()));
-}
-
-TEST(ChromeHugePagesMappingDeducerTest, MultipleMappings) {
- TestDeducer deducer;
-
- deducer.ProcessMmap("foo", 0x1000, 0x1000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("bar", 0x2000, 0x10000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
-
- // First valid mapping.
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x20000, 0x8000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("//anon", 0x28000, 0x1e00000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x1e28000, 0x10000,
- 0x1e08000, 789);
- EXPECT_TRUE(deducer.CombinedMappingAvailable());
- EXPECT_EQ("/opt/google/chrome/chrome", deducer.combined_mapping().filename());
- EXPECT_EQ(0x20000, deducer.combined_mapping().start());
- EXPECT_EQ(0x1e18000, deducer.combined_mapping().len());
- EXPECT_EQ(0U, deducer.combined_mapping().pgoff());
- EXPECT_EQ(789U, deducer.combined_mapping().pid());
-
- // Second valid mapping.
- deducer.ProcessMmap("//anon", 0x40028000, 0x1e00000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x41e28000, 0x10000,
- 0x1e08000, 789);
- EXPECT_TRUE(deducer.CombinedMappingAvailable());
-
- EXPECT_EQ("/opt/google/chrome/chrome", deducer.combined_mapping().filename());
- EXPECT_EQ(0x40028000, deducer.combined_mapping().start());
- EXPECT_EQ(0x1e10000, deducer.combined_mapping().len());
- EXPECT_EQ(0x8000, deducer.combined_mapping().pgoff());
- EXPECT_EQ(789U, deducer.combined_mapping().pid());
-
- deducer.ProcessMmap("goo", 0x12000, 0x4000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("baz", 0x16000, 0xa000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
-
- // Third valid mapping.
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x7f000000, 0x8000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("//anon", 0x7f008000, 0x1e00000, 0, 789);
- EXPECT_FALSE(deducer.CombinedMappingAvailable());
- deducer.ProcessMmap("/opt/google/chrome/chrome", 0x80e08000, 0x10000,
- 0x1e08000, 789);
- EXPECT_TRUE(deducer.CombinedMappingAvailable());
- EXPECT_EQ("/opt/google/chrome/chrome", deducer.combined_mapping().filename());
- EXPECT_EQ(0x7f000000, deducer.combined_mapping().start());
- EXPECT_EQ(0x1e18000, deducer.combined_mapping().len());
- EXPECT_EQ(0U, deducer.combined_mapping().pgoff());
- EXPECT_EQ(789U, deducer.combined_mapping().pid());
-}
-
-} // namespace perftools
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/perf_data_handler.cc b/perf_data_handler.cc
index d356a6e..cde4671 100644
--- a/perf_data_handler.cc
+++ b/perf_data_handler.cc
@@ -12,7 +12,6 @@
#include <unordered_map>
#include <vector>
-#include "chrome_huge_pages_mapping_deducer.h"
#include "int_compat.h"
#include "intervalmap.h"
#include "path_matching.h"
@@ -130,11 +129,6 @@
// filename of the main executable for that pid.
PidToMMapMap pid_to_executable_mmap_;
- // Use a separate huge pages mapping deducer for each process, to resolve
- // split huge pages mappings into a single mapping.
- std::unordered_map<uint32, ChromeHugePagesMappingDeducer>
- pid_to_chrome_mapping_deducer_;
-
// map filenames to build-ids.
std::unordered_map<string, string> filename_to_build_id_;
@@ -345,15 +339,6 @@
} else {
interval_map = it->second.get();
}
-
- auto& deducer = pid_to_chrome_mapping_deducer_[pid];
- deducer.ProcessMmap(*mmap);
- if (deducer.CombinedMappingAvailable()) {
- owned_quipper_mappings_.emplace_back(
- new quipper::PerfDataProto_MMapEvent(deducer.combined_mapping()));
- mmap = owned_quipper_mappings_.back().get();
- }
-
std::unordered_map<string, string>::const_iterator build_id_it;
if (mmap->filename() != "") {
build_id_it = filename_to_build_id_.find(mmap->filename());