| 993 | } |
| 994 | |
| 995 | void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size) { |
| 996 | #ifdef EMMALLOC_VERBOSE |
| 997 | MAIN_THREAD_ASYNC_EM_ASM(out('aligned_realloc(ptr=' + ptrToString($0) + ', alignment=' + $1 + ', size=' + Number($2)), ptr, alignment, size); |
| 998 | #endif |
| 999 | |
| 1000 | if (!ptr) { |
| 1001 | return emmalloc_memalign(alignment, size); |
| 1002 | } |
| 1003 | |
| 1004 | if (size == 0) { |
| 1005 | free(ptr); |
| 1006 | return 0; |
| 1007 | } |
| 1008 | |
| 1009 | if (size > MAX_ALLOC_SIZE) { |
| 1010 | #ifdef EMMALLOC_VERBOSE |
| 1011 | MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + Number($0) + 'bytes! (negative integer wraparound?)'), size); |
| 1012 | #endif |
| 1013 | return 0; |
| 1014 | } |
| 1015 | |
| 1016 | assert(IS_POWER_OF_2(alignment)); |
| 1017 | // aligned_realloc() cannot be used to ask to change the alignment of a pointer. |
| 1018 | assert(HAS_ALIGNMENT(ptr, alignment)); |
| 1019 | size = validate_alloc_size(size); |
| 1020 | |
| 1021 | // Calculate the region start address of the original allocation |
| 1022 | Region *region = (Region*)((uint8_t*)ptr - sizeof(size_t)); |
| 1023 | |
| 1024 | // First attempt to resize the given region to avoid having to copy memory around |
| 1025 | if (acquire_and_attempt_region_resize(region, size + REGION_HEADER_SIZE)) { |
| 1026 | #ifdef __EMSCRIPTEN_TRACING__ |
| 1027 | emscripten_trace_record_reallocation(ptr, ptr, size); |
| 1028 | #endif |
| 1029 | return ptr; |
| 1030 | } |
| 1031 | |
| 1032 | // If resize failed, we must allocate a new region, copy the data over, and then |
| 1033 | // free the old region. |
| 1034 | void *newptr = emmalloc_memalign(alignment, size); |
| 1035 | if (newptr) { |
| 1036 | memcpy(newptr, ptr, MIN(size, region->size - REGION_HEADER_SIZE)); |
| 1037 | free(ptr); |
| 1038 | } |
| 1039 | // N.B. If there is not enough memory, the old memory block should not be freed and |
| 1040 | // null pointer is returned. |
| 1041 | return newptr; |
| 1042 | } |
| 1043 | EMMALLOC_ALIAS(aligned_realloc, emmalloc_aligned_realloc); |
| 1044 | |
| 1045 | // realloc_try() is like realloc(), but only attempts to try to resize the existing memory |
no test coverage detected