[clang] [compiler-rt] [llvm] [DRAFT][memprof][darwin] Support memprof on Darwin platform and add binary access profile (PR #142884)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 5 10:03:19 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-pgo
Author: None (SharonXSharon)
<details>
<summary>Changes</summary>
The patch has two main parts,
1) add support for memprof on Darwin platform
2) add a new binary access profile, including the format definition, the serialization from the memprof compiler-rt, and the code in llvm-profdata to deserialize.
For 1) @<!-- -->manman-ren tried to upstream earlier on at https://github.com/llvm/llvm-project/pull/69640/files, this patch has some changes compared with it.
Currently, in order to properly upstream this patch, we need to resolve 3 issues,
a) The Darwin support may have some issues in the interception part, especially the `llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp/.h` files, given interceptions on Apple is a bit different. (For our internal testing, we are commenting out a lot of the interceptions). In theory we should be able to follow what Asan is doing for Apple, but I am not super familiar with asan interception either, so having a little learning curve here.
b) We need to discuss how to integrate the binary access profile format into the existing raw profile format, rather than creating a new format
c) we have been using the `MEM_GRANULARITY` = 8 bytes before the `HISTOGRAM_GRANULARITY` was added, now we should be able to just reuse the histogram code? Does the histogram just effectively make the profile granularity being 8 bytes and then show the access count of every 8 bytes memblock in a histogram?
Please let me know your thoughts/insights on the above 3 issues, thanks a lot!
@<!-- -->snehasish @<!-- -->teresajohnson @<!-- -->mingmingl-llvm @<!-- -->manman-ren
---
Patch is 63.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/142884.diff
26 Files Affected:
- (modified) clang/lib/Driver/ToolChains/Darwin.cpp (+2)
- (added) clang/test/Driver/fmemprof-darwin.c (+11)
- (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+1-1)
- (modified) compiler-rt/cmake/config-ix.cmake (+1-1)
- (added) compiler-rt/include/profile/MemProfBinaryAccessData.inc (+41)
- (modified) compiler-rt/include/profile/MemProfData.inc (+2)
- (modified) compiler-rt/lib/memprof/CMakeLists.txt (+130-107)
- (modified) compiler-rt/lib/memprof/memprof_allocator.cpp (+32-6)
- (modified) compiler-rt/lib/memprof/memprof_allocator.h (+22-7)
- (modified) compiler-rt/lib/memprof/memprof_flags.inc (+2)
- (modified) compiler-rt/lib/memprof/memprof_interceptors.cpp (+2)
- (modified) compiler-rt/lib/memprof/memprof_interceptors.h (+5)
- (modified) compiler-rt/lib/memprof/memprof_linux.cpp (+2-3)
- (added) compiler-rt/lib/memprof/memprof_mac.cpp (+56)
- (modified) compiler-rt/lib/memprof/memprof_malloc_linux.cpp (+2-3)
- (added) compiler-rt/lib/memprof/memprof_malloc_mac.cpp (+72)
- (modified) compiler-rt/lib/memprof/memprof_mapping.h (+12-2)
- (modified) compiler-rt/lib/memprof/memprof_new_delete.cpp (+37-4)
- (modified) compiler-rt/lib/memprof/memprof_rawprofile.cpp (+134)
- (modified) compiler-rt/lib/memprof/memprof_rawprofile.h (+6)
- (modified) compiler-rt/test/memprof/CMakeLists.txt (+74-15)
- (modified) compiler-rt/test/memprof/lit.cfg.py (+1-1)
- (added) llvm/include/llvm/ProfileData/MemProfBinaryAccessData.inc (+40)
- (modified) llvm/include/llvm/ProfileData/MemProfData.inc (+2)
- (modified) llvm/include/module.modulemap (+1)
- (modified) llvm/tools/llvm-profdata/llvm-profdata.cpp (+266-20)
``````````diff
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 26e24ad0ab17c..113127ace8356 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1619,6 +1619,8 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
}
+ if (Sanitize.needsMemProfRt())
+ AddLinkSanitizerLibArgs(Args, CmdArgs, "memprof");
}
if (Sanitize.needsMemProfRt())
diff --git a/clang/test/Driver/fmemprof-darwin.c b/clang/test/Driver/fmemprof-darwin.c
new file mode 100644
index 0000000000000..2b1ad67d176ff
--- /dev/null
+++ b/clang/test/Driver/fmemprof-darwin.c
@@ -0,0 +1,11 @@
+
+// Test sanitizer link flags on Darwin.
+
+// RUN: %clang -### --target=x86_64-darwin \
+// RUN: -stdlib=platform -fmemory-profile %s 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MEMPROF %s
+
+// CHECK-MEMPROF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MEMPROF-SAME: libclang_rt.memprof_osx_dynamic.dylib"
+// CHECK-MEMPROF-SAME: "-rpath" "@executable_path"
+// CHECK-MEMPROF-SAME: "-rpath" "{{[^"]*}}lib{{[^"]*}}darwin"
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index ca45d7bd2af7f..d89c07f690740 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -78,7 +78,7 @@ else()
endif()
set(ALL_NSAN_SUPPORTED_ARCH ${X86_64})
set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
-set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
+set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64} ${ARM64})
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index e3310b1ff0e2c..305dbadde71a9 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -829,7 +829,7 @@ else()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND MEMPROF_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Linux")
+ OS_NAME MATCHES "Linux|Darwin")
set(COMPILER_RT_HAS_MEMPROF TRUE)
else()
set(COMPILER_RT_HAS_MEMPROF FALSE)
diff --git a/compiler-rt/include/profile/MemProfBinaryAccessData.inc b/compiler-rt/include/profile/MemProfBinaryAccessData.inc
new file mode 100644
index 0000000000000..25333a8f7fcc5
--- /dev/null
+++ b/compiler-rt/include/profile/MemProfBinaryAccessData.inc
@@ -0,0 +1,41 @@
+/*===-- MemProfBinaryAccessData.inc - MemProf profiling runtime macros -*- C++
+-*-======== *\
+|*
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+|* See https://llvm.org/LICENSE.txt for license information.
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+|*
+\*===----------------------------------------------------------------------===*/
+/*
+ * This file defines the macros for memprof profiling data structures
+ * for binary access.
+ *
+ * This file has two identical copies. The primary copy lives in LLVM and
+ * the other one sits in compiler-rt/include/profile directory. To make changes
+ * in this file, first modify the primary copy and copy it over to compiler-rt.
+ * Testing of any change in this file can start only after the two copies are
+ * synced up.
+ *
+\*===----------------------------------------------------------------------===*/
+
+// A 64-bit magic number to uniquely identify the raw binary memprof binary
+// access profile file.
+#define MEMPROF_BINARY_ACCESS_RAW_MAGIC_64 \
+ ((uint64_t)255 << 56 | (uint64_t)'f' << 48 | (uint64_t)'b' << 40 | \
+ (uint64_t)'m' << 32 | (uint64_t)'b' << 24 | (uint64_t)'i' << 16 | \
+ (uint64_t)'n' << 8 | (uint64_t)129)
+
+// The version number of the raw binary format.
+#define MEMPROF_BINARY_ACCESS_RAW_VERSION 1ULL
+
+// A struct describing the header used for the raw binary memprof profile
+// format.
+PACKED(struct BinaryAccessHeader {
+ uint64_t Magic;
+ uint64_t Version;
+ uint64_t TotalSize;
+ uint64_t SegmentOffset;
+ uint64_t NumSegments;
+ uint64_t MemAddressOffset;
+ uint64_t NumMemBlockAddresses;
+});
diff --git a/compiler-rt/include/profile/MemProfData.inc b/compiler-rt/include/profile/MemProfData.inc
index 3f785bd23fce3..f30e95bc51111 100644
--- a/compiler-rt/include/profile/MemProfData.inc
+++ b/compiler-rt/include/profile/MemProfData.inc
@@ -45,6 +45,8 @@
namespace llvm {
namespace memprof {
+#include "MemProfBinaryAccessData.inc"
+
// A struct describing the header used for the raw binary memprof profile format.
PACKED(struct Header {
uint64_t Magic;
diff --git a/compiler-rt/lib/memprof/CMakeLists.txt b/compiler-rt/lib/memprof/CMakeLists.txt
index e6d99daca6ee7..d1c4d607ef396 100644
--- a/compiler-rt/lib/memprof/CMakeLists.txt
+++ b/compiler-rt/lib/memprof/CMakeLists.txt
@@ -7,7 +7,9 @@ set(MEMPROF_SOURCES
memprof_interceptors.cpp
memprof_interceptors_memintrinsics.cpp
memprof_linux.cpp
+ memprof_mac.cpp
memprof_malloc_linux.cpp
+ memprof_malloc_mac.cpp
memprof_mibmap.cpp
memprof_posix.cpp
memprof_rawprofile.cpp
@@ -86,124 +88,145 @@ add_compiler_rt_object_libraries(RTMemprof_dynamic
DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
DEPS ${MEMPROF_DEPS})
-add_compiler_rt_object_libraries(RTMemprof
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- SOURCES ${MEMPROF_SOURCES}
- ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- DEPS ${MEMPROF_DEPS})
-add_compiler_rt_object_libraries(RTMemprof_cxx
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- SOURCES ${MEMPROF_CXX_SOURCES}
- ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- DEPS ${MEMPROF_DEPS})
-add_compiler_rt_object_libraries(RTMemprof_preinit
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- SOURCES ${MEMPROF_PREINIT_SOURCES}
- ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- DEPS ${MEMPROF_DEPS})
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
-add_compiler_rt_object_libraries(RTMemprof_dynamic_version_script_dummy
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
- CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
- DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
- DEPS ${MEMPROF_DEPS})
+if(NOT APPLE)
+ add_compiler_rt_object_libraries(RTMemprof
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ SOURCES ${MEMPROF_SOURCES}
+ ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ DEPS ${MEMPROF_DEPS})
+ add_compiler_rt_object_libraries(RTMemprof_cxx
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ SOURCES ${MEMPROF_CXX_SOURCES}
+ ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ DEPS ${MEMPROF_DEPS})
+ add_compiler_rt_object_libraries(RTMemprof_preinit
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ SOURCES ${MEMPROF_PREINIT_SOURCES}
+ ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ DEPS ${MEMPROF_DEPS})
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
+ add_compiler_rt_object_libraries(RTMemprof_dynamic_version_script_dummy
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+ CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
+ DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
+ DEPS ${MEMPROF_DEPS})
+endif()
# Build MemProf runtimes shipped with Clang.
add_compiler_rt_component(memprof)
-# Build separate libraries for each target.
-
-set(MEMPROF_COMMON_RUNTIME_OBJECT_LIBS
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- # FIXME: hangs.
- # RTSanitizerCommonSymbolizerInternal
-)
-
-add_compiler_rt_runtime(clang_rt.memprof
- STATIC
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- OBJECT_LIBS RTMemprof_preinit
- RTMemprof
- ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- PARENT_TARGET memprof)
-
-add_compiler_rt_runtime(clang_rt.memprof_cxx
- STATIC
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- OBJECT_LIBS RTMemprof_cxx
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- PARENT_TARGET memprof)
-
-add_compiler_rt_runtime(clang_rt.memprof-preinit
- STATIC
- ARCHS ${MEMPROF_SUPPORTED_ARCH}
- OBJECT_LIBS RTMemprof_preinit
- CFLAGS ${MEMPROF_CFLAGS}
- DEFS ${MEMPROF_COMMON_DEFINITIONS}
- PARENT_TARGET memprof)
-
-foreach(arch ${MEMPROF_SUPPORTED_ARCH})
- if (UNIX)
- add_sanitizer_rt_version_list(clang_rt.memprof-dynamic-${arch}
- LIBS clang_rt.memprof-${arch} clang_rt.memprof_cxx-${arch}
- EXTRA memprof.syms.extra)
- set(VERSION_SCRIPT_FLAG
- -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
- set_property(SOURCE
- ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
- APPEND PROPERTY
- OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
- else()
- set(VERSION_SCRIPT_FLAG)
- endif()
-
- set(MEMPROF_DYNAMIC_WEAK_INTERCEPTION)
-
+if(APPLE)
+ # following asan
+ add_weak_symbols("memprof" WEAK_SYMBOL_LINK_FLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
add_compiler_rt_runtime(clang_rt.memprof
SHARED
- ARCHS ${arch}
- OBJECT_LIBS ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
- RTMemprof_dynamic
- # The only purpose of RTMemprof_dynamic_version_script_dummy is to
- # carry a dependency of the shared runtime on the version script.
- # Replacing it with a straightforward
- # add_dependencies(clang_rt.memprof-dynamic-${arch} clang_rt.memprof-dynamic-${arch}-version-list)
- # generates an order-only dependency in ninja.
- RTMemprof_dynamic_version_script_dummy
- ${MEMPROF_DYNAMIC_WEAK_INTERCEPTION}
+ OS ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ OBJECT_LIBS RTMemprof_dynamic
+ RTInterception
+ RTSanitizerCommon
+ RTSanitizerCommonLibc
+ RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
- LINK_FLAGS ${MEMPROF_DYNAMIC_LINK_FLAGS}
- ${VERSION_SCRIPT_FLAG}
- LINK_LIBS ${MEMPROF_DYNAMIC_LIBS}
+ LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
PARENT_TARGET memprof)
+else()
+ # Build separate libraries for each target.
+
+ set(MEMPROF_COMMON_RUNTIME_OBJECT_LIBS
+ RTInterception
+ RTSanitizerCommon
+ RTSanitizerCommonLibc
+ RTSanitizerCommonCoverage
+ RTSanitizerCommonSymbolizer
+ # FIXME: hangs.
+ # RTSanitizerCommonSymbolizerInternal
+ )
- if (SANITIZER_USE_SYMBOLS)
- add_sanitizer_rt_symbols(clang_rt.memprof_cxx
- ARCHS ${arch})
- add_dependencies(memprof clang_rt.memprof_cxx-${arch}-symbols)
- add_sanitizer_rt_symbols(clang_rt.memprof
- ARCHS ${arch}
- EXTRA memprof.syms.extra)
- add_dependencies(memprof clang_rt.memprof-${arch}-symbols)
- endif()
-endforeach()
+ add_compiler_rt_runtime(clang_rt.memprof
+ STATIC
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ OBJECT_LIBS RTMemprof_preinit
+ RTMemprof
+ ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ PARENT_TARGET memprof)
+
+ add_compiler_rt_runtime(clang_rt.memprof_cxx
+ STATIC
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ OBJECT_LIBS RTMemprof_cxx
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ PARENT_TARGET memprof)
+ add_compiler_rt_runtime(clang_rt.memprof-preinit
+ STATIC
+ ARCHS ${MEMPROF_SUPPORTED_ARCH}
+ OBJECT_LIBS RTMemprof_preinit
+ CFLAGS ${MEMPROF_CFLAGS}
+ DEFS ${MEMPROF_COMMON_DEFINITIONS}
+ PARENT_TARGET memprof)
+
+ foreach(arch ${MEMPROF_SUPPORTED_ARCH})
+ if (UNIX)
+ add_sanitizer_rt_version_list(clang_rt.memprof-dynamic-${arch}
+ LIBS clang_rt.memprof-${arch} clang_rt.memprof_cxx-${arch}
+ EXTRA memprof.syms.extra)
+ set(VERSION_SCRIPT_FLAG
+ -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
+ set_property(SOURCE
+ ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+ APPEND PROPERTY
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
+ else()
+ set(VERSION_SCRIPT_FLAG)
+ endif()
+
+ set(MEMPROF_DYNAMIC_WEAK_INTERCEPTION)
+
+ add_compiler_rt_runtime(clang_rt.memprof
+ SHARED
+ ARCHS ${arch}
+ OBJECT_LIBS ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
+ RTMemprof_dynamic
+ # The only purpose of RTMemprof_dynamic_version_script_dummy is to
+ # carry a dependency of the shared runtime on the version script.
+ # Replacing it with a straightforward
+ # add_dependencies(clang_rt.memprof-dynamic-${arch} clang_rt.memprof-dynamic-${arch}-version-list)
+ # generates an order-only dependency in ninja.
+ RTMemprof_dynamic_version_script_dummy
+ ${MEMPROF_DYNAMIC_WEAK_INTERCEPTION}
+ CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
+ LINK_FLAGS ${MEMPROF_DYNAMIC_LINK_FLAGS}
+ ${VERSION_SCRIPT_FLAG}
+ LINK_LIBS ${MEMPROF_DYNAMIC_LIBS}
+ DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
+ PARENT_TARGET memprof)
+
+ if (SANITIZER_USE_SYMBOLS)
+ add_sanitizer_rt_symbols(clang_rt.memprof_cxx
+ ARCHS ${arch})
+ add_dependencies(memprof clang_rt.memprof_cxx-${arch}-symbols)
+ add_sanitizer_rt_symbols(clang_rt.memprof
+ ARCHS ${arch}
+ EXTRA memprof.syms.extra)
+ add_dependencies(memprof clang_rt.memprof-${arch}-symbols)
+ endif()
+ endforeach()
+endif()
if(COMPILER_RT_INCLUDE_TESTS)
add_subdirectory(tests)
diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp
index 60f5c853f9d76..5b3e18e8a750c 100644
--- a/compiler-rt/lib/memprof/memprof_allocator.cpp
+++ b/compiler-rt/lib/memprof/memprof_allocator.cpp
@@ -90,7 +90,13 @@ static int GetCpuId(void) {
// will seg fault as the address of __vdso_getcpu will be null.
if (!memprof_inited)
return -1;
+#if SANITIZER_APPLE
+ // On Apple platforms, sched_getcpu is not available.
+ // TODO: better way to handle this?
+ return -100;
+#else
return sched_getcpu();
+#endif
}
// Compute the timestamp in ms.
@@ -356,11 +362,15 @@ struct Allocator {
InsertLiveBlocks();
if (flags()->print_text) {
- if (!flags()->print_terse)
- Printf("Recorded MIBs (incl. live on exit):\n");
- MIBMap.ForEach(PrintCallback,
- reinterpret_cast<void *>(flags()->print_terse));
- StackDepotPrintAll();
+ if (flags()->dump_binary_access_profile_only)
+ DumpBinaryAccesses();
+ else {
+ if (!flags()->print_terse)
+ Printf("Recorded MIBs (incl. live on exit):\n");
+ MIBMap.ForEach(PrintCallback,
+ reinterpret_cast<void *>(flags()->print_terse));
+ StackDepotPrintAll();
+ }
} else {
// Serialize the contents to a raw profile. Format documented in
// memprof_rawprofile.h.
@@ -369,7 +379,11 @@ struct Allocator {
__sanitizer::ListOfModules List;
List.init();
ArrayRef<LoadedModule> Modules(List.begin(), List.end());
- u64 BytesSerialized = SerializeToRawProfile(MIBMap, Modules, Buffer);
+ u64 BytesSerialized = 0;
+ if (flags()->dump_binary_access_profile_only)
+ BytesSerialized = SerializeBinaryAccesses(Modules, Buffer);
+ else
+ BytesSerialized = SerializeToRawProfile(MIBMap, Modules, Buffer);
CHECK(Buffer && BytesSerialized && "could not serialize to buffer");
report_file.Write(Buffer, BytesSerialized);
}
@@ -766,6 +780,18 @@ uptr memprof_malloc_usable_size(const void *ptr) {
return usable_size;
}
+uptr memprof_mz_size(const void *ptr) {
+ return instance.AllocationSize(reinterpret_cast<uptr>(ptr));
+}
+
+void memprof_mz_force_lock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
+ instance.ForceLock();
+}
+
+void memprof_mz_force_unlock() SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
+ instance.ForceUnlock();
+}
+
} // namespace __memprof
// ---------------------- Interface ---------------- {{{1
diff --git a/compiler-rt/lib/memprof/memprof_allocator.h b/compiler-rt/lib/memprof/memprof_allocator.h
index 6d898f06f7e42..11cf93fce7c08 100644
--- a/compiler-rt/lib/memprof/memprof_allocator.h
+++ b/compiler-rt/lib/memprof/memprof_allocator.h
@@ -20,13 +20,6 @@
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_list.h"
-#if !defined(__x86_64__)
-#error Unsupported platform
-#endif
-#if !SANITIZER_CAN_USE_ALLOCATOR64
-#error Only 64-bit allocator supported
-#endif
-
namespace __memprof {
enum AllocType {
@@ -46,6 +39,7 @@ struct MemprofMapUnmapCallback {
void OnUnmap(uptr p, uptr size) const;
};
+#if SANITIZER_CAN_USE_ALLOCATOR64
constexpr uptr kAllocatorSpace = ~(uptr)0;
constexpr uptr kAllocatorSize = 0x40000000000ULL; // 4T.
typedef DefaultSizeClassMap SizeClassMap;
@@ -64,6 +58,23 @@ template <typename AddressSpaceView>
using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
+#else // Fallback to SizeClassAllocator32.
+typedef CompactSizeClassMap SizeClassMap;
+template <typename AddressSpaceViewTy> struct AP32 {
+ static const uptr kSpaceBeg = 0;
+ static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
+ static const uptr kMetadataSize = 0;
+ typedef __memprof::SizeClassMap SizeClassMap;
+ static const uptr kRegionSizeLog = 20;
+ using AddressSpaceView = AddressSpaceViewTy;
+ typedef MemprofMapUnmapCallback MapUnmapCallback;
+ static const uptr kFlags = 0;
+};
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
+#endif
+
static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
template <typename AddressSpaceView>
@@ -101,6 +112,10 @@ int memprof_posix_memalign(void **memptr, uptr alignment, uptr size,
BufferedStackTrace *stack);
uptr memprof_malloc_usable_size(const void *ptr);
+uptr memprof_mz_size(const void *ptr);
+void memprof_mz_force_lock();
+void memprof_mz_force_unlock();
+
void PrintInternalAllocatorStats();
} // namespace __memprof
diff --git a/compiler-rt/lib/memprof/memprof_flags.inc b/compiler-rt/lib/memprof/memprof_flags.inc
index 1d8e77752caa5..d2c5ebe000d7a 100644
--- a/compiler-rt/lib/memprof/memprof_flags.inc
+++ b/compiler-rt/lib/memprof/memprof_flags.inc
@@ -42,3 +42,5 @@ MEMPROF_FLAG(bool, print_terse, false,
"if print_text = true.")
MEMPROF_FLAG(bool, dump_at_exit, true,
"If set, dump profiles when the program terminates.")
+MEMPROF_FLAG(bool, dump_binary_access_profile_only, false,
+ "Dump the binary access MemProf format only.")
diff --git a/compiler-rt/lib/memprof/memprof_interceptors.cpp b/compiler-rt/lib/memprof/memprof_interceptors.cpp
index f4d7fd46e6198..c87144900eace 100644
--- a/compiler-rt/lib/memprof/memprof_interceptors.cpp
+++ b/compiler-rt/lib/memprof/memprof_interceptors.cpp
@@ -18,7 +18,9 @@
#include "memprof_stack.h"
#include "memprof_stats.h"
#include "sanitizer_common/sanitizer_libc.h"
+#if SANITIZER_POSIX
#include "sanitizer_common/sanitizer_posix.h"
+#endif
namespace __memprof {
diff --git a/compiler-rt/lib/memprof/memprof_interceptors.h b/compiler-rt/lib/memprof/memprof_interceptors.h
index 53d685706b849..5793df2c0ed45 100644
--- a/compiler-rt/lib/memprof/memprof_interceptors.h
+++ b/compiler-rt/lib/memprof/memprof_interceptors.h
@@ -40,6 +40,7 @@ DECLARE_REAL(char *, strncpy, char *to, const char *from, SIZE_T siz...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/142884
More information about the llvm-commits
mailing list