diff --git a/src/core/continuation.c b/src/core/continuation.c index f9d933a553..64c4ae493b 100644 --- a/src/core/continuation.c +++ b/src/core/continuation.c @@ -35,6 +35,8 @@ void MVM_continuation_reset(MVMThreadContext *tc, MVMObject *tag, MVM_frame_special_return(tc, tc->cur_frame, clear_tag, NULL, tag_record, NULL); STABLE(code)->invoke(tc, code, null_args_callsite, tc->cur_frame->args); } + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); } void MVM_continuation_control(MVMThreadContext *tc, MVMint64 protect, @@ -134,6 +136,8 @@ void MVM_continuation_control(MVMThreadContext *tc, MVMint64 protect, MVM_args_setup_thunk(tc, tc->cur_frame->return_value, tc->cur_frame->return_type, inv_arg_callsite); tc->cur_frame->args[0].o = cont; STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); } void MVM_continuation_invoke(MVMThreadContext *tc, MVMContinuation *cont, @@ -192,6 +196,8 @@ void MVM_continuation_invoke(MVMThreadContext *tc, MVMContinuation *cont, MVM_args_setup_thunk(tc, cont->body.res_reg, MVM_RETURN_OBJ, null_args_callsite); STABLE(code)->invoke(tc, code, null_args_callsite, tc->cur_frame->args); } + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); } void MVM_continuation_free_tags(MVMThreadContext *tc, MVMFrame *f) { diff --git a/src/core/frame.c b/src/core/frame.c index ddef60f866..71c78b19f7 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -715,20 +715,7 @@ MVMFrame * MVM_frame_move_to_heap(MVMThreadContext *tc, MVMFrame *frame) { }); }); }); -#if MVM_GC_DEBUG - { - MVMFrame *check = new_cur_frame; - while (check) { - MVM_ASSERT_NOT_FROMSPACE(tc, check); - if ((check->header.flags & MVM_CF_SECOND_GEN) && - check->caller && - !(check->caller->header.flags & MVM_CF_SECOND_GEN) && - !(check->header.flags & MVM_CF_IN_GEN2_ROOT_LIST)) - MVM_panic(1, "Gen2 -> Nursery after promotion without inter-gen set entry"); - check = check->caller; - } - } -#endif + MVM_CHECK_CALLER_CHAIN(tc, new_cur_frame); /* All is promoted. Update thread's current frame and reset the thread * local callstack. */ diff --git a/src/gc/debug.h b/src/gc/debug.h index 15f73aeaea..9c613ca946 100644 --- a/src/gc/debug.h +++ b/src/gc/debug.h @@ -18,6 +18,19 @@ cur_thread = cur_thread->body.next; \ } \ } while (0) +#define MVM_CHECK_CALLER_CHAIN(tc, f) do { \ + MVMFrame *check = f; \ + while (check) { \ + MVM_ASSERT_NOT_FROMSPACE(tc, check); \ + if ((check->header.flags & MVM_CF_SECOND_GEN) && \ + check->caller && \ + !(check->caller->header.flags & MVM_CF_SECOND_GEN) && \ + !(check->header.flags & MVM_CF_IN_GEN2_ROOT_LIST)) \ + MVM_panic(1, "Illegal Gen2 -> Nursery in caller chain (not in inter-gen set)"); \ + check = check->caller; \ + } \ +} while (0) #else #define MVM_ASSERT_NOT_FROMSPACE(tc, c) +#define MVM_CHECK_CALLER_CHAIN(tc, f) #endif diff --git a/src/spesh/deopt.c b/src/spesh/deopt.c index aaf9adbd91..32f04b2104 100644 --- a/src/spesh/deopt.c +++ b/src/spesh/deopt.c @@ -83,6 +83,7 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand, uf->return_value = uf->work + last_res_reg; /* Set up last uninlined's caller to us. */ + MVM_ASSERT_NOT_FROMSPACE(tc, uf); MVM_ASSIGN_REF(tc, &(last_uninlined->header), last_uninlined->caller, uf); } else { @@ -91,6 +92,7 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand, if (callee) { /* Tweak the callee's caller to the uninlined frame, not * the frame holding the inlinings. */ + MVM_ASSERT_NOT_FROMSPACE(tc, uf); MVM_ASSIGN_REF(tc, &(callee->header), callee->caller, uf); /* Copy over the return location. */ @@ -141,6 +143,7 @@ static void uninline(MVMThreadContext *tc, MVMFrame *f, MVMSpeshCandidate *cand, f->return_value = f->work + last_res_reg; /* Set up inliner as the caller, given we now have a direct inline. */ + MVM_ASSERT_NOT_FROMSPACE(tc, f); MVM_ASSIGN_REF(tc, &(last_uninlined->header), last_uninlined->caller, f); } else { @@ -224,6 +227,8 @@ void MVM_spesh_deopt_one(MVMThreadContext *tc, MVMuint32 deopt_target) { MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.name), MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid)); } + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); } /* De-optimizes the current frame by directly specifying the addresses */ @@ -240,6 +245,8 @@ void MVM_spesh_deopt_one_direct(MVMThreadContext *tc, MVMuint32 deopt_offset, MVM_profiler_log_deopt_one(tc); clear_dynlex_cache(tc, f); deopt_frame(tc, tc->cur_frame, deopt_offset, deopt_target); + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); } /* De-optimizes all specialized frames on the call stack. Used when a change @@ -340,4 +347,6 @@ void MVM_spesh_deopt_all(MVMThreadContext *tc) { l = f; f = f->caller; } + + MVM_CHECK_CALLER_CHAIN(tc, tc->cur_frame); }