|
@@ -214,6 +214,13 @@ static void gc_save_context(hl_thread_info *t, void *prev_stack ) {
|
|
// to gc_save_context (or before) which might hold a gc value !
|
|
// to gc_save_context (or before) which might hold a gc value !
|
|
// let's capture them immediately in extra per-thread data
|
|
// let's capture them immediately in extra per-thread data
|
|
t->stack_cur = &prev_stack;
|
|
t->stack_cur = &prev_stack;
|
|
|
|
+
|
|
|
|
+ // We have no guarantee prev_stack is pointer-aligned
|
|
|
|
+ // All calls are passing a pointer to a bool, which is aligned on 1 byte
|
|
|
|
+ // If pointer is wrongly aligned, the extra_stack_data is misaligned
|
|
|
|
+ // and register pointers save in stack will not be discovered correctly by the GC
|
|
|
|
+ uintptr_t aligned_prev_stack = ((uintptr_t)prev_stack) & ~(sizeof(void*) - 1);
|
|
|
|
+ prev_stack = (void*)aligned_prev_stack;
|
|
int size = (int)((char*)prev_stack - (char*)stack_cur) / sizeof(void*);
|
|
int size = (int)((char*)prev_stack - (char*)stack_cur) / sizeof(void*);
|
|
if( size > HL_MAX_EXTRA_STACK ) hl_fatal("GC_SAVE_CONTEXT");
|
|
if( size > HL_MAX_EXTRA_STACK ) hl_fatal("GC_SAVE_CONTEXT");
|
|
t->extra_stack_size = size;
|
|
t->extra_stack_size = size;
|