-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Update emmalloc #10145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update emmalloc #10145
Changes from all commits
977ec7d
f883a95
2c0e6a5
5218324
7ff0e12
b4e7475
4fd3fac
db14ec6
8b3788a
14a83e4
643428e
0acfc0b
d75a62e
c2d48d9
889c0bd
e1f61ce
73cd7a3
8892ec0
f9421c5
710ca0c
5cbffb5
178ff31
a5746d7
26c9833
82071cd
aef4af4
d0b8d99
3fee227
3a3e0c2
7f1ddfa
3d726a8
a1761a1
c512595
f61fa24
2f2fca6
448d340
5369f8b
62b11ac
5752116
d02a293
1648386
be84597
b8d5599
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
mergeInto(LibraryManager.library, { | ||
emmalloc_unclaimed_heap_memory__deps: ['emscripten_get_sbrk_ptr'], | ||
emmalloc_unclaimed_heap_memory: function() { | ||
var dynamicTop = HEAPU32[_emscripten_get_sbrk_ptr()>>2]; | ||
#if ALLOW_MEMORY_GROWTH | ||
#if WASM | ||
#if WASM_MEM_MAX != -1 | ||
// Using WASM_MEM_MAX to constrain max heap size. | ||
return {{{ WASM_MEM_MAX }}} - dynamicTop; | ||
#else | ||
// Not using a Wasm memory bound. | ||
return 2*1024*1024*1024 - 65536 - dynamicTop; | ||
#endif | ||
#else | ||
// asm.js: | ||
return 2*1024*1024*1024 - 16777216 - dynamicTop; | ||
#endif | ||
#else | ||
// ALLOW_MEMORY_GROWTH is disabled, the current heap size | ||
// is all we got. | ||
return HEAPU8.length - dynamicTop; | ||
#endif | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ | |
var LibraryPThread = { | ||
$PThread__postset: 'if (!ENVIRONMENT_IS_PTHREAD) PThread.initMainThreadBlock(); else PThread.initWorker();', | ||
$PThread__deps: ['$PROCINFO', '_register_pthread_ptr', | ||
'emscripten_main_thread_process_queued_calls', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Split out this change along with src/deps_info.json? Seems unrelated but maybe I'm wrong? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It only started failing in this branch because of the deps structure changing. |
||
'$ERRNO_CODES', 'emscripten_futex_wake', '_kill_thread', | ||
'_cancel_thread', '_cleanup_thread'], | ||
$PThread: { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#pragma once | ||
|
||
#include <stddef.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// emmalloc: A lightweight web-friendly memory allocator suitable for very small applications. | ||
// Enable the usage of emmalloc by passing the linker flag -s MALLOC=emmalloc to the application. | ||
|
||
// A debug function that dumps the whole structure of malloc internal memory blocks to console. | ||
// *extremely slow*, use for debugging allocation test cases. | ||
void emmalloc_dump_memory_regions(void); | ||
|
||
// Allocates size bytes with the given pow-2 alignment. | ||
void *memalign(size_t alignment, size_t size); | ||
void *emmalloc_memalign(size_t alignment, size_t size); | ||
void *emscripten_builtin_memalign(size_t alignment, size_t size); | ||
void *aligned_alloc(size_t alignment, size_t size); | ||
|
||
// Allocates size bytes with default alignment (8 bytes) | ||
void *malloc(size_t size); | ||
void *emmalloc_malloc(size_t size); | ||
void *emscripten_builtin_malloc(size_t size); | ||
|
||
// Returns the number of bytes that are actually allocated to the given pointer ptr. | ||
// E.g. due to alignment or size requirements, the actual size of the allocation can be | ||
// larger than what was requested. | ||
size_t malloc_usable_size(void *ptr); | ||
size_t emmalloc_usable_size(void *ptr); | ||
|
||
// Frees a memory pointer allocated with any of | ||
// emmalloc_memalign, emmalloc_malloc, | ||
void free(void *ptr); | ||
void emmalloc_free(void *ptr); | ||
void emscripten_builtin_free(void *ptr); | ||
|
||
// Performs a reallocation of the given memory pointer to a new size. If the memory region | ||
// pointed by ptr cannot be resized in place, a new memory region will be allocated, old | ||
// memory copied over, and the old memory area freed. The pointer ptr must have been | ||
// allocated with one of the emmalloc memory allocation functions (malloc, memalign, ...). | ||
// If called with size == 0, the pointer ptr is freed, and a null pointer is returned. If | ||
// called with null ptr, a new pointer is allocated. | ||
void *realloc(void *ptr, size_t size); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to re-declare all the POSIX names here? Would it be better to use the ones from stdlib.h and only declare the specific emmalloc symbols in this header? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's more documentative to re-declare them here. No harm in doing so, in fact, if there ever were a change in signature of one of the names, then this would loudly complain, and it'd trigger to change the signature of the corresponding |
||
void *emmalloc_realloc(void *ptr, size_t size); | ||
|
||
// emmalloc_realloc_try() is like realloc(), but only attempts to try to resize the existing | ||
// memory area. If resizing the existing memory area fails, then realloc_try() will return 0 | ||
// (the original memory block is not freed or modified). If resizing succeeds, previous | ||
// memory contents will be valid up to min(old length, new length) bytes. | ||
// If a null pointer is passed, no allocation is attempted but the function will return 0. | ||
// If zero size is passed, the function will behave like free(). | ||
void *emmalloc_realloc_try(void *ptr, size_t size); | ||
|
||
// emmalloc_realloc_uninitialized() is like realloc(), but old memory contents | ||
// will be undefined after reallocation. (old memory is not preserved in any case) | ||
void *emmalloc_realloc_uninitialized(void *ptr, size_t size); | ||
|
||
// Like realloc(), but allows specifying the alignment to allocate to. This function cannot | ||
// be used to change the alignment of an existing allocation, but the original pointer should | ||
// be aligned to the given alignment already. | ||
void *aligned_realloc(void *ptr, size_t alignment, size_t size); | ||
void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size); | ||
|
||
// emmalloc_aligned_realloc_uninitialized() is like aligned_realloc(), but old memory contents | ||
// will be undefined after reallocation. (old memory is not preserved in any case) | ||
void *emmalloc_aligned_realloc_uninitialized(void *ptr, size_t alignment, size_t size); | ||
|
||
// posix_memalign allocates memory with a given alignment, like memalign, but with a slightly | ||
// different usage signature. | ||
int posix_memalign(void **memptr, size_t alignment, size_t size); | ||
int emmalloc_posix_memalign(void **memptr, size_t alignment, size_t size); | ||
|
||
// calloc allocates memory that is initialized to zero. | ||
void *calloc(size_t num, size_t size); | ||
void *emmalloc_calloc(size_t num, size_t size); | ||
|
||
// mallinfo() returns information about current emmalloc allocation state. This function | ||
// is very slow, only good for debugging. Avoid calling it for "routine" diagnostics. | ||
struct mallinfo mallinfo(); | ||
struct mallinfo emmalloc_mallinfo(); | ||
|
||
// malloc_trim() returns unused dynamic memory back to the WebAssembly heap. Returns 1 if it | ||
// actually freed any memory, and 0 if not. Note: this function does not release memory back to | ||
// the system, but it only marks memory held by emmalloc back to unused state for other users | ||
// of sbrk() to claim. | ||
int malloc_trim(size_t pad); | ||
int emmalloc_trim(size_t pad); | ||
|
||
// Validates the consistency of the malloc heap. Returns non-zero and prints an error to console | ||
// if memory map is corrupt. Returns 0 (and does not print anything) if memory is intact. | ||
int emmalloc_validate_memory_regions(void); | ||
|
||
// Computes the size of the dynamic memory region governed by emmalloc. This represents the | ||
// amount of memory that emmalloc has sbrk()ed in for itself to manage. Use this function | ||
// for memory statistics tracking purposes. Calling this function is quite fast, practically | ||
// O(1) time. | ||
size_t emmalloc_dynamic_heap_size(void); | ||
|
||
// Computes the amount of memory currently reserved under emmalloc's governance that is free | ||
// for the application to allocate. Use this function for memory statistics tracking purposes. | ||
// Note that calling this function is very slow, as it walks through each free memory block in | ||
// linear time. | ||
size_t emmalloc_free_dynamic_memory(void); | ||
|
||
// Estimates the amount of untapped memory that emmalloc could expand its dynamic memory area | ||
// via sbrk()ing. Theoretically the maximum amount of memory that can still be malloc()ed can | ||
// be calculated via emmalloc_free_dynamic_memory() + emmalloc_unclaimed_heap_memory(). | ||
// Calling this function is very fast constant time lookup. | ||
size_t emmalloc_unclaimed_heap_memory(void); | ||
|
||
// Computes a detailed fragmentation map of available free memory. Pass in a pointer to a | ||
// 32 element long array. This function populates into each array index i the number of free | ||
// memory regions that have a size 2^i <= size < 2^(i+1), and returns the total number of | ||
// free memory regions (the sum of the array entries). This function runs very slowly, as it | ||
// iterates through all free memory blocks. | ||
size_t emmalloc_compute_free_dynamic_memory_fragmentation_map(size_t freeMemorySizeMap[32]); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also looks like it just used in tests. Is it worth added this JS library just for sake of a test case? Maybe there is some way to avoid it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intent is to expose that function to public API for users of emmalloc, hence testing that it works in that test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But isn't that function internal-only right now? So the fact that it has a bad name is currently not an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this should be split out into a separate PR btw. Although I'm still not convinced about the need to shrink memory (since its not possible with wasm).