#pragma once /** ** \defgroup mem Memory management ** tf_malloc() and friends use malloc() behind the scenes but optionally ** track memory per system (OpenSSL, sqlite, libuv, ...) and store callstacks ** to help debug leaks. ** @{ */ #include #include #include /** JS malloc functions. */ typedef struct JSMallocFunctions JSMallocFunctions; /** ** Do early setup for memory tracking. ** @param tracking Whether tracking will be enabled, which adds a time and ** memory cost of storing stack traces for every allocation. */ void tf_mem_startup(bool tracking); /** ** Clean up the memory system. */ void tf_mem_shutdown(); /** ** Register a custom allocator with libuv. */ void tf_mem_replace_uv_allocator(); /** ** Get the number of bytes currently allocated by libuv. ** @return The allocated size in bytes. */ size_t tf_mem_get_uv_malloc_size(); /** ** Register a custom allocator with OpenSSL. */ void tf_mem_replace_tls_allocator(); /** ** Get the number of bytes currently allocated by OpenSSL. ** @return The allocated size in bytes. */ size_t tf_mem_get_tls_malloc_size(); /** ** Register a custom allocator with SQLite. */ void tf_mem_replace_sqlite_allocator(); /** ** Get the number of bytes currently allocated by SQLite. ** @return The allocated size in bytes. */ size_t tf_mem_get_sqlite_malloc_size(); /** ** Get the number of bytes currently allocated by tf_malloc(). ** @return The allocated size in bytes. */ size_t tf_mem_get_tf_malloc_size(); /** ** Allocate memory. Like malloc() but with more tracking. ** @param size The number of bytes to allocate. ** @return The allocated memory. */ void* tf_malloc(size_t size); /** ** Reallocate memory. Like realloc() but with more tracking. ** @param ptr The previously allocated memory or NULL. ** @param size The new desired size. ** @return The new allocation. */ void* tf_realloc(void* ptr, size_t size); /** ** Free memory allocated by tf_malloc() or tf_realloc(). ** @param ptr The allocation. */ void tf_free(void* ptr); /** ** Duplicate a string. ** @param string The string to copy. ** @return The newly allocated string. Free with tf_free(). */ char* tf_strdup(const char* string); /** ** Resize a vector. Like tf_realloc() but overallocatess and prefers not to ** shrink in order to speed up repeated growth. ** @param ptr The allocation to resize. ** @param size The desired new size. ** @return The new allocation. */ void* tf_resize_vec(void* ptr, size_t size); /** ** Populate a struct with custom JS allocation functions. ** @param[out] out The struct to receive the functions. */ void tf_get_js_malloc_functions(JSMallocFunctions* out); /** ** Get the number of bytes currently allocated by JS allocators. ** @return The allocated size in bytes. */ size_t tf_mem_get_js_malloc_size(); /** ** Call a function for every live memory allocation. ** @param callback The callback to call. ** @param user_data User data to pass to the callback. */ void tf_mem_walk_allocations(void (*callback)(void* ptr, size_t size, int frames_count, void* const* frames, void* user_data), void* user_data); /** ** Information about a memory allocation. */ typedef struct _tf_mem_allocation_t { /** A hash of the callstack used for determining uniqueness. */ uint32_t stack_hash; /** The number of instances of this allocation. */ int count; /** The size of this allocation. */ size_t size; /** The callstack from which this allocation was made. */ void* frames[32]; /** The number of frames in the callstack. */ int frames_count; } tf_mem_allocation_t; /** ** Generate a list of live allocations. ** @param[out] out_count The number of allocations returned. ** @return An array of allocation information. Free with tf_free(). */ tf_mem_allocation_t* tf_mem_summarize_allocations(int* out_count); /** @} */