summaryrefslogtreecommitdiff
path: root/src/c/urweb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/c/urweb.c')
-rw-r--r--src/c/urweb.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c
index 26046461..a9b08092 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -1256,17 +1256,34 @@ void uw_end_initializing(uw_context ctx) {
ctx->amInitializing = 0;
}
+static void align_heap(uw_context ctx) {
+ size_t posn = ctx->heap.front - ctx->heap.start;
+
+ if (posn % 4 != 0) {
+ size_t bump = 4 - posn % 4;
+ uw_check_heap(ctx, bump);
+ ctx->heap.front += bump;
+ }
+}
+
void *uw_malloc(uw_context ctx, size_t len) {
+ // On some architectures, it's important that all word-sized memory accesses
+ // be to word-aligned addresses, so we'll do a little bit of extra work here
+ // in anticipation of a possible word-aligned access to the address we'll
+ // return.
+
void *result;
if (ctx->amInitializing) {
- result = malloc(len);
+ int error = posix_memalign(&result, 4, len);
- if (result)
+ if (!error)
return result;
else
- uw_error(ctx, FATAL, "uw_malloc: malloc() returns 0");
+ uw_error(ctx, FATAL, "uw_malloc: posix_memalign() returns %d", error);
} else {
+ align_heap(ctx);
+
uw_check_heap(ctx, len);
result = ctx->heap.front;
@@ -1276,6 +1293,8 @@ void *uw_malloc(uw_context ctx, size_t len) {
}
void uw_begin_region(uw_context ctx) {
+ align_heap(ctx);
+
regions *r = (regions *) ctx->heap.front;
uw_check_heap(ctx, sizeof(regions));