diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -154,6 +154,13 @@ clangdSupport ) +check_symbol_exists(malloc_trim malloc.h HAVE_MALLOC_TRIM) +if (HAVE_MALLOC_TRIM) + target_compile_definitions(obj.clangDaemon + PRIVATE HAVE_MALLOC_TRIM + ) +endif () + add_subdirectory(refactor/tweaks) if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") # FIXME: Make fuzzer not use linux-specific APIs, build it everywhere. diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp --- a/clang-tools-extra/clangd/index/FileIndex.cpp +++ b/clang-tools-extra/clangd/index/FileIndex.cpp @@ -32,6 +32,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -41,10 +42,21 @@ #include #include +#ifdef HAVE_MALLOC_TRIM +#include +#endif // HAVE_MALLOC_TRIM + namespace clang { namespace clangd { namespace { +void trimMemory() { +#ifdef HAVE_MALLOC_TRIM + if (malloc_trim(0)) + vlog("Trimmed memory"); +#endif // HAVE_MALLOC_TRIM +} + SlabTuple indexSymbols(ASTContext &AST, std::shared_ptr PP, llvm::ArrayRef DeclsToIndex, const MainFileMacros *MacroRefsToIndex, @@ -263,6 +275,10 @@ std::unique_ptr FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle, size_t *Version) { + // Building the index often leaves a lof of freed but unreleased memory + // (at the OS level): manually trim the memory after the index is built + auto _ = llvm::make_scope_exit(trimMemory); + std::vector> SymbolSlabs; std::vector> RefSlabs; std::vector> RelationSlabs;