From 5ea3201dca66d933afa7d937117fe970ad9756dc Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Mon, 13 Oct 2025 18:25:19 +0000 Subject: [PATCH] [MPS] Use xmalloc to allocate 'bc_thread_state' struct This struct cannot live in MPS-managed memory because it's required for scanning the bytecode stack. * src/bytecode.c (free_bc_thread) [MPS]: Free bytecode structure. (Finternal_stack_stats, exec_byte_code): * src/igc.c (scan_bc): Adjust. (root_create_bc): Save 'bc' pointer. * src/lisp.h (get_act_rec, set_act_rec): * src/thread.c (mark_one_thread, finalize_one_thread): Adjust. (Fmake_thread) [MPS]: (init_threads) [MPS]: Allocate bytecode structure. * src/thread.h (struct thread_state): Turn 'bc' member into a pointer (MPS) or single-member array. --- src/bytecode.c | 9 ++++++--- src/igc.c | 8 +++++--- src/lisp.h | 4 ++-- src/thread.c | 12 ++++++++---- src/thread.h | 9 +++++---- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/bytecode.c b/src/bytecode.c index 2ab28d231c5..4ef3f8b3f53 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -399,6 +399,9 @@ void free_bc_thread (struct bc_thread_state *bc) { xfree (bc->stack); +#ifdef HAVE_MPS + xfree (bc); +#endif } #ifndef HAVE_MPS @@ -439,7 +442,7 @@ DEFUN ("internal-stack-stats", Finternal_stack_stats, Sinternal_stack_stats, doc: /* internal */) (void) { - struct bc_thread_state *bc = ¤t_thread->bc; + struct bc_thread_state *bc = current_thread->bc; int nframes = 0; int nruns = 0; for (struct bc_frame *fp = bc->fp; fp; fp = fp->saved_fp) @@ -474,7 +477,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, int volatile this_op = 0; #endif unsigned char quitcounter = 1; - struct bc_thread_state *bc = ¤t_thread->bc; + struct bc_thread_state *bc = current_thread->bc; /* Values used for the first stack record when called from C. */ Lisp_Object *top = NULL; @@ -983,7 +986,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, handlerlist = c->next; top = c->bytecode_top; op = c->bytecode_dest; - bc = ¤t_thread->bc; + bc = current_thread->bc; struct bc_frame *fp = bc->fp; Lisp_Object fun = fp->fun; diff --git a/src/igc.c b/src/igc.c index df5726ae7dc..b45d40adec9 100644 --- a/src/igc.c +++ b/src/igc.c @@ -163,7 +163,7 @@ along with GNU Emacs. If not, see . */ # ifndef HASH_Lisp_User_Ptr_7DC5544B44 # error "struct Lisp_User_Ptr changed" # endif -# ifndef HASH_thread_state_67C02A2EF0 +# ifndef HASH_thread_state_6DAE3DDD15 # error "struct thread_state changed" # endif # ifndef HASH_Lisp_Mutex_744F44A86D @@ -923,6 +923,7 @@ struct igc_thread /* Back pointer to Emacs' thread object. Allocated so that it doesn't move in memory. */ struct thread_state *ts; + struct bc_thread_state *bc; }; typedef struct igc_thread igc_thread; @@ -1732,7 +1733,7 @@ scan_bc (mps_ss_t ss, void *start, void *end, void *closure) MPS_SCAN_BEGIN (ss) { struct igc_thread_list *t = closure; - struct bc_thread_state *bc = &t->d.ts->bc; + struct bc_thread_state *bc = t->d.bc; igc_assert (start == (void *) bc->stack); igc_assert (end == (void *) bc->stack_end); /* FIXME/igc: AFAIU the current top frame starts at @@ -3135,7 +3136,8 @@ static void root_create_bc (struct igc_thread_list *t) { struct igc *gc = t->d.gc; - struct bc_thread_state *bc = &t->d.ts->bc; + struct bc_thread_state *bc = t->d.ts->bc; + t->d.bc = bc; igc_assert (bc->stack != NULL); mps_root_t root; mps_res_t res = mps_root_create_area (&root, gc->arena, mps_rank_ambig (), 0, diff --git a/src/lisp.h b/src/lisp.h index 9a51a75ffed..596274eccde 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -5640,13 +5640,13 @@ extern void *bc_next_frame (struct bc_frame *bc); INLINE struct bc_frame * get_act_rec (struct thread_state *th) { - return th->bc.fp; + return th->bc->fp; } INLINE void set_act_rec (struct thread_state *th, struct bc_frame *act_rec) { - th->bc.fp = act_rec; + th->bc->fp = act_rec; } /* Defined in macros.c. */ diff --git a/src/thread.c b/src/thread.c index ffb728a4822..291dde775f8 100644 --- a/src/thread.c +++ b/src/thread.c @@ -687,7 +687,7 @@ mark_one_thread (struct thread_state *thread) mark_object (tem); } - mark_bytecode (&thread->bc); + mark_bytecode (thread->bc); /* No need to mark Lisp_Object members like m_last_thing_searched, as mark_threads_callback does that by calling mark_object. */ @@ -895,7 +895,7 @@ finalize_one_thread (struct thread_state *state) free_search_regs (&state->m_search_regs); free_search_regs (&state->m_saved_search_regs); sys_cond_destroy (&state->thread_condvar); - free_bc_thread (&state->bc); + free_bc_thread (state->bc); } DEFUN ("make-thread", Fmake_thread, Smake_thread, 1, 3, 0, @@ -925,6 +925,7 @@ will be signaled. */) new_thread->name = name; #ifdef HAVE_MPS new_thread->m_getcjmp = igc_xzalloc_ambig (sizeof (*new_thread->m_getcjmp)); + new_thread->bc = xzalloc (sizeof (*new_thread->bc)); #endif /* Perhaps copy m_last_thing_searched from parent? */ new_thread->m_current_buffer = current_thread->m_current_buffer; @@ -935,7 +936,7 @@ will be signaled. */) new_thread->m_specpdl_end = new_thread->m_specpdl + size; new_thread->m_specpdl_ptr = new_thread->m_specpdl; - init_bc_thread (&new_thread->bc); + init_bc_thread (new_thread->bc); sys_cond_init (&new_thread->thread_condvar); /* We'll need locking here eventually. */ @@ -1273,7 +1274,10 @@ init_threads (void) main_thread.s.thread_id = sys_thread_self (); main_thread.s.buffer_disposition = Qnil; - init_bc_thread (&main_thread.s.bc); +#ifdef HAVE_MPS + main_thread.s.bc = xzalloc (sizeof (*main_thread.s.bc)); +#endif + init_bc_thread (main_thread.s.bc); #ifdef HAVE_MPS igc_on_alloc_main_thread_bc (); #endif diff --git a/src/thread.h b/src/thread.h index 895c4944f29..e1df0853392 100644 --- a/src/thread.h +++ b/src/thread.h @@ -224,12 +224,13 @@ struct thread_state /* Threads are kept on a linked list. */ struct thread_state *next_thread; - struct bc_thread_state bc; - -# ifdef HAVE_MPS +#ifndef HAVE_MPS + struct bc_thread_state bc[1]; +#else + struct bc_thread_state *bc; void *gc_info; ptrdiff_t pin_index; -# endif +#endif } GCALIGNED_STRUCT;