Skip to content

Commit

Permalink
Take 2
Browse files Browse the repository at this point in the history
  • Loading branch information
neobrain committed Sep 4, 2024
1 parent 4f80daa commit 82ffa33
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 167 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -244,7 +243,6 @@ 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)
Expand Down
30 changes: 15 additions & 15 deletions FEXCore/Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -372,23 +372,23 @@ if (NOT MINGW_BUILD)
COMPONENT Libraries)
endif()

if (NOT MINGW_BUILD)
# 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 INTERFACE)
if (ENABLE_JEMALLOC)
add_library(JemallocLibsSillyWorkaround Nothing.cpp)
target_link_libraries(JemallocLibsSillyWorkaround PRIVATE FEX_jemalloc)
target_link_libraries(JemallocLibs INTERFACE JemallocLibsSillyWorkaround)
endif()
if (ENABLE_JEMALLOC_GLIBC_ALLOC)
add_library(JemallocLibsSillyWorkaround2 Nothing.cpp)
target_link_libraries(JemallocLibsSillyWorkaround PRIVATE FEX_jemalloc_glibc)
target_link_libraries(JemallocLibs INTERFACE JemallocLibsSillyWorkaround2)
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 -DENABLE_JEMALLOC=1)
add_library(JemallocLibsSillyWorkaround Nothing.cpp)
target_link_libraries(JemallocLibsSillyWorkaround PRIVATE FEX_jemalloc)
target_link_libraries(JemallocLibs INTERFACE JemallocLibsSillyWorkaround)
endif()
if (ENABLE_JEMALLOC_GLIBC_ALLOC)
set_source_files_properties(Interface/HLE/Thunks/Thunks.cpp PROPERTIES COMPILE_DEFINITIONS -DENABLE_JEMALLOC_GLIBC=1)
add_library(JemallocLibsSillyWorkaround2 Nothing.cpp)
target_link_libraries(JemallocLibsSillyWorkaround PRIVATE FEX_jemalloc_glibc)
target_link_libraries(JemallocLibs INTERFACE JemallocLibsSillyWorkaround2)
endif()

# Dummy project to use for host tools.
# This overrides use of jemalloc in FEXCore with the normal glibc allocator.
add_library(JemallocDummy Utils/JemallocDummy.cpp)
add_library(JemallocDummy STATIC Utils/AllocatorHooks.cpp)
target_include_directories(JemallocDummy PRIVATE "${PROJECT_SOURCE_DIR}/include/")
25 changes: 4 additions & 21 deletions FEXCore/Source/Utils/Allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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;

Expand Down
97 changes: 97 additions & 0 deletions FEXCore/Source/Utils/AllocatorHooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: MIT
// #include <FEXCore/Utils/CompilerDefs.h>

#ifdef ENABLE_JEMALLOC
#include <jemalloc/jemalloc.h>
#endif

#include <malloc.h>
#include <stdlib.h>

namespace FEXCore::Allocator {

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);

#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);
}

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;
}

#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
43 changes: 0 additions & 43 deletions FEXCore/Source/Utils/JemallocDummy.cpp

This file was deleted.

101 changes: 16 additions & 85 deletions FEXCore/include/FEXCore/Utils/AllocatorHooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,6 @@
#include <cstdint>
#include <sys/types.h>

extern "C" {
// jemalloc defines nothrow on its internal C function signatures.

#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
}

namespace FEXCore::Allocator {
enum class ProtectOptions : uint32_t {
None = 0,
Expand Down Expand Up @@ -134,74 +117,22 @@ inline bool VirtualProtect(void* Ptr, size_t Size, ProtectOptions options) {

#endif

#if !defined(_WIN32)
// Memory allocation routines aliased to jemalloc functions
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);
}
#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 ::_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);
}
#endif
// 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);

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));

struct FEXAllocOperators {
FEXAllocOperators() = default;
Expand Down
2 changes: 1 addition & 1 deletion Source/Windows/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_library(CommonWindows STATIC CPUFeatures.cpp InvalidationTracker.cpp Logging.cpp)
add_subdirectory(CRT)
add_subdirectory(WinAPI)
target_link_libraries(CommonWindows FEXCore_Base JemallocDummy)
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/"
Expand Down

0 comments on commit 82ffa33

Please sign in to comment.