summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis <thakis@chromium.org>2015-09-11 06:50:59 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-11 13:51:44 +0000
commit5747a19cad8feb463125f3c80376d3c535f25523 (patch)
tree1bc808412d73082fa5b8f6ede63c197eeb5653aa
parent8ee79634c84a8a26ec2993163cc1d606f656986b (diff)
downloadchromium_src-5747a19cad8feb463125f3c80376d3c535f25523.zip
chromium_src-5747a19cad8feb463125f3c80376d3c535f25523.tar.gz
chromium_src-5747a19cad8feb463125f3c80376d3c535f25523.tar.bz2
Remove clang type profiler and deep memory profiler.
Looks like it's no longer functional and unused. BUG=490464 TBR=jochen Review URL: https://codereview.chromium.org/1331973002 Cr-Commit-Position: refs/heads/master@{#348392}
-rw-r--r--base/BUILD.gn4
-rw-r--r--base/allocator/BUILD.gn4
-rw-r--r--base/allocator/allocator.gyp114
-rw-r--r--base/allocator/type_profiler.cc63
-rw-r--r--base/allocator/type_profiler.h40
-rw-r--r--base/allocator/type_profiler_control.cc38
-rw-r--r--base/allocator/type_profiler_control.h31
-rw-r--r--base/allocator/type_profiler_map_unittest.cc99
-rw-r--r--base/allocator/type_profiler_tcmalloc.cc37
-rw-r--r--base/allocator/type_profiler_tcmalloc.h29
-rw-r--r--base/allocator/type_profiler_unittest.cc189
-rw-r--r--base/base.gypi4
-rw-r--r--base/process/launch_posix.cc11
-rw-r--r--build/common.gypi36
-rw-r--r--build/toolchain/android/BUILD.gn10
-rw-r--r--build/toolchain/clang.gni9
-rw-r--r--build/toolchain/cros/BUILD.gn1
-rw-r--r--build/toolchain/linux/BUILD.gn19
-rw-r--r--build/toolchain/mac/BUILD.gn1
-rw-r--r--chrome/chrome_exe.gypi5
-rw-r--r--content/app/content_main_runner.cc11
-rw-r--r--third_party/tcmalloc/chromium/src/deep-heap-profile.cc1161
-rw-r--r--third_party/tcmalloc/chromium/src/deep-heap-profile.h407
-rw-r--r--third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h20
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profile-table.cc61
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profile-table.h32
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profiler.cc83
-rw-r--r--third_party/tcmalloc/chromium/src/type_profiler_map.cc112
28 files changed, 10 insertions, 2621 deletions
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 8058c77..48409f9 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -64,8 +64,6 @@ component("base") {
sources = [
"allocator/allocator_extension.cc",
"allocator/allocator_extension.h",
- "allocator/type_profiler_control.cc",
- "allocator/type_profiler_control.h",
"android/animation_frame_time_histogram.cc",
"android/animation_frame_time_histogram.h",
"android/apk_assets.cc",
@@ -728,8 +726,6 @@ component("base") {
set_sources_assignment_filter(sources_assignment_filter)
sources -= [
- "allocator/type_profiler_control.cc",
- "allocator/type_profiler_control.h",
"async_socket_io_handler_posix.cc",
"cpu.cc",
"files/file_enumerator_posix.cc",
diff --git a/base/allocator/BUILD.gn b/base/allocator/BUILD.gn
index b6b7fc2..c12431b 100644
--- a/base/allocator/BUILD.gn
+++ b/base/allocator/BUILD.gn
@@ -100,7 +100,7 @@ if (use_allocator == "tcmalloc") {
check_includes = false
sources = [
- # Generated for our configuration from tcmalloc"s build
+ # Generated for our configuration from tcmalloc's build
# and checked in.
"$tcmalloc_dir/src/config.h",
"$tcmalloc_dir/src/config_android.h",
@@ -151,8 +151,6 @@ if (use_allocator == "tcmalloc") {
# #included by debugallocation_shim.cc
#"$tcmalloc_dir/src/debugallocation.cc",
- "$tcmalloc_dir/src/deep-heap-profile.cc",
- "$tcmalloc_dir/src/deep-heap-profile.h",
"$tcmalloc_dir/src/free_list.cc",
"$tcmalloc_dir/src/free_list.h",
"$tcmalloc_dir/src/heap-profile-table.cc",
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp
index 7cd9b64..ae93e9e 100644
--- a/base/allocator/allocator.gyp
+++ b/base/allocator/allocator.gyp
@@ -153,8 +153,6 @@
'<(tcmalloc_dir)/src/common.cc',
'<(tcmalloc_dir)/src/common.h',
'<(tcmalloc_dir)/src/debugallocation.cc',
- '<(tcmalloc_dir)/src/deep-heap-profile.cc',
- '<(tcmalloc_dir)/src/deep-heap-profile.h',
'<(tcmalloc_dir)/src/free_list.cc',
'<(tcmalloc_dir)/src/free_list.h',
'<(tcmalloc_dir)/src/getpc.h',
@@ -296,19 +294,6 @@
'../..',
],
}],
- ['OS=="linux" and clang_type_profiler==1', {
- 'dependencies': [
- 'type_profiler_tcmalloc',
- ],
- # It is undoing dependencies and cflags_cc for type_profiler which
- # build/common.gypi injects into all targets.
- 'dependencies!': [
- 'type_profiler',
- ],
- 'cflags_cc!': [
- '-fintercept-allocation-functions',
- ],
- }],
['OS=="win" and component!="shared_library"', {
'dependencies': [
'libcmt',
@@ -382,18 +367,6 @@
'include_dirs': [
'../../'
],
- 'conditions': [
- ['OS=="linux" and clang_type_profiler==1', {
- # It is undoing dependencies and cflags_cc for type_profiler which
- # build/common.gypi injects into all targets.
- 'dependencies!': [
- 'type_profiler',
- ],
- 'cflags_cc!': [
- '-fintercept-allocation-functions',
- ],
- }],
- ],
},
],
'conditions': [
@@ -462,93 +435,6 @@
},
],
}],
- ['OS=="linux" and clang_type_profiler==1', {
- # Some targets in this section undo dependencies and cflags_cc for
- # type_profiler which build/common.gypi injects into all targets.
- 'targets': [
- {
- 'target_name': 'type_profiler',
- 'type': 'static_library',
- 'dependencies!': [
- 'type_profiler',
- ],
- 'cflags_cc!': [
- '-fintercept-allocation-functions',
- ],
- 'include_dirs': [
- '../..',
- ],
- 'sources': [
- 'type_profiler.cc',
- 'type_profiler.h',
- 'type_profiler_control.h',
- ],
- 'toolsets': ['host', 'target'],
- },
- {
- 'target_name': 'type_profiler_tcmalloc',
- 'type': 'static_library',
- 'dependencies!': [
- 'type_profiler',
- ],
- 'cflags_cc!': [
- '-fintercept-allocation-functions',
- ],
- 'include_dirs': [
- '<(tcmalloc_dir)/src',
- '../..',
- ],
- 'sources': [
- '<(tcmalloc_dir)/src/gperftools/type_profiler_map.h',
- '<(tcmalloc_dir)/src/type_profiler_map.cc',
- 'type_profiler_tcmalloc.cc',
- 'type_profiler_tcmalloc.h',
- ],
- },
- {
- 'target_name': 'type_profiler_unittests',
- 'type': 'executable',
- 'dependencies': [
- '../../testing/gtest.gyp:gtest',
- '../base.gyp:base',
- 'allocator',
- 'type_profiler_tcmalloc',
- ],
- 'include_dirs': [
- '../..',
- ],
- 'sources': [
- 'type_profiler_control.cc',
- 'type_profiler_control.h',
- 'type_profiler_unittest.cc',
- ],
- },
- {
- 'target_name': 'type_profiler_map_unittests',
- 'type': 'executable',
- 'dependencies': [
- '../../testing/gtest.gyp:gtest',
- '../base.gyp:base',
- 'allocator',
- ],
- 'dependencies!': [
- 'type_profiler',
- ],
- 'cflags_cc!': [
- '-fintercept-allocation-functions',
- ],
- 'include_dirs': [
- '<(tcmalloc_dir)/src',
- '../..',
- ],
- 'sources': [
- '<(tcmalloc_dir)/src/gperftools/type_profiler_map.h',
- '<(tcmalloc_dir)/src/type_profiler_map.cc',
- 'type_profiler_map_unittest.cc',
- ],
- },
- ],
- }],
['use_allocator=="tcmalloc"', {
'targets': [
{
diff --git a/base/allocator/type_profiler.cc b/base/allocator/type_profiler.cc
deleted file mode 100644
index 635fbcf..0000000
--- a/base/allocator/type_profiler.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#if defined(TYPE_PROFILING)
-
-#include "base/allocator/type_profiler.h"
-
-#include <assert.h>
-
-namespace {
-
-void* NopIntercept(void* ptr, size_t size, const std::type_info& type) {
- return ptr;
-}
-
-base::type_profiler::InterceptFunction* g_new_intercept = NopIntercept;
-base::type_profiler::InterceptFunction* g_delete_intercept = NopIntercept;
-
-}
-
-void* __op_new_intercept__(void* ptr,
- size_t size,
- const std::type_info& type) {
- return g_new_intercept(ptr, size, type);
-}
-
-void* __op_delete_intercept__(void* ptr,
- size_t size,
- const std::type_info& type) {
- return g_delete_intercept(ptr, size, type);
-}
-
-namespace base {
-namespace type_profiler {
-
-// static
-void InterceptFunctions::SetFunctions(InterceptFunction* new_intercept,
- InterceptFunction* delete_intercept) {
- // Don't use DCHECK, as this file is injected into targets
- // that do not and should not depend on base/base.gyp:base
- assert(g_new_intercept == NopIntercept);
- assert(g_delete_intercept == NopIntercept);
-
- g_new_intercept = new_intercept;
- g_delete_intercept = delete_intercept;
-}
-
-// static
-void InterceptFunctions::ResetFunctions() {
- g_new_intercept = NopIntercept;
- g_delete_intercept = NopIntercept;
-}
-
-// static
-bool InterceptFunctions::IsAvailable() {
- return g_new_intercept != NopIntercept || g_delete_intercept != NopIntercept;
-}
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
diff --git a/base/allocator/type_profiler.h b/base/allocator/type_profiler.h
deleted file mode 100644
index 86b5711..0000000
--- a/base/allocator/type_profiler.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ALLOCATOR_TYPE_PROFILER_H_
-#define BASE_ALLOCATOR_TYPE_PROFILER_H_
-
-#if defined(TYPE_PROFILING)
-
-#include <stddef.h> // for size_t
-#include <typeinfo> // for std::typeinfo
-
-namespace base {
-namespace type_profiler {
-
-typedef void* InterceptFunction(void*, size_t, const std::type_info&);
-
-class InterceptFunctions {
- public:
- // It must be called only once in a process while it is in single-thread.
- // For now, ContentMainRunnerImpl::Initialize is the only supposed caller
- // of this function except for single-threaded unit tests.
- static void SetFunctions(InterceptFunction* new_intercept,
- InterceptFunction* delete_intercept);
-
- private:
- friend class TypeProfilerTest;
-
- // These functions are not thread safe.
- // They must be used only from single-threaded unit tests.
- static void ResetFunctions();
- static bool IsAvailable();
-};
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
-
-#endif // BASE_ALLOCATOR_TYPE_PROFILER_H_
diff --git a/base/allocator/type_profiler_control.cc b/base/allocator/type_profiler_control.cc
deleted file mode 100644
index 6be7984..0000000
--- a/base/allocator/type_profiler_control.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/allocator/type_profiler_control.h"
-
-namespace base {
-namespace type_profiler {
-
-namespace {
-
-#if defined(TYPE_PROFILING)
-const bool kTypeProfilingEnabled = true;
-#else
-const bool kTypeProfilingEnabled = false;
-#endif
-
-bool g_enable_intercept = kTypeProfilingEnabled;
-
-} // namespace
-
-// static
-void Controller::Stop() {
- g_enable_intercept = false;
-}
-
-// static
-bool Controller::IsProfiling() {
- return kTypeProfilingEnabled && g_enable_intercept;
-}
-
-// static
-void Controller::Restart() {
- g_enable_intercept = kTypeProfilingEnabled;
-}
-
-} // namespace type_profiler
-} // namespace base
diff --git a/base/allocator/type_profiler_control.h b/base/allocator/type_profiler_control.h
deleted file mode 100644
index 17cf5b6..0000000
--- a/base/allocator/type_profiler_control.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ALLOCATOR_TYPE_PROFILER_CONTROL_H_
-#define BASE_ALLOCATOR_TYPE_PROFILER_CONTROL_H_
-
-#include "base/gtest_prod_util.h"
-
-namespace base {
-namespace type_profiler {
-
-class Controller {
- public:
- static void Stop();
- static bool IsProfiling();
-
- private:
- FRIEND_TEST_ALL_PREFIXES(TypeProfilerTest,
- TestProfileNewWithoutProfiledDelete);
-
- // It must be used only from allowed unit tests. The following is only
- // allowed for use in unit tests. Profiling should never be restarted in
- // regular use.
- static void Restart();
-};
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // BASE_ALLOCATOR_TYPE_PROFILER_CONTROL_H_
diff --git a/base/allocator/type_profiler_map_unittest.cc b/base/allocator/type_profiler_map_unittest.cc
deleted file mode 100644
index 514ec16..0000000
--- a/base/allocator/type_profiler_map_unittest.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a unittest set for type_profiler_map in third_party/tcmalloc. It is
-// independent from other tests and executed manually like allocator_unittests
-// since type_profiler_map is a singleton (like TCMalloc's heap-profiler), and
-// it requires RTTI and different compiling/linking options from others.
-
-#if defined(TYPE_PROFILING)
-
-#include "base/memory/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h"
-
-namespace base {
-namespace type_profiler {
-
-static const void* const g_const_null = static_cast<const void*>(NULL);
-
-TEST(TypeProfilerMapTest, NormalOperation) {
- // Allocate an object just to get a valid address.
- // This 'new' is not profiled by type_profiler.
- scoped_ptr<int> dummy(new int(48));
- const std::type_info* type;
-
- type = LookupType(dummy.get());
- EXPECT_EQ(g_const_null, type);
-
- InsertType(dummy.get(), 12, typeid(int));
- type = LookupType(dummy.get());
- ASSERT_NE(g_const_null, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
-
- EraseType(dummy.get());
- type = LookupType(dummy.get());
- EXPECT_EQ(g_const_null, type);
-}
-
-TEST(TypeProfilerMapTest, EraseWithoutInsert) {
- scoped_ptr<int> dummy(new int(48));
- const std::type_info* type;
-
- for (int i = 0; i < 10; ++i) {
- EraseType(dummy.get());
- type = LookupType(dummy.get());
- EXPECT_EQ(g_const_null, type);
- }
-}
-
-TEST(TypeProfilerMapTest, InsertThenMultipleErase) {
- scoped_ptr<int> dummy(new int(48));
- const std::type_info* type;
-
- InsertType(dummy.get(), 12, typeid(int));
- type = LookupType(dummy.get());
- ASSERT_NE(g_const_null, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
-
- for (int i = 0; i < 10; ++i) {
- EraseType(dummy.get());
- type = LookupType(dummy.get());
- EXPECT_EQ(g_const_null, type);
- }
-}
-
-TEST(TypeProfilerMapTest, MultipleInsertWithoutErase) {
- scoped_ptr<int> dummy(new int(48));
- const std::type_info* type;
-
- InsertType(dummy.get(), 12, typeid(int));
- type = LookupType(dummy.get());
- ASSERT_NE(g_const_null, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
-
- InsertType(dummy.get(), 5, typeid(char));
- type = LookupType(dummy.get());
- ASSERT_NE(g_const_null, type);
- EXPECT_STREQ(typeid(char).name(), type->name());
-
- InsertType(dummy.get(), 129, typeid(long));
- type = LookupType(dummy.get());
- ASSERT_NE(g_const_null, type);
- EXPECT_STREQ(typeid(long).name(), type->name());
-
- EraseType(dummy.get());
- type = LookupType(dummy.get());
- EXPECT_EQ(g_const_null, type);
-}
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
-
-int main(int argc, char** argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/base/allocator/type_profiler_tcmalloc.cc b/base/allocator/type_profiler_tcmalloc.cc
deleted file mode 100644
index e5e10e0..0000000
--- a/base/allocator/type_profiler_tcmalloc.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#if defined(TYPE_PROFILING)
-
-#include "base/allocator/type_profiler_tcmalloc.h"
-
-#include "base/allocator/type_profiler_control.h"
-#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
-#include "third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h"
-
-namespace base {
-namespace type_profiler {
-
-void* NewInterceptForTCMalloc(void* ptr,
- size_t size,
- const std::type_info& type) {
- if (Controller::IsProfiling())
- InsertType(ptr, size, type);
-
- return ptr;
-}
-
-void* DeleteInterceptForTCMalloc(void* ptr,
- size_t size,
- const std::type_info& type) {
- if (Controller::IsProfiling())
- EraseType(ptr);
-
- return ptr;
-}
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
diff --git a/base/allocator/type_profiler_tcmalloc.h b/base/allocator/type_profiler_tcmalloc.h
deleted file mode 100644
index ac55995..0000000
--- a/base/allocator/type_profiler_tcmalloc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_ALLOCATOR_TYPE_PROFILER_TCMALLOC_H_
-#define BASE_ALLOCATOR_TYPE_PROFILER_TCMALLOC_H_
-
-#if defined(TYPE_PROFILING)
-
-#include <cstddef> // for size_t
-#include <typeinfo> // for std::type_info
-
-namespace base {
-namespace type_profiler {
-
-void* NewInterceptForTCMalloc(void* ptr,
- size_t size,
- const std::type_info& type);
-
-void* DeleteInterceptForTCMalloc(void* ptr,
- size_t size,
- const std::type_info& type);
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
-
-#endif // BASE_ALLOCATOR_TYPE_PROFILER_TCMALLOC_H_
diff --git a/base/allocator/type_profiler_unittest.cc b/base/allocator/type_profiler_unittest.cc
deleted file mode 100644
index 3d7369c38..0000000
--- a/base/allocator/type_profiler_unittest.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a unittest set for type_profiler. It is independent from other
-// tests and executed manually like allocator_unittests since type_profiler_map
-// used in type_profiler is a singleton (like TCMalloc's heap-profiler), and
-// it requires RTTI and different compiling/linking options from others
-//
-// It tests that the profiler doesn't fail in suspicous cases. For example,
-// 'new' is not profiled, but 'delete' for the created object is profiled.
-
-#if defined(TYPE_PROFILING)
-
-#include "base/allocator/type_profiler.h"
-#include "base/allocator/type_profiler_control.h"
-#include "base/allocator/type_profiler_tcmalloc.h"
-#include "base/basictypes.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h"
-
-namespace base {
-namespace type_profiler {
-
-class TypeProfilerTest : public testing::Test {
- public:
- TypeProfilerTest() {}
-
- void SetInterceptFunctions() {
- InterceptFunctions::SetFunctions(NewInterceptForTCMalloc,
- DeleteInterceptForTCMalloc);
- }
-
- void ResetInterceptFunctions() {
- InterceptFunctions::ResetFunctions();
- }
-
- void SetUp() {
- SetInterceptFunctions();
- }
-
- void TearDown() {
- ResetInterceptFunctions();
- }
-
- protected:
- static const size_t kDummyArraySize;
- static const void* const kConstNull;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TypeProfilerTest);
-};
-
-const size_t TypeProfilerTest::kDummyArraySize = 10;
-const void* const TypeProfilerTest::kConstNull = static_cast<const void*>(NULL);
-
-TEST_F(TypeProfilerTest, TestNormalProfiling) {
- int* dummy = new int(48);
- const std::type_info* type;
-
- type = LookupType(dummy);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
- delete dummy;
-
- type = LookupType(dummy);
- EXPECT_EQ(kConstNull, type);
-}
-
-TEST_F(TypeProfilerTest, TestNormalArrayProfiling) {
- int* dummy = new int[kDummyArraySize];
- const std::type_info* type;
-
- type = LookupType(dummy);
- ASSERT_NE(kConstNull, type);
- // For an array, the profiler remembers its base type.
- EXPECT_STREQ(typeid(int).name(), type->name());
- delete[] dummy;
-
- type = LookupType(dummy);
- EXPECT_EQ(kConstNull, type);
-}
-
-TEST_F(TypeProfilerTest, TestRepeatedNewAndDelete) {
- int *dummy[kDummyArraySize];
- const std::type_info* type;
- for (int i = 0; i < kDummyArraySize; ++i)
- dummy[i] = new int(i);
-
- for (int i = 0; i < kDummyArraySize; ++i) {
- type = LookupType(dummy[i]);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
- }
-
- for (int i = 0; i < kDummyArraySize; ++i) {
- delete dummy[i];
- type = LookupType(dummy[i]);
- ASSERT_EQ(kConstNull, type);
- }
-}
-
-TEST_F(TypeProfilerTest, TestMultipleNewWithDroppingDelete) {
- static const size_t large_size = 256 * 1024;
-
- char* dummy_char = new char[large_size / sizeof(*dummy_char)];
- const std::type_info* type;
-
- type = LookupType(dummy_char);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(char).name(), type->name());
-
- // Call "::operator delete" directly to drop __op_delete_intercept__.
- ::operator delete[](dummy_char);
-
- type = LookupType(dummy_char);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(char).name(), type->name());
-
- // Allocates a little different size.
- int* dummy_int = new int[large_size / sizeof(*dummy_int) - 1];
-
- // We expect that tcmalloc returns the same address for these large (over 32k)
- // allocation calls. It usually happens, but maybe probablistic.
- ASSERT_EQ(static_cast<void*>(dummy_char), static_cast<void*>(dummy_int)) <<
- "two new (malloc) calls didn't return the same address; retry it.";
-
- type = LookupType(dummy_int);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
-
- delete[] dummy_int;
-
- type = LookupType(dummy_int);
- EXPECT_EQ(kConstNull, type);
-}
-
-TEST_F(TypeProfilerTest, TestProfileDeleteWithoutProfiledNew) {
- // 'dummy' should be new'ed in this test before intercept functions are set.
- ResetInterceptFunctions();
-
- int* dummy = new int(48);
- const std::type_info* type;
-
- // Set intercept functions again after 'dummy' is new'ed.
- SetInterceptFunctions();
-
- delete dummy;
-
- type = LookupType(dummy);
- EXPECT_EQ(kConstNull, type);
-
- ResetInterceptFunctions();
-}
-
-TEST_F(TypeProfilerTest, TestProfileNewWithoutProfiledDelete) {
- int* dummy = new int(48);
- const std::type_info* type;
-
- EXPECT_TRUE(Controller::IsProfiling());
-
- // Stop profiling before deleting 'dummy'.
- Controller::Stop();
- EXPECT_FALSE(Controller::IsProfiling());
-
- delete dummy;
-
- // NOTE: We accept that a profile entry remains when a profiled object is
- // deleted after Controller::Stop().
- type = LookupType(dummy);
- ASSERT_NE(kConstNull, type);
- EXPECT_STREQ(typeid(int).name(), type->name());
-
- Controller::Restart();
- EXPECT_TRUE(Controller::IsProfiling());
-
- // Remove manually since 'dummy' is not removed from type_profiler_map.
- EraseType(dummy);
-}
-
-} // namespace type_profiler
-} // namespace base
-
-#endif // defined(TYPE_PROFILING)
-
-int main(int argc, char** argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/base/base.gypi b/base/base.gypi
index ea02165..ab1f380 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -18,8 +18,6 @@
'../build/build_config.h',
'allocator/allocator_extension.cc',
'allocator/allocator_extension.h',
- 'allocator/type_profiler_control.cc',
- 'allocator/type_profiler_control.h',
'android/animation_frame_time_histogram.cc',
'android/animation_frame_time_histogram.h',
'android/apk_assets.cc',
@@ -795,8 +793,6 @@
],
['>(nacl_untrusted_build)==1', {
'sources!': [
- 'allocator/type_profiler_control.cc',
- 'allocator/type_profiler_control.h',
'base_paths.cc',
'cpu.cc',
'debug/stack_trace.cc',
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc
index 0ebf984..edae49b 100644
--- a/base/process/launch_posix.cc
+++ b/base/process/launch_posix.cc
@@ -22,7 +22,6 @@
#include <limits>
#include <set>
-#include "base/allocator/type_profiler_control.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/debug/debugger.h"
@@ -392,11 +391,6 @@ Process LaunchProcess(const std::vector<std::string>& argv,
}
}
- // Stop type-profiler.
- // The profiler should be stopped between fork and exec since it inserts
- // locks at new/delete expressions. See http://crbug.com/36678.
- base::type_profiler::Controller::Stop();
-
if (options.maximize_rlimits) {
// Some resource limits need to be maximal in this child.
for (size_t i = 0; i < options.maximize_rlimits->size(); ++i) {
@@ -593,11 +587,6 @@ static GetAppOutputInternalResult GetAppOutputInternal(
if (dev_null < 0)
_exit(127);
- // Stop type-profiler.
- // The profiler should be stopped between fork and exec since it inserts
- // locks at new/delete expressions. See http://crbug.com/36678.
- base::type_profiler::Controller::Stop();
-
fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
fd_shuffle1.push_back(InjectionArc(
include_stderr ? pipe_fd[1] : dev_null,
diff --git a/build/common.gypi b/build/common.gypi
index 08d1e2a..f7d2141 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -517,12 +517,6 @@
# This is intended for iOS builds only.
'use_system_libcxx%': 0,
- # Use a modified version of Clang to intercept allocated types and sizes
- # for allocated objects. clang_type_profiler=1 implies clang=1.
- # See http://dev.chromium.org/developers/deep-memory-profiler/cpp-object-type-identifier
- # TODO(dmikurube): Support mac. See http://crbug.com/123758#c11
- 'clang_type_profiler%': 0,
-
# Set to true to instrument the code with function call logger.
# See src/third_party/cygprofile/cyg-profile.cc for details.
'order_profiling%': 0,
@@ -1205,7 +1199,6 @@
'use_prebuilt_instrumented_libraries%': '<(use_prebuilt_instrumented_libraries)',
'use_custom_libcxx%': '<(use_custom_libcxx)',
'use_system_libcxx%': '<(use_system_libcxx)',
- 'clang_type_profiler%': '<(clang_type_profiler)',
'order_profiling%': '<(order_profiling)',
'order_text_section%': '<(order_text_section)',
'enable_extensions%': '<(enable_extensions)',
@@ -2281,23 +2274,6 @@
'v8_target_arch': 'arm64',
}],
- ['OS=="linux" and clang_type_profiler==1', {
- 'clang%': 1,
- 'clang_use_chrome_plugins%': 0,
- 'conditions': [
- ['host_arch=="x64"', {
- 'make_clang_dir%': 'third_party/llvm-allocated-type/Linux_x64',
- }],
- ['host_arch=="ia32"', {
- # 32-bit Clang is unsupported. It may not build. Put your 32-bit
- # Clang in this directory at your own risk if needed for some
- # purpose (e.g. to compare 32-bit and 64-bit behavior like memory
- # usage). Any failure by this compiler should not close the tree.
- 'make_clang_dir%': 'third_party/llvm-allocated-type/Linux_ia32',
- }],
- ],
- }],
-
# On valgrind bots, override the optimizer settings so we don't inline too
# much and make the stacks harder to figure out.
#
@@ -2675,18 +2651,6 @@
'<(DEPTH)/build/win/asan.gyp:asan_dynamic_runtime',
],
}],
- ['OS=="linux" and use_allocator!="none" and clang_type_profiler==1', {
- 'cflags_cc!': ['-fno-rtti'],
- 'cflags_cc+': [
- '-frtti',
- '-gline-tables-only',
- '-fintercept-allocation-functions',
- ],
- 'defines': ['TYPE_PROFILING'],
- 'dependencies': [
- '<(DEPTH)/base/allocator/allocator.gyp:type_profiler',
- ],
- }],
['branding=="Chrome"', {
'defines': ['GOOGLE_CHROME_BUILD'],
}, { # else: branding!="Chrome"
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index ed7c407..749d28b 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -4,7 +4,6 @@
import("//build/config/sysroot.gni") # Imports android/config.gni.
import("//build/toolchain/ccache.gni")
-import("//build/toolchain/clang.gni")
import("//build/toolchain/goma.gni")
import("//build/toolchain/gcc_toolchain.gni")
@@ -47,13 +46,8 @@ template("android_gcc_toolchain") {
is_clang = invoker.is_clang
if (is_clang) {
- if (use_clang_type_profiler) {
- prefix = rebase_path("//third_party/llvm-allocated-type/Linux_x64/bin",
- root_build_dir)
- } else {
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- }
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
} else {
diff --git a/build/toolchain/clang.gni b/build/toolchain/clang.gni
deleted file mode 100644
index c680384..0000000
--- a/build/toolchain/clang.gni
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
- # Enable the optional type profiler in Clang, which will tag heap allocations
- # with the allocation type.
- use_clang_type_profiler = false
-}
diff --git a/build/toolchain/cros/BUILD.gn b/build/toolchain/cros/BUILD.gn
index 140958b..755721b 100644
--- a/build/toolchain/cros/BUILD.gn
+++ b/build/toolchain/cros/BUILD.gn
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/toolchain/clang.gni")
import("//build/toolchain/gcc_toolchain.gni")
declare_args() {
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index 9145284..94d9a16 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -4,7 +4,6 @@
import("//build/config/sysroot.gni")
import("//build/toolchain/ccache.gni")
-import("//build/toolchain/clang.gni")
import("//build/toolchain/gcc_toolchain.gni")
import("//build/toolchain/goma.gni")
@@ -32,13 +31,8 @@ gcc_toolchain("arm") {
}
gcc_toolchain("clang_x86") {
- if (use_clang_type_profiler) {
- prefix = rebase_path("//third_party/llvm-allocated-type/Linux_ia32/bin",
- root_build_dir)
- } else {
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- }
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
readelf = "readelf"
@@ -66,13 +60,8 @@ gcc_toolchain("x86") {
}
gcc_toolchain("clang_x64") {
- if (use_clang_type_profiler) {
- prefix = rebase_path("//third_party/llvm-allocated-type/Linux_x64/bin",
- root_build_dir)
- } else {
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- }
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 4053511..80d782f 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -11,7 +11,6 @@ import("//build/config/ios/ios_sdk.gni")
assert(host_os == "mac")
-import("//build/toolchain/clang.gni")
import("//build/toolchain/goma.gni")
if (use_goma) {
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index f6976c2..c64b27d 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -9,11 +9,6 @@
'type': 'none',
'dependencies': [ 'chrome_initial', ],
'conditions': [
- ['OS=="linux" and clang_type_profiler==1', {
- 'dependencies!': [
- '<(DEPTH)/base/allocator/allocator.gyp:type_profiler',
- ],
- }],
['OS == "win"', {
'actions': [
{
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index f35ed29..7e6d6db 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -60,10 +60,6 @@
#if defined(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
-#if defined(TYPE_PROFILING)
-#include "base/allocator/type_profiler.h"
-#include "base/allocator/type_profiler_tcmalloc.h"
-#endif
#endif
#if !defined(OS_IOS)
@@ -464,13 +460,6 @@ class ContentMainRunnerImpl : public ContentMainRunner {
// implement this EnableTerminationOnOutOfMemory() function. Whateverz.
// This works for now.
#if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
-
-#if defined(TYPE_PROFILING)
- base::type_profiler::InterceptFunctions::SetFunctions(
- base::type_profiler::NewInterceptForTCMalloc,
- base::type_profiler::DeleteInterceptForTCMalloc);
-#endif
-
// For tcmalloc, we need to tell it to behave like new.
tc_set_new_mode(1);
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc
deleted file mode 100644
index bbf002a..0000000
--- a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc
+++ /dev/null
@@ -1,1161 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ---
-// Author: Sainbayar Sukhbaatar
-// Dai Mikurube
-//
-
-#include "deep-heap-profile.h"
-
-#ifdef USE_DEEP_HEAP_PROFILE
-#include <algorithm>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // for getpagesize and getpid
-#endif // HAVE_UNISTD_H
-
-#if defined(__linux__)
-#include <endian.h>
-#if !defined(__LITTLE_ENDIAN__) and !defined(__BIG_ENDIAN__)
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define __BIG_ENDIAN__
-#endif // __BYTE_ORDER == __BIG_ENDIAN
-#endif // !defined(__LITTLE_ENDIAN__) and !defined(__BIG_ENDIAN__)
-#if defined(__BIG_ENDIAN__)
-#include <byteswap.h>
-#endif // defined(__BIG_ENDIAN__)
-#endif // defined(__linux__)
-#if defined(COMPILER_MSVC)
-#include <Winsock2.h> // for gethostname
-#endif // defined(COMPILER_MSVC)
-
-#include "base/cycleclock.h"
-#include "base/sysinfo.h"
-#include "internal_logging.h" // for ASSERT, etc
-
-static const int kProfilerBufferSize = 1 << 20;
-static const int kHashTableSize = 179999; // Same as heap-profile-table.cc.
-
-static const int PAGEMAP_BYTES = 8;
-static const int KPAGECOUNT_BYTES = 8;
-static const uint64 MAX_ADDRESS = kuint64max;
-
-// Tag strings in heap profile dumps.
-static const char kProfileHeader[] = "heap profile: ";
-static const char kProfileVersion[] = "DUMP_DEEP_6";
-static const char kMetaInformationHeader[] = "META:\n";
-static const char kMMapListHeader[] = "MMAP_LIST:\n";
-static const char kGlobalStatsHeader[] = "GLOBAL_STATS:\n";
-static const char kStacktraceHeader[] = "STACKTRACES:\n";
-static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
-
-static const char kVirtualLabel[] = "virtual";
-static const char kCommittedLabel[] = "committed";
-
-#if defined(__linux__)
-#define OS_NAME "linux"
-#elif defined(_WIN32) || defined(_WIN64)
-#define OS_NAME "windows"
-#else
-#define OS_NAME "unknown-os"
-#endif
-
-bool DeepHeapProfile::AppendCommandLine(TextBuffer* buffer) {
-#if defined(__linux__)
- RawFD fd;
- char filename[100];
- char cmdline[4096];
- snprintf(filename, sizeof(filename), "/proc/%d/cmdline",
- static_cast<int>(getpid()));
- fd = open(filename, O_RDONLY);
- if (fd == kIllegalRawFD) {
- RAW_VLOG(0, "Failed to open /proc/self/cmdline");
- return false;
- }
-
- size_t length = read(fd, cmdline, sizeof(cmdline) - 1);
- close(fd);
-
- for (int i = 0; i < length; ++i)
- if (cmdline[i] == '\0')
- cmdline[i] = ' ';
- cmdline[length] = '\0';
-
- buffer->AppendString("CommandLine: ", 0);
- buffer->AppendString(cmdline, 0);
- buffer->AppendChar('\n');
-
- return true;
-#else
- return false;
-#endif
-}
-
-#if defined(_WIN32) || defined(_WIN64)
-
-// TODO(peria): Implement this function.
-void DeepHeapProfile::MemoryInfoGetterWindows::Initialize() {
-}
-
-// TODO(peria): Implement this function.
-size_t DeepHeapProfile::MemoryInfoGetterWindows::CommittedSize(
- uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer) const {
- return 0;
-}
-
-// TODO(peria): Implement this function.
-bool DeepHeapProfile::MemoryInfoGetterWindows::IsPageCountAvailable() const {
- return false;
-}
-
-#endif // defined(_WIN32) || defined(_WIN64)
-
-#if defined(__linux__)
-
-void DeepHeapProfile::MemoryInfoGetterLinux::Initialize() {
- char filename[100];
- snprintf(filename, sizeof(filename), "/proc/%d/pagemap",
- static_cast<int>(getpid()));
- pagemap_fd_ = open(filename, O_RDONLY);
- RAW_CHECK(pagemap_fd_ != -1, "Failed to open /proc/self/pagemap");
-
- if (pageframe_type_ == DUMP_PAGECOUNT) {
- snprintf(filename, sizeof(filename), "/proc/kpagecount");
- kpagecount_fd_ = open(filename, O_RDONLY);
- if (kpagecount_fd_ == -1)
- RAW_VLOG(0, "Failed to open /proc/kpagecount");
- }
-}
-
-size_t DeepHeapProfile::MemoryInfoGetterLinux::CommittedSize(
- uint64 first_address,
- uint64 last_address,
- DeepHeapProfile::TextBuffer* buffer) const {
- int page_size = getpagesize();
- uint64 page_address = (first_address / page_size) * page_size;
- size_t committed_size = 0;
- size_t pageframe_list_length = 0;
-
- Seek(first_address);
-
- // Check every page on which the allocation resides.
- while (page_address <= last_address) {
- // Read corresponding physical page.
- State state;
- // TODO(dmikurube): Read pagemap in bulk for speed.
- // TODO(dmikurube): Consider using mincore(2).
- if (Read(&state, pageframe_type_ != DUMP_NO_PAGEFRAME) == false) {
- // We can't read the last region (e.g vsyscall).
-#ifndef NDEBUG
- RAW_VLOG(0, "pagemap read failed @ %#llx %" PRId64 " bytes",
- first_address, last_address - first_address + 1);
-#endif
- return 0;
- }
-
- // Dump pageframes of resident pages. Non-resident pages are just skipped.
- if (pageframe_type_ != DUMP_NO_PAGEFRAME &&
- buffer != NULL && state.pfn != 0) {
- if (pageframe_list_length == 0) {
- buffer->AppendString(" PF:", 0);
- pageframe_list_length = 5;
- }
- buffer->AppendChar(' ');
- if (page_address < first_address)
- buffer->AppendChar('<');
- buffer->AppendBase64(state.pfn, 4);
- pageframe_list_length += 5;
- if (pageframe_type_ == DUMP_PAGECOUNT && IsPageCountAvailable()) {
- uint64 pagecount = ReadPageCount(state.pfn);
- // Assume pagecount == 63 if the pageframe is mapped more than 63 times.
- if (pagecount > 63)
- pagecount = 63;
- buffer->AppendChar('#');
- buffer->AppendBase64(pagecount, 1);
- pageframe_list_length += 2;
- }
- if (last_address < page_address - 1 + page_size)
- buffer->AppendChar('>');
- // Begins a new line every 94 characters.
- if (pageframe_list_length > 94) {
- buffer->AppendChar('\n');
- pageframe_list_length = 0;
- }
- }
-
- if (state.is_committed) {
- // Calculate the size of the allocation part in this page.
- size_t bytes = page_size;
-
- // If looking at the last page in a given region.
- if (last_address <= page_address - 1 + page_size) {
- bytes = last_address - page_address + 1;
- }
-
- // If looking at the first page in a given region.
- if (page_address < first_address) {
- bytes -= first_address - page_address;
- }
-
- committed_size += bytes;
- }
- if (page_address > MAX_ADDRESS - page_size) {
- break;
- }
- page_address += page_size;
- }
-
- if (pageframe_type_ != DUMP_NO_PAGEFRAME &&
- buffer != NULL && pageframe_list_length != 0) {
- buffer->AppendChar('\n');
- }
-
- return committed_size;
-}
-
-uint64 DeepHeapProfile::MemoryInfoGetterLinux::ReadPageCount(uint64 pfn) const {
- int64 index = pfn * KPAGECOUNT_BYTES;
- int64 offset = lseek64(kpagecount_fd_, index, SEEK_SET);
- RAW_DCHECK(offset == index, "Failed in seeking in kpagecount.");
-
- uint64 kpagecount_value;
- int result = read(kpagecount_fd_, &kpagecount_value, KPAGECOUNT_BYTES);
- if (result != KPAGECOUNT_BYTES)
- return 0;
-
- return kpagecount_value;
-}
-
-bool DeepHeapProfile::MemoryInfoGetterLinux::Seek(uint64 address) const {
- int64 index = (address / getpagesize()) * PAGEMAP_BYTES;
- RAW_DCHECK(pagemap_fd_ != -1, "Failed to seek in /proc/self/pagemap");
- int64 offset = lseek64(pagemap_fd_, index, SEEK_SET);
- RAW_DCHECK(offset == index, "Failed in seeking.");
- return offset >= 0;
-}
-
-bool DeepHeapProfile::MemoryInfoGetterLinux::Read(
- State* state, bool get_pfn) const {
- static const uint64 U64_1 = 1;
- static const uint64 PFN_FILTER = (U64_1 << 55) - U64_1;
- static const uint64 PAGE_PRESENT = U64_1 << 63;
- static const uint64 PAGE_SWAP = U64_1 << 62;
- static const uint64 PAGE_RESERVED = U64_1 << 61;
- static const uint64 FLAG_NOPAGE = U64_1 << 20;
- static const uint64 FLAG_KSM = U64_1 << 21;
- static const uint64 FLAG_MMAP = U64_1 << 11;
-
- uint64 pagemap_value;
- RAW_DCHECK(pagemap_fd_ != -1, "Failed to read from /proc/self/pagemap");
- int result = read(pagemap_fd_, &pagemap_value, PAGEMAP_BYTES);
- if (result != PAGEMAP_BYTES) {
- return false;
- }
-
- // Check if the page is committed.
- state->is_committed = (pagemap_value & (PAGE_PRESENT | PAGE_SWAP));
-
- state->is_present = (pagemap_value & PAGE_PRESENT);
- state->is_swapped = (pagemap_value & PAGE_SWAP);
- state->is_shared = false;
-
- if (get_pfn && state->is_present && !state->is_swapped)
- state->pfn = (pagemap_value & PFN_FILTER);
- else
- state->pfn = 0;
-
- return true;
-}
-
-bool DeepHeapProfile::MemoryInfoGetterLinux::IsPageCountAvailable() const {
- return kpagecount_fd_ != -1;
-}
-
-#endif // defined(__linux__)
-
-DeepHeapProfile::MemoryResidenceInfoGetterInterface::
- MemoryResidenceInfoGetterInterface() {}
-
-DeepHeapProfile::MemoryResidenceInfoGetterInterface::
- ~MemoryResidenceInfoGetterInterface() {}
-
-DeepHeapProfile::MemoryResidenceInfoGetterInterface*
- DeepHeapProfile::MemoryResidenceInfoGetterInterface::Create(
- PageFrameType pageframe_type) {
-#if defined(_WIN32) || defined(_WIN64)
- return new MemoryInfoGetterWindows(pageframe_type);
-#elif defined(__linux__)
- return new MemoryInfoGetterLinux(pageframe_type);
-#else
- return NULL;
-#endif
-}
-
-DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile,
- const char* prefix,
- enum PageFrameType pageframe_type)
- : memory_residence_info_getter_(
- MemoryResidenceInfoGetterInterface::Create(pageframe_type)),
- most_recent_pid_(-1),
- stats_(),
- dump_count_(0),
- filename_prefix_(NULL),
- deep_table_(kHashTableSize, heap_profile->alloc_, heap_profile->dealloc_),
- pageframe_type_(pageframe_type),
- heap_profile_(heap_profile) {
- // Copy filename prefix.
- const int prefix_length = strlen(prefix);
- filename_prefix_ =
- reinterpret_cast<char*>(heap_profile_->alloc_(prefix_length + 1));
- memcpy(filename_prefix_, prefix, prefix_length);
- filename_prefix_[prefix_length] = '\0';
-
- strncpy(run_id_, "undetermined-run-id", sizeof(run_id_));
-}
-
-DeepHeapProfile::~DeepHeapProfile() {
- heap_profile_->dealloc_(filename_prefix_);
- delete memory_residence_info_getter_;
-}
-
-// Global malloc() should not be used in this function.
-// Use LowLevelAlloc if required.
-void DeepHeapProfile::DumpOrderedProfile(const char* reason,
- char raw_buffer[],
- int buffer_size,
- RawFD fd) {
- TextBuffer buffer(raw_buffer, buffer_size, fd);
-
-#ifndef NDEBUG
- int64 starting_cycles = CycleClock::Now();
-#endif
-
- // Get the time before starting snapshot.
- // TODO(dmikurube): Consider gettimeofday if available.
- time_t time_value = time(NULL);
-
- ++dump_count_;
-
- // Re-open files in /proc/pid/ if the process is newly forked one.
- if (most_recent_pid_ != getpid()) {
- char hostname[64];
- if (0 == gethostname(hostname, sizeof(hostname))) {
- char* dot = strchr(hostname, '.');
- if (dot != NULL)
- *dot = '\0';
- } else {
- strcpy(hostname, "unknown");
- }
-
- most_recent_pid_ = getpid();
-
- snprintf(run_id_, sizeof(run_id_), "%s-" OS_NAME "-%d-%lu",
- hostname, most_recent_pid_, time(NULL));
-
- if (memory_residence_info_getter_)
- memory_residence_info_getter_->Initialize();
- deep_table_.ResetIsLogged();
-
- // Write maps into "|filename_prefix_|.<pid>.maps".
- WriteProcMaps(filename_prefix_, raw_buffer, buffer_size);
- }
-
- // Reset committed sizes of buckets.
- deep_table_.ResetCommittedSize();
-
- // Record committed sizes.
- stats_.SnapshotAllocations(this);
-
- // TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
- // glibc's snprintf internally allocates memory by alloca normally, but it
- // allocates memory by malloc if large memory is required.
-
- buffer.AppendString(kProfileHeader, 0);
- buffer.AppendString(kProfileVersion, 0);
- buffer.AppendString("\n", 0);
-
- // Fill buffer with meta information.
- buffer.AppendString(kMetaInformationHeader, 0);
-
- buffer.AppendString("Time: ", 0);
- buffer.AppendUnsignedLong(time_value, 0);
- buffer.AppendChar('\n');
-
- if (reason != NULL) {
- buffer.AppendString("Reason: ", 0);
- buffer.AppendString(reason, 0);
- buffer.AppendChar('\n');
- }
-
- AppendCommandLine(&buffer);
-
- buffer.AppendString("RunID: ", 0);
- buffer.AppendString(run_id_, 0);
- buffer.AppendChar('\n');
-
- buffer.AppendString("PageSize: ", 0);
- buffer.AppendInt(getpagesize(), 0, 0);
- buffer.AppendChar('\n');
-
- // Assumes the physical memory <= 64GB (PFN < 2^24).
- if (pageframe_type_ == DUMP_PAGECOUNT && memory_residence_info_getter_ &&
- memory_residence_info_getter_->IsPageCountAvailable()) {
- buffer.AppendString("PageFrame: 24,Base64,PageCount", 0);
- buffer.AppendChar('\n');
- } else if (pageframe_type_ != DUMP_NO_PAGEFRAME) {
- buffer.AppendString("PageFrame: 24,Base64", 0);
- buffer.AppendChar('\n');
- }
-
- // Fill buffer with the global stats.
- buffer.AppendString(kMMapListHeader, 0);
-
- stats_.SnapshotMaps(memory_residence_info_getter_, this, &buffer);
-
- // Fill buffer with the global stats.
- buffer.AppendString(kGlobalStatsHeader, 0);
-
- stats_.Unparse(&buffer);
-
- buffer.AppendString(kStacktraceHeader, 0);
- buffer.AppendString(kVirtualLabel, 10);
- buffer.AppendChar(' ');
- buffer.AppendString(kCommittedLabel, 10);
- buffer.AppendString("\n", 0);
-
- // Fill buffer.
- deep_table_.UnparseForStats(&buffer);
-
- buffer.Flush();
-
- // Write the bucket listing into a .bucket file.
- deep_table_.WriteForBucketFile(
- filename_prefix_, dump_count_, raw_buffer, buffer_size);
-
-#ifndef NDEBUG
- int64 elapsed_cycles = CycleClock::Now() - starting_cycles;
- double elapsed_seconds = elapsed_cycles / CyclesPerSecond();
- RAW_VLOG(0, "Time spent on DeepProfiler: %.3f sec\n", elapsed_seconds);
-#endif
-}
-
-int DeepHeapProfile::TextBuffer::Size() {
- return size_;
-}
-
-int DeepHeapProfile::TextBuffer::FilledBytes() {
- return cursor_;
-}
-
-void DeepHeapProfile::TextBuffer::Clear() {
- cursor_ = 0;
-}
-
-void DeepHeapProfile::TextBuffer::Flush() {
- RawWrite(fd_, buffer_, cursor_);
- cursor_ = 0;
-}
-
-// TODO(dmikurube): These Append* functions should not use snprintf.
-bool DeepHeapProfile::TextBuffer::AppendChar(char value) {
- return ForwardCursor(snprintf(buffer_ + cursor_, size_ - cursor_,
- "%c", value));
-}
-
-bool DeepHeapProfile::TextBuffer::AppendString(const char* value, int width) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%s", value);
- else
- appended = snprintf(position, available, "%*s",
- width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendInt(int value, int width,
- bool leading_zero) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%d", value);
- else if (leading_zero)
- appended = snprintf(position, available, "%0*d", width, value);
- else
- appended = snprintf(position, available, "%*d", width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendLong(long value, int width) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%ld", value);
- else
- appended = snprintf(position, available, "%*ld", width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendUnsignedLong(unsigned long value,
- int width) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%lu", value);
- else
- appended = snprintf(position, available, "%*lu", width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendInt64(int64 value, int width) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%" PRId64, value);
- else
- appended = snprintf(position, available, "%*" PRId64, width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendPtr(uint64 value, int width) {
- char* position = buffer_ + cursor_;
- int available = size_ - cursor_;
- int appended;
- if (width == 0)
- appended = snprintf(position, available, "%" PRIx64, value);
- else
- appended = snprintf(position, available, "%0*" PRIx64, width, value);
- return ForwardCursor(appended);
-}
-
-bool DeepHeapProfile::TextBuffer::AppendBase64(uint64 value, int width) {
- static const char base64[65] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#if defined(__BIG_ENDIAN__)
- value = bswap_64(value);
-#endif
- for (int shift = (width - 1) * 6; shift >= 0; shift -= 6) {
- if (!AppendChar(base64[(value >> shift) & 0x3f]))
- return false;
- }
- return true;
-}
-
-bool DeepHeapProfile::TextBuffer::ForwardCursor(int appended) {
- if (appended < 0 || appended >= size_ - cursor_)
- return false;
- cursor_ += appended;
- if (cursor_ > size_ * 4 / 5)
- Flush();
- return true;
-}
-
-void DeepHeapProfile::DeepBucket::UnparseForStats(TextBuffer* buffer) {
- buffer->AppendInt64(bucket->alloc_size - bucket->free_size, 10);
- buffer->AppendChar(' ');
- buffer->AppendInt64(committed_size, 10);
- buffer->AppendChar(' ');
- buffer->AppendInt(bucket->allocs, 6, false);
- buffer->AppendChar(' ');
- buffer->AppendInt(bucket->frees, 6, false);
- buffer->AppendString(" @ ", 0);
- buffer->AppendInt(id, 0, false);
- buffer->AppendString("\n", 0);
-}
-
-void DeepHeapProfile::DeepBucket::UnparseForBucketFile(TextBuffer* buffer) {
- buffer->AppendInt(id, 0, false);
- buffer->AppendChar(' ');
- buffer->AppendString(is_mmap ? "mmap" : "malloc", 0);
-
-#if defined(TYPE_PROFILING)
- buffer->AppendString(" t0x", 0);
- buffer->AppendPtr(reinterpret_cast<uintptr_t>(type), 0);
- if (type == NULL) {
- buffer->AppendString(" nno_typeinfo", 0);
- } else {
- buffer->AppendString(" n", 0);
- buffer->AppendString(type->name(), 0);
- }
-#endif
-
- for (int depth = 0; depth < bucket->depth; depth++) {
- buffer->AppendString(" 0x", 0);
- buffer->AppendPtr(reinterpret_cast<uintptr_t>(bucket->stack[depth]), 8);
- }
- buffer->AppendString("\n", 0);
-}
-
-DeepHeapProfile::DeepBucketTable::DeepBucketTable(
- int table_size,
- HeapProfileTable::Allocator alloc,
- HeapProfileTable::DeAllocator dealloc)
- : table_(NULL),
- table_size_(table_size),
- alloc_(alloc),
- dealloc_(dealloc),
- bucket_id_(0) {
- const int bytes = table_size * sizeof(DeepBucket*);
- table_ = reinterpret_cast<DeepBucket**>(alloc(bytes));
- memset(table_, 0, bytes);
-}
-
-DeepHeapProfile::DeepBucketTable::~DeepBucketTable() {
- ASSERT(table_ != NULL);
- for (int db = 0; db < table_size_; db++) {
- for (DeepBucket* x = table_[db]; x != 0; /**/) {
- DeepBucket* db = x;
- x = x->next;
- dealloc_(db);
- }
- }
- dealloc_(table_);
-}
-
-DeepHeapProfile::DeepBucket* DeepHeapProfile::DeepBucketTable::Lookup(
- Bucket* bucket,
-#if defined(TYPE_PROFILING)
- const std::type_info* type,
-#endif
- bool is_mmap) {
- // Make hash-value
- uintptr_t h = 0;
-
- AddToHashValue(reinterpret_cast<uintptr_t>(bucket), &h);
- if (is_mmap) {
- AddToHashValue(1, &h);
- } else {
- AddToHashValue(0, &h);
- }
-
-#if defined(TYPE_PROFILING)
- if (type == NULL) {
- AddToHashValue(0, &h);
- } else {
- AddToHashValue(reinterpret_cast<uintptr_t>(type->name()), &h);
- }
-#endif
-
- FinishHashValue(&h);
-
- // Lookup stack trace in table
- unsigned int buck = ((unsigned int) h) % table_size_;
- for (DeepBucket* db = table_[buck]; db != 0; db = db->next) {
- if (db->bucket == bucket) {
- return db;
- }
- }
-
- // Create a new bucket
- DeepBucket* db = reinterpret_cast<DeepBucket*>(alloc_(sizeof(DeepBucket)));
- memset(db, 0, sizeof(*db));
- db->bucket = bucket;
-#if defined(TYPE_PROFILING)
- db->type = type;
-#endif
- db->committed_size = 0;
- db->is_mmap = is_mmap;
- db->id = (bucket_id_++);
- db->is_logged = false;
- db->next = table_[buck];
- table_[buck] = db;
- return db;
-}
-
-// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
-void DeepHeapProfile::DeepBucketTable::UnparseForStats(TextBuffer* buffer) {
- for (int i = 0; i < table_size_; i++) {
- for (DeepBucket* deep_bucket = table_[i];
- deep_bucket != NULL;
- deep_bucket = deep_bucket->next) {
- Bucket* bucket = deep_bucket->bucket;
- if (bucket->alloc_size - bucket->free_size == 0) {
- continue; // Skip empty buckets.
- }
- deep_bucket->UnparseForStats(buffer);
- }
- }
-}
-
-void DeepHeapProfile::DeepBucketTable::WriteForBucketFile(
- const char* prefix, int dump_count, char raw_buffer[], int buffer_size) {
- char filename[100];
- snprintf(filename, sizeof(filename),
- "%s.%05d.%04d.buckets", prefix, getpid(), dump_count);
- RawFD fd = RawOpenForWriting(filename);
- RAW_DCHECK(fd != kIllegalRawFD, "");
-
- TextBuffer buffer(raw_buffer, buffer_size, fd);
-
- for (int i = 0; i < table_size_; i++) {
- for (DeepBucket* deep_bucket = table_[i];
- deep_bucket != NULL;
- deep_bucket = deep_bucket->next) {
- Bucket* bucket = deep_bucket->bucket;
- if (deep_bucket->is_logged) {
- continue; // Skip the bucket if it is already logged.
- }
- if (!deep_bucket->is_mmap &&
- bucket->alloc_size - bucket->free_size <= 64) {
- continue; // Skip small malloc buckets.
- }
-
- deep_bucket->UnparseForBucketFile(&buffer);
- deep_bucket->is_logged = true;
- }
- }
-
- buffer.Flush();
- RawClose(fd);
-}
-
-void DeepHeapProfile::DeepBucketTable::ResetCommittedSize() {
- for (int i = 0; i < table_size_; i++) {
- for (DeepBucket* deep_bucket = table_[i];
- deep_bucket != NULL;
- deep_bucket = deep_bucket->next) {
- deep_bucket->committed_size = 0;
- }
- }
-}
-
-void DeepHeapProfile::DeepBucketTable::ResetIsLogged() {
- for (int i = 0; i < table_size_; i++) {
- for (DeepBucket* deep_bucket = table_[i];
- deep_bucket != NULL;
- deep_bucket = deep_bucket->next) {
- deep_bucket->is_logged = false;
- }
- }
-}
-
-// This hash function is from HeapProfileTable::GetBucket.
-// static
-void DeepHeapProfile::DeepBucketTable::AddToHashValue(
- uintptr_t add, uintptr_t* hash_value) {
- *hash_value += add;
- *hash_value += *hash_value << 10;
- *hash_value ^= *hash_value >> 6;
-}
-
-// This hash function is from HeapProfileTable::GetBucket.
-// static
-void DeepHeapProfile::DeepBucketTable::FinishHashValue(uintptr_t* hash_value) {
- *hash_value += *hash_value << 3;
- *hash_value ^= *hash_value >> 11;
-}
-
-void DeepHeapProfile::RegionStats::Initialize() {
- virtual_bytes_ = 0;
- committed_bytes_ = 0;
-}
-
-uint64 DeepHeapProfile::RegionStats::Record(
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer) {
- uint64 committed = 0;
- virtual_bytes_ += static_cast<size_t>(last_address - first_address + 1);
- if (memory_residence_info_getter)
- committed = memory_residence_info_getter->CommittedSize(first_address,
- last_address,
- buffer);
- committed_bytes_ += committed;
- return committed;
-}
-
-void DeepHeapProfile::RegionStats::Unparse(const char* name,
- TextBuffer* buffer) {
- buffer->AppendString(name, 25);
- buffer->AppendChar(' ');
- buffer->AppendLong(virtual_bytes_, 12);
- buffer->AppendChar(' ');
- buffer->AppendLong(committed_bytes_, 12);
- buffer->AppendString("\n", 0);
-}
-
-// Snapshots all virtual memory mapping stats by merging mmap(2) records from
-// MemoryRegionMap and /proc/maps, the OS-level memory mapping information.
-// Memory regions described in /proc/maps, but which are not created by mmap,
-// are accounted as "unhooked" memory regions.
-//
-// This function assumes that every memory region created by mmap is covered
-// by VMA(s) described in /proc/maps except for http://crbug.com/189114.
-// Note that memory regions created with mmap don't align with borders of VMAs
-// in /proc/maps. In other words, a memory region by mmap can cut across many
-// VMAs. Also, of course a VMA can include many memory regions by mmap.
-// It means that the following situation happens:
-//
-// => Virtual address
-// <----- VMA #1 -----><----- VMA #2 ----->...<----- VMA #3 -----><- VMA #4 ->
-// ..< mmap #1 >.<- mmap #2 -><- mmap #3 ->...<- mmap #4 ->..<-- mmap #5 -->..
-//
-// It can happen easily as permission can be changed by mprotect(2) for a part
-// of a memory region. A change in permission splits VMA(s).
-//
-// To deal with the situation, this function iterates over MemoryRegionMap and
-// /proc/maps independently. The iterator for MemoryRegionMap is initialized
-// at the top outside the loop for /proc/maps, and it goes forward inside the
-// loop while comparing their addresses.
-//
-// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
-void DeepHeapProfile::GlobalStats::SnapshotMaps(
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- DeepHeapProfile* deep_profile,
- TextBuffer* mmap_dump_buffer) {
- MemoryRegionMap::LockHolder lock_holder;
- ProcMapsIterator::Buffer procmaps_iter_buffer;
- ProcMapsIterator procmaps_iter(0, &procmaps_iter_buffer);
- uint64 vma_start_addr, vma_last_addr, offset;
- int64 inode;
- char* flags;
- char* filename;
- enum MapsRegionType type;
-
- for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) {
- all_[i].Initialize();
- unhooked_[i].Initialize();
- }
- profiled_mmap_.Initialize();
-
- MemoryRegionMap::RegionIterator mmap_iter =
- MemoryRegionMap::BeginRegionLocked();
- DeepBucket* deep_bucket = NULL;
- if (mmap_iter != MemoryRegionMap::EndRegionLocked()) {
- deep_bucket = GetInformationOfMemoryRegion(
- mmap_iter, memory_residence_info_getter, deep_profile);
- }
-
- while (procmaps_iter.Next(&vma_start_addr, &vma_last_addr,
- &flags, &offset, &inode, &filename)) {
- if (mmap_dump_buffer) {
- char buffer[1024];
- int written = procmaps_iter.FormatLine(buffer, sizeof(buffer),
- vma_start_addr, vma_last_addr,
- flags, offset, inode, filename, 0);
- mmap_dump_buffer->AppendString(buffer, 0);
- }
-
- // 'vma_last_addr' should be the last inclusive address of the region.
- vma_last_addr -= 1;
- if (strcmp("[vsyscall]", filename) == 0) {
- continue; // Reading pagemap will fail in [vsyscall].
- }
-
- // TODO(dmikurube): |type| will be deprecated in the dump.
- // See http://crbug.com/245603.
- type = ABSENT;
- if (filename[0] == '/') {
- if (flags[2] == 'x')
- type = FILE_EXEC;
- else
- type = FILE_NONEXEC;
- } else if (filename[0] == '\0' || filename[0] == '\n') {
- type = ANONYMOUS;
- } else if (strcmp(filename, "[stack]") == 0) {
- type = STACK;
- } else {
- type = OTHER;
- }
- // TODO(dmikurube): This |all_| count should be removed in future soon.
- // See http://crbug.com/245603.
- uint64 vma_total = all_[type].Record(
- memory_residence_info_getter, vma_start_addr, vma_last_addr, NULL);
- uint64 vma_subtotal = 0;
-
- // TODO(dmikurube): Stop double-counting pagemap.
- // It will be fixed when http://crbug.com/245603 finishes.
- if (MemoryRegionMap::IsRecordingLocked()) {
- uint64 cursor = vma_start_addr;
- bool first = true;
-
- // Iterates over MemoryRegionMap until the iterator moves out of the VMA.
- do {
- if (!first) {
- cursor = mmap_iter->end_addr;
- ++mmap_iter;
- // Don't break here even if mmap_iter == EndRegionLocked().
-
- if (mmap_iter != MemoryRegionMap::EndRegionLocked()) {
- deep_bucket = GetInformationOfMemoryRegion(
- mmap_iter, memory_residence_info_getter, deep_profile);
- }
- }
- first = false;
-
- uint64 last_address_of_unhooked;
- // If the next mmap entry is away from the current VMA.
- if (mmap_iter == MemoryRegionMap::EndRegionLocked() ||
- mmap_iter->start_addr > vma_last_addr) {
- last_address_of_unhooked = vma_last_addr;
- } else {
- last_address_of_unhooked = mmap_iter->start_addr - 1;
- }
-
- if (last_address_of_unhooked + 1 > cursor) {
- RAW_CHECK(cursor >= vma_start_addr,
- "Wrong calculation for unhooked");
- RAW_CHECK(last_address_of_unhooked <= vma_last_addr,
- "Wrong calculation for unhooked");
- uint64 committed_size = unhooked_[type].Record(
- memory_residence_info_getter,
- cursor,
- last_address_of_unhooked,
- mmap_dump_buffer);
- vma_subtotal += committed_size;
- if (mmap_dump_buffer) {
- mmap_dump_buffer->AppendString(" ", 0);
- mmap_dump_buffer->AppendPtr(cursor, 0);
- mmap_dump_buffer->AppendString(" - ", 0);
- mmap_dump_buffer->AppendPtr(last_address_of_unhooked + 1, 0);
- mmap_dump_buffer->AppendString(" unhooked ", 0);
- mmap_dump_buffer->AppendInt64(committed_size, 0);
- mmap_dump_buffer->AppendString(" / ", 0);
- mmap_dump_buffer->AppendInt64(
- last_address_of_unhooked - cursor + 1, 0);
- mmap_dump_buffer->AppendString("\n", 0);
- }
- cursor = last_address_of_unhooked + 1;
- }
-
- if (mmap_iter != MemoryRegionMap::EndRegionLocked() &&
- mmap_iter->start_addr <= vma_last_addr &&
- mmap_dump_buffer) {
- bool trailing = mmap_iter->start_addr < vma_start_addr;
- bool continued = mmap_iter->end_addr - 1 > vma_last_addr;
- uint64 partial_first_address, partial_last_address;
- if (trailing)
- partial_first_address = vma_start_addr;
- else
- partial_first_address = mmap_iter->start_addr;
- if (continued)
- partial_last_address = vma_last_addr;
- else
- partial_last_address = mmap_iter->end_addr - 1;
- uint64 committed_size = 0;
- if (memory_residence_info_getter)
- committed_size = memory_residence_info_getter->CommittedSize(
- partial_first_address, partial_last_address, mmap_dump_buffer);
- vma_subtotal += committed_size;
- mmap_dump_buffer->AppendString(trailing ? " (" : " ", 0);
- mmap_dump_buffer->AppendPtr(mmap_iter->start_addr, 0);
- mmap_dump_buffer->AppendString(trailing ? ")" : " ", 0);
- mmap_dump_buffer->AppendString("-", 0);
- mmap_dump_buffer->AppendString(continued ? "(" : " ", 0);
- mmap_dump_buffer->AppendPtr(mmap_iter->end_addr, 0);
- mmap_dump_buffer->AppendString(continued ? ")" : " ", 0);
- mmap_dump_buffer->AppendString(" hooked ", 0);
- mmap_dump_buffer->AppendInt64(committed_size, 0);
- mmap_dump_buffer->AppendString(" / ", 0);
- mmap_dump_buffer->AppendInt64(
- partial_last_address - partial_first_address + 1, 0);
- mmap_dump_buffer->AppendString(" @ ", 0);
- if (deep_bucket != NULL) {
- mmap_dump_buffer->AppendInt(deep_bucket->id, 0, false);
- } else {
- mmap_dump_buffer->AppendInt(0, 0, false);
- }
- mmap_dump_buffer->AppendString("\n", 0);
- }
- } while (mmap_iter != MemoryRegionMap::EndRegionLocked() &&
- mmap_iter->end_addr - 1 <= vma_last_addr);
- }
-
- if (vma_total != vma_subtotal) {
- char buffer[1024];
- int written = procmaps_iter.FormatLine(buffer, sizeof(buffer),
- vma_start_addr, vma_last_addr,
- flags, offset, inode, filename, 0);
- RAW_VLOG(0, "[%d] Mismatched total in VMA %" PRId64 ":"
- "%" PRId64 " (%" PRId64 ")",
- getpid(), vma_total, vma_subtotal, vma_total - vma_subtotal);
- RAW_VLOG(0, "[%d] in %s", getpid(), buffer);
- }
- }
-
- // TODO(dmikurube): Investigate and fix http://crbug.com/189114.
- //
- // The total committed memory usage in all_ (from /proc/<pid>/maps) is
- // sometimes smaller than the sum of the committed mmap'ed addresses and
- // unhooked regions. Within our observation, the difference was only 4KB
- // in committed usage, zero in reserved virtual addresses
- //
- // A guess is that an uncommitted (but reserved) page may become committed
- // during counting memory usage in the loop above.
- //
- // The difference is accounted as "ABSENT" to investigate such cases.
- //
- // It will be fixed when http://crbug.com/245603 finishes (no double count).
-
- RegionStats all_total;
- RegionStats unhooked_total;
- for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) {
- all_total.AddAnotherRegionStat(all_[i]);
- unhooked_total.AddAnotherRegionStat(unhooked_[i]);
- }
-
- size_t absent_virtual = profiled_mmap_.virtual_bytes() +
- unhooked_total.virtual_bytes() -
- all_total.virtual_bytes();
- if (absent_virtual > 0)
- all_[ABSENT].AddToVirtualBytes(absent_virtual);
-
- size_t absent_committed = profiled_mmap_.committed_bytes() +
- unhooked_total.committed_bytes() -
- all_total.committed_bytes();
- if (absent_committed > 0)
- all_[ABSENT].AddToCommittedBytes(absent_committed);
-}
-
-void DeepHeapProfile::GlobalStats::SnapshotAllocations(
- DeepHeapProfile* deep_profile) {
- profiled_malloc_.Initialize();
-
- deep_profile->heap_profile_->address_map_->Iterate(RecordAlloc, deep_profile);
-}
-
-void DeepHeapProfile::GlobalStats::Unparse(TextBuffer* buffer) {
- RegionStats all_total;
- RegionStats unhooked_total;
- for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) {
- all_total.AddAnotherRegionStat(all_[i]);
- unhooked_total.AddAnotherRegionStat(unhooked_[i]);
- }
-
- // "# total (%lu) %c= profiled-mmap (%lu) + nonprofiled-* (%lu)\n"
- buffer->AppendString("# total (", 0);
- buffer->AppendUnsignedLong(all_total.committed_bytes(), 0);
- buffer->AppendString(") ", 0);
- buffer->AppendChar(all_total.committed_bytes() ==
- profiled_mmap_.committed_bytes() +
- unhooked_total.committed_bytes() ? '=' : '!');
- buffer->AppendString("= profiled-mmap (", 0);
- buffer->AppendUnsignedLong(profiled_mmap_.committed_bytes(), 0);
- buffer->AppendString(") + nonprofiled-* (", 0);
- buffer->AppendUnsignedLong(unhooked_total.committed_bytes(), 0);
- buffer->AppendString(")\n", 0);
-
- // " virtual committed"
- buffer->AppendString("", 26);
- buffer->AppendString(kVirtualLabel, 12);
- buffer->AppendChar(' ');
- buffer->AppendString(kCommittedLabel, 12);
- buffer->AppendString("\n", 0);
-
- all_total.Unparse("total", buffer);
- all_[ABSENT].Unparse("absent", buffer);
- all_[FILE_EXEC].Unparse("file-exec", buffer);
- all_[FILE_NONEXEC].Unparse("file-nonexec", buffer);
- all_[ANONYMOUS].Unparse("anonymous", buffer);
- all_[STACK].Unparse("stack", buffer);
- all_[OTHER].Unparse("other", buffer);
- unhooked_total.Unparse("nonprofiled-total", buffer);
- unhooked_[ABSENT].Unparse("nonprofiled-absent", buffer);
- unhooked_[ANONYMOUS].Unparse("nonprofiled-anonymous", buffer);
- unhooked_[FILE_EXEC].Unparse("nonprofiled-file-exec", buffer);
- unhooked_[FILE_NONEXEC].Unparse("nonprofiled-file-nonexec", buffer);
- unhooked_[STACK].Unparse("nonprofiled-stack", buffer);
- unhooked_[OTHER].Unparse("nonprofiled-other", buffer);
- profiled_mmap_.Unparse("profiled-mmap", buffer);
- profiled_malloc_.Unparse("profiled-malloc", buffer);
-}
-
-// static
-void DeepHeapProfile::GlobalStats::RecordAlloc(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile) {
- uint64 address = reinterpret_cast<uintptr_t>(pointer);
- size_t committed = deep_profile->memory_residence_info_getter_->CommittedSize(
- address, address + alloc_value->bytes - 1, NULL);
-
- DeepBucket* deep_bucket = deep_profile->deep_table_.Lookup(
- alloc_value->bucket(),
-#if defined(TYPE_PROFILING)
- LookupType(pointer),
-#endif
- /* is_mmap */ false);
- deep_bucket->committed_size += committed;
- deep_profile->stats_.profiled_malloc_.AddToVirtualBytes(alloc_value->bytes);
- deep_profile->stats_.profiled_malloc_.AddToCommittedBytes(committed);
-}
-
-DeepHeapProfile::DeepBucket*
- DeepHeapProfile::GlobalStats::GetInformationOfMemoryRegion(
- const MemoryRegionMap::RegionIterator& mmap_iter,
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- DeepHeapProfile* deep_profile) {
- size_t committed = deep_profile->memory_residence_info_getter_->
- CommittedSize(mmap_iter->start_addr, mmap_iter->end_addr - 1, NULL);
-
- // TODO(dmikurube): Store a reference to the bucket in region.
- Bucket* bucket = MemoryRegionMap::GetBucket(
- mmap_iter->call_stack_depth, mmap_iter->call_stack);
- DeepBucket* deep_bucket = NULL;
- if (bucket != NULL) {
- deep_bucket = deep_profile->deep_table_.Lookup(
- bucket,
-#if defined(TYPE_PROFILING)
- NULL, // No type information for memory regions by mmap.
-#endif
- /* is_mmap */ true);
- if (deep_bucket != NULL)
- deep_bucket->committed_size += committed;
- }
-
- profiled_mmap_.AddToVirtualBytes(
- mmap_iter->end_addr - mmap_iter->start_addr);
- profiled_mmap_.AddToCommittedBytes(committed);
-
- return deep_bucket;
-}
-
-// static
-void DeepHeapProfile::WriteProcMaps(const char* prefix,
- char raw_buffer[],
- int buffer_size) {
- char filename[100];
- snprintf(filename, sizeof(filename),
- "%s.%05d.maps", prefix, static_cast<int>(getpid()));
-
- RawFD fd = RawOpenForWriting(filename);
- RAW_DCHECK(fd != kIllegalRawFD, "");
-
- int length;
- bool wrote_all;
- length = tcmalloc::FillProcSelfMaps(raw_buffer, buffer_size, &wrote_all);
- RAW_DCHECK(wrote_all, "");
- RAW_DCHECK(length <= buffer_size, "");
- RawWrite(fd, raw_buffer, length);
- RawClose(fd);
-}
-#else // USE_DEEP_HEAP_PROFILE
-
-DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile,
- const char* prefix,
- enum PageFrameType pageframe_type)
- : heap_profile_(heap_profile) {
-}
-
-DeepHeapProfile::~DeepHeapProfile() {
-}
-
-void DeepHeapProfile::DumpOrderedProfile(const char* reason,
- char raw_buffer[],
- int buffer_size,
- RawFD fd) {
-}
-
-#endif // USE_DEEP_HEAP_PROFILE
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h
deleted file mode 100644
index 0544b31..0000000
--- a/third_party/tcmalloc/chromium/src/deep-heap-profile.h
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ---
-// Author: Sainbayar Sukhbaatar
-// Dai Mikurube
-//
-// This file contains a class DeepHeapProfile and its public function
-// DeepHeapProfile::DumpOrderedProfile(). The function works like
-// HeapProfileTable::FillOrderedProfile(), but dumps directory to files.
-//
-// DeepHeapProfile::DumpOrderedProfile() dumps more detailed information about
-// heap usage, which includes OS-level information such as memory residency and
-// type information if the type profiler is available.
-//
-// DeepHeapProfile::DumpOrderedProfile() uses data stored in HeapProfileTable.
-// Any code in DeepHeapProfile runs only when DumpOrderedProfile() is called.
-// It has overhead in dumping, but no overhead in logging.
-//
-// It currently works only on Linux including Android. It does nothing in
-// non-Linux environments.
-
-// Note that uint64 is used to represent addresses instead of uintptr_t, and
-// int is used to represent buffer sizes instead of size_t.
-// It's for consistency with other TCMalloc functions. ProcMapsIterator uses
-// uint64 for addresses, and HeapProfileTable::DumpOrderedProfile uses int
-// for buffer sizes.
-
-#ifndef BASE_DEEP_HEAP_PROFILE_H_
-#define BASE_DEEP_HEAP_PROFILE_H_
-
-#include "config.h"
-
-#if defined(TYPE_PROFILING)
-#include <typeinfo>
-#endif
-
-#if defined(__linux__) || defined(_WIN32) || defined(_WIN64)
-#define USE_DEEP_HEAP_PROFILE 1
-#endif
-
-#include "addressmap-inl.h"
-#include "heap-profile-table.h"
-#include "memory_region_map.h"
-
-class DeepHeapProfile {
- public:
- enum PageFrameType {
- DUMP_NO_PAGEFRAME = 0, // Dumps nothing about pageframes
- DUMP_PFN = 1, // Dumps only pageframe numbers (PFNs)
- DUMP_PAGECOUNT = 2, // Dumps PFNs and pagecounts
- };
-
- // Constructs a DeepHeapProfile instance. It works as a wrapper of
- // HeapProfileTable.
- //
- // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads
- // data in |heap_profile| and forwards operations to |heap_profile| if
- // DeepHeapProfile is not available (non-Linux).
- // |prefix| is a prefix of dumped file names.
- // |pageframe_type| means what information is dumped for pageframes.
- DeepHeapProfile(HeapProfileTable* heap_profile,
- const char* prefix,
- enum PageFrameType pageframe_type);
- ~DeepHeapProfile();
-
- // Dumps a deep profile into |fd| with using |raw_buffer| of |buffer_size|.
- //
- // In addition, a list of buckets is dumped into a ".buckets" file in
- // descending order of allocated bytes.
- void DumpOrderedProfile(const char* reason,
- char raw_buffer[],
- int buffer_size,
- RawFD fd);
-
- private:
-#ifdef USE_DEEP_HEAP_PROFILE
- typedef HeapProfileTable::Stats Stats;
- typedef HeapProfileTable::Bucket Bucket;
- typedef HeapProfileTable::AllocValue AllocValue;
- typedef HeapProfileTable::AllocationMap AllocationMap;
-
- enum MapsRegionType {
- // Bytes of memory which were not recognized with /proc/<pid>/maps.
- // This size should be 0.
- ABSENT,
-
- // Bytes of memory which is mapped anonymously.
- // Regions which contain nothing in the last column of /proc/<pid>/maps.
- ANONYMOUS,
-
- // Bytes of memory which is mapped to a executable/non-executable file.
- // Regions which contain file paths in the last column of /proc/<pid>/maps.
- FILE_EXEC,
- FILE_NONEXEC,
-
- // Bytes of memory which is labeled [stack] in /proc/<pid>/maps.
- STACK,
-
- // Bytes of memory which is labeled, but not mapped to any file.
- // Regions which contain non-path strings in the last column of
- // /proc/<pid>/maps.
- OTHER,
-
- NUMBER_OF_MAPS_REGION_TYPES
- };
-
- static const char* kMapsRegionTypeDict[NUMBER_OF_MAPS_REGION_TYPES];
-
- // Manages a buffer to keep a text to be dumped to a file.
- class TextBuffer {
- public:
- TextBuffer(char *raw_buffer, int size, RawFD fd)
- : buffer_(raw_buffer),
- size_(size),
- cursor_(0),
- fd_(fd) {
- }
-
- int Size();
- int FilledBytes();
- void Clear();
- void Flush();
-
- bool AppendChar(char value);
- bool AppendString(const char* value, int width);
- bool AppendInt(int value, int width, bool leading_zero);
- bool AppendLong(long value, int width);
- bool AppendUnsignedLong(unsigned long value, int width);
- bool AppendInt64(int64 value, int width);
- bool AppendBase64(uint64 value, int width);
- bool AppendPtr(uint64 value, int width);
-
- private:
- bool ForwardCursor(int appended);
-
- char *buffer_;
- int size_;
- int cursor_;
- RawFD fd_;
- DISALLOW_COPY_AND_ASSIGN(TextBuffer);
- };
-
- // Defines an interface for getting info about memory residence.
- class MemoryResidenceInfoGetterInterface {
- public:
- virtual ~MemoryResidenceInfoGetterInterface();
-
- // Initializes the instance.
- virtual void Initialize() = 0;
-
- // Returns the number of resident (including swapped) bytes of the given
- // memory region from |first_address| to |last_address| inclusive.
- virtual size_t CommittedSize(uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer) const = 0;
-
- // Creates a new platform specific MemoryResidenceInfoGetterInterface.
- static MemoryResidenceInfoGetterInterface* Create(
- PageFrameType pageframe_type);
-
- virtual bool IsPageCountAvailable() const = 0;
-
- protected:
- MemoryResidenceInfoGetterInterface();
- };
-
-#if defined(_WIN32) || defined(_WIN64)
- // TODO(peria): Implement this class.
- class MemoryInfoGetterWindows : public MemoryResidenceInfoGetterInterface {
- public:
- MemoryInfoGetterWindows(PageFrameType) {}
- virtual ~MemoryInfoGetterWindows() {}
-
- virtual void Initialize();
-
- virtual size_t CommittedSize(uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer) const;
-
- virtual bool IsPageCountAvailable() const;
- };
-#endif // defined(_WIN32) || defined(_WIN64)
-
-#if defined(__linux__)
- // Implements MemoryResidenceInfoGetterInterface for Linux.
- class MemoryInfoGetterLinux : public MemoryResidenceInfoGetterInterface {
- public:
- MemoryInfoGetterLinux(PageFrameType pageframe_type)
- : pageframe_type_(pageframe_type),
- pagemap_fd_(kIllegalRawFD),
- kpagecount_fd_(kIllegalRawFD) {}
- virtual ~MemoryInfoGetterLinux() {}
-
- // Opens /proc/<pid>/pagemap and stores its file descriptor.
- // It keeps open while the process is running.
- //
- // Note that file descriptors need to be refreshed after fork.
- virtual void Initialize();
-
- // Returns the number of resident (including swapped) bytes of the given
- // memory region from |first_address| to |last_address| inclusive.
- virtual size_t CommittedSize(uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer) const;
-
- virtual bool IsPageCountAvailable() const;
-
- private:
- struct State {
- uint64 pfn;
- bool is_committed; // Currently, we use only this
- bool is_present;
- bool is_swapped;
- bool is_shared;
- bool is_mmap;
- };
-
- uint64 ReadPageCount(uint64 pfn) const;
-
- // Seeks to the offset of the open pagemap file.
- // It returns true if succeeded.
- bool Seek(uint64 address) const;
-
- // Reads a pagemap state from the current offset.
- // It returns true if succeeded.
- bool Read(State* state, bool get_pfn) const;
-
- PageFrameType pageframe_type_;
- RawFD pagemap_fd_;
- RawFD kpagecount_fd_;
- };
-#endif // defined(__linux__)
-
- // Contains extended information for HeapProfileTable::Bucket. These objects
- // are managed in a hash table (DeepBucketTable) whose key is an address of
- // a Bucket and other additional information.
- struct DeepBucket {
- public:
- void UnparseForStats(TextBuffer* buffer);
- void UnparseForBucketFile(TextBuffer* buffer);
-
- Bucket* bucket;
-#if defined(TYPE_PROFILING)
- const std::type_info* type; // A type of the object
-#endif
- size_t committed_size; // A resident size of this bucket
- bool is_mmap; // True if the bucket represents a mmap region
- int id; // A unique ID of the bucket
- bool is_logged; // True if the stracktrace is logged to a file
- DeepBucket* next; // A reference to the next entry in the hash table
- };
-
- // Manages a hash table for DeepBucket.
- class DeepBucketTable {
- public:
- DeepBucketTable(int size,
- HeapProfileTable::Allocator alloc,
- HeapProfileTable::DeAllocator dealloc);
- ~DeepBucketTable();
-
- // Finds a DeepBucket instance corresponding to the given |bucket|, or
- // creates a new DeepBucket object if it doesn't exist.
- DeepBucket* Lookup(Bucket* bucket,
-#if defined(TYPE_PROFILING)
- const std::type_info* type,
-#endif
- bool is_mmap);
-
- // Writes stats of the hash table to |buffer| for DumpOrderedProfile.
- void UnparseForStats(TextBuffer* buffer);
-
- // Writes all buckets for a bucket file with using |buffer|.
- void WriteForBucketFile(const char* prefix,
- int dump_count,
- char raw_buffer[],
- int buffer_size);
-
- // Resets 'committed_size' members in DeepBucket objects.
- void ResetCommittedSize();
-
- // Resets all 'is_loggeed' flags in DeepBucket objects.
- void ResetIsLogged();
-
- private:
- // Adds |add| to a |hash_value| for Lookup.
- inline static void AddToHashValue(uintptr_t add, uintptr_t* hash_value);
- inline static void FinishHashValue(uintptr_t* hash_value);
-
- DeepBucket** table_;
- size_t table_size_;
- HeapProfileTable::Allocator alloc_;
- HeapProfileTable::DeAllocator dealloc_;
- int bucket_id_;
- };
-
- class RegionStats {
- public:
- RegionStats(): virtual_bytes_(0), committed_bytes_(0) {}
- ~RegionStats() {}
-
- // Initializes 'virtual_bytes_' and 'committed_bytes_'.
- void Initialize();
-
- // Updates itself to contain the tallies of 'virtual_bytes' and
- // 'committed_bytes' in the region from |first_adress| to |last_address|
- // inclusive.
- uint64 Record(
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- uint64 first_address,
- uint64 last_address,
- TextBuffer* buffer);
-
- // Writes stats of the region into |buffer| with |name|.
- void Unparse(const char* name, TextBuffer* buffer);
-
- size_t virtual_bytes() const { return virtual_bytes_; }
- size_t committed_bytes() const { return committed_bytes_; }
- void AddToVirtualBytes(size_t additional_virtual_bytes) {
- virtual_bytes_ += additional_virtual_bytes;
- }
- void AddToCommittedBytes(size_t additional_committed_bytes) {
- committed_bytes_ += additional_committed_bytes;
- }
- void AddAnotherRegionStat(const RegionStats& other) {
- virtual_bytes_ += other.virtual_bytes_;
- committed_bytes_ += other.committed_bytes_;
- }
-
- private:
- size_t virtual_bytes_;
- size_t committed_bytes_;
- DISALLOW_COPY_AND_ASSIGN(RegionStats);
- };
-
- class GlobalStats {
- public:
- // Snapshots and calculates global stats from /proc/<pid>/maps and pagemap.
- void SnapshotMaps(
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- DeepHeapProfile* deep_profile,
- TextBuffer* mmap_dump_buffer);
-
- // Snapshots allocations by malloc and mmap.
- void SnapshotAllocations(DeepHeapProfile* deep_profile);
-
- // Writes global stats into |buffer|.
- void Unparse(TextBuffer* buffer);
-
- private:
- // Records both virtual and committed byte counts of malloc and mmap regions
- // as callback functions for AllocationMap::Iterate().
- static void RecordAlloc(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile);
-
- DeepBucket* GetInformationOfMemoryRegion(
- const MemoryRegionMap::RegionIterator& mmap_iter,
- const MemoryResidenceInfoGetterInterface* memory_residence_info_getter,
- DeepHeapProfile* deep_profile);
-
- // All RegionStats members in this class contain the bytes of virtual
- // memory and committed memory.
- // TODO(dmikurube): These regions should be classified more precisely later
- // for more detailed analysis.
- RegionStats all_[NUMBER_OF_MAPS_REGION_TYPES];
-
- RegionStats unhooked_[NUMBER_OF_MAPS_REGION_TYPES];
-
- // Total bytes of malloc'ed regions.
- RegionStats profiled_malloc_;
-
- // Total bytes of mmap'ed regions.
- RegionStats profiled_mmap_;
- };
-
- // Writes reformatted /proc/<pid>/maps into a file "|prefix|.<pid>.maps"
- // with using |raw_buffer| of |buffer_size|.
- static void WriteProcMaps(const char* prefix,
- char raw_buffer[],
- int buffer_size);
-
- // Appends the command line (/proc/pid/cmdline on Linux) into |buffer|.
- bool AppendCommandLine(TextBuffer* buffer);
-
- MemoryResidenceInfoGetterInterface* memory_residence_info_getter_;
-
- // Process ID of the last dump. This can change by fork.
- pid_t most_recent_pid_;
-
- GlobalStats stats_; // Stats about total memory.
- int dump_count_; // The number of dumps.
- char* filename_prefix_; // Output file prefix.
- char run_id_[128];
-
- DeepBucketTable deep_table_;
-
- enum PageFrameType pageframe_type_;
-#endif // USE_DEEP_HEAP_PROFILE
-
- HeapProfileTable* heap_profile_;
-
- DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile);
-};
-
-#endif // BASE_DEEP_HEAP_PROFILE_H_
diff --git a/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h b/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h
deleted file mode 100644
index 1236258..0000000
--- a/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef TYPE_PROFILER_MAP_H_
-#define TYPE_PROFILER_MAP_H_
-
-#if defined(TYPE_PROFILING)
-
-#include <typeinfo>
-
-// PERFTOOLS_DLL_DECL is unnecessary, as it is Windows specific.
-
-void InsertType(void* address, size_t size, const std::type_info& type);
-void EraseType(void* address);
-const std::type_info* LookupType(const void* address);
-
-#endif // defined(TYPE_PROFILING)
-
-#endif // TYPE_PROFILER_MAP_H_
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc
index 1e0eea5..985ea20 100644
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc
@@ -92,9 +92,6 @@ DEFINE_int32(heap_check_max_leaks,
// header of the dumped heap profile
static const char kProfileHeader[] = "heap profile: ";
static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
-#if defined(TYPE_PROFILING)
-static const char kTypeProfileStatsHeader[] = "type statistics:\n";
-#endif // defined(TYPE_PROFILING)
//----------------------------------------------------------------------
@@ -361,29 +358,6 @@ void HeapProfileTable::DumpMarkedObjects(AllocationMark mark,
RawClose(fd);
}
-#if defined(TYPE_PROFILING)
-void HeapProfileTable::DumpTypeStatistics(const char* file_name) const {
- RawFD fd = RawOpenForWriting(file_name);
- if (fd == kIllegalRawFD) {
- RAW_LOG(ERROR, "Failed dumping type statistics to %s", file_name);
- return;
- }
-
- AddressMap<TypeCount>* type_size_map;
- type_size_map = new(alloc_(sizeof(AddressMap<TypeCount>)))
- AddressMap<TypeCount>(alloc_, dealloc_);
- address_map_->Iterate(TallyTypesItererator, type_size_map);
-
- RawWrite(fd, kTypeProfileStatsHeader, strlen(kTypeProfileStatsHeader));
- const DumpArgs args(fd, NULL);
- type_size_map->Iterate<const DumpArgs&>(DumpTypesIterator, args);
- RawClose(fd);
-
- type_size_map->~AddressMap<TypeCount>();
- dealloc_(type_size_map);
-}
-#endif // defined(TYPE_PROFILING)
-
void HeapProfileTable::IterateOrderedAllocContexts(
AllocContextIterator callback) const {
Bucket** list = MakeSortedBucketList();
@@ -451,41 +425,6 @@ void HeapProfileTable::DumpBucketIterator(const Bucket* bucket,
"", NULL);
}
-#if defined(TYPE_PROFILING)
-// static
-void HeapProfileTable::TallyTypesItererator(
- const void* ptr,
- AllocValue* value,
- AddressMap<TypeCount>* type_size_map) {
- const std::type_info* type = LookupType(ptr);
-
- const void* key = NULL;
- if (type)
- key = type->name();
-
- TypeCount* count = type_size_map->FindMutable(key);
- if (count) {
- count->bytes += value->bytes;
- ++count->objects;
- } else {
- type_size_map->Insert(key, TypeCount(value->bytes, 1));
- }
-}
-
-// static
-void HeapProfileTable::DumpTypesIterator(const void* ptr,
- TypeCount* count,
- const DumpArgs& args) {
- char buf[1024];
- int len;
- const char* mangled_type_name = static_cast<const char*>(ptr);
- len = snprintf(buf, sizeof(buf), "%6d: %8" PRId64 " @ %s\n",
- count->objects, count->bytes,
- mangled_type_name ? mangled_type_name : "(no_typeinfo)");
- RawWrite(args.fd, buf, len);
-}
-#endif // defined(TYPE_PROFILING)
-
inline
void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,
const DumpArgs& args) {
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h
index c2ad39f..b0c3695 100644
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.h
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h
@@ -40,10 +40,6 @@
#include "base/logging.h" // for RawFD
#include "heap-profile-stats.h"
-#if defined(TYPE_PROFILING)
-#include <gperftools/type_profiler_map.h>
-#endif // defined(TYPE_PROFILING)
-
// Table to maintain a heap profile data inside,
// i.e. the set of currently active heap memory allocations.
// thread-unsafe and non-reentrant code:
@@ -223,13 +219,7 @@ class HeapProfileTable {
// used for leak checking (using HeapLeakChecker).
void DumpMarkedObjects(AllocationMark mark, const char* file_name);
-#if defined(TYPE_PROFILING)
- void DumpTypeStatistics(const char* file_name) const;
-#endif // defined(TYPE_PROFILING)
-
private:
- friend class DeepHeapProfile;
-
// data types ----------------------------
// Hash table bucket to hold (de)allocation stats
@@ -328,18 +318,6 @@ class HeapProfileTable {
// mark unmarked allocations.
};
-#if defined(TYPE_PROFILING)
- struct TypeCount {
- TypeCount(size_t bytes_arg, unsigned int objects_arg)
- : bytes(bytes_arg),
- objects(objects_arg) {
- }
-
- size_t bytes;
- unsigned int objects;
- };
-#endif // defined(TYPE_PROFILING)
-
struct AllocationAddressIteratorArgs {
AllocationAddressIteratorArgs(AddressIterator callback_arg, void* data_arg)
: callback(callback_arg),
@@ -409,16 +387,6 @@ class HeapProfileTable {
inline static void DumpMarkedIterator(const void* ptr, AllocValue* v,
const DumpMarkedArgs& args);
-#if defined(TYPE_PROFILING)
- inline static void TallyTypesItererator(const void* ptr,
- AllocValue* value,
- AddressMap<TypeCount>* type_size_map);
-
- inline static void DumpTypesIterator(const void* ptr,
- TypeCount* size,
- const DumpArgs& args);
-#endif // defined(TYPE_PROFILING)
-
// Helper for IterateOrderedAllocContexts and FillOrderedProfile.
// Creates a sorted list of Buckets whose length is num_buckets_.
// The caller is responsible for deallocating the returned list.
diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc
index 46a81a4..43a6f35 100644
--- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
+++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc
@@ -68,7 +68,6 @@
#include "base/spinlock.h"
#include "base/low_level_alloc.h"
#include "base/sysinfo.h" // for GetUniquePathFromEnv()
-#include "deep-heap-profile.h"
#include "heap-profile-table.h"
#include "memory_region_map.h"
@@ -81,38 +80,6 @@
#endif
#endif
-#if defined(__ANDROID__) || defined(ANDROID)
-// On android, there are no environment variables.
-// Instead, we use system properties, set via:
-// adb shell setprop prop_name prop_value
-// From <sys/system_properties.h>,
-// PROP_NAME_MAX 32
-// PROP_VALUE_MAX 92
-#define HEAPPROFILE "heapprof"
-#define HEAP_PROFILE_ALLOCATION_INTERVAL "heapprof.allocation_interval"
-#define HEAP_PROFILE_DEALLOCATION_INTERVAL "heapprof.deallocation_interval"
-#define HEAP_PROFILE_INUSE_INTERVAL "heapprof.inuse_interval"
-#define HEAP_PROFILE_TIME_INTERVAL "heapprof.time_interval"
-#define HEAP_PROFILE_MMAP_LOG "heapprof.mmap_log"
-#define HEAP_PROFILE_MMAP "heapprof.mmap"
-#define HEAP_PROFILE_ONLY_MMAP "heapprof.only_mmap"
-#define DEEP_HEAP_PROFILE "heapprof.deep_heap_profile"
-#define DEEP_HEAP_PROFILE_PAGEFRAME "heapprof.deep.pageframe"
-#define HEAP_PROFILE_TYPE_STATISTICS "heapprof.type_statistics"
-#else // defined(__ANDROID__) || defined(ANDROID)
-#define HEAPPROFILE "HEAPPROFILE"
-#define HEAP_PROFILE_ALLOCATION_INTERVAL "HEAP_PROFILE_ALLOCATION_INTERVAL"
-#define HEAP_PROFILE_DEALLOCATION_INTERVAL "HEAP_PROFILE_DEALLOCATION_INTERVAL"
-#define HEAP_PROFILE_INUSE_INTERVAL "HEAP_PROFILE_INUSE_INTERVAL"
-#define HEAP_PROFILE_TIME_INTERVAL "HEAP_PROFILE_TIME_INTERVAL"
-#define HEAP_PROFILE_MMAP_LOG "HEAP_PROFILE_MMAP_LOG"
-#define HEAP_PROFILE_MMAP "HEAP_PROFILE_MMAP"
-#define HEAP_PROFILE_ONLY_MMAP "HEAP_PROFILE_ONLY_MMAP"
-#define DEEP_HEAP_PROFILE "DEEP_HEAP_PROFILE"
-#define DEEP_HEAP_PROFILE_PAGEFRAME "DEEP_HEAP_PROFILE_PAGEFRAME"
-#define HEAP_PROFILE_TYPE_STATISTICS "HEAP_PROFILE_TYPE_STATISTICS"
-#endif // defined(__ANDROID__) || defined(ANDROID)
-
using STL_NAMESPACE::string;
using STL_NAMESPACE::sort;
@@ -154,20 +121,6 @@ DEFINE_bool(only_mmap_profile,
EnvToBool(HEAP_PROFILE_ONLY_MMAP, false),
"If heap-profiling is on, only profile mmap, mremap, and sbrk; "
"do not profile malloc/new/etc");
-DEFINE_bool(deep_heap_profile,
- EnvToBool(DEEP_HEAP_PROFILE, false),
- "If heap-profiling is on, profile deeper (Linux and Android)");
-DEFINE_int32(deep_heap_profile_pageframe,
- EnvToInt(DEEP_HEAP_PROFILE_PAGEFRAME, 0),
- "Needs deeper profile. If 1, dump page frame numbers (PFNs). "
- "If 2, dump page counts (/proc/kpagecount) with PFNs.");
-#if defined(TYPE_PROFILING)
-DEFINE_bool(heap_profile_type_statistics,
- EnvToBool(HEAP_PROFILE_TYPE_STATISTICS, false),
- "If heap-profiling is on, dump type statistics.");
-#endif // defined(TYPE_PROFILING)
-
-
//----------------------------------------------------------------------
// Locking
//----------------------------------------------------------------------
@@ -220,7 +173,6 @@ static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
static int64 last_dump_time = 0; // The time of the last dump
static HeapProfileTable* heap_profile = NULL; // the heap profile table
-static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
// Callback to generate a stack trace for an allocation. May be overriden
// by an application to provide its own pseudo-stacks.
@@ -301,25 +253,11 @@ static void DumpProfileLocked(const char* reason) {
reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
}
- if (deep_profile) {
- deep_profile->DumpOrderedProfile(reason, global_profiler_buffer,
- kProfileBufferSize, fd);
- } else {
- char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
- kProfileBufferSize);
- RawWrite(fd, profile, strlen(profile));
- }
+ char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
+ kProfileBufferSize);
+ RawWrite(fd, profile, strlen(profile));
RawClose(fd);
-#if defined(TYPE_PROFILING)
- if (FLAGS_heap_profile_type_statistics) {
- snprintf(file_name, sizeof(file_name), "%s.%05d.%04d.type",
- filename_prefix, getpid(), dump_count);
- RAW_VLOG(0, "Dumping type statistics to %s", file_name);
- heap_profile->DumpTypeStatistics(file_name);
- }
-#endif // defined(TYPE_PROFILING)
-
dumping = false;
}
@@ -529,14 +467,6 @@ extern "C" void HeapProfilerStart(const char* prefix) {
high_water_mark = 0;
last_dump_time = 0;
- if (FLAGS_deep_heap_profile) {
- // Initialize deep memory profiler
- RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
- deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
- DeepHeapProfile(heap_profile, prefix, DeepHeapProfile::PageFrameType(
- FLAGS_deep_heap_profile_pageframe));
- }
-
// We do not reset dump_count so if the user does a sequence of
// HeapProfilerStart/HeapProfileStop, we will get a continuous
// sequence of profiles.
@@ -598,13 +528,6 @@ extern "C" void HeapProfilerStop() {
RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
}
- if (deep_profile) {
- // free deep memory profiler
- deep_profile->~DeepHeapProfile();
- ProfilerFree(deep_profile);
- deep_profile = NULL;
- }
-
// free profile
heap_profile->~HeapProfileTable();
ProfilerFree(heap_profile);
diff --git a/third_party/tcmalloc/chromium/src/type_profiler_map.cc b/third_party/tcmalloc/chromium/src/type_profiler_map.cc
deleted file mode 100644
index a2f21f8..0000000
--- a/third_party/tcmalloc/chromium/src/type_profiler_map.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#if defined(TYPE_PROFILING)
-
-#include <config.h>
-
-#include <new>
-#include <stddef.h>
-#include <typeinfo>
-
-#include <gperftools/type_profiler_map.h>
-
-#include "addressmap-inl.h"
-#include "base/logging.h"
-#include "base/low_level_alloc.h"
-#include "base/spinlock.h"
-#include "tcmalloc_guard.h"
-
-namespace {
-
-const TCMallocGuard tcmalloc_initializer;
-
-//----------------------------------------------------------------------
-// A struct to store size and type_info of an object
-//----------------------------------------------------------------------
-
-struct ObjectInfo {
- public:
- ObjectInfo(): size(0), type(NULL) {}
- ObjectInfo(size_t size_arg, const std::type_info* type_arg)
- : size(size_arg),
- type(type_arg) {
- }
-
- size_t size;
- const std::type_info* type;
-};
-
-//----------------------------------------------------------------------
-// Locking
-//----------------------------------------------------------------------
-
-SpinLock g_type_profiler_lock(SpinLock::LINKER_INITIALIZED);
-
-//----------------------------------------------------------------------
-// Simple allocator for type_info map's internal memory
-//----------------------------------------------------------------------
-
-LowLevelAlloc::Arena* g_type_profiler_map_memory = NULL;
-
-void* TypeProfilerMalloc(size_t bytes) {
- return LowLevelAlloc::AllocWithArena(bytes, g_type_profiler_map_memory);
-}
-
-void TypeProfilerFree(void* p) {
- LowLevelAlloc::Free(p);
-}
-
-//----------------------------------------------------------------------
-// Profiling control/state data
-//----------------------------------------------------------------------
-
-AddressMap<ObjectInfo>* g_type_profiler_map = NULL;
-
-//----------------------------------------------------------------------
-// Manage type_info map
-//----------------------------------------------------------------------
-
-void InitializeTypeProfilerMemory() {
- if (g_type_profiler_map_memory != NULL) {
- RAW_DCHECK(g_type_profiler_map != NULL, "TypeProfilerMap is NULL");
- return;
- }
-
- g_type_profiler_map_memory =
- LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
-
- g_type_profiler_map =
- new(TypeProfilerMalloc(sizeof(*g_type_profiler_map)))
- AddressMap<ObjectInfo>(TypeProfilerMalloc, TypeProfilerFree);
-}
-
-} // namespace
-
-void InsertType(void* address, size_t size, const std::type_info& type) {
- SpinLockHolder lock(&g_type_profiler_lock);
- InitializeTypeProfilerMemory();
-
- g_type_profiler_map->Insert(address, ObjectInfo(size, &type));
-}
-
-void EraseType(void* address) {
- SpinLockHolder lock(&g_type_profiler_lock);
- InitializeTypeProfilerMemory();
-
- ObjectInfo obj;
- g_type_profiler_map->FindAndRemove(address, &obj);
-}
-
-const std::type_info* LookupType(const void* address) {
- SpinLockHolder lock(&g_type_profiler_lock);
- InitializeTypeProfilerMemory();
-
- const ObjectInfo* found = g_type_profiler_map->Find(address);
- if (found == NULL)
- return NULL;
- return found->type;
-}
-
-#endif // defined(TYPE_PROFILING)