#include <string.h>
#include <stdint.h>
+#include "util/macros.h"
+#include "util/u_math.h"
+
/* Some versions of MinGW are missing _vscprintf's declaration, although they
* still provide the symbol in the import library. */
#ifdef __MINGW32__
*/
struct
#ifdef _MSC_VER
+#if _WIN64
+__declspec(align(16))
+#else
__declspec(align(8))
+#endif
#elif defined(__LP64__)
__attribute__((aligned(16)))
#else
void *
ralloc_size(const void *ctx, size_t size)
{
- void *block = malloc(size + sizeof(ralloc_header));
+ /* Some malloc allocation doesn't always align to 16 bytes even on 64 bits
+ * system, from Android bionic/tests/malloc_test.cpp:
+ * - Allocations of a size that rounds up to a multiple of 16 bytes
+ * must have at least 16 byte alignment.
+ * - Allocations of a size that rounds up to a multiple of 8 bytes and
+ * not 16 bytes, are only required to have at least 8 byte alignment.
+ */
+ void *block = malloc(align64(size + sizeof(ralloc_header),
+ alignof(ralloc_header)));
ralloc_header *info;
ralloc_header *parent;
ralloc_header *child, *old, *info;
old = get_header(ptr);
- info = realloc(old, size + sizeof(ralloc_header));
+ info = realloc(old, align64(size + sizeof(ralloc_header),
+ alignof(ralloc_header)));
if (info == NULL)
return NULL;
return resize(ptr, size);
}
+void *
+rerzalloc_size(const void *ctx, void *ptr, size_t old_size, size_t new_size)
+{
+ if (unlikely(ptr == NULL))
+ return rzalloc_size(ctx, new_size);
+
+ assert(ralloc_parent(ptr) == ctx);
+ ptr = resize(ptr, new_size);
+
+ if (new_size > old_size)
+ memset((char *)ptr + old_size, 0, new_size - old_size);
+
+ return ptr;
+}
+
void *
ralloc_array_size(const void *ctx, size_t size, unsigned count)
{
return reralloc_size(ctx, ptr, size * count);
}
+void *
+rerzalloc_array_size(const void *ctx, void *ptr, size_t size,
+ unsigned old_count, unsigned new_count)
+{
+ if (new_count > SIZE_MAX/size)
+ return NULL;
+
+ return rerzalloc_size(ctx, ptr, size * old_count, size * new_count);
+}
+
void
ralloc_free(void *ptr)
{