Skip to content
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

Avoid trampolines in emmalloc #20496

Merged
merged 2 commits into from
Oct 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 13 additions & 74 deletions system/lib/emmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ static_assert((((int32_t)0x80000000U) >> 31) == -1, "This malloc implementation
static_assert(alignof(max_align_t) == 8, "max_align_t must be correct");

#ifdef EMMALLOC_NO_STD_EXPORTS
#define EMMALLOC_EXPORT
#define EMMALLOC_ALIAS(ALIAS, ORIGINAL)
#else
#define EMMALLOC_EXPORT __attribute__((weak, __visibility__("default")))
#define EMMALLOC_ALIAS(ALIAS, ORIGINAL) extern __typeof(ORIGINAL) ALIAS __attribute__((alias(#ORIGINAL)));
#define EMMALLOC_ALIAS(ALIAS, ORIGINAL) extern __typeof(ORIGINAL) ALIAS __attribute__((weak, alias(#ORIGINAL)));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to make these weak?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to match the previous behavior.

If we don't do this then e.g. malloc would not be weak, so the user couldn't override it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that it true though.. the existing symbols are strong in that if you link the object file you are forced to take that definition. Do you have a test that fails without weak?

Overriding malloc as far as I know only works today if you don't actually use any symbols from emmalloc.o (or dlmalloc.o).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry. I see the existing EMMALLOC_EXPORT is weak... I'm not sure it should be but lgtm given that

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also dlmalloc.c uses weak aliases for all of these..

#endif

#define MIN(x, y) ((x) < (y) ? (x) : (y))
Expand Down Expand Up @@ -826,13 +825,7 @@ void *emmalloc_memalign(size_t alignment, size_t size)
return ptr;
}
EMMALLOC_ALIAS(emscripten_builtin_memalign, emmalloc_memalign);

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT memalign(size_t alignment, size_t size)
{
return emmalloc_memalign(alignment, size);
}
#endif
EMMALLOC_ALIAS(memalign, emmalloc_memalign);

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT aligned_alloc(size_t alignment, size_t size)
Expand All @@ -848,14 +841,8 @@ void *emmalloc_malloc(size_t size)
return emmalloc_memalign(MALLOC_ALIGNMENT, size);
}
EMMALLOC_ALIAS(emscripten_builtin_malloc, emmalloc_malloc);
EMMALLOC_ALIAS(__libc_malloc, emmalloc_malloc);

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT malloc(size_t size)
{
return emmalloc_malloc(size);
}
#endif
EMMALLOC_ALIAS(__libc_malloc, emmalloc_malloc);
EMMALLOC_ALIAS(malloc, emmalloc_malloc);

size_t emmalloc_usable_size(void *ptr)
{
Expand All @@ -876,13 +863,7 @@ size_t emmalloc_usable_size(void *ptr)

return size - REGION_HEADER_SIZE;
}

#ifndef EMMALLOC_NO_STD_EXPORTS
size_t EMMALLOC_EXPORT malloc_usable_size(void *ptr)
{
return emmalloc_usable_size(ptr);
}
#endif
EMMALLOC_ALIAS(malloc_usable_size, emmalloc_usable_size);

void emmalloc_free(void *ptr)
{
Expand Down Expand Up @@ -954,14 +935,8 @@ void emmalloc_free(void *ptr)
#endif
}
EMMALLOC_ALIAS(emscripten_builtin_free, emmalloc_free);
EMMALLOC_ALIAS(__libc_free, emmalloc_free);

#ifndef EMMALLOC_NO_STD_EXPORTS
void EMMALLOC_EXPORT free(void *ptr)
{
return emmalloc_free(ptr);
}
#endif
EMMALLOC_ALIAS(__libc_free, emmalloc_free);
EMMALLOC_ALIAS(free, emmalloc_free);

// Can be called to attempt to increase or decrease the size of the given region
// to a new size (in-place). Returns 1 if resize succeeds, and 0 on failure.
Expand Down Expand Up @@ -1089,13 +1064,7 @@ void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size)
// null pointer is returned.
return newptr;
}

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT aligned_realloc(void *ptr, size_t alignment, size_t size)
{
return emmalloc_aligned_realloc(ptr, alignment, size);
}
#endif
EMMALLOC_ALIAS(aligned_realloc, emmalloc_aligned_realloc);

// 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
Expand Down Expand Up @@ -1180,13 +1149,7 @@ void *emmalloc_realloc(void *ptr, size_t size)
return emmalloc_aligned_realloc(ptr, MALLOC_ALIGNMENT, size);
}
EMMALLOC_ALIAS(__libc_realloc, emmalloc_realloc);

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT realloc(void *ptr, size_t size)
{
return emmalloc_realloc(ptr, size);
}
#endif
EMMALLOC_ALIAS(realloc, emmalloc_realloc);

// realloc_uninitialized() is like realloc(), but old memory contents
// will be undefined after reallocation. (old memory is not preserved in any case)
Expand All @@ -1203,13 +1166,7 @@ int emmalloc_posix_memalign(void **memptr, size_t alignment, size_t size)
*memptr = emmalloc_memalign(alignment, size);
return *memptr ? 0 : 12/*ENOMEM*/;
}

#ifndef EMMALLOC_NO_STD_EXPORTS
int EMMALLOC_EXPORT posix_memalign(void **memptr, size_t alignment, size_t size)
{
return emmalloc_posix_memalign(memptr, alignment, size);
}
#endif
EMMALLOC_ALIAS(posix_memalign, emmalloc_posix_memalign);

void *emmalloc_calloc(size_t num, size_t size)
{
Expand All @@ -1220,13 +1177,7 @@ void *emmalloc_calloc(size_t num, size_t size)
return ptr;
}
EMMALLOC_ALIAS(__libc_calloc, emmalloc_calloc);

#ifndef EMMALLOC_NO_STD_EXPORTS
void * EMMALLOC_EXPORT calloc(size_t num, size_t size)
{
return emmalloc_calloc(num, size);
}
#endif
EMMALLOC_ALIAS(calloc, emmalloc_calloc);

static int count_linked_list_size(Region *list)
{
Expand Down Expand Up @@ -1316,13 +1267,7 @@ struct mallinfo emmalloc_mallinfo()
MALLOC_RELEASE();
return info;
}

#ifndef EMMALLOC_NO_STD_EXPORTS
struct mallinfo EMMALLOC_EXPORT mallinfo()
{
return emmalloc_mallinfo();
}
#endif
EMMALLOC_ALIAS(mallinfo, emmalloc_mallinfo);

// Note! This function is not fully multithreading safe: while this function is running, other threads should not be
// allowed to call sbrk()!
Expand Down Expand Up @@ -1384,13 +1329,7 @@ int emmalloc_trim(size_t pad)
MALLOC_RELEASE();
return success;
}

#ifndef EMMALLOC_NO_STD_EXPORTS
int EMMALLOC_EXPORT malloc_trim(size_t pad)
{
return emmalloc_trim(pad);
}
#endif
EMMALLOC_ALIAS(malloc_trim, emmalloc_trim)

size_t emmalloc_dynamic_heap_size()
{
Expand Down