Build host tools without jemalloc

Jemalloc blocks use on platforms with 16K pages.
This commit is contained in:
Tony Wasserka 2024-09-30 20:36:03 +02:00
parent 8c47a40625
commit 682b8ef705
18 changed files with 158 additions and 169 deletions

View File

@ -232,7 +232,6 @@ if (ENABLE_JEMALLOC_GLIBC_ALLOC)
# The glibc jemalloc subproject which hooks the glibc allocator.
# Required for thunks to work.
# All host native libraries will use this allocator, while *most* other FEX internal allocations will use the other jemalloc allocator.
add_definitions(-DENABLE_JEMALLOC_GLIBC=1)
add_subdirectory(External/jemalloc_glibc/)
elseif (NOT MINGW_BUILD)
message (STATUS
@ -244,9 +243,7 @@ endif()
if (ENABLE_JEMALLOC)
# The jemalloc subproject that all FEXCore fextl objects allocate through.
add_definitions(-DENABLE_JEMALLOC=1)
add_subdirectory(External/jemalloc/)
include_directories(External/jemalloc/pregen/include/)
elseif (NOT MINGW_BUILD)
message (STATUS
" jemalloc disabled!\n"

View File

@ -193,14 +193,6 @@ else()
endif()
endif()
if (ENABLE_JEMALLOC)
list (APPEND LIBS FEX_jemalloc)
endif()
if (ENABLE_JEMALLOC_GLIBC_ALLOC)
list (APPEND LIBS FEX_jemalloc_glibc)
endif()
# Generate config
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Interface/Config/Config.json.in
@ -375,3 +367,25 @@ if (NOT MINGW_BUILD)
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Libraries)
endif()
# Meta-library to link jemalloc libraries enabled in the build configuration.
# Only needed for targets that run emulation. For others, use JemallocDummy.
add_library(JemallocLibs STATIC Utils/AllocatorHooks.cpp)
if (ENABLE_JEMALLOC)
target_compile_definitions(JemallocLibs PRIVATE ENABLE_JEMALLOC=1 JEMALLOC_NO_RENAME=1)
target_link_libraries(JemallocLibs PUBLIC FEX_jemalloc)
endif()
if (ENABLE_JEMALLOC_GLIBC_ALLOC)
set_source_files_properties(Interface/HLE/Thunks/Thunks.cpp PROPERTIES COMPILE_DEFINITIONS ENABLE_JEMALLOC_GLIBC=1)
target_link_libraries(JemallocLibs INTERFACE FEX_jemalloc_glibc)
endif()
if (NOT MINGW_BUILD)
# Dummy project to use for host tools.
# This overrides use of jemalloc in FEXCore with the normal glibc allocator.
add_library(JemallocDummy STATIC Utils/AllocatorHooks.cpp)
target_include_directories(JemallocDummy PRIVATE "${PROJECT_SOURCE_DIR}/include/")
endif()
# The shared library should always link enabled jemalloc libraries
target_link_libraries(${PROJECT_NAME}_shared JemallocLibs)

View File

@ -19,24 +19,11 @@
#include <sys/user.h>
#endif
#ifdef ENABLE_JEMALLOC
#include <jemalloc/jemalloc.h>
#endif
#include <errno.h>
#include <memory>
#include <stddef.h>
#include <stdint.h>
extern "C" {
typedef void* (*mmap_hook_type)(void* addr, size_t length, int prot, int flags, int fd, off_t offset);
typedef int (*munmap_hook_type)(void* addr, size_t length);
#ifdef ENABLE_JEMALLOC
extern mmap_hook_type je___mmap_hook;
extern munmap_hook_type je___munmap_hook;
#endif
}
namespace fextl::pmr {
static fextl::pmr::default_resource FEXDefaultResource;
std::pmr::memory_resource* get_default_resource() {
@ -127,19 +114,15 @@ void ReenableSBRKAllocations(void* Ptr) {
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
void SetupHooks() {
Alloc64 = Alloc::OSAllocator::Create64BitAllocator();
#ifdef ENABLE_JEMALLOC
je___mmap_hook = FEX_mmap;
je___munmap_hook = FEX_munmap;
#endif
SetJemallocMmapHook(FEX_mmap);
SetJemallocMunmapHook(FEX_munmap);
FEXCore::Allocator::mmap = FEX_mmap;
FEXCore::Allocator::munmap = FEX_munmap;
}
void ClearHooks() {
#ifdef ENABLE_JEMALLOC
je___mmap_hook = ::mmap;
je___munmap_hook = ::munmap;
#endif
SetJemallocMmapHook(::mmap);
SetJemallocMunmapHook(::munmap);
FEXCore::Allocator::mmap = ::mmap;
FEXCore::Allocator::munmap = ::munmap;

View File

@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT
#ifdef ENABLE_JEMALLOC
#include <jemalloc/jemalloc.h>
#endif
#include <malloc.h>
#include <stdlib.h>
namespace FEXCore::Allocator {
#ifndef _WIN32
using mmap_hook_type = void* (*)(void* addr, size_t length, int prot, int flags, int fd, off_t offset);
using munmap_hook_type = int (*)(void* addr, size_t length);
#endif
#ifdef ENABLE_JEMALLOC
void* malloc(size_t size) {
return ::je_malloc(size);
}
void* calloc(size_t n, size_t size) {
return ::je_calloc(n, size);
}
void* memalign(size_t align, size_t s) {
return ::je_memalign(align, s);
}
void* valloc(size_t size) {
return ::je_valloc(size);
}
int posix_memalign(void** r, size_t a, size_t s) {
return ::je_posix_memalign(r, a, s);
}
void* realloc(void* ptr, size_t size) {
return ::je_realloc(ptr, size);
}
void free(void* ptr) {
return ::je_free(ptr);
}
size_t malloc_usable_size(void* ptr) {
return ::je_malloc_usable_size(ptr);
}
void* aligned_alloc(size_t a, size_t s) {
return ::je_aligned_alloc(a, s);
}
void aligned_free(void* ptr) {
return ::je_free(ptr);
}
#ifndef _WIN32
extern "C" mmap_hook_type je___mmap_hook;
extern "C" munmap_hook_type je___munmap_hook;
void SetJemallocMmapHook(mmap_hook_type Hook) {
je___mmap_hook = Hook;
}
void SetJemallocMunmapHook(munmap_hook_type Hook) {
je___munmap_hook = Hook;
}
#endif
#elif defined(_WIN32)
#error "Tried building _WIN32 without jemalloc"
#else
void* malloc(size_t size) {
return ::malloc(size);
}
void* calloc(size_t n, size_t size) {
return ::calloc(n, size);
}
void* memalign(size_t align, size_t s) {
return ::memalign(align, s);
}
void* valloc(size_t size) {
return ::valloc(size);
}
int posix_memalign(void** r, size_t a, size_t s) {
return ::posix_memalign(r, a, s);
}
void* realloc(void* ptr, size_t size) {
return ::realloc(ptr, size);
}
void free(void* ptr) {
return ::free(ptr);
}
size_t malloc_usable_size(void* ptr) {
return ::malloc_usable_size(ptr);
}
void* aligned_alloc(size_t a, size_t s) {
return ::aligned_alloc(a, s);
}
void aligned_free(void* ptr) {
return ::free(ptr);
}
void SetJemallocMmapHook(mmap_hook_type) {}
void SetJemallocMunmapHook(munmap_hook_type) {}
#endif
} // namespace FEXCore::Allocator

View File

@ -4,16 +4,13 @@
#include <FEXCore/Utils/EnumOperators.h>
#include <FEXCore/Utils/LogManager.h>
#ifndef ENABLE_JEMALLOC
#ifndef _WIN32
#include <stdlib.h>
#include <malloc.h>
#endif
#ifdef _WIN32
#include <sys/mman.h>
#else
#define NTDDI_VERSION 0x0A000005
#include <memoryapi.h>
#else
#include <sys/mman.h>
#endif
#include <new>
@ -21,24 +18,6 @@
#include <cstdint>
#include <sys/types.h>
extern "C" {
// jemalloc defines nothrow on its internal C function signatures.
#ifdef ENABLE_JEMALLOC
#define JEMALLOC_NOTHROW __attribute__((nothrow))
// Forward declare jemalloc functions so we don't need to pull in the jemalloc header in to the public API.
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_malloc(size_t size);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_calloc(size_t n, size_t size);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_memalign(size_t align, size_t s);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_valloc(size_t size);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern int je_posix_memalign(void** r, size_t a, size_t s);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_realloc(void* ptr, size_t size);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void je_free(void* ptr);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern size_t je_malloc_usable_size(void* ptr);
FEX_DEFAULT_VISIBILITY JEMALLOC_NOTHROW extern void* je_aligned_alloc(size_t a, size_t s);
#undef JEMALLOC_NOTHROW
#endif
}
namespace FEXCore::Allocator {
enum class ProtectOptions : uint32_t {
None = 0,
@ -143,108 +122,23 @@ inline bool VirtualProtect(void* Ptr, size_t Size, ProtectOptions options) {
#endif
// Memory allocation routines aliased to jemalloc functions.
#ifdef ENABLE_JEMALLOC
inline void* malloc(size_t size) {
return ::je_malloc(size);
}
inline void* calloc(size_t n, size_t size) {
return ::je_calloc(n, size);
}
inline void* memalign(size_t align, size_t s) {
return ::je_memalign(align, s);
}
inline void* valloc(size_t size) {
return ::je_valloc(size);
}
inline int posix_memalign(void** r, size_t a, size_t s) {
return ::je_posix_memalign(r, a, s);
}
inline void* realloc(void* ptr, size_t size) {
return ::je_realloc(ptr, size);
}
inline void free(void* ptr) {
return ::je_free(ptr);
}
inline size_t malloc_usable_size(void* ptr) {
return ::je_malloc_usable_size(ptr);
}
inline void* aligned_alloc(size_t a, size_t s) {
return ::je_aligned_alloc(a, s);
}
inline void aligned_free(void* ptr) {
return ::je_free(ptr);
}
#elif defined(_WIN32)
inline void* malloc(size_t size) {
return ::malloc(size);
}
inline void* calloc(size_t n, size_t size) {
return ::calloc(n, size);
}
inline void* memalign(size_t align, size_t s) {
return ::_aligned_malloc(s, align);
}
inline void* valloc(size_t size) {
return ::_aligned_malloc(size, 4096);
}
inline int posix_memalign(void** r, size_t a, size_t s) {
void* ptr = _aligned_malloc(s, a);
if (ptr) {
*r = ptr;
}
return errno;
}
inline void* realloc(void* ptr, size_t size) {
return ::realloc(ptr, size);
}
inline void free(void* ptr) {
return ::free(ptr);
}
inline size_t malloc_usable_size(void* ptr) {
return ::_msize(ptr);
}
inline void* aligned_alloc(size_t a, size_t s) {
return ::_aligned_malloc(s, a);
}
inline void aligned_free(void* ptr) {
return ::_aligned_free(ptr);
}
#else
inline void* malloc(size_t size) {
return ::malloc(size);
}
inline void* calloc(size_t n, size_t size) {
return ::calloc(n, size);
}
inline void* memalign(size_t align, size_t s) {
return ::memalign(align, s);
}
inline void* valloc(size_t size) {
#ifdef __ANDROID__
return ::aligned_alloc(4096, size);
#else
return ::valloc(size);
#endif
}
inline int posix_memalign(void** r, size_t a, size_t s) {
return ::posix_memalign(r, a, s);
}
inline void* realloc(void* ptr, size_t size) {
return ::realloc(ptr, size);
}
inline void free(void* ptr) {
return ::free(ptr);
}
inline size_t malloc_usable_size(void* ptr) {
return ::malloc_usable_size(ptr);
}
inline void* aligned_alloc(size_t a, size_t s) {
return ::aligned_alloc(a, s);
}
inline void aligned_free(void* ptr) {
return ::free(ptr);
}
// Memory allocation routines to be defined externally.
// This allows to use jemalloc for emulation while using the normal allocator
// for host tools without building FEXCore twice.
void* malloc(size_t size);
void* calloc(size_t n, size_t size);
void* memalign(size_t align, size_t s);
void* valloc(size_t size);
int posix_memalign(void** r, size_t a, size_t s);
void* realloc(void* ptr, size_t size);
void free(void* ptr);
size_t malloc_usable_size(void* ptr);
void* aligned_alloc(size_t a, size_t s);
void aligned_free(void* ptr);
#ifndef _WIN32
void SetJemallocMmapHook(void* (*)(void* addr, size_t length, int prot, int flags, int fd, off_t offset));
void SetJemallocMunmapHook(int (*)(void* addr, size_t length));
#endif
struct FEXAllocOperators {

View File

@ -1,6 +1,6 @@
file(GLOB_RECURSE TESTS CONFIGURE_DEPENDS *.cpp)
set (LIBS fmt::fmt vixl Catch2::Catch2WithMain FEXCore_Base)
set (LIBS fmt::fmt vixl Catch2::Catch2WithMain FEXCore_Base JemallocLibs)
foreach(TEST ${TESTS})
get_filename_component(TEST_NAME ${TEST} NAME_WLE)
add_executable(FEXCore_Tests_${TEST_NAME} ${TEST})

View File

@ -1,7 +1,7 @@
if (COMPILE_VIXL_DISASSEMBLER)
file(GLOB_RECURSE TESTS CONFIGURE_DEPENDS *.cpp)
set (LIBS fmt::fmt vixl Catch2::Catch2WithMain FEXCore_Base)
set (LIBS fmt::fmt vixl Catch2::Catch2WithMain FEXCore_Base JemallocLibs)
foreach(TEST ${TESTS})
get_filename_component(TEST_NAME ${TEST} NAME_WLE)
add_executable(Emitter_${TEST_NAME} ${TEST})

View File

@ -1,4 +1,4 @@
list(APPEND LIBS FEXCore Common CommonTools)
list(APPEND LIBS FEXCore Common CommonTools JemallocLibs)
set (SRCS Main.cpp)
add_executable(CodeSizeValidation ${SRCS})

View File

@ -9,6 +9,7 @@ target_link_libraries(FEXBash
PRIVATE
FEXCore
Common
JemallocLibs
LinuxEmulation
${PTHREAD_LIB}
)

View File

@ -3,7 +3,7 @@ set(CMAKE_AUTOMOC ON)
add_executable(FEXConfig)
target_sources(FEXConfig PRIVATE Main.cpp Main.h)
target_include_directories(FEXConfig PRIVATE ${CMAKE_SOURCE_DIR}/Source/)
target_link_libraries(FEXConfig PRIVATE Common)
target_link_libraries(FEXConfig PRIVATE Common JemallocDummy)
if (Qt6_FOUND)
qt_add_resources(QT_RESOURCES qml6.qrc)
target_link_libraries(FEXConfig PRIVATE Qt6::Qml Qt6::Quick Qt6::Widgets)

View File

@ -3,7 +3,7 @@ set(SRCS Main.cpp)
add_executable(${NAME} ${SRCS})
list(APPEND LIBS Common)
list(APPEND LIBS Common JemallocDummy)
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
target_link_options(${NAME}

View File

@ -1,4 +1,4 @@
list(APPEND LIBS FEXCore Common)
list(APPEND LIBS FEXCore Common JemallocLibs)
set (DEFINES)
if (ENABLE_VIXL_SIMULATOR)

View File

@ -3,7 +3,7 @@ set(SRCS Main.cpp
XXFileHash.cpp)
add_executable(${NAME} ${SRCS})
list(APPEND LIBS FEXCore Common xxHash::xxhash)
list(APPEND LIBS FEXCore Common JemallocDummy xxHash::xxhash)
target_include_directories(${NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Source/)

View File

@ -12,7 +12,7 @@ target_include_directories(${NAME} PRIVATE
${CMAKE_BINARY_DIR}/generated
${CMAKE_SOURCE_DIR}/Source/)
target_link_libraries(${NAME} PRIVATE FEXCore Common ${PTHREAD_LIB})
target_link_libraries(${NAME} PRIVATE FEXCore Common JemallocDummy ${PTHREAD_LIB})
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
target_link_options(${NAME}

View File

@ -1,4 +1,4 @@
list(APPEND LIBS FEXCore Common)
list(APPEND LIBS FEXCore Common JemallocLibs)
set (SRCS TestHarnessRunner.cpp)
if (NOT MINGW_BUILD)

View File

@ -6,6 +6,7 @@ target_include_directories(FEXpidof
target_link_libraries(FEXpidof
PRIVATE
cpp-optparse
JemallocDummy
fmt::fmt
)

View File

@ -1,7 +1,7 @@
add_library(CommonWindows STATIC CPUFeatures.cpp InvalidationTracker.cpp Logging.cpp LoadConfig.S)
add_subdirectory(CRT)
add_subdirectory(WinAPI)
target_link_libraries(CommonWindows FEXCore_Base)
target_link_libraries(CommonWindows FEXCore_Base JemallocLibs)
target_compile_options(CommonWindows PRIVATE -Wno-inconsistent-dllimport)
target_include_directories(CommonWindows PRIVATE
"${CMAKE_SOURCE_DIR}/Source/Windows/include/"

View File

@ -4,7 +4,7 @@ set (TESTS
Filesystem
)
list(APPEND LIBS FEXCore)
list(APPEND LIBS FEXCore JemallocLibs)
foreach(API_TEST ${TESTS})
add_executable(${API_TEST} ${API_TEST}.cpp)