├── .bazelrc
├── .gitignore
├── BUILD
├── CONTRIBUTING.md
├── LICENSE
├── MODULE.bazel
├── README.md
├── WORKSPACE
├── WORKSPACE.bzlmod
├── ci
├── linux_clang-latest_libcxx_bazel.sh
├── linux_clang-latest_libstdcxx_bazel.sh
└── linux_gcc-latest_libstdcxx_bazel.sh
├── docs
├── README.md
├── compatibility.md
├── design.md
├── gperftools.md
├── gwp-asan.md
├── images
│ ├── legacy_pageheap.png
│ ├── lifetimes-counterfactual.png
│ ├── lifetimes-enabled.png
│ ├── pagemap.png
│ ├── per-cpu-cache-internals.png
│ ├── per-thread-structure.png
│ ├── spanmap.gif
│ └── tcmalloc_internals.png
├── lifetime-based-allocator.md
├── mismatched-sized-delete.md
├── overview.md
├── platforms.md
├── quickstart.md
├── reference.md
├── regions-are-not-optional.md
├── rseq.md
├── sampling.md
├── stats.md
├── temeraire.md
└── tuning.md
└── tcmalloc
├── .clang-format
├── .github
├── CODEOWNERS
└── workflows
│ └── ci.yml
├── BUILD
├── allocation_sample.cc
├── allocation_sample.h
├── allocation_sample_test.cc
├── allocation_sampling.cc
├── allocation_sampling.h
├── arena.cc
├── arena.h
├── arena_test.cc
├── background.cc
├── central_freelist.cc
├── central_freelist.h
├── central_freelist_benchmark.cc
├── central_freelist_fuzz.cc
├── central_freelist_test.cc
├── common.cc
├── common.h
├── copts.bzl
├── cpu_cache.cc
├── cpu_cache.h
├── cpu_cache_activate_test.cc
├── cpu_cache_test.cc
├── deallocation_profiler.cc
├── deallocation_profiler.h
├── error_reporting.cc
├── error_reporting.h
├── experiment.cc
├── experiment.h
├── experiment_config.h
├── experiment_config_test.cc
├── experiment_fuzz.cc
├── experimental_pow2_size_class.cc
├── global_stats.cc
├── global_stats.h
├── guarded_allocations.h
├── guarded_page_allocator.cc
├── guarded_page_allocator.h
├── guarded_page_allocator_benchmark.cc
├── guarded_page_allocator_profile_test.cc
├── guarded_page_allocator_test.cc
├── hinted_tracker_lists.h
├── huge_address_map.cc
├── huge_address_map.h
├── huge_address_map_test.cc
├── huge_allocator.cc
├── huge_allocator.h
├── huge_allocator_test.cc
├── huge_cache.cc
├── huge_cache.h
├── huge_cache_test.cc
├── huge_page_aware_allocator.cc
├── huge_page_aware_allocator.h
├── huge_page_aware_allocator_fuzz.cc
├── huge_page_aware_allocator_test.cc
├── huge_page_filler.h
├── huge_page_filler_fuzz.cc
├── huge_page_filler_test.cc
├── huge_page_subrelease.h
├── huge_page_subrelease_test.cc
├── huge_pages.h
├── huge_region.h
├── huge_region_fuzz.cc
├── huge_region_test.cc
├── internal
├── BUILD
├── affinity.cc
├── affinity.h
├── affinity_test.cc
├── allocation_guard.cc
├── allocation_guard.h
├── allocation_guard_test.cc
├── atomic_danger.h
├── atomic_stats_counter.h
├── cache_topology.cc
├── cache_topology.h
├── cache_topology_test.cc
├── clock.h
├── config.h
├── config_test.cc
├── cpu_utils.h
├── declarations.h
├── environment.cc
├── environment.h
├── environment_test.cc
├── explicitly_constructed.h
├── exponential_biased.h
├── exponential_biased_test.cc
├── fake_profile.h
├── gwp_asan_state.h
├── hook_list.cc
├── hook_list.h
├── linked_list.h
├── linked_list_benchmark.cc
├── linked_list_test.cc
├── linux_syscall_support.h
├── logging.cc
├── logging.h
├── logging_test.cc
├── logging_test_helper.cc
├── memory_stats.cc
├── memory_stats.h
├── memory_stats_test.cc
├── memory_tag.cc
├── memory_tag.h
├── mincore.cc
├── mincore.h
├── mincore_benchmark.cc
├── mincore_test.cc
├── mock_span.h
├── numa.cc
├── numa.h
├── numa_test.cc
├── optimization.h
├── overflow.h
├── page_size.cc
├── page_size.h
├── pageflags.cc
├── pageflags.h
├── pageflags_test.cc
├── parameter_accessors.h
├── percpu.cc
├── percpu.h
├── percpu_early_test.cc
├── percpu_rseq_aarch64.S
├── percpu_rseq_asm.S
├── percpu_rseq_unsupported.cc
├── percpu_rseq_x86_64.S
├── percpu_tcmalloc.h
├── percpu_tcmalloc_test.cc
├── percpu_test.cc
├── prefetch.h
├── prefetch_test.cc
├── proc_maps.cc
├── proc_maps.h
├── profile.proto
├── profile_builder.cc
├── profile_builder.h
├── profile_builder_fuzz.cc
├── profile_builder_no_tcmalloc_test.cc
├── profile_builder_test.cc
├── range_tracker.h
├── range_tracker_benchmark.cc
├── range_tracker_test.cc
├── residency.cc
├── residency.h
├── residency_test.cc
├── sampled_allocation.h
├── sampled_allocation_recorder.h
├── sampled_allocation_recorder_test.cc
├── sampled_allocation_test.cc
├── stacktrace_filter.h
├── stacktrace_filter_test.cc
├── sysinfo.cc
├── sysinfo.h
├── sysinfo_fuzz.cc
├── sysinfo_test.cc
├── testdata
│ ├── b180635896.so
│ ├── gnu-property.so
│ └── profile_builder_fuzz
│ │ ├── clusterfuzz-testcase-minimized-profile_builder_fuzz-5534221534363648
│ │ ├── clusterfuzz-testcase-minimized-profile_builder_fuzz-5647243657216000
│ │ ├── clusterfuzz-testcase-minimized-profile_builder_fuzz-5915530833559552
│ │ ├── clusterfuzz-testcase-minimized-profile_builder_fuzz-6685031907328000.fuzz
│ │ └── crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
├── timeseries_tracker.h
├── timeseries_tracker_test.cc
├── util.cc
└── util.h
├── internal_malloc_extension.h
├── internal_malloc_tracing_extension.h
├── legacy_size_classes.cc
├── libc_override.h
├── malloc_extension.cc
├── malloc_extension.h
├── malloc_extension_fuzz.cc
├── malloc_hook.cc
├── malloc_hook.h
├── malloc_hook_invoke.h
├── malloc_tracing_extension.cc
├── malloc_tracing_extension.h
├── metadata_allocator.h
├── metadata_object_allocator.h
├── mock_central_freelist.cc
├── mock_central_freelist.h
├── mock_huge_page_static_forwarder.cc
├── mock_huge_page_static_forwarder.h
├── mock_metadata_allocator.h
├── mock_static_forwarder.h
├── mock_transfer_cache.cc
├── mock_transfer_cache.h
├── mock_virtual_allocator.h
├── new_extension.h
├── new_extension_test.cc
├── page_allocator.cc
├── page_allocator.h
├── page_allocator_interface.cc
├── page_allocator_interface.h
├── page_allocator_test.cc
├── page_allocator_test_util.h
├── pagemap.cc
├── pagemap.h
├── pagemap_test.cc
├── pages.h
├── pages_test.cc
├── parameters.cc
├── parameters.h
├── peak_heap_tracker.cc
├── peak_heap_tracker.h
├── profile_marshaler.cc
├── profile_marshaler.h
├── profile_marshaler_test.cc
├── profile_test.cc
├── reuse_size_classes.cc
├── sampler.cc
├── sampler.h
├── segv_handler.cc
├── segv_handler.h
├── segv_handler_test.cc
├── selsan
├── BUILD
├── README.md
├── report_test.cc
├── selsan.cc
├── selsan.h
└── shadow_test.cc
├── size_class_info.h
├── size_classes.cc
├── size_classes_test.cc
├── sizemap.cc
├── sizemap.h
├── sizemap_fuzz.cc
├── sizemap_test.cc
├── span.cc
├── span.h
├── span_benchmark.cc
├── span_fuzz.cc
├── span_stats.h
├── span_test.cc
├── stack_trace_table.cc
├── stack_trace_table.h
├── stack_trace_table_test.cc
├── static_vars.cc
├── static_vars.h
├── stats.cc
├── stats.h
├── stats_test.cc
├── system-alloc.cc
├── system-alloc.h
├── tcmalloc.cc
├── tcmalloc.h
├── tcmalloc_policy.h
├── testdata
├── central_freelist_fuzz
│ ├── clusterfuzz-testcase-central_freelist_fuzz-6338860943802368
│ └── clusterfuzz-testcase-minimized-central_freelist_fuzz-5328515345809408
├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-4796454007799808
├── huge_page_aware_allocator_fuzz
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-4650158169391104
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-5216394376773632
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-5397442449178624
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-5580915038093312
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-6140744194457600
│ ├── clusterfuzz-testcase-minimized-huge_page_aware_allocator_fuzz-6302517124005888
│ ├── testcase-4507694249082880
│ ├── testcase-4582514590875648
│ ├── testcase-5091122805276672
│ ├── testcase-5185382849773568
│ ├── testcase-5781242586923008
│ ├── testcase-5876893820977152
│ └── testcase-6591694528970752
├── huge_page_filler_fuzz
│ ├── clusterfuzz-testcase-huge_page_filler_fuzz-5476984341004288
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-5161409228701696.test
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-5516474505363456.test
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-6053674183688192.test
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-6159120802381824
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-6512022070886400.test
│ ├── clusterfuzz-testcase-minimized-huge_page_filler_fuzz-6622985612820480
│ ├── crash-869dbc1cdf6a1f79b386adf046c7df32257ef684
│ ├── crash-e9f3aa3ad83e808a5588ec529c6cdf00d5d397fc
│ └── testcase-6686265543557120
├── huge_region_fuzz
│ ├── testcase-5235702354214912
│ └── testcase-5618130730156032
├── malloc_extension_fuzz
│ ├── crash-4338e5c59e1bda5104fb5f0aa5553aeb1d3d6465
│ └── crash-c20bfc5c10e885f8e5498c2907cfab82da7c0cff
├── sizemap_fuzz
│ └── clusterfuzz-testcase-minimized-sizemap_fuzz-5240920228626432
├── span_fuzz
│ ├── clusterfuzz-testcase-minimized-span_fuzz-6271015625031680
│ ├── clusterfuzz-testcase-minimized-span_fuzz-6321706670620672.fuzz
│ ├── crash-01d72a40d5815461b92d3f7c0f6377fd441b0034
│ ├── crash-32697afd59029eb8356fee8ba568e7f6b58d728f
│ ├── crash-42b80edf9551d1095aebb6724c070ee43d490125
│ ├── crash-500955af6568b0ed234bd40d6a01af496ba15eb2
│ ├── crash-6ef2b6ae2246d1bda0190983b1007df2699e7738
│ ├── crash-746940d0368bfe3e4a94b60659eeb6cb87106618
│ └── testcase-5877384059617280
└── transfer_cache_fuzz
│ └── leak-0b593173f17376c77a3a74a6644af58f77d7a366
├── testing
├── BUILD
├── aligned_new_test.cc
├── background_test.cc
├── benchmark_main.cc
├── current_allocated_bytes_test.cc
├── deallocation_profiler_test.cc
├── default_parameters_test.cc
├── disable_numa_test.cc
├── fast_path.insecure.golden
├── fast_path.opt.golden
├── fast_path.release+insecure.golden
├── fast_path.release.golden
├── fast_path.unstable.release.golden
├── frag_test.cc
├── get_stats_test.cc
├── heap_profiling_test.cc
├── hello_main.cc
├── hooks_test.cc
├── large_alloc_size_test.cc
├── largesmall_frag_test.cc
├── limit_test.cc
├── malloc_extension_system_malloc_test.cc
├── malloc_extension_test.cc
├── malloc_tracing_extension_test.cc
├── markidle_test.cc
├── memalign_test.cc
├── memory_errors_test.cc
├── no_deps_test.cc
├── numa_locality_test.cc
├── outofmemory_test.cc
├── parallel_test.cc
├── peak_heap_profiling_test.cc
├── profile_drop_frames_test.cc
├── profile_test.cc
├── realized_fragmentation_test.cc
├── realloc_test.cc
├── reclaim_test.cc
├── releasing_test.cc
├── sample_size_class_test.cc
├── sampled_hooks_test.cc
├── sampler_test.cc
├── sampling_memusage_test.cc
├── sampling_test.cc
├── startup_size_test.cc
├── system-alloc_test.cc
├── tcmalloc_benchmark.cc
├── tcmalloc_large_test.cc
├── tcmalloc_test.cc
├── test_allocator_harness.h
├── testutil.cc
├── testutil.h
├── thread_ctor_test.cc
├── thread_ctor_test_lib.cc
├── thread_manager.h
├── threadcachesize_test.cc
├── variants_test.cc
├── want_disable_huge_region_more_often_test_helper.cc
├── want_disable_wider_slabs_test_helper.cc
├── want_hpaa_test_helper.cc
└── want_pow2below64_size_classes_helper.cc
├── thread_cache.cc
├── thread_cache.h
├── thread_cache_test.cc
├── transfer_cache.cc
├── transfer_cache.h
├── transfer_cache_benchmark.cc
├── transfer_cache_fuzz.cc
├── transfer_cache_internals.h
├── transfer_cache_stats.h
├── transfer_cache_test.cc
├── variants.bzl
├── want_disable_dynamic_slabs.cc
├── want_disable_huge_region_more_often.cc
├── want_hpaa.cc
├── want_legacy_size_classes.cc
├── want_legacy_size_classes_test.cc
└── want_numa_aware.cc
/.bazelrc:
--------------------------------------------------------------------------------
1 | # Copyright 2019 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | build --cxxopt='-std=c++17'
16 |
17 | # Flip incompatible_disallow_empty_glob to avoid breaking forward compatibility, see
18 | # https://github.com/bazelbuild/bazel/pull/15327 for details.
19 | build --incompatible_disallow_empty_glob
20 |
21 | # Flip incompatible_config_setting_private_default_visibility to avoid breaking
22 | # forward compatibility. See https://github.com/bazelbuild/bazel/issues/12933
23 | # for details.
24 | common --incompatible_config_setting_private_default_visibility
25 |
26 | # Link Google Test against Abseil and RE2.
27 | build --define='absl=1'
28 |
29 | # AllocationGuard.CooperativeDeathTest checks for "SIGABRT received"
30 | # message printed by this signal handler.
31 | test --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1"
32 |
33 | # Define the --config=asan-libfuzzer configuration.
34 | build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:libfuzzer
35 | build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer
36 | build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Bazel
2 | bazel-*
3 | MODULE.bazel.lock
4 |
--------------------------------------------------------------------------------
/BUILD:
--------------------------------------------------------------------------------
1 | # Copyright 2024 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
--------------------------------------------------------------------------------
/MODULE.bazel:
--------------------------------------------------------------------------------
1 | # Copyright 2024 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | module(
16 | name = "tcmalloc",
17 | version = "0",
18 | compatibility_level = 0,
19 | repo_name = "com_google_tcmalloc",
20 | )
21 |
22 | bazel_dep(name = "abseil-cpp", version = "20240722.0", repo_name = "com_google_absl")
23 | bazel_dep(name = "bazel_skylib", version = "1.7.1")
24 | bazel_dep(name = "protobuf", version = "27.5", repo_name = "com_google_protobuf")
25 | bazel_dep(name = "re2", version = "2024-02-01", repo_name = "com_googlesource_code_re2")
26 | bazel_dep(name = "rules_cc", version = "0.0.9")
27 |
28 | bazel_dep(name = "fuzztest", version = "20241028.0", dev_dependency = True, repo_name = "com_google_fuzztest")
29 | bazel_dep(name = "google_benchmark", version = "1.9.2", dev_dependency = True, repo_name = "com_github_google_benchmark")
30 | bazel_dep(name = "googletest", version = "1.13.0", dev_dependency = True, repo_name = "com_google_googletest")
31 | bazel_dep(name = "rules_fuzzing", version = "0.5.2", dev_dependency = True)
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TCMalloc
2 |
3 | This repository contains the TCMalloc C++ code.
4 |
5 | TCMalloc is Google's customized implementation of C's `malloc()` and C++'s
6 | `operator new` used for memory allocation within our C and C++ code. TCMalloc is
7 | a fast, multi-threaded malloc implementation.
8 |
9 | ## Building TCMalloc
10 |
11 | [Bazel](https://bazel.build) is the official build system for TCMalloc.
12 |
13 | The [TCMalloc Platforms Guide](docs/platforms.md) contains information on
14 | platform support for TCMalloc.
15 |
16 | ## Documentation
17 |
18 | All users of TCMalloc should consult the following documentation resources:
19 |
20 | * The [TCMalloc Quickstart](docs/quickstart.md) covers downloading,
21 | installing, building, and testing TCMalloc, including incorporating within
22 | your codebase.
23 | * The [TCMalloc Overview](docs/overview.md) covers the basic architecture of
24 | TCMalloc, and how that may affect configuration choices.
25 | * The [TCMalloc Reference](docs/reference.md) covers the C and C++ TCMalloc
26 | API endpoints.
27 |
28 | More advanced usages of TCMalloc may find the following documentation useful:
29 |
30 | * The [TCMalloc Tuning Guide](docs/tuning.md) covers the configuration
31 | choices in more depth, and also illustrates other ways to customize
32 | TCMalloc. This also covers important operating system-level properties for
33 | improving TCMalloc performance.
34 | * The [TCMalloc Design Doc](docs/design.md) covers how TCMalloc works
35 | underneath the hood, and why certain design choices were made. Most
36 | developers will not need this level of implementation detail.
37 | * The [TCMalloc Compatibility Guide](docs/compatibility.md) which documents
38 | our expectations for how our APIs are used.
39 |
40 | ## License
41 |
42 | The TCMalloc library is licensed under the terms of the Apache license. See
43 | LICENSE for more information.
44 |
45 | Disclaimer: This is not an officially supported Google product.
46 |
--------------------------------------------------------------------------------
/WORKSPACE.bzlmod:
--------------------------------------------------------------------------------
1 | # Copyright 2024 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # https://bazel.build/external/migration#workspace.bzlmod
16 | #
17 | # This file is intentionally empty. When bzlmod is enabled and this
18 | # file exists, the content of WORKSPACE is ignored. This prevents
19 | # bzlmod builds from unintentionally depending on the WORKSPACE file.
20 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # TCMalloc
2 |
3 | This repository contains the TCMalloc C++ code.
4 |
5 | TCMalloc is Google's customized implementation of C's `malloc()` and C++'s
6 | `operator new` used for memory allocation within our C and C++ code. TCMalloc is
7 | a fast, multi-threaded malloc implementation.
8 |
9 | ## Building TCMalloc
10 |
11 | [Bazel](https://bazel.build) is the official build system for TCMalloc.
12 |
13 | The [TCMalloc Platforms Guide](platforms.md) contains information on platform
14 | support for TCMalloc.
15 |
16 | ## Documentation
17 |
18 | All users of TCMalloc should consult the following documentation resources:
19 |
20 | * The [TCMalloc Quickstart](quickstart.md) covers downloading, installing,
21 | building, and testing TCMalloc, including incorporating within your
22 | codebase.
23 | * The [TCMalloc Overview](overview.md) covers the basic architecture of
24 | TCMalloc, and how that may affect configuration choices.
25 | * The [TCMalloc Reference](reference.md) covers the C and C++ TCMalloc API
26 | endpoints.
27 |
28 | More advanced usages of TCMalloc may find the following documentation useful:
29 |
30 | * The [TCMalloc Tuning Guide](tuning.md) covers the configuration choices in
31 | more depth, and also illustrates other ways to customize TCMalloc.
32 | * The [TCMalloc Design Doc](design.md) covers how TCMalloc works underneath
33 | the hood, and why certain design choices were made. Most developers will not
34 | need this level of implementation detail.
35 | * The [TCMalloc Compatibility Guide](compatibility.md) which documents our
36 | expectations for how our APIs are used.
37 | * The [history and differences](gperftools.md) between this repository and
38 | gperftools.
39 |
40 | ## Publications
41 |
42 | We've published several papers relating to TCMalloc optimizations:
43 |
44 | * ["Beyond malloc efficiency to fleet efficiency: a hugepage-aware memory
45 | allocator" (OSDI 2021)](https://research.google/pubs/pub50370/) relating to
46 | the development and rollout of [Temeraire](temeraire.md), TCMalloc's
47 | hugepage-aware page heap implementation.
48 | * ["Adaptive Hugepage Subrelease for Non-moving Memory Allocators in
49 | Warehouse-Scale Computers" (ISMM
50 | 2021)](https://research.google/pubs/pub50436/) relating to optimizations for
51 | releasing partial hugepages to the operating system.
52 | * ["Characterizing a Memory Allocator at Warehouse Scale" (ASPLOS 2024)](https://research.google/pubs/characterizing-a-memory-allocator-at-warehouse-scale/)
53 | relating to several optimizations developed since 2018.
54 |
55 | ## License
56 |
57 | The TCMalloc library is licensed under the terms of the Apache license. See
58 | LICENSE for more information.
59 |
60 | Disclaimer: This is not an officially supported Google product.
61 |
--------------------------------------------------------------------------------
/docs/compatibility.md:
--------------------------------------------------------------------------------
1 | # TCMalloc Compatibility Guidelines
2 |
3 | This document details what we expect from well-behaved users. Any usage of
4 | TCMalloc libraries outside of these technical boundaries may result in breakage
5 | when upgrading to newer versions of TCMalloc.
6 |
7 | Put another way: don't do things that make TCMalloc API maintenance tasks
8 | harder. If you misuse TCMalloc APIs, you're on your own.
9 |
10 | Additionally, because TCMalloc depends on Abseil, Abseil's
11 | [compatibility guidelines](https://abseil.io/about/compatibility) also apply.
12 |
13 | ## What Users Must (And Must Not) Do
14 |
15 | * **Do not depend on a compiled representation of TCMalloc.** We do not
16 | promise any ABI compatibility — we intend for TCMalloc to be built
17 | from source, hopefully from head. The internal layout of our types may
18 | change at any point, without notice. Building TCMalloc in the presence of
19 | different C++ standard library types may change Abseil types, especially for
20 | pre-adopted types (`string_view`, `variant`, etc) — these will become
21 | typedefs and their ABI will change accordingly.
22 | * **Do not rely on dynamic loading/unloading.** TCMalloc does not support
23 | dynamic loading and unloading.
24 | * **You may not open namespace `tcmalloc`.** You are not allowed to define
25 | additional names in namespace `tcmalloc`, nor are you allowed to specialize
26 | anything we provide.
27 | * **You may not depend on the signatures of TCMalloc APIs.** You cannot take
28 | the address of APIs in TCMalloc (that would prevent us from adding overloads
29 | without breaking you). You cannot use metaprogramming tricks to depend on
30 | those signatures either. (This is also similar to the restrictions in the
31 | C++ standard.)
32 | * **You may not forward declare TCMalloc APIs.** This is actually a sub-point
33 | of "do not depend on the signatures of TCMalloc APIs" as well as "do not
34 | open namespace `tcmalloc`", but can be surprising. Any refactoring that
35 | changes template parameters, default parameters, or namespaces will be a
36 | breaking change in the face of forward-declarations.
37 | * **Do not depend upon internal details.** This should go without saying: if
38 | something is in a namespace or filename/path that includes the word
39 | "internal", you are not allowed to depend upon it. It's an implementation
40 | detail. You cannot friend it, you cannot include it, you cannot mention it
41 | or refer to it in any way.
42 | * **Include What You Use.** We may make changes to the internal `#include`
43 | graph for TCMalloc headers - if you use an API, please include the relevant
44 | header file directly.
45 |
--------------------------------------------------------------------------------
/docs/images/legacy_pageheap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/legacy_pageheap.png
--------------------------------------------------------------------------------
/docs/images/lifetimes-counterfactual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/lifetimes-counterfactual.png
--------------------------------------------------------------------------------
/docs/images/lifetimes-enabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/lifetimes-enabled.png
--------------------------------------------------------------------------------
/docs/images/pagemap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/pagemap.png
--------------------------------------------------------------------------------
/docs/images/per-cpu-cache-internals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/per-cpu-cache-internals.png
--------------------------------------------------------------------------------
/docs/images/per-thread-structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/per-thread-structure.png
--------------------------------------------------------------------------------
/docs/images/spanmap.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/spanmap.gif
--------------------------------------------------------------------------------
/docs/images/tcmalloc_internals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/docs/images/tcmalloc_internals.png
--------------------------------------------------------------------------------
/docs/platforms.md:
--------------------------------------------------------------------------------
1 | # TCMalloc Platforms
2 |
3 | The TCMalloc code is supported on the following platforms. By "platforms", we
4 | mean the union of operating system, architecture (e.g. little-endian vs.
5 | big-endian), compiler, and standard library.
6 |
7 | ## Language Requirements
8 |
9 | TCMalloc requires a code base that supports C++17 and our code is
10 | C++17-compliant. C code is required to be compliant to C11.
11 |
12 | We guarantee that our code will compile under the following compilation flags:
13 |
14 | Linux:
15 |
16 | * gcc 9.2+, clang 9.0+: `-std=c++17`
17 |
18 | (TL;DR; All code at this time must be built under C++17. We will update this
19 | list if circumstances change.)
20 |
21 | ## Supported Platforms
22 |
23 | The document below lists each platform, broken down by Operating System,
24 | Architecture, Specific Compiler, and Standard Library implementation.
25 |
26 | ### Linux
27 |
28 | **Supported**
29 |
30 |
31 |
32 |
33 |
34 |
35 | Operating System |
36 | Endianness/Word Size |
37 | Processor Architectures |
38 | Compilers* |
39 | Standard Libraries |
40 |
41 |
42 | Linux |
43 | little-endian, 64-bit |
44 | x86, AArch64 |
45 | gcc 9.2+ clang 9.0+ |
46 | libstdc++ libc++ |
47 |
48 |
49 |
50 |
51 | \* We test on gcc 9.2, though gcc versions (which support C++17) prior to that
52 | release should also work.
53 |
54 | **Best Effort**
55 |
56 |
57 |
58 |
59 |
60 |
61 | Operating System |
62 | Endianness/Word Size |
63 | Processor Architectures |
64 | Compilers* |
65 | Standard Libraries |
66 |
67 |
68 | Linux |
69 | little-endian, 64-bit |
70 | PPC |
71 | gcc 9.2+ clang 9.0+ |
72 | libstdc++ libc++ |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/tcmalloc/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | BasedOnStyle: Google
4 | DerivePointerAlignment: false
5 | PointerAlignment: Left
6 | ...
7 |
--------------------------------------------------------------------------------
/tcmalloc/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Default owners
2 | * @ckennelly
3 |
4 | # Documentation
5 | docs/* @manshreck
6 |
--------------------------------------------------------------------------------
/tcmalloc/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | name: ci
15 |
16 | on:
17 | push:
18 | branches:
19 | - master
20 |
21 | pull_request:
22 |
23 | jobs:
24 | Linux:
25 | runs-on: ubuntu-latest
26 | strategy:
27 | fail-fast: false
28 | matrix:
29 | compiler:
30 | - g++
31 | - clang++
32 |
33 | name: "Build/Test ${{matrix.compiler}}"
34 | steps:
35 | - name: Cancel previous
36 | uses: styfle/cancel-workflow-action@0.8.0
37 | with:
38 | access_token: ${{ github.token }}
39 |
40 | - name: Prepare
41 | run: |
42 | sudo apt-get update -qq
43 | sudo apt install -y g++ clang
44 |
45 | - uses: actions/checkout@v2
46 | with:
47 | fetch-depth: 0
48 |
49 | - name: Create Cache Timestamp
50 | id: cache_timestamp
51 | uses: nanzm/get-time-action@v1.1
52 | with:
53 | format: 'YYYY-MM-DD-HH-mm-ss'
54 |
55 | - name: Mount bazel cache
56 | uses: actions/cache@v2
57 | with:
58 | path: "/home/runner/.cache/bazel"
59 | key: bazelcache_${{matrix.compiler}}_${{ steps.cache_timestamp.outputs.time }}
60 | restore-keys: bazelcache_${{matrix.compiler}}_
61 |
62 | - name: Tests
63 | run: CXX=${{matrix.compiler}} bazel test --test_output=errors //...
64 |
--------------------------------------------------------------------------------
/tcmalloc/allocation_sample.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/allocation_sample.h"
16 |
17 | #include
18 | #include
19 |
20 | #include "absl/time/clock.h"
21 | #include "absl/time/time.h"
22 | #include "tcmalloc/internal/config.h"
23 | #include "tcmalloc/internal_malloc_extension.h"
24 | #include "tcmalloc/malloc_extension.h"
25 | #include "tcmalloc/stack_trace_table.h"
26 |
27 | GOOGLE_MALLOC_SECTION_BEGIN
28 | namespace tcmalloc::tcmalloc_internal {
29 |
30 | AllocationSample::AllocationSample(AllocationSampleList* list, absl::Time start)
31 | : list_(list), start_(start) {
32 | mallocs_ = std::make_unique(ProfileType::kAllocations);
33 | mallocs_->SetStartTime(start_);
34 | list->Add(this);
35 | }
36 |
37 | AllocationSample::~AllocationSample() {
38 | if (mallocs_ == nullptr) {
39 | return;
40 | }
41 |
42 | // deleted before ending profile, do it for them
43 | list_->Remove(this);
44 | }
45 |
46 | Profile AllocationSample::Stop() && {
47 | // We need to remove ourselves from list_ before we mutate mallocs_;
48 | //
49 | // A concurrent call to AllocationSampleList::ReportMalloc can access mallocs_
50 | // until we remove it from list_.
51 | if (mallocs_) {
52 | list_->Remove(this);
53 | mallocs_->SetDuration(absl::Now() - start_);
54 | }
55 | return ProfileAccessor::MakeProfile(std::move(mallocs_));
56 | }
57 |
58 | } // namespace tcmalloc::tcmalloc_internal
59 | GOOGLE_MALLOC_SECTION_END
60 |
--------------------------------------------------------------------------------
/tcmalloc/common.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/common.h"
16 |
17 | #include "tcmalloc/internal/config.h"
18 | #include "tcmalloc/internal/optimization.h"
19 |
20 | GOOGLE_MALLOC_SECTION_BEGIN
21 | namespace tcmalloc {
22 | namespace tcmalloc_internal {
23 |
24 | // This only provides correct answer for TCMalloc-allocated memory,
25 | // and may give a false positive for non-allocated block.
26 | extern "C" bool TCMalloc_Internal_PossiblyCold(const void* ptr) {
27 | return GetMemoryTag(ptr) == MemoryTag::kCold;
28 | }
29 |
30 | } // namespace tcmalloc_internal
31 | } // namespace tcmalloc
32 | GOOGLE_MALLOC_SECTION_END
33 |
--------------------------------------------------------------------------------
/tcmalloc/copts.bzl:
--------------------------------------------------------------------------------
1 | # Copyright 2019 The TCMalloc Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """This package provides default compiler warning flags for the OSS release"""
16 |
17 | TCMALLOC_LLVM_FLAGS = [
18 | # Ensure TCMalloc itself builds without errors, even if its dependencies
19 | # aren't necessarily -Werror clean.
20 | "-Werror",
21 | "-Wno-deprecated-declarations",
22 | "-Wno-deprecated-volatile",
23 | "-Wno-implicit-int-float-conversion",
24 | "-Wno-sign-compare",
25 | "-Wno-uninitialized",
26 | "-Wno-unused-function",
27 | "-Wno-unused-variable",
28 | ]
29 |
30 | TCMALLOC_GCC_FLAGS = [
31 | # Ensure TCMalloc itself builds without errors, even if its dependencies
32 | # aren't necessarily -Werror clean.
33 | "-Werror",
34 | "-Wno-array-bounds",
35 | "-Wno-attribute-alias",
36 | "-Wno-deprecated-declarations",
37 | "-Wno-sign-compare",
38 | "-Wno-stringop-overflow",
39 | "-Wno-uninitialized",
40 | "-Wno-unused-function",
41 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
42 | "-Wno-unused-result",
43 | "-Wno-unused-variable",
44 | ]
45 |
46 | TCMALLOC_DEFAULT_COPTS = select({
47 | "//tcmalloc:llvm": TCMALLOC_LLVM_FLAGS,
48 | "//conditions:default": TCMALLOC_GCC_FLAGS,
49 | })
50 |
--------------------------------------------------------------------------------
/tcmalloc/cpu_cache.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/cpu_cache.h"
16 |
17 | #include
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/base/attributes.h"
23 | #include "tcmalloc/experiment.h"
24 | #include "tcmalloc/experiment_config.h"
25 | #include "tcmalloc/internal/config.h"
26 | #include "tcmalloc/internal/environment.h"
27 | #include "tcmalloc/internal/logging.h"
28 | #include "tcmalloc/internal/percpu.h"
29 | #include "tcmalloc/internal_malloc_extension.h"
30 | #include "tcmalloc/parameters.h"
31 | #include "tcmalloc/static_vars.h"
32 |
33 | GOOGLE_MALLOC_SECTION_BEGIN
34 | namespace tcmalloc {
35 | namespace tcmalloc_internal {
36 |
37 | static void ActivatePerCpuCaches() {
38 | if (tcmalloc::tcmalloc_internal::tc_globals.CpuCacheActive()) {
39 | // Already active.
40 | return;
41 | }
42 |
43 | if (Parameters::per_cpu_caches() && subtle::percpu::IsFast()) {
44 | tc_globals.InitIfNecessary();
45 | tc_globals.cpu_cache().Activate();
46 | tc_globals.ActivateCpuCache();
47 | // no need for this thread cache anymore, I guess.
48 | ThreadCache::BecomeIdle();
49 | // If there's a problem with this code, let's notice it right away:
50 | ::operator delete(::operator new(1));
51 | }
52 | }
53 |
54 | class PerCPUInitializer {
55 | public:
56 | PerCPUInitializer() {
57 | ActivatePerCpuCaches();
58 | }
59 | };
60 | static PerCPUInitializer module_enter_exit;
61 |
62 | } // namespace tcmalloc_internal
63 | } // namespace tcmalloc
64 | GOOGLE_MALLOC_SECTION_END
65 |
66 | extern "C" void TCMalloc_Internal_ForceCpuCacheActivation() {
67 | tcmalloc::tcmalloc_internal::ActivatePerCpuCaches();
68 | }
69 |
70 | extern "C" bool MallocExtension_Internal_GetPerCpuCachesActive() {
71 | return tcmalloc::tcmalloc_internal::tc_globals.CpuCacheActive();
72 | }
73 |
74 | extern "C" int32_t MallocExtension_Internal_GetMaxPerCpuCacheSize() {
75 | return tcmalloc::tcmalloc_internal::Parameters::max_per_cpu_cache_size();
76 | }
77 |
78 | extern "C" void MallocExtension_Internal_SetMaxPerCpuCacheSize(int32_t value) {
79 | tcmalloc::tcmalloc_internal::Parameters::set_max_per_cpu_cache_size(value);
80 | }
81 |
--------------------------------------------------------------------------------
/tcmalloc/deallocation_profiler.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_DEALLOCATION_PROFILER_H_
16 | #define TCMALLOC_DEALLOCATION_PROFILER_H_
17 |
18 | #include
19 |
20 | #include "absl/base/const_init.h"
21 | #include "absl/base/internal/spinlock.h"
22 | #include "absl/time/time.h"
23 | #include "tcmalloc/internal/config.h"
24 | #include "tcmalloc/internal/logging.h"
25 | #include "tcmalloc/malloc_extension.h"
26 |
27 | GOOGLE_MALLOC_SECTION_BEGIN
28 | namespace tcmalloc {
29 | namespace deallocationz {
30 |
31 | class DeallocationProfiler;
32 |
33 | class DeallocationProfilerList {
34 | public:
35 | constexpr DeallocationProfilerList() = default;
36 |
37 | void ReportMalloc(const tcmalloc_internal::StackTrace& stack_trace);
38 | void ReportFree(tcmalloc_internal::AllocHandle handle);
39 | void Add(DeallocationProfiler* profiler);
40 | void Remove(DeallocationProfiler* profiler);
41 |
42 | private:
43 | DeallocationProfiler* first_ = nullptr;
44 | absl::base_internal::SpinLock profilers_lock_{
45 | absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY};
46 | };
47 |
48 | class DeallocationSample final
49 | : public tcmalloc_internal::AllocationProfilingTokenBase {
50 | public:
51 | explicit DeallocationSample(DeallocationProfilerList* list);
52 | // We define the dtor to ensure it is placed in the desired text section.
53 | ~DeallocationSample() override;
54 |
55 | tcmalloc::Profile Stop() && override;
56 |
57 | private:
58 | std::unique_ptr profiler_;
59 | };
60 |
61 | namespace internal {
62 | absl::Duration LifetimeNsToBucketedDuration(double lifetime_ns);
63 | } // namespace internal
64 | } // namespace deallocationz
65 | } // namespace tcmalloc
66 | GOOGLE_MALLOC_SECTION_END
67 |
68 | #endif // TCMALLOC_DEALLOCATION_PROFILER_H_
69 |
--------------------------------------------------------------------------------
/tcmalloc/error_reporting.h:
--------------------------------------------------------------------------------
1 | // Copyright 2025 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_ERROR_REPORTING_H_
16 | #define TCMALLOC_ERROR_REPORTING_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/config.h"
21 | #include "tcmalloc/static_vars.h"
22 |
23 | GOOGLE_MALLOC_SECTION_BEGIN
24 | namespace tcmalloc::tcmalloc_internal {
25 |
26 | [[noreturn]] ABSL_ATTRIBUTE_NOINLINE void ReportMismatchedDelete(
27 | Static& state, const SampledAllocation& alloc, size_t size,
28 | size_t requested_size, std::optional allocated_size);
29 |
30 | [[noreturn]] ABSL_ATTRIBUTE_NOINLINE void ReportMismatchedDelete(
31 | Static& state, void* ptr, size_t size, size_t minimum_size,
32 | size_t maximum_size);
33 |
34 | [[noreturn]]
35 | ABSL_ATTRIBUTE_NOINLINE void ReportMismatchedSizeClass(Static& state,
36 | void* object,
37 | int page_size_class,
38 | int object_size_class);
39 |
40 | [[noreturn]]
41 | ABSL_ATTRIBUTE_NOINLINE void ReportDoubleFree(Static& state, void* ptr);
42 |
43 | [[noreturn]]
44 | ABSL_ATTRIBUTE_NOINLINE void ReportCorruptedFree(
45 | Static& state, std::align_val_t expected_alignment, void* ptr);
46 |
47 | } // namespace tcmalloc::tcmalloc_internal
48 | GOOGLE_MALLOC_SECTION_END
49 |
50 | #endif // TCMALLOC_ERROR_REPORTING_H_
51 |
--------------------------------------------------------------------------------
/tcmalloc/experiment.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_EXPERIMENT_H_
16 | #define TCMALLOC_EXPERIMENT_H_
17 |
18 | #include
19 |
20 | #include
21 |
22 | #include "absl/functional/function_ref.h"
23 | #include "absl/strings/string_view.h"
24 | #include "absl/types/optional.h"
25 | #include "tcmalloc/experiment_config.h"
26 | #include "tcmalloc/internal/config.h"
27 |
28 | // TCMalloc Experiment Controller
29 | //
30 | // This consumes environment variables to decide whether to activate experiments
31 | // to control TCMalloc behavior. It avoids memory allocations when making
32 | // experiment decisions to allow experiments to be used in critical TCMalloc
33 | // initialization paths.
34 | //
35 | // If an experiment is causing difficulty, all experiments can be disabled by
36 | // setting the environment variable:
37 | // BORG_DISABLE_EXPERIMENTS=all *or*
38 | // BORG_DISABLE_EXPERIMENTS=BAD_EXPERIMENT_LABEL
39 |
40 | GOOGLE_MALLOC_SECTION_BEGIN
41 | namespace tcmalloc {
42 | namespace tcmalloc_internal {
43 |
44 | constexpr size_t kNumExperiments =
45 | static_cast(Experiment::kMaxExperimentID);
46 |
47 | // SelectExperiments parses the experiments enumerated by active and disabled
48 | // and updates buffer[experiment_id] accordingly.
49 | //
50 | // buffer must be sized for kMaxExperimentID entries.
51 | //
52 | // This is exposed for testing purposes only.
53 | const bool* SelectExperiments(bool* buffer, absl::string_view test_target,
54 | absl::string_view active,
55 | absl::string_view disabled,
56 | bool unset);
57 |
58 | } // namespace tcmalloc_internal
59 |
60 | bool IsExperimentActive(Experiment exp);
61 |
62 | std::optional FindExperimentByName(absl::string_view name);
63 |
64 | void WalkExperiments(
65 | absl::FunctionRef callback);
66 |
67 | } // namespace tcmalloc
68 | GOOGLE_MALLOC_SECTION_END
69 |
70 | #endif // TCMALLOC_EXPERIMENT_H_
71 |
--------------------------------------------------------------------------------
/tcmalloc/experiment_config.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_EXPERIMENT_CONFIG_H_
16 | #define TCMALLOC_EXPERIMENT_CONFIG_H_
17 |
18 | #include "absl/strings/string_view.h"
19 |
20 | // Autogenerated by experiments_proto_test --experiments_generate_config=true
21 | namespace tcmalloc {
22 |
23 | enum class Experiment : int {
24 | // clang-format off
25 | // go/keep-sorted start
26 | TCMALLOC_MIN_HOT_ACCESS_HINT_ABLATION, // TODO(b/376902157): Complete experiment.
27 | TCMALLOC_USERMODE_HUGEPAGE_COLLAPSE, // TODO(b/287498389): Complete experiment.
28 | TEST_ONLY_L3_AWARE, // TODO(b/239977380): Complete experiment.
29 | TEST_ONLY_TCMALLOC_COARSE_LFR_TRACKERS, // TODO(b/368054442): Complete experiment.
30 | TEST_ONLY_TCMALLOC_HUGE_CACHE_RELEASE_30S, // TODO(b/319872040): Complete experiment.
31 | TEST_ONLY_TCMALLOC_POW2_SIZECLASS,
32 | TEST_ONLY_TCMALLOC_SHARDED_TRANSFER_CACHE,
33 | // go/keep-sorted end
34 | kMaxExperimentID,
35 | // clang-format on
36 | };
37 |
38 | struct ExperimentConfig {
39 | Experiment id;
40 | absl::string_view name;
41 | };
42 |
43 | // clang-format off
44 | inline constexpr ExperimentConfig experiments[] = {
45 | // go/keep-sorted start
46 | {Experiment::TCMALLOC_MIN_HOT_ACCESS_HINT_ABLATION, "TCMALLOC_MIN_HOT_ACCESS_HINT_ABLATION"},
47 | {Experiment::TCMALLOC_USERMODE_HUGEPAGE_COLLAPSE, "TCMALLOC_USERMODE_HUGEPAGE_COLLAPSE"},
48 | {Experiment::TEST_ONLY_L3_AWARE, "TEST_ONLY_L3_AWARE"},
49 | {Experiment::TEST_ONLY_TCMALLOC_COARSE_LFR_TRACKERS, "TEST_ONLY_TCMALLOC_COARSE_LFR_TRACKERS"},
50 | {Experiment::TEST_ONLY_TCMALLOC_HUGE_CACHE_RELEASE_30S, "TEST_ONLY_TCMALLOC_HUGE_CACHE_RELEASE_30S"},
51 | {Experiment::TEST_ONLY_TCMALLOC_POW2_SIZECLASS, "TEST_ONLY_TCMALLOC_POW2_SIZECLASS"},
52 | {Experiment::TEST_ONLY_TCMALLOC_SHARDED_TRANSFER_CACHE, "TEST_ONLY_TCMALLOC_SHARDED_TRANSFER_CACHE"},
53 | // go/keep-sorted end
54 | };
55 | // clang-format on
56 |
57 | } // namespace tcmalloc
58 |
59 | #endif // TCMALLOC_EXPERIMENT_CONFIG_H_
60 |
--------------------------------------------------------------------------------
/tcmalloc/experiment_config_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/experiment_config.h"
16 |
17 | #include "gtest/gtest.h"
18 |
19 | namespace tcmalloc {
20 | namespace {
21 |
22 | // Verify IDs are non-negative and strictly less than kMaxExperimentID.
23 | TEST(ExperimentConfigTest, ValidateIDs) {
24 | for (const auto& exp : experiments) {
25 | ASSERT_LE(0, static_cast(exp.id));
26 | ASSERT_LT(exp.id, Experiment::kMaxExperimentID);
27 | }
28 | }
29 |
30 | } // namespace
31 | } // namespace tcmalloc
32 |
--------------------------------------------------------------------------------
/tcmalloc/experiment_fuzz.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 |
18 | #include "gtest/gtest.h"
19 | #include "fuzztest/fuzztest.h"
20 | #include "absl/strings/string_view.h"
21 | #include "tcmalloc/experiment.h"
22 |
23 | namespace tcmalloc::tcmalloc_internal {
24 | namespace {
25 |
26 | void FuzzSelectExperiments(absl::string_view test_target,
27 | absl::string_view active, absl::string_view disabled,
28 | bool unset) {
29 | if (unset && !test_target.empty() && (!active.empty() || !disabled.empty())) {
30 | return;
31 | }
32 |
33 | bool buffer[tcmalloc::tcmalloc_internal::kNumExperiments];
34 |
35 | SelectExperiments(buffer, test_target, active, disabled,
36 | unset);
37 | }
38 |
39 | FUZZ_TEST(ExperimentTest, FuzzSelectExperiments);
40 |
41 | TEST(ExperimentTest, FuzzSelectExperiments_b395212979) {
42 | FuzzSelectExperiments(
43 | "t_fuenchmark&"
44 | "vvvvvvvvvvvvvvvvvvVvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv",
45 | "", "",
46 | true);
47 | }
48 |
49 | } // namespace
50 | } // namespace tcmalloc::tcmalloc_internal
51 |
--------------------------------------------------------------------------------
/tcmalloc/guarded_allocations.h:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_GUARDED_ALLOCATIONS_H_
16 | #define TCMALLOC_GUARDED_ALLOCATIONS_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/config.h"
21 | #include "tcmalloc/internal/logging.h"
22 | #include "tcmalloc/malloc_extension.h"
23 |
24 | GOOGLE_MALLOC_SECTION_BEGIN
25 | namespace tcmalloc {
26 | namespace tcmalloc_internal {
27 |
28 | struct GuardedAllocationsStackTrace {
29 | void* stack[kMaxStackDepth];
30 | size_t depth = 0;
31 | pid_t thread_id = 0;
32 | };
33 |
34 | enum class WriteFlag : int { Unknown, Read, Write };
35 |
36 | enum class GuardedAllocationsErrorType {
37 | kUseAfterFree,
38 | kUseAfterFreeRead,
39 | kUseAfterFreeWrite,
40 | kBufferUnderflow,
41 | kBufferUnderflowRead,
42 | kBufferUnderflowWrite,
43 | kBufferOverflow,
44 | kBufferOverflowRead,
45 | kBufferOverflowWrite,
46 | kDoubleFree,
47 | kBufferOverflowOnDealloc,
48 | kUnknown,
49 | };
50 |
51 | struct GuardedAllocWithStatus {
52 | void* alloc = nullptr;
53 | Profile::Sample::GuardedStatus status;
54 | };
55 |
56 | } // namespace tcmalloc_internal
57 | } // namespace tcmalloc
58 | GOOGLE_MALLOC_SECTION_END
59 |
60 | #endif // TCMALLOC_GUARDED_ALLOCATIONS_H_
61 |
--------------------------------------------------------------------------------
/tcmalloc/huge_address_map_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/huge_address_map.h"
16 |
17 | #include
18 | #include
19 |
20 | #include
21 |
22 | #include "gmock/gmock.h"
23 | #include "gtest/gtest.h"
24 | #include "tcmalloc/mock_metadata_allocator.h"
25 |
26 | namespace tcmalloc {
27 | namespace tcmalloc_internal {
28 | namespace {
29 |
30 | class HugeAddressMapTest : public ::testing::Test {
31 | protected:
32 | HugeAddressMapTest() : map_(malloc_metadata_) {}
33 |
34 | std::vector Contents() {
35 | std::vector ret;
36 | auto node = map_.first();
37 | while (node) {
38 | ret.push_back(node->range());
39 | node = node->next();
40 | }
41 |
42 | return ret;
43 | }
44 |
45 | HugePage hp(size_t i) { return {i}; }
46 | HugeLength hl(size_t i) { return NHugePages(i); }
47 |
48 | HugeAddressMap map_;
49 |
50 | private:
51 | FakeMetadataAllocator malloc_metadata_;
52 | };
53 |
54 | // This test verifies that HugeAddressMap merges properly.
55 | TEST_F(HugeAddressMapTest, Merging) {
56 | const HugeRange r1 = HugeRange::Make(hp(0), hl(1));
57 | const HugeRange r2 = HugeRange::Make(hp(1), hl(1));
58 | const HugeRange r3 = HugeRange::Make(hp(2), hl(1));
59 | const HugeRange all = Join(r1, Join(r2, r3));
60 | map_.Insert(r1);
61 | map_.Check();
62 | EXPECT_THAT(Contents(), testing::ElementsAre(r1));
63 | map_.Insert(r3);
64 | map_.Check();
65 | EXPECT_THAT(Contents(), testing::ElementsAre(r1, r3));
66 | map_.Insert(r2);
67 | map_.Check();
68 | EXPECT_THAT(Contents(), testing::ElementsAre(all));
69 | }
70 |
71 | } // namespace
72 | } // namespace tcmalloc_internal
73 | } // namespace tcmalloc
74 |
--------------------------------------------------------------------------------
/tcmalloc/internal/affinity.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_AFFINITY_H_
16 | #define TCMALLOC_INTERNAL_AFFINITY_H_
17 |
18 | #include
19 |
20 | #include
21 |
22 | #include "absl/types/span.h"
23 | #include "tcmalloc/internal/config.h"
24 | #include "tcmalloc/internal/cpu_utils.h"
25 |
26 | GOOGLE_MALLOC_SECTION_BEGIN
27 | namespace tcmalloc {
28 | namespace tcmalloc_internal {
29 |
30 | // Affinity helpers.
31 |
32 | // Returns a vector of the which cpus the currently allowed thread is allowed to
33 | // run on. There are no guarantees that this will not change before, after, or
34 | // even during, the call to AllowedCpus().
35 | std::vector AllowedCpus();
36 |
37 | // Enacts a scoped affinity mask on the constructing thread. Attempts to
38 | // restore the original affinity mask on destruction.
39 | //
40 | // REQUIRES: For test-use only. Do not use this in production code.
41 | class ScopedAffinityMask {
42 | public:
43 | // When racing with an external restriction that has a zero-intersection with
44 | // "allowed_cpus" we will construct, but immediately register as "Tampered()",
45 | // without actual changes to affinity.
46 | explicit ScopedAffinityMask(absl::Span allowed_cpus);
47 | explicit ScopedAffinityMask(int allowed_cpu);
48 |
49 | // Restores original affinity iff our scoped affinity has not been externally
50 | // modified (i.e. Tampered()). Otherwise, the updated affinity is preserved.
51 | ~ScopedAffinityMask();
52 |
53 | // Returns true if the affinity mask no longer matches what was set at point
54 | // of construction.
55 | //
56 | // Note: This is instantaneous and not fool-proof. It's possible for an
57 | // external affinity modification to subsequently align with our originally
58 | // specified "allowed_cpus". In this case Tampered() will return false when
59 | // time may have been spent executing previously on non-specified cpus.
60 | bool Tampered();
61 |
62 | private:
63 | CpuSet original_cpus_, specified_cpus_;
64 | };
65 |
66 | } // namespace tcmalloc_internal
67 | } // namespace tcmalloc
68 | GOOGLE_MALLOC_SECTION_END
69 |
70 | #endif // TCMALLOC_INTERNAL_AFFINITY_H_
71 |
--------------------------------------------------------------------------------
/tcmalloc/internal/allocation_guard.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/allocation_guard.h"
16 |
17 | #include "absl/base/attributes.h"
18 | #include "tcmalloc/internal/config.h"
19 |
20 | GOOGLE_MALLOC_SECTION_BEGIN
21 | namespace tcmalloc::tcmalloc_internal {
22 |
23 | } // namespace tcmalloc::tcmalloc_internal
24 | GOOGLE_MALLOC_SECTION_END
25 |
--------------------------------------------------------------------------------
/tcmalloc/internal/allocation_guard.h:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_ALLOCATION_GUARD_H_
16 | #define TCMALLOC_INTERNAL_ALLOCATION_GUARD_H_
17 |
18 | #include "absl/base/attributes.h"
19 | #include "absl/base/internal/spinlock.h"
20 | #include "absl/base/thread_annotations.h"
21 | #include "tcmalloc/internal/config.h"
22 |
23 | GOOGLE_MALLOC_SECTION_BEGIN
24 | namespace tcmalloc::tcmalloc_internal {
25 |
26 | // TODO(b/143069684): actually ensure no allocations in debug mode here.
27 | struct AllocationGuard {
28 | AllocationGuard() {}
29 | };
30 |
31 | // A SpinLockHolder that also enforces no allocations while the lock is held in
32 | // debug mode.
33 | class ABSL_SCOPED_LOCKABLE AllocationGuardSpinLockHolder {
34 | public:
35 | explicit AllocationGuardSpinLockHolder(absl::base_internal::SpinLock* l)
36 | ABSL_EXCLUSIVE_LOCK_FUNCTION(l)
37 | : lock_holder_(l) {
38 | #ifndef NDEBUG
39 | if (l->IsCooperative()) {
40 | abort();
41 | }
42 | #endif // NDEBUG
43 | }
44 |
45 | inline ~AllocationGuardSpinLockHolder() ABSL_UNLOCK_FUNCTION() = default;
46 |
47 | private:
48 | absl::base_internal::SpinLockHolder lock_holder_;
49 | // In debug mode, enforces no allocations.
50 | AllocationGuard enforce_no_alloc_;
51 | };
52 |
53 | } // namespace tcmalloc::tcmalloc_internal
54 | GOOGLE_MALLOC_SECTION_END
55 |
56 | #endif // TCMALLOC_INTERNAL_ALLOCATION_GUARD_H_
57 |
--------------------------------------------------------------------------------
/tcmalloc/internal/allocation_guard_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2023 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/allocation_guard.h"
16 |
17 | #include
18 |
19 | #include "gtest/gtest.h"
20 | #include "absl/base/const_init.h"
21 | #include "absl/base/internal/spinlock.h"
22 |
23 | namespace tcmalloc::tcmalloc_internal {
24 | namespace {
25 |
26 | TEST(AllocationGuard, Noncooperative) {
27 | absl::base_internal::SpinLock lock(absl::kConstInit,
28 | absl::base_internal::SCHEDULE_KERNEL_ONLY);
29 | AllocationGuardSpinLockHolder h(&lock);
30 | }
31 |
32 | TEST(AllocationGuard, CooperativeDeathTest) {
33 | absl::base_internal::SpinLock lock;
34 |
35 | EXPECT_DEBUG_DEATH(
36 | { AllocationGuardSpinLockHolder h(&lock); }, "SIGABRT received");
37 | }
38 |
39 | } // namespace
40 | } // namespace tcmalloc::tcmalloc_internal
41 |
--------------------------------------------------------------------------------
/tcmalloc/internal/atomic_danger.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // The routines exported by this module are subtle and dangerous.
16 |
17 | #ifndef TCMALLOC_INTERNAL_ATOMIC_DANGER_H_
18 | #define TCMALLOC_INTERNAL_ATOMIC_DANGER_H_
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include "tcmalloc/internal/config.h"
25 |
26 | GOOGLE_MALLOC_SECTION_BEGIN
27 | namespace tcmalloc {
28 | namespace tcmalloc_internal {
29 | namespace atomic_danger {
30 |
31 | // Casts the address of a std::atomic to the address of an IntType.
32 | //
33 | // This is almost certainly not the function you are looking for! It is
34 | // undefined behavior, as the object under a std::atomic isn't
35 | // fundamentally an int. This function is intended for passing the address of an
36 | // atomic integer to syscalls or for assembly interpretation.
37 | //
38 | // Callers should be migrated if C++ standardizes a better way to do this:
39 | // * http://wg21.link/n4013 (Atomic operations on non-atomic data)
40 | // * http://wg21.link/p0019 (Atomic Ref, merged into C++20)
41 | // * http://wg21.link/p1478 (Byte-wise atomic memcpy)
42 | template
43 | IntType* CastToIntegral(std::atomic* atomic_for_syscall) {
44 | static_assert(std::is_integral::value,
45 | "CastToIntegral must be instantiated with an integral type.");
46 | #if __cpp_lib_atomic_is_always_lock_free >= 201603
47 | static_assert(std::atomic::is_always_lock_free,
48 | "CastToIntegral must be instantiated with a lock-free type.");
49 | #else
50 | static_assert(__atomic_always_lock_free(sizeof(IntType),
51 | nullptr /* typical alignment */),
52 | "CastToIntegral must be instantiated with a lock-free type.");
53 | #endif
54 | return reinterpret_cast(atomic_for_syscall);
55 | }
56 | } // namespace atomic_danger
57 | } // namespace tcmalloc_internal
58 | } // namespace tcmalloc
59 | GOOGLE_MALLOC_SECTION_END
60 |
61 | #endif // TCMALLOC_INTERNAL_ATOMIC_DANGER_H_
62 |
--------------------------------------------------------------------------------
/tcmalloc/internal/cache_topology.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_CACHE_TOPOLOGY_H_
16 | #define TCMALLOC_INTERNAL_CACHE_TOPOLOGY_H_
17 |
18 | #include
19 |
20 | #include "absl/base/attributes.h"
21 | #include "absl/strings/string_view.h"
22 | #include "tcmalloc/internal/config.h"
23 | #include "tcmalloc/internal/cpu_utils.h"
24 | #include "tcmalloc/internal/logging.h"
25 |
26 | GOOGLE_MALLOC_SECTION_BEGIN
27 | namespace tcmalloc {
28 | namespace tcmalloc_internal {
29 |
30 | class CacheTopology {
31 | public:
32 | static CacheTopology& Instance() {
33 | ABSL_CONST_INIT static CacheTopology instance;
34 | return instance;
35 | }
36 |
37 | constexpr CacheTopology() = default;
38 |
39 | void Init();
40 |
41 | unsigned l3_count() const { return l3_count_; }
42 |
43 | unsigned GetL3FromCpuId(int cpu) const {
44 | TC_ASSERT_GE(cpu, 0);
45 | TC_ASSERT_LT(cpu, cpu_count_);
46 | unsigned l3 = l3_cache_index_[cpu];
47 | TC_ASSERT_LT(l3, l3_count_);
48 | return l3;
49 | }
50 |
51 | private:
52 | unsigned cpu_count_ = 0;
53 | unsigned l3_count_ = 0;
54 | uint8_t l3_cache_index_[kMaxCpus] = {};
55 | };
56 |
57 | } // namespace tcmalloc_internal
58 | } // namespace tcmalloc
59 | GOOGLE_MALLOC_SECTION_END
60 |
61 | #endif // TCMALLOC_INTERNAL_CACHE_TOPOLOGY_H_
62 |
--------------------------------------------------------------------------------
/tcmalloc/internal/cache_topology_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/cache_topology.h"
16 |
17 | #include "gtest/gtest.h"
18 | #include "tcmalloc/internal/sysinfo.h"
19 |
20 | namespace tcmalloc::tcmalloc_internal {
21 | namespace {
22 |
23 | TEST(CacheTopology, ComputesSomethingReasonable) {
24 | // This test verifies that each L3 cache serves the same number of CPU. This
25 | // is not a strict requirement for the correct operation of this code, but a
26 | // sign of sanity.
27 | CacheTopology topology;
28 | topology.Init();
29 | EXPECT_EQ(NumCPUs() % topology.l3_count(), 0);
30 | ASSERT_GT(topology.l3_count(), 0);
31 | static const int kMaxNodes = 256 / 8;
32 | int count_per_node[kMaxNodes] = {0};
33 | for (int i = 0, n = NumCPUs(); i < n; ++i) {
34 | count_per_node[topology.GetL3FromCpuId(i)]++;
35 | }
36 | for (int i = 0; i < topology.l3_count(); ++i) {
37 | EXPECT_EQ(count_per_node[i], NumCPUs() / topology.l3_count());
38 | }
39 | }
40 |
41 | } // namespace
42 | } // namespace tcmalloc::tcmalloc_internal
43 |
--------------------------------------------------------------------------------
/tcmalloc/internal/clock.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_CLOCK_H_
16 | #define TCMALLOC_INTERNAL_CLOCK_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/config.h"
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc {
24 | namespace tcmalloc_internal {
25 |
26 | // Represents an abstract clock. The now and freq functions are analogous to
27 | // CycleClock::Now and CycleClock::Frequency, which will be the most commonly
28 | // used implementations. Tests can use this interface to mock out the clock.
29 | struct Clock {
30 | // Returns the current time in ticks (relative to an arbitrary time base).
31 | int64_t (*now)();
32 |
33 | // Returns the number of ticks per second.
34 | double (*freq)();
35 | };
36 |
37 | } // namespace tcmalloc_internal
38 | } // namespace tcmalloc
39 | GOOGLE_MALLOC_SECTION_END
40 |
41 | #endif // TCMALLOC_INTERNAL_CLOCK_H_
42 |
--------------------------------------------------------------------------------
/tcmalloc/internal/declarations.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // These declarations are for internal use, allowing us to have access to
16 | // allocation functions whose declarations are not provided by the standard
17 | // library.
18 | #ifndef TCMALLOC_INTERNAL_DECLARATIONS_H_
19 | #define TCMALLOC_INTERNAL_DECLARATIONS_H_
20 |
21 | #if !defined(__cpp_sized_deallocation) || !defined(__cpp_aligned_new)
22 | #include
23 | #include
24 | #endif // !defined(__cpp_sized_deallocation) || !defined(__cpp_aligned_new)
25 |
26 | #if !defined(__cpp_sized_deallocation)
27 |
28 | void operator delete(void*, std::size_t) noexcept;
29 | void operator delete[](void*, std::size_t) noexcept;
30 |
31 | #endif // !defined(__cpp_sized_deallocation)
32 |
33 | #if !defined(__cpp_aligned_new)
34 |
35 | namespace std {
36 | enum class align_val_t : size_t;
37 | } // namespace std
38 |
39 | void* operator new(std::size_t, std::align_val_t);
40 | void* operator new(std::size_t, std::align_val_t,
41 | const std::nothrow_t&) noexcept;
42 | void* operator new[](std::size_t, std::align_val_t);
43 | void* operator new[](std::size_t, std::align_val_t,
44 | const std::nothrow_t&) noexcept;
45 |
46 | void operator delete(void*, std::align_val_t) noexcept;
47 | void operator delete[](void*, std::align_val_t) noexcept;
48 |
49 | #endif // !defined(__cpp_aligned_new)
50 |
51 | #if !defined(__cpp_sized_deallocation) || !defined(__cpp_aligned_new)
52 |
53 | void operator delete(void*, std::size_t, std::align_val_t) noexcept;
54 | void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
55 |
56 | #endif // !defined(__cpp_sized_deallocation) || !defined(__cpp_aligned_new)
57 |
58 | #endif // TCMALLOC_INTERNAL_DECLARATIONS_H_
59 |
--------------------------------------------------------------------------------
/tcmalloc/internal/environment.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | #include "tcmalloc/internal/environment.h"
15 |
16 | #include
17 |
18 | #include "absl/base/attributes.h"
19 | #include "tcmalloc/internal/config.h"
20 |
21 | GOOGLE_MALLOC_SECTION_BEGIN
22 | namespace tcmalloc {
23 | namespace tcmalloc_internal {
24 |
25 | #ifdef __linux__
26 | // POSIX provides the **environ array which contains environment variables in a
27 | // linear array, terminated by a NULL string. This array is only perturbed when
28 | // the environment is changed (which is inherently unsafe) so it's safe to
29 | // return a const pointer into it.
30 | // e.g. { "SHELL=/bin/bash", "MY_ENV_VAR=1", "" }
31 | extern "C" char** environ;
32 | ABSL_ATTRIBUTE_WEAK const char* thread_safe_getenv(const char* env_var) {
33 | int var_len = strlen(env_var);
34 |
35 | char** envv = environ;
36 | if (!envv) {
37 | return nullptr;
38 | }
39 |
40 | for (; *envv != nullptr; envv++)
41 | if (strncmp(*envv, env_var, var_len) == 0 && (*envv)[var_len] == '=')
42 | return *envv + var_len + 1; // skip over the '='
43 |
44 | return nullptr;
45 | }
46 | #else
47 | const char* thread_safe_getenv(const char* env_var) { return nullptr; }
48 | #endif
49 |
50 | } // namespace tcmalloc_internal
51 | } // namespace tcmalloc
52 | GOOGLE_MALLOC_SECTION_END
53 |
--------------------------------------------------------------------------------
/tcmalloc/internal/environment.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_ENVIRONMENT_H_
16 | #define TCMALLOC_INTERNAL_ENVIRONMENT_H_
17 |
18 | #include "tcmalloc/internal/config.h"
19 |
20 | GOOGLE_MALLOC_SECTION_BEGIN
21 | namespace tcmalloc {
22 | namespace tcmalloc_internal {
23 |
24 | // WARNING ********************************************************************
25 | // getenv(2) can only be safely used in the absence of calls which perturb the
26 | // environment (e.g. putenv/setenv/clearenv). The use of such calls is
27 | // strictly thread-hostile since these calls do *NOT* synchronize and there is
28 | // *NO* thread-safe way in which the POSIX **environ array may be queried about
29 | // modification.
30 | // ****************************************************************************
31 | // The default getenv(2) is not guaranteed to be thread-safe as there are no
32 | // semantics specifying the implementation of the result buffer. The result
33 | // from thread_safe_getenv() may be safely queried in a multi-threaded context.
34 | // If you have explicit synchronization with changes environment variables then
35 | // any copies of the returned pointer must be invalidated across modification.
36 | const char* thread_safe_getenv(const char* env_var);
37 |
38 | } // namespace tcmalloc_internal
39 | } // namespace tcmalloc
40 | GOOGLE_MALLOC_SECTION_END
41 |
42 | #endif // TCMALLOC_INTERNAL_ENVIRONMENT_H_
43 |
--------------------------------------------------------------------------------
/tcmalloc/internal/environment_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/environment.h"
16 |
17 | #include
18 | #include
19 |
20 | #include "gtest/gtest.h"
21 |
22 | namespace tcmalloc {
23 | namespace tcmalloc_internal {
24 | namespace {
25 |
26 | TEST(EnvironmentTest, thread_safe_getenv) {
27 | // Should never be defined at test start
28 | const char *result, *undefined_env_var = "UTIL_TEST_UNDEFINED_ENV_VAR";
29 |
30 | // Check that we handle an undefined variable and then set it
31 | ASSERT_TRUE(getenv(undefined_env_var) == nullptr);
32 | ASSERT_TRUE(thread_safe_getenv(undefined_env_var) == nullptr);
33 | ASSERT_EQ(setenv(undefined_env_var, "1234567890", 0), 0);
34 | ASSERT_TRUE(getenv(undefined_env_var) != nullptr);
35 |
36 | // Make sure we can find the new variable
37 | result = thread_safe_getenv(undefined_env_var);
38 | ASSERT_TRUE(result != nullptr);
39 | // ... and that it matches what was set
40 | EXPECT_EQ(strcmp(result, getenv(undefined_env_var)), 0);
41 | }
42 |
43 | } // namespace
44 | } // namespace tcmalloc_internal
45 | } // namespace tcmalloc
46 |
--------------------------------------------------------------------------------
/tcmalloc/internal/explicitly_constructed.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_EXPLICITLY_CONSTRUCTED_H_
16 | #define TCMALLOC_INTERNAL_EXPLICITLY_CONSTRUCTED_H_
17 |
18 | #include
19 |
20 | #include
21 |
22 | #include "tcmalloc/internal/config.h"
23 |
24 | GOOGLE_MALLOC_SECTION_BEGIN
25 | namespace tcmalloc {
26 | namespace tcmalloc_internal {
27 |
28 | // Wraps a variable whose constructor is explicitly called. It is particularly
29 | // useful for a global variable, without its constructor and destructor run on
30 | // start and end of the program lifetime. This circumvents the initial
31 | // construction order fiasco, while keeping the address of the empty string a
32 | // compile time constant.
33 | //
34 | // Pay special attention to the initialization state of the object.
35 | // 1. The object is "uninitialized" to begin with.
36 | // 2. Call Construct() only if the object is uninitialized. After the call, the
37 | // object becomes "initialized".
38 | // 3. Call get_mutable() only if the object is initialized.
39 | template
40 | class ExplicitlyConstructed {
41 | public:
42 | template
43 | void Construct(Args&&... args) {
44 | new (&union_) T(std::forward(args)...);
45 | }
46 |
47 | T& get_mutable() { return reinterpret_cast(union_); }
48 |
49 | private:
50 | union AlignedUnion {
51 | constexpr AlignedUnion() = default;
52 | alignas(T) char space[sizeof(T)];
53 | int64_t align_to_int64;
54 | void* align_to_ptr;
55 | } union_;
56 | };
57 |
58 | } // namespace tcmalloc_internal
59 | } // namespace tcmalloc
60 | GOOGLE_MALLOC_SECTION_END
61 |
62 | #endif // TCMALLOC_INTERNAL_EXPLICITLY_CONSTRUCTED_H_
63 |
--------------------------------------------------------------------------------
/tcmalloc/internal/exponential_biased.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_EXPONENTIAL_BIASED_H_
16 | #define TCMALLOC_INTERNAL_EXPONENTIAL_BIASED_H_
17 |
18 | #include
19 | #include
20 |
21 | namespace tcmalloc {
22 | namespace tcmalloc_internal {
23 |
24 | class ExponentialBiased {
25 | public:
26 | static uint64_t NextRandom(uint64_t rnd);
27 | static uint32_t GetRandom(uint64_t rnd);
28 | };
29 |
30 | // Returns the next prng value.
31 | // pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48
32 | // This is the lrand64 generator.
33 | inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) {
34 | const uint64_t prng_mult = UINT64_C(0x5DEECE66D);
35 | const uint64_t prng_add = 0xB;
36 | const uint64_t prng_mod_power = 48;
37 | const uint64_t prng_mod_mask =
38 | ~((~static_cast(0)) << prng_mod_power);
39 | return (prng_mult * rnd + prng_add) & prng_mod_mask;
40 | }
41 |
42 | // Extracts higher-quality random bits.
43 | // The raw value returned from NextRandom has poor randomness low bits
44 | // and is not directly suitable for things like 'if (rnd % 2)'.
45 | inline uint32_t ExponentialBiased::GetRandom(uint64_t rnd) { return rnd >> 16; }
46 |
47 | // Convenience wrapper to initialize a seed and return a sequence of
48 | // pseudo-random values. Thread-safety: thread safe.
49 | class Random {
50 | public:
51 | constexpr explicit Random(uint64_t seed) : state_(seed) {}
52 |
53 | // Return the next pseudo-random value.
54 | uint32_t Next();
55 |
56 | // Reset internal state with provided seed.
57 | void Reset(uint64_t seed);
58 |
59 | private:
60 | std::atomic state_;
61 | };
62 |
63 | inline uint32_t Random::Next() {
64 | uint64_t r = state_.load(std::memory_order_relaxed);
65 | r = ExponentialBiased::NextRandom(r);
66 | state_.store(r, std::memory_order_relaxed);
67 | return ExponentialBiased::GetRandom(r);
68 | }
69 |
70 | inline void Random::Reset(uint64_t seed) {
71 | state_.store(seed, std::memory_order_relaxed);
72 | }
73 |
74 | } // namespace tcmalloc_internal
75 | } // namespace tcmalloc
76 |
77 | #endif // TCMALLOC_INTERNAL_EXPONENTIAL_BIASED_H_
78 |
--------------------------------------------------------------------------------
/tcmalloc/internal/fake_profile.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_FAKE_PROFILE_H_
16 | #define TCMALLOC_INTERNAL_FAKE_PROFILE_H_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "absl/functional/function_ref.h"
23 | #include "absl/time/time.h"
24 | #include "tcmalloc/malloc_extension.h"
25 |
26 | namespace tcmalloc {
27 | namespace tcmalloc_internal {
28 |
29 | class FakeProfile final : public ProfileBase {
30 | public:
31 | void SetSamples(std::vector samples) {
32 | samples_ = std::move(samples);
33 | }
34 |
35 | // For each sample in the profile, Iterate invokes the callback f on the
36 | // sample.
37 | void Iterate(
38 | absl::FunctionRef f) const override {
39 | for (const auto& sample : samples_) {
40 | f(sample);
41 | }
42 | }
43 |
44 | // The type of profile (live objects, allocated, etc.).
45 | ProfileType Type() const override { return type_; }
46 | void SetType(ProfileType type) { type_ = type; }
47 |
48 | // The duration of the profile
49 | absl::Duration Duration() const override { return duration_; }
50 | void SetDuration(absl::Duration duration) { duration_ = duration; }
51 |
52 | std::optional StartTime() const override { return start_time_; }
53 | void SetStartTime(std::optional t) { start_time_ = t; }
54 |
55 | private:
56 | std::vector samples_;
57 | ProfileType type_;
58 | absl::Duration duration_;
59 | std::optional start_time_;
60 | };
61 |
62 | } // namespace tcmalloc_internal
63 | } // namespace tcmalloc
64 |
65 | #endif // TCMALLOC_INTERNAL_FAKE_PROFILE_H_
66 |
--------------------------------------------------------------------------------
/tcmalloc/internal/hook_list.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2025 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/hook_list.h"
16 |
17 | #include "absl/base/attributes.h"
18 | #include "absl/base/const_init.h"
19 | #include "absl/base/internal/spinlock.h"
20 | #include "tcmalloc/internal/config.h"
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc::tcmalloc_internal {
24 |
25 | ABSL_CONST_INIT absl::base_internal::SpinLock HookListBase::hooklist_spinlock_{
26 | absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY};
27 |
28 | } // namespace tcmalloc::tcmalloc_internal
29 | GOOGLE_MALLOC_SECTION_END
30 |
--------------------------------------------------------------------------------
/tcmalloc/internal/linux_syscall_support.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_LINUX_SYSCALL_SUPPORT_H_
16 | #define TCMALLOC_INTERNAL_LINUX_SYSCALL_SUPPORT_H_
17 |
18 | #ifdef __linux__
19 | #ifdef __has_include
20 | #if __has_include()
21 | #include
22 | #endif // __has_include()
23 | #endif // __has_include
24 | #endif // __linux__
25 |
26 | /* include/uapi/linux/rseq.h */
27 |
28 | struct kernel_rseq {
29 | unsigned cpu_id_start;
30 | unsigned cpu_id;
31 | unsigned long long rseq_cs;
32 | unsigned flags;
33 | unsigned padding[2];
34 | // This is a prototype extension to the rseq() syscall. Since a process may
35 | // run on only a few cores at a time, we can use a dense set of "v(irtual)
36 | // cpus." This can reduce cache requirements, as we only need N caches for
37 | // the cores we actually run on simultaneously, rather than a cache for every
38 | // physical core.
39 | union {
40 | struct {
41 | short numa_node_id;
42 | short vcpu_id;
43 | };
44 | int vcpu_flat;
45 | };
46 | } __attribute__((aligned(4 * sizeof(unsigned long long))));
47 |
48 | static_assert(sizeof(kernel_rseq) == (4 * sizeof(unsigned long long)),
49 | "Unexpected size for rseq structure");
50 |
51 | struct kernel_rseq_cs {
52 | // This is aligned, per upstream RSEQ specification.
53 | } __attribute__((aligned(4 * sizeof(unsigned long long))));
54 |
55 | static_assert(sizeof(kernel_rseq_cs) == (4 * sizeof(unsigned long long)),
56 | "Unexpected size for rseq_cs structure");
57 |
58 | #if !defined(__NR_rseq)
59 | #if defined(__x86_64__)
60 | #define __NR_rseq 334
61 | #elif defined(__aarch64__)
62 | #define __NR_rseq 293
63 | #elif defined(__PPC__)
64 | #define __NR_rseq 387
65 | #endif
66 | #endif
67 |
68 | #ifndef KPF_ZERO_PAGE
69 | #define KPF_ZERO_PAGE 24
70 | #endif
71 |
72 | #endif // TCMALLOC_INTERNAL_LINUX_SYSCALL_SUPPORT_H_
73 |
--------------------------------------------------------------------------------
/tcmalloc/internal/logging_test_helper.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // This is a trivial program. When run with a virtual address size rlimit,
16 | // TCMalloc should crash cleanly, rather than hang.
17 |
18 | int main() { return 0; }
19 |
--------------------------------------------------------------------------------
/tcmalloc/internal/memory_stats.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_MEMORY_STATS_H_
16 | #define TCMALLOC_INTERNAL_MEMORY_STATS_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/config.h"
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc {
24 | namespace tcmalloc_internal {
25 |
26 | struct MemoryStats {
27 | int64_t vss;
28 | int64_t rss;
29 | int64_t shared;
30 | int64_t code;
31 | int64_t data;
32 | };
33 |
34 | // Memory stats of a process
35 | bool GetMemoryStats(MemoryStats* stats);
36 |
37 | } // namespace tcmalloc_internal
38 | } // namespace tcmalloc
39 | GOOGLE_MALLOC_SECTION_END
40 |
41 | #endif // TCMALLOC_INTERNAL_MEMORY_STATS_H_
42 |
--------------------------------------------------------------------------------
/tcmalloc/internal/memory_stats_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/memory_stats.h"
16 |
17 | #include
18 | #include
19 |
20 | #include "gtest/gtest.h"
21 |
22 | namespace tcmalloc {
23 | namespace tcmalloc_internal {
24 | namespace {
25 |
26 | TEST(Stats, ValidRanges) {
27 | MemoryStats stats;
28 | #if defined(__linux__)
29 | ASSERT_TRUE(GetMemoryStats(&stats));
30 | #else
31 | ASSERT_FALSE(GetMemoryStats(&stats));
32 | return;
33 | #endif
34 |
35 | EXPECT_GT(stats.vss, 0);
36 | EXPECT_GT(stats.rss, 0);
37 | EXPECT_GT(stats.shared, 0);
38 | EXPECT_GT(stats.code, 0);
39 | EXPECT_GT(stats.data, 0);
40 | }
41 |
42 | } // namespace
43 | } // namespace tcmalloc_internal
44 | } // namespace tcmalloc
45 |
--------------------------------------------------------------------------------
/tcmalloc/internal/memory_tag.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/memory_tag.h"
16 |
17 | #include "absl/strings/string_view.h"
18 | #include "tcmalloc/internal/config.h"
19 | #include "tcmalloc/internal/optimization.h"
20 |
21 | GOOGLE_MALLOC_SECTION_BEGIN
22 | namespace tcmalloc::tcmalloc_internal {
23 |
24 | absl::string_view MemoryTagToLabel(MemoryTag tag) {
25 | switch (tag) {
26 | case MemoryTag::kNormal:
27 | return "NORMAL";
28 | case MemoryTag::kNormalP1:
29 | return "NORMAL_P1";
30 | case MemoryTag::kSampled:
31 | return "SAMPLED";
32 | case MemoryTag::kSelSan:
33 | return "SELSAN";
34 | case MemoryTag::kCold:
35 | return "COLD";
36 | case MemoryTag::kMetadata:
37 | return "METADATA";
38 | }
39 |
40 | ASSUME(false);
41 | }
42 |
43 | } // namespace tcmalloc::tcmalloc_internal
44 | GOOGLE_MALLOC_SECTION_END
45 |
--------------------------------------------------------------------------------
/tcmalloc/internal/mincore.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_MINCORE_H_
16 | #define TCMALLOC_INTERNAL_MINCORE_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/config.h"
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc {
24 | namespace tcmalloc_internal {
25 |
26 | // Class to wrap mincore so that we can replace it for testing.
27 | class MInCoreInterface {
28 | public:
29 | MInCoreInterface() {}
30 | virtual ~MInCoreInterface() {}
31 | virtual int mincore(void* addr, size_t length, unsigned char* result) = 0;
32 |
33 | private:
34 | MInCoreInterface(const MInCoreInterface&) = delete;
35 | MInCoreInterface& operator=(const MInCoreInterface&) = delete;
36 | };
37 |
38 | // The MInCore class through the function residence(addr, size) provides
39 | // a convenient way to report the residence of an arbitrary memory region.
40 | // This is a wrapper for the ::mincore() function. The ::mincore() function has
41 | // the constraint of requiring the base address to be page aligned.
42 | class MInCore {
43 | public:
44 | MInCore() {}
45 | // For a region of memory return the number of bytes that are
46 | // actually resident in memory. Note that the address and size
47 | // do not need to be a multiple of the system page size.
48 | static size_t residence(void* addr, size_t size);
49 |
50 | private:
51 | // Separate out the implementation to make the code easier to test.
52 | static size_t residence_impl(void* addr, size_t size,
53 | MInCoreInterface* mincore);
54 |
55 | // Size of the array used to gather results from mincore().
56 | static constexpr int kArrayLength = 4096;
57 | // Friends required for testing
58 | friend class MInCoreTest;
59 | };
60 |
61 | } // namespace tcmalloc_internal
62 | } // namespace tcmalloc
63 | GOOGLE_MALLOC_SECTION_END
64 |
65 | #endif // TCMALLOC_INTERNAL_MINCORE_H_
66 |
--------------------------------------------------------------------------------
/tcmalloc/internal/mincore_benchmark.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "benchmark/benchmark.h"
24 | #include "tcmalloc/internal/config.h"
25 | #include "tcmalloc/internal/logging.h"
26 | #include "tcmalloc/internal/page_size.h"
27 |
28 | GOOGLE_MALLOC_SECTION_BEGIN
29 | namespace tcmalloc {
30 | namespace {
31 |
32 | // Benchmark performance of mincore. We use an array on the stack to gather
33 | // mincore data. The larger the array the more we amortise the cost of calling
34 | // mincore, but the more stack space the array takes up.
35 | void BM_mincore(benchmark::State& state) {
36 | const int size = state.range(0);
37 |
38 | // If we want to place the array on the stack then the maximum frame size is
39 | // 16KiB. So there is no point in benchmarking sizes larger than this.
40 | const int kMaxArraySize = 16 * 1024;
41 | TC_CHECK_LE(size, kMaxArraySize);
42 | auto resident = std::make_unique(kMaxArraySize);
43 |
44 | const size_t kPageSize = tcmalloc_internal::GetPageSize();
45 | // We want to scan the same amount of memory in all cases
46 | const size_t regionSize = 1 * 1024 * 1024 * 1024;
47 | for (auto s : state) {
48 | uintptr_t memory = 0;
49 | while (memory < regionSize) {
50 | // Call mincore for the next section
51 | int length = std::min(size * kPageSize, (regionSize - memory));
52 | ::mincore(reinterpret_cast(memory), length, resident.get());
53 | memory += length * kPageSize;
54 | }
55 | }
56 | }
57 | BENCHMARK(BM_mincore)->Range(1, 16 * 1024);
58 |
59 | } // namespace
60 | } // namespace tcmalloc
61 | GOOGLE_MALLOC_SECTION_END
62 |
--------------------------------------------------------------------------------
/tcmalloc/internal/mock_span.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_MOCK_SPAN_H_
16 | #define TCMALLOC_INTERNAL_MOCK_SPAN_H_
17 |
18 | #include "tcmalloc/internal/linked_list.h"
19 |
20 | namespace tcmalloc {
21 | namespace tcmalloc_internal {
22 |
23 | class MockSpan;
24 | typedef TList MockSpanList;
25 |
26 | class MockSpan : public MockSpanList::Elem {
27 | public:
28 | MockSpan() {}
29 |
30 | static MockSpan* New(int idx = 0) {
31 | MockSpan* ret = new MockSpan();
32 | ret->index_ = idx;
33 | return ret;
34 | }
35 |
36 | int index_;
37 | };
38 |
39 | } // namespace tcmalloc_internal
40 | } // namespace tcmalloc
41 |
42 | #endif // TCMALLOC_INTERNAL_MOCK_SPAN_H_
43 |
--------------------------------------------------------------------------------
/tcmalloc/internal/optimization.h:
--------------------------------------------------------------------------------
1 | // Copyright 2020 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_OPTIMIZATION_H_
16 | #define TCMALLOC_INTERNAL_OPTIMIZATION_H_
17 |
18 | #include "absl/base/attributes.h"
19 | #include "tcmalloc/internal/config.h"
20 | #include "tcmalloc/internal/logging.h"
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc {
24 | namespace tcmalloc_internal {
25 |
26 | // Our wrapper for __builtin_assume, allowing us to check the assumption on
27 | // debug builds.
28 | #ifndef NDEBUG
29 | #ifdef __clang__
30 | #define ASSUME(cond) TC_CHECK(cond), __builtin_assume(cond)
31 | #else
32 | #define ASSUME(cond) \
33 | TC_CHECK(cond), (!(cond) ? __builtin_unreachable() : (void)0)
34 | #endif
35 | #else
36 | #ifdef __clang__
37 | #define ASSUME(cond) __builtin_assume(cond)
38 | #else
39 | #define ASSUME(cond) (!(cond) ? __builtin_unreachable() : (void)0)
40 | #endif
41 | #endif
42 |
43 | // Annotations for functions that are not affected by nor affect observable
44 | // state of the program.
45 | #if ABSL_HAVE_ATTRIBUTE(const)
46 | #define TCMALLOC_ATTRIBUTE_CONST __attribute__((const))
47 | #else
48 | #define TCMALLOC_ATTRIBUTE_CONST
49 | #endif
50 |
51 | // Can be applied to a return statement to tell the compiler to generate
52 | // a tail call.
53 | #if ABSL_HAVE_CPP_ATTRIBUTE(clang::musttail)
54 | #define TCMALLOC_MUSTTAIL [[clang::musttail]]
55 | #else
56 | #define TCMALLOC_MUSTTAIL
57 | #endif
58 |
59 | inline void* AssumeNotNull(void* p) {
60 | ASSUME(p != nullptr);
61 | return p;
62 | }
63 |
64 | } // namespace tcmalloc_internal
65 | } // namespace tcmalloc
66 | GOOGLE_MALLOC_SECTION_END
67 |
68 | #endif // TCMALLOC_INTERNAL_OPTIMIZATION_H_
69 |
--------------------------------------------------------------------------------
/tcmalloc/internal/overflow.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_OVERFLOW_H_
16 | #define TCMALLOC_INTERNAL_OVERFLOW_H_
17 |
18 | #include
19 |
20 | #include "absl/base/config.h"
21 | #include "tcmalloc/internal/config.h"
22 |
23 | GOOGLE_MALLOC_SECTION_BEGIN
24 | namespace tcmalloc {
25 | namespace tcmalloc_internal {
26 |
27 | inline bool MultiplyOverflow(size_t a, size_t b, size_t* out) {
28 | #if ABSL_HAVE_BUILTIN(__builtin_mul_overflow)
29 | return __builtin_mul_overflow(a, b, out);
30 | #else
31 | *out = a * b;
32 | return b != 0 && *out / b != a;
33 | #endif
34 | }
35 |
36 | } // namespace tcmalloc_internal
37 | } // namespace tcmalloc
38 | GOOGLE_MALLOC_SECTION_END
39 |
40 | #endif // TCMALLOC_INTERNAL_OVERFLOW_H_
41 |
--------------------------------------------------------------------------------
/tcmalloc/internal/page_size.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/page_size.h"
16 |
17 | #include
18 |
19 | #include
20 |
21 | #include "absl/base/attributes.h"
22 | #include "absl/base/call_once.h"
23 | #include "tcmalloc/internal/config.h"
24 |
25 | GOOGLE_MALLOC_SECTION_BEGIN
26 | namespace tcmalloc {
27 | namespace tcmalloc_internal {
28 |
29 | size_t GetPageSize() {
30 | ABSL_CONST_INIT static size_t page_size;
31 | ABSL_CONST_INIT static absl::once_flag flag;
32 |
33 | absl::base_internal::LowLevelCallOnce(&flag, [&]() {
34 | #if defined(__wasm__) || defined(__asmjs__)
35 | page_size = static_cast(getpagesize());
36 | #else
37 | page_size = static_cast(sysconf(_SC_PAGESIZE));
38 | #endif
39 | });
40 | return page_size;
41 | }
42 |
43 | } // namespace tcmalloc_internal
44 | } // namespace tcmalloc
45 | GOOGLE_MALLOC_SECTION_END
46 |
--------------------------------------------------------------------------------
/tcmalloc/internal/page_size.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_PAGE_SIZE_H_
16 | #define TCMALLOC_INTERNAL_PAGE_SIZE_H_
17 |
18 | #include
19 |
20 | #include "absl/base/attributes.h"
21 | #include "tcmalloc/internal/config.h"
22 |
23 | GOOGLE_MALLOC_SECTION_BEGIN
24 | namespace tcmalloc {
25 | namespace tcmalloc_internal {
26 |
27 | ABSL_ATTRIBUTE_PURE_FUNCTION size_t GetPageSize();
28 |
29 | } // namespace tcmalloc_internal
30 | } // namespace tcmalloc
31 | GOOGLE_MALLOC_SECTION_END
32 |
33 | #endif // TCMALLOC_INTERNAL_PAGE_SIZE_H_
34 |
--------------------------------------------------------------------------------
/tcmalloc/internal/percpu_early_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 |
17 | #include "gtest/gtest.h"
18 | #include "absl/base/attributes.h"
19 | #include "tcmalloc/internal/percpu.h"
20 |
21 | namespace tcmalloc::tcmalloc_internal::subtle::percpu {
22 | namespace {
23 |
24 | ABSL_CONST_INIT std::optional success;
25 |
26 | TEST(PerCpu, IsRegistered) {
27 | // Verify preinit ran. Its success should be identical to running it after
28 | // main has started.
29 | EXPECT_TRUE(success.has_value());
30 | EXPECT_EQ(success, IsFast());
31 | }
32 |
33 | void register_rseq() { success = IsFast(); }
34 |
35 | __attribute__((section(".preinit_array"),
36 | used)) void (*__local_install_factory_preinit)() = register_rseq;
37 |
38 | } // namespace
39 | } // namespace tcmalloc::tcmalloc_internal::subtle::percpu
40 |
--------------------------------------------------------------------------------
/tcmalloc/internal/percpu_rseq_asm.S:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Single file to include target specific implementations for percpu.
16 |
17 | #include "tcmalloc/internal/percpu.h"
18 |
19 | #ifdef __GCC_HAVE_DWARF2_CFI_ASM
20 | #define CFI(...) __VA_ARGS__
21 | #else
22 | #define CFI(...)
23 | #endif
24 |
25 | #if TCMALLOC_PERCPU_RSEQ_SUPPORTED_PLATFORM
26 | #if defined(__x86_64__)
27 | #include "tcmalloc/internal/percpu_rseq_x86_64.S"
28 | #elif defined(__aarch64__)
29 | #include "tcmalloc/internal/percpu_rseq_aarch64.S"
30 | #else
31 | #error "RSEQ support expected, but not found."
32 | #endif
33 |
34 | // See the comment about data layout in percpu.h for details.
35 | .type tcmalloc_sampler, @object
36 | .type tcmalloc_cached_vcpu, @object
37 | .type tcmalloc_slabs, @object
38 | .type __rseq_abi, @object
39 | .section .tdata, "awT", @progbits
40 | .globl tcmalloc_sampler
41 | .globl tcmalloc_cached_vcpu
42 | .globl tcmalloc_slabs
43 | .globl __rseq_abi
44 | .p2align 6
45 | .zero 64 + 32 - TCMALLOC_SAMPLER_SIZE - 8
46 | tcmalloc_sampler:
47 | .zero TCMALLOC_SAMPLER_SIZE
48 | tcmalloc_cached_vcpu:
49 | .long 0xffffffff // cpu_id (kCpuIdUninitialized)
50 | tcmalloc_slabs:
51 | .long 0
52 | __rseq_abi:
53 | .long 0 // cpu_id_start
54 | .long 0xffffffff // cpu_id (kCpuIdUninitialized)
55 | .quad 0 // rseq_cs
56 | .long 0 // flags
57 | .quad 0 // padding
58 | .short 0xffff // numa_node_id (kCpuIdUninitialized)
59 | .short 0xffff // vcpu_id (kCpuIdUninitialized)
60 | .size __rseq_abi, 32
61 | .size tcmalloc_sampler, TCMALLOC_SAMPLER_SIZE
62 | .size tcmalloc_slabs, 8
63 |
64 | #endif // TCMALLOC_PERCPU_RSEQ_SUPPORTED_PLATFORM
65 |
66 | // We do not need an executable stack. Put this outside the
67 | // architecture-specific region above in order to suppress "missing
68 | // .note.GNU-stack section implies executable stack" errors.
69 | //
70 | // Cf. http://en.chys.info/2010/12/note-gnu-stack/
71 | #if defined(__arm__)
72 | .section .note.GNU-stack, "", %progbits
73 | #else
74 | .section .note.GNU-stack, "", @progbits
75 | #endif // __arm__
76 |
77 |
--------------------------------------------------------------------------------
/tcmalloc/internal/percpu_rseq_unsupported.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // Provides skeleton RSEQ functions which raise a hard error in the case of
16 | // being erroneously called on an unsupported platform.
17 |
18 | #include "tcmalloc/internal/percpu.h"
19 |
20 | #if !TCMALLOC_PERCPU_RSEQ_SUPPORTED_PLATFORM
21 |
22 | GOOGLE_MALLOC_SECTION_BEGIN
23 | namespace tcmalloc {
24 | namespace tcmalloc_internal {
25 | namespace subtle {
26 | namespace percpu {
27 |
28 | static void Unsupported() {
29 | TC_BUG("RSEQ function called on unsupported platform.");
30 | }
31 |
32 | int TcmallocSlab_Internal_PerCpuCmpxchg64(int target_cpu, intptr_t* p,
33 | intptr_t old_val, intptr_t new_val,
34 | size_t virtual_cpu_id_offset) {
35 | Unsupported();
36 | return -1;
37 | }
38 |
39 | size_t TcmallocSlab_Internal_PushBatch(size_t size_class, void** batch,
40 | size_t len, uintptr_t slabs_and_shift,
41 | size_t virtual_cpu_id_offset) {
42 | Unsupported();
43 | return 0;
44 | }
45 |
46 | size_t TcmallocSlab_Internal_PopBatch(size_t size_class, void** batch,
47 | size_t len, uintptr_t slabs_and_shift,
48 | size_t virtual_cpu_id_offset) {
49 | Unsupported();
50 | return 0;
51 | }
52 |
53 | int PerCpuReadCycleCounter(int64_t* cycles) {
54 | Unsupported();
55 | return -1;
56 | }
57 |
58 | } // namespace percpu
59 | } // namespace subtle
60 | } // namespace tcmalloc_internal
61 | } // namespace tcmalloc
62 | GOOGLE_MALLOC_SECTION_END
63 |
64 | #endif // !TCMALLOC_PERCPU_RSEQ_SUPPORTED_PLATFORM
65 |
--------------------------------------------------------------------------------
/tcmalloc/internal/percpu_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/percpu.h"
16 |
17 | #include
18 |
19 | #include
20 | #include
21 |
22 | #include "gtest/gtest.h"
23 | #include "absl/base/attributes.h"
24 | #include "absl/log/absl_check.h"
25 | #include "absl/time/time.h"
26 | #include "tcmalloc/internal/logging.h"
27 | #include "tcmalloc/testing/testutil.h"
28 |
29 | namespace tcmalloc::tcmalloc_internal::subtle::percpu {
30 | namespace {
31 |
32 | ABSL_CONST_INIT std::atomic alarms{0};
33 |
34 | void sa_alrm(int sig) {
35 | alarms.fetch_add(1, std::memory_order_relaxed);
36 | TC_CHECK(IsFast());
37 | }
38 |
39 | TEST(PerCpu, SignalHandling) {
40 | if (!IsFast()) {
41 | GTEST_SKIP() << "per-CPU unavailable";
42 | }
43 |
44 | struct sigaction sig;
45 | memset(&sig, 0, sizeof(sig)); // sa_flags == 0 => SA_RESTART not set
46 | sig.sa_handler = sa_alrm;
47 | ABSL_CHECK_EQ(sigaction(SIGALRM, &sig, nullptr),
48 | 0); // install signal handler
49 |
50 | constexpr absl::Duration interval = absl::Microseconds(1);
51 | struct timeval timeval = absl::ToTimeval(interval);
52 |
53 | struct itimerval signal_interval;
54 | signal_interval.it_value = timeval;
55 | signal_interval.it_interval = timeval;
56 |
57 | setitimer(ITIMER_REAL, &signal_interval, nullptr);
58 |
59 | for (int i = 0; i < 100000; ++i) {
60 | UnregisterRseq();
61 | TC_CHECK(IsFast());
62 | }
63 |
64 | timeval = absl::ToTimeval(absl::ZeroDuration());
65 | signal_interval.it_value = timeval;
66 | signal_interval.it_interval = timeval;
67 |
68 | setitimer(ITIMER_REAL, &signal_interval, nullptr);
69 |
70 | EXPECT_GT(alarms.load(std::memory_order_relaxed), 0);
71 | }
72 |
73 | } // namespace
74 | } // namespace tcmalloc::tcmalloc_internal::subtle::percpu
75 |
--------------------------------------------------------------------------------
/tcmalloc/internal/prefetch_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/prefetch.h"
16 |
17 | #include "gtest/gtest.h"
18 |
19 | namespace tcmalloc {
20 | namespace tcmalloc_internal {
21 | namespace {
22 |
23 | int number = 42;
24 |
25 | TEST(Prefetch, TemporalLocalityNone) {
26 | PrefetchNta(&number);
27 | EXPECT_EQ(number, 42);
28 | }
29 |
30 | TEST(Prefetch, TemporalLocalityLow) {
31 | PrefetchT2(&number);
32 | EXPECT_EQ(number, 42);
33 | }
34 |
35 | TEST(Prefetch, TemporalLocalityMedium) {
36 | PrefetchT1(&number);
37 | EXPECT_EQ(number, 42);
38 | }
39 |
40 | TEST(Prefetch, TemporalLocalityHigh) {
41 | PrefetchT0(&number);
42 | EXPECT_EQ(number, 42);
43 | }
44 |
45 | TEST(Prefetch, PrefetchForWrite) {
46 | PrefetchW(&number);
47 | EXPECT_EQ(number, 42);
48 | }
49 |
50 | TEST(Prefetch, WriteTemporalLocalityNone) {
51 | PrefetchWNta(&number);
52 | EXPECT_EQ(number, 42);
53 | }
54 |
55 | TEST(Prefetch, WriteTemporalLocalityLow) {
56 | PrefetchWT2(&number);
57 | EXPECT_EQ(number, 42);
58 | }
59 |
60 | TEST(Prefetch, WriteTemporalLocalityMedium) {
61 | PrefetchWT1(&number);
62 | EXPECT_EQ(number, 42);
63 | }
64 |
65 | TEST(Prefetch, WriteTemporalLocalityHigh) {
66 | PrefetchWT0(&number);
67 | EXPECT_EQ(number, 42);
68 | }
69 |
70 | } // namespace
71 | } // namespace tcmalloc_internal
72 | } // namespace tcmalloc
73 |
--------------------------------------------------------------------------------
/tcmalloc/internal/proc_maps.h:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_PROC_MAPS_H_
16 | #define TCMALLOC_INTERNAL_PROC_MAPS_H_
17 |
18 | #include
19 | #include
20 |
21 | #include
22 |
23 | #include "tcmalloc/internal/config.h"
24 |
25 | GOOGLE_MALLOC_SECTION_BEGIN
26 | namespace tcmalloc {
27 | namespace tcmalloc_internal {
28 |
29 | // A ProcMapsIterator abstracts access to /proc/maps for a given process.
30 | class ProcMapsIterator {
31 | public:
32 | struct Buffer {
33 | static constexpr size_t kBufSize = PATH_MAX + 1024;
34 | char buf[kBufSize];
35 | };
36 |
37 | // Create an iterator with specified storage (for use in signal handler).
38 | //
39 | // pid can be 0 for "self".
40 | ProcMapsIterator(pid_t pid, Buffer* buffer);
41 |
42 | // Returns true if the iterator successfully initialized;
43 | bool Valid() const;
44 |
45 | bool NextExt(uint64_t* start, uint64_t* end, char** flags, uint64_t* offset,
46 | int64_t* inode, char** filename, dev_t* dev);
47 |
48 | ~ProcMapsIterator();
49 |
50 | private:
51 | char* ibuf_; // input buffer
52 | char* stext_; // start of text
53 | char* etext_; // end of text
54 | char* nextline_; // start of next line
55 | char* ebuf_; // end of buffer (1 char for a nul)
56 | int fd_; // filehandle on /proc/*/maps
57 | pid_t pid_;
58 | char flags_[10];
59 | };
60 |
61 | } // namespace tcmalloc_internal
62 | } // namespace tcmalloc
63 | GOOGLE_MALLOC_SECTION_END
64 |
65 | #endif // TCMALLOC_INTERNAL_PROC_MAPS_H_
66 |
--------------------------------------------------------------------------------
/tcmalloc/internal/profile_builder_fuzz.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "tcmalloc/internal/profile_builder.h"
16 |
17 | #if defined(__linux__)
18 | #include
19 | #include
20 | #endif // defined(__linux__)
21 |
22 | #include
23 |
24 | #include "fuzztest/fuzztest.h"
25 |
26 | namespace tcmalloc::tcmalloc_internal {
27 | namespace {
28 |
29 | void ParseBuildID(const std::string& s) {
30 | const char* data = s.data();
31 | size_t size = s.size();
32 | #if defined(__linux__)
33 | ElfW(Phdr) note;
34 | note.p_type = PT_NOTE;
35 | note.p_vaddr = reinterpret_cast(nullptr);
36 | note.p_filesz = size;
37 | note.p_memsz = size;
38 | note.p_align = 4;
39 |
40 | dl_phdr_info info = {};
41 | info.dlpi_name = "test";
42 | info.dlpi_addr = reinterpret_cast(data);
43 | info.dlpi_phdr = ¬e;
44 | info.dlpi_phnum = 1;
45 |
46 | GetBuildId(&info);
47 | #endif // defined(__linux__)
48 | }
49 |
50 | FUZZ_TEST(ProfileBuilderTest, ParseBuildID)
51 | ;
52 |
53 | } // namespace
54 | } // namespace tcmalloc::tcmalloc_internal
55 |
--------------------------------------------------------------------------------
/tcmalloc/internal/profile_builder_no_tcmalloc_test.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include "gmock/gmock.h"
16 | #include "gtest/gtest.h"
17 | #include "absl/status/status.h"
18 | #include "absl/status/status_matchers.h"
19 | #include "tcmalloc/internal/profile_builder.h"
20 | #include "tcmalloc/malloc_extension.h"
21 |
22 | namespace tcmalloc {
23 | namespace tcmalloc_internal {
24 | namespace {
25 |
26 | using ::absl_testing::StatusIs;
27 | using ::testing::HasSubstr;
28 |
29 | TEST(ProfileBuilderNoTCMallocTest, StatusErrorTest) {
30 | auto profile_st =
31 | MakeProfileProto(MallocExtension::SnapshotCurrent(ProfileType::kHeap));
32 | #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
33 | defined(ABSL_HAVE_LEAK_SANITIZER) || \
34 | defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
35 | EXPECT_THAT(profile_st,
36 | StatusIs(absl::StatusCode::kUnimplemented,
37 | HasSubstr("Program was built with sanitizers enabled")));
38 | #else
39 | EXPECT_THAT(profile_st, StatusIs(absl::StatusCode::kInvalidArgument,
40 | HasSubstr("Empty heap profile")));
41 | #endif
42 | }
43 |
44 | } // namespace
45 | } // namespace tcmalloc_internal
46 | } // namespace tcmalloc
47 |
--------------------------------------------------------------------------------
/tcmalloc/internal/sampled_allocation.h:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef TCMALLOC_INTERNAL_SAMPLED_ALLOCATION_H_
16 | #define TCMALLOC_INTERNAL_SAMPLED_ALLOCATION_H_
17 |
18 | #include
19 |
20 | #include "tcmalloc/internal/logging.h"
21 | #include "tcmalloc/internal/sampled_allocation_recorder.h"
22 |
23 | GOOGLE_MALLOC_SECTION_BEGIN
24 | namespace tcmalloc {
25 | namespace tcmalloc_internal {
26 |
27 | // Stores information about the sampled allocation.
28 | struct SampledAllocation : public tcmalloc_internal::Sample {
29 | // We use this constructor to initialize `graveyard_`, which is used to
30 | // maintain the freelist of SampledAllocations. When we revive objects from
31 | // the freelist, we use `PrepareForSampling()` to update the state of the
32 | // object.
33 | constexpr SampledAllocation() = default;
34 |
35 | // When no object is available on the freelist, we allocate for a new
36 | // SampledAllocation object and invoke this constructor with
37 | // `PrepareForSampling()`.
38 | explicit SampledAllocation(StackTrace&& stack_trace) {
39 | PrepareForSampling(std::move(stack_trace));
40 | }
41 |
42 | SampledAllocation(const SampledAllocation&) = delete;
43 | SampledAllocation& operator=(const SampledAllocation&) = delete;
44 |
45 | SampledAllocation(SampledAllocation&&) = delete;
46 | SampledAllocation& operator=(SampledAllocation&&) = delete;
47 |
48 | // Prepares the state of the object. It is invoked when either a new sampled
49 | // allocation is constructed or when an object is revived from the freelist.
50 | void PrepareForSampling(StackTrace&& stack_trace)
51 | ABSL_EXCLUSIVE_LOCKS_REQUIRED(lock) {
52 | sampled_stack = std::move(stack_trace);
53 | }
54 |
55 | // The stack trace of the sampled allocation.
56 | StackTrace sampled_stack = {};
57 | };
58 |
59 | } // namespace tcmalloc_internal
60 | } // namespace tcmalloc
61 | GOOGLE_MALLOC_SECTION_END
62 |
63 | #endif // TCMALLOC_INTERNAL_SAMPLED_ALLOCATION_H_
64 |
--------------------------------------------------------------------------------
/tcmalloc/internal/sysinfo_fuzz.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include "fuzztest/fuzztest.h"
21 | #include "tcmalloc/internal/cpu_utils.h"
22 | #include "tcmalloc/internal/sysinfo.h"
23 |
24 | namespace tcmalloc::tcmalloc_internal {
25 | namespace {
26 |
27 | void ParseInput(const std::string& s) {
28 | const char* data = s.data();
29 | size_t size = s.size();
30 |
31 | std::optional r =
32 | ParseCpulist([&](char* buf, size_t count) -> ssize_t {
33 | size_t to_read = std::min(size, count);
34 | if (to_read > 0) {
35 | memcpy(buf, data, to_read);
36 | data += to_read;
37 | size -= to_read;
38 | }
39 | return to_read;
40 | });
41 | (void)r;
42 | }
43 |
44 | FUZZ_TEST(SysinfoTest, ParseInput);
45 |
46 | } // namespace
47 | } // namespace tcmalloc::tcmalloc_internal
48 |
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/b180635896.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/b180635896.so
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/gnu-property.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/gnu-property.so
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5534221534363648:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5534221534363648
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5647243657216000:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5647243657216000
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5915530833559552:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-5915530833559552
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-6685031907328000.fuzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/tcmalloc/5181028bb5a889ca0d0da941e715906b7ef45029/tcmalloc/internal/testdata/profile_builder_fuzz/clusterfuzz-testcase-minimized-profile_builder_fuzz-6685031907328000.fuzz
--------------------------------------------------------------------------------
/tcmalloc/internal/testdata/profile_builder_fuzz/crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tcmalloc/internal_malloc_tracing_extension.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Extra extensions exported by some malloc implementations. These
16 | // extensions are accessed through a virtual base class so an
17 | // application can link against a malloc that does not implement these
18 | // extensions, and it will get default versions that do nothing.
19 |
20 | #ifndef TCMALLOC_INTERNAL_MALLOC_TRACING_EXTENSION_H_
21 | #define TCMALLOC_INTERNAL_MALLOC_TRACING_EXTENSION_H_
22 |
23 | #include "absl/base/attributes.h"
24 | #include "absl/status/statusor.h"
25 | #include "tcmalloc/malloc_tracing_extension.h"
26 |
27 | #if ABSL_HAVE_ATTRIBUTE_WEAK && !defined(__APPLE__) && !defined(__EMSCRIPTEN__)
28 |
29 | ABSL_ATTRIBUTE_WEAK
30 | absl::StatusOr
31 | MallocTracingExtension_Internal_GetAllocatedAddressRanges();
32 |
33 | #endif
34 |
35 | #endif // TCMALLOC_INTERNAL_MALLOC_TRACING_EXTENSION_H_
36 |
--------------------------------------------------------------------------------
/tcmalloc/malloc_extension_fuzz.cc:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The TCMalloc Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // https://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #include
16 |
17 | #include
18 | #include