From 2b3b843f82e86583c797a19a9827bf7d4b085a79 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 30 Jun 2025 14:16:52 +0200 Subject: [PATCH] Dynstack uses inline functions instead of macros * libguile/control.c: * libguile/dynstack.c: * libguile/dynstack.h: * libguile/vm.c: Move SCM_DYNSTACK_TAG etc to be inline functions. Adapt all callers. --- libguile/control.c | 2 +- libguile/dynstack.c | 110 +++++++++++++++++++------------------- libguile/dynstack.h | 127 +++++++++++++++++++++++++++++++++----------- libguile/vm.c | 12 ++--- 4 files changed, 158 insertions(+), 93 deletions(-) diff --git a/libguile/control.c b/libguile/control.c index 772d93791..5abfaadc6 100644 --- a/libguile/control.c +++ b/libguile/control.c @@ -41,7 +41,7 @@ #define PROMPT_ESCAPE_P(p) \ - (SCM_DYNSTACK_TAG_FLAGS (SCM_DYNSTACK_TAG (p)) \ + (scm_dynstack_tag_flags (scm_dynstack_tag (p)) \ & SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY) diff --git a/libguile/dynstack.c b/libguile/dynstack.c index 6d188f24d..898112760 100644 --- a/libguile/dynstack.c +++ b/libguile/dynstack.c @@ -101,8 +101,8 @@ clear_scm_t_bits (scm_t_bits *items, size_t n) static void dynstack_ensure_space (scm_t_dynstack *dynstack, size_t n) { - size_t capacity = SCM_DYNSTACK_CAPACITY (dynstack); - size_t height = SCM_DYNSTACK_HEIGHT (dynstack); + size_t capacity = scm_dynstack_capacity (dynstack); + size_t height = scm_dynstack_height (dynstack); n += SCM_DYNSTACK_HEADER_LEN; @@ -142,18 +142,18 @@ scm_trace_dynstack (struct scm_dynstack *dynstack, { scm_t_bits *walk; - for (walk = SCM_DYNSTACK_PREV (dynstack->top); walk; - walk = SCM_DYNSTACK_PREV (walk)) + for (walk = scm_dynstack_prev (dynstack->top); walk; + walk = scm_dynstack_prev (walk)) { - scm_t_bits tag = SCM_DYNSTACK_TAG (walk); + scm_t_bits tag = scm_dynstack_tag (walk); - switch (SCM_DYNSTACK_TAG_TYPE (tag)) + switch (scm_dynstack_tag_type (tag)) { case SCM_DYNSTACK_TYPE_FRAME: break; case SCM_DYNSTACK_TYPE_UNWINDER: case SCM_DYNSTACK_TYPE_REWINDER: - if (SCM_DYNSTACK_TAG_FLAGS (tag) & SCM_F_DYNSTACK_WINDER_MANAGED) + if (scm_dynstack_tag_flags (tag) & SCM_F_DYNSTACK_WINDER_MANAGED) trace (gc_edge (WINDER_DATA_LOC (walk)), heap, trace_data); break; case SCM_DYNSTACK_TYPE_WITH_FLUID: @@ -220,10 +220,10 @@ push_dynstack_entry_unchecked (scm_t_dynstack *dynstack, { scm_t_bits *ret = dynstack->top; - SCM_DYNSTACK_SET_TAG (dynstack->top, SCM_MAKE_DYNSTACK_TAG (type, flags, len)); + scm_dynstack_set_tag (dynstack->top, scm_make_dynstack_tag (type, flags, len)); dynstack->top += SCM_DYNSTACK_HEADER_LEN + len; - SCM_DYNSTACK_SET_TAG (dynstack->top, 0); - SCM_DYNSTACK_SET_PREV_OFFSET (dynstack->top, SCM_DYNSTACK_HEADER_LEN + len); + scm_dynstack_set_tag (dynstack->top, 0); + scm_dynstack_set_prev_offset (dynstack->top, SCM_DYNSTACK_HEADER_LEN + len); return ret; } @@ -233,7 +233,7 @@ push_dynstack_entry (scm_t_dynstack *dynstack, scm_t_dynstack_item_type type, scm_t_bits flags, size_t len) { - if (SCM_UNLIKELY (!SCM_DYNSTACK_HAS_SPACE (dynstack, len))) + if (SCM_UNLIKELY (!scm_dynstack_has_space (dynstack, len))) dynstack_ensure_space (dynstack, len); return push_dynstack_entry_unchecked (dynstack, type, flags, len); } @@ -328,17 +328,17 @@ scm_dynstack_push_dynwind (scm_t_dynstack *dynstack, SCM enter, SCM leave) static inline scm_t_bits dynstack_pop (scm_t_dynstack *dynstack, scm_t_bits **words) { - scm_t_bits *prev = SCM_DYNSTACK_PREV (dynstack->top); + scm_t_bits *prev = scm_dynstack_prev (dynstack->top); scm_t_bits tag; if (SCM_UNLIKELY (!prev)) abort (); - SCM_DYNSTACK_SET_PREV_OFFSET (dynstack->top, 0); + scm_dynstack_set_prev_offset (dynstack->top, 0); dynstack->top = prev; - tag = SCM_DYNSTACK_TAG (dynstack->top); - SCM_DYNSTACK_SET_TAG (dynstack->top, 0); + tag = scm_dynstack_tag (dynstack->top); + scm_dynstack_set_tag (dynstack->top, 0); *words = dynstack->top; return tag; @@ -365,13 +365,13 @@ scm_dynstack_pop (scm_t_dynstack *dynstack) { scm_t_bits tag, *words; tag = dynstack_pop (dynstack, &words); - clear_scm_t_bits (words, SCM_DYNSTACK_TAG_LEN (tag)); + clear_scm_t_bits (words, scm_dynstack_tag_len (tag)); } scm_t_dynstack * scm_dynstack_capture_all (scm_t_dynstack *dynstack) { - return scm_dynstack_capture (dynstack, SCM_DYNSTACK_FIRST (dynstack)); + return scm_dynstack_capture (dynstack, scm_dynstack_first (dynstack)); } scm_t_dynstack * @@ -380,7 +380,7 @@ scm_dynstack_capture (scm_t_dynstack *dynstack, scm_t_bits *item) scm_t_dynstack *ret; size_t len; - assert (item >= SCM_DYNSTACK_FIRST (dynstack)); + assert (item >= scm_dynstack_first (dynstack)); assert (item <= dynstack->top); len = dynstack->top - item + SCM_DYNSTACK_HEADER_LEN; @@ -392,7 +392,7 @@ scm_dynstack_capture (scm_t_dynstack *dynstack, scm_t_bits *item) ret->top = ret->base + len; copy_scm_t_bits (ret->base, item - SCM_DYNSTACK_HEADER_LEN, len); - SCM_DYNSTACK_SET_PREV_OFFSET (SCM_DYNSTACK_FIRST (ret), 0); + scm_dynstack_set_prev_offset (scm_dynstack_first (ret), 0); return ret; } @@ -403,11 +403,11 @@ scm_dynstack_relocate_prompts (scm_t_dynstack *dynstack, ptrdiff_t base) scm_t_bits *walk; /* Relocate prompts. */ - for (walk = dynstack->top; walk; walk = SCM_DYNSTACK_PREV (walk)) + for (walk = dynstack->top; walk; walk = scm_dynstack_prev (walk)) { - scm_t_bits tag = SCM_DYNSTACK_TAG (walk); + scm_t_bits tag = scm_dynstack_tag (walk); - if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT) + if (scm_dynstack_tag_type (tag) == SCM_DYNSTACK_TYPE_PROMPT) { SET_PROMPT_FP (walk, PROMPT_FP (walk) - base); SET_PROMPT_SP (walk, PROMPT_SP (walk) - base); @@ -418,10 +418,10 @@ scm_dynstack_relocate_prompts (scm_t_dynstack *dynstack, ptrdiff_t base) void scm_dynstack_wind_1 (scm_t_dynstack *dynstack, scm_t_bits *item) { - scm_t_bits tag = SCM_DYNSTACK_TAG (item); - scm_t_dynstack_item_type type = SCM_DYNSTACK_TAG_TYPE (tag); - scm_t_bits flags = SCM_DYNSTACK_TAG_FLAGS (tag); - size_t len = SCM_DYNSTACK_TAG_LEN (tag); + scm_t_bits tag = scm_dynstack_tag (item); + scm_t_dynstack_item_type type = scm_dynstack_tag_type (tag); + scm_t_bits flags = scm_dynstack_tag_flags (tag); + size_t len = scm_dynstack_tag_len (tag); switch (type) { @@ -480,7 +480,7 @@ scm_dynstack_unwind_1 (scm_t_dynstack *dynstack) tag = dynstack_pop (dynstack, &words); - type = SCM_DYNSTACK_TAG_TYPE (tag); + type = scm_dynstack_tag_type (tag); switch (type) { @@ -534,7 +534,7 @@ scm_dynstack_unwind_1 (scm_t_dynstack *dynstack) void scm_dynstack_wind (scm_t_dynstack *dynstack, scm_t_bits *item) { - for (; SCM_DYNSTACK_TAG (item); item = SCM_DYNSTACK_NEXT (item)) + for (; scm_dynstack_tag (item); item = scm_dynstack_next (item)) scm_dynstack_wind_1 (dynstack, item); } @@ -549,14 +549,14 @@ static int same_entries (scm_t_bits *walk_a, scm_t_bits *next_a, scm_t_bits *walk_b, scm_t_bits *next_b) { - if (SCM_DYNSTACK_TAG (walk_a) != SCM_DYNSTACK_TAG (walk_b)) + if (scm_dynstack_tag (walk_a) != scm_dynstack_tag (walk_b)) return 0; if (next_a - walk_a != next_b - walk_b) return 0; - assert (SCM_DYNSTACK_PREV_OFFSET (next_a) == next_a - walk_a); - assert (SCM_DYNSTACK_PREV_OFFSET (next_b) == next_b - walk_b); + assert (scm_dynstack_prev_offset (next_a) == next_a - walk_a); + assert (scm_dynstack_prev_offset (next_b) == next_b - walk_b); while (walk_a != next_a) if (*(walk_a++) != *(walk_b++)) @@ -570,19 +570,19 @@ shared_prefix_length (scm_t_dynstack *a, scm_t_dynstack *b) { scm_t_bits *walk_a, *next_a, *walk_b, *next_b; - walk_a = SCM_DYNSTACK_FIRST (a); - walk_b = SCM_DYNSTACK_FIRST (b); + walk_a = scm_dynstack_first (a); + walk_b = scm_dynstack_first (b); - next_a = SCM_DYNSTACK_NEXT (walk_a); - next_b = SCM_DYNSTACK_NEXT (walk_b); + next_a = scm_dynstack_next (walk_a); + next_b = scm_dynstack_next (walk_b); while (next_a && next_b && same_entries (walk_a, next_a, walk_b, next_b)) { walk_a = next_a; walk_b = next_b; - next_a = SCM_DYNSTACK_NEXT (walk_a); - next_b = SCM_DYNSTACK_NEXT (walk_b); + next_a = scm_dynstack_next (walk_a); + next_b = scm_dynstack_next (walk_b); } return walk_a - a->base; @@ -608,16 +608,16 @@ scm_dynstack_find_prompt (scm_t_dynstack *dynstack, SCM key, { scm_t_bits *walk; - for (walk = SCM_DYNSTACK_PREV (dynstack->top); walk; - walk = SCM_DYNSTACK_PREV (walk)) + for (walk = scm_dynstack_prev (dynstack->top); walk; + walk = scm_dynstack_prev (walk)) { - scm_t_bits tag = SCM_DYNSTACK_TAG (walk); + scm_t_bits tag = scm_dynstack_tag (walk); - if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT + if (scm_dynstack_tag_type (tag) == SCM_DYNSTACK_TYPE_PROMPT && scm_is_eq (PROMPT_KEY (walk), key)) { if (flags) - *flags = SCM_DYNSTACK_TAG_FLAGS (tag); + *flags = scm_dynstack_tag_flags (tag); if (fp_offset) *fp_offset = PROMPT_FP (walk); if (sp_offset) @@ -641,12 +641,12 @@ scm_dynstack_find_old_fluid_value (scm_t_dynstack *dynstack, SCM fluid, { scm_t_bits *walk; - for (walk = SCM_DYNSTACK_PREV (dynstack->top); walk; - walk = SCM_DYNSTACK_PREV (walk)) + for (walk = scm_dynstack_prev (dynstack->top); walk; + walk = scm_dynstack_prev (walk)) { - scm_t_bits tag = SCM_DYNSTACK_TAG (walk); + scm_t_bits tag = scm_dynstack_tag (walk); - switch (SCM_DYNSTACK_TAG_TYPE (tag)) + switch (scm_dynstack_tag_type (tag)) { case SCM_DYNSTACK_TYPE_WITH_FLUID: { @@ -689,13 +689,13 @@ scm_dynstack_wind_prompt (scm_t_dynstack *dynstack, scm_t_bits *item, ptrdiff_t base_fp_offset, jmp_buf *registers) { - scm_t_bits tag = SCM_DYNSTACK_TAG (item); + scm_t_bits tag = scm_dynstack_tag (item); - if (SCM_DYNSTACK_TAG_TYPE (tag) != SCM_DYNSTACK_TYPE_PROMPT) + if (scm_dynstack_tag_type (tag) != SCM_DYNSTACK_TYPE_PROMPT) abort (); scm_dynstack_push_prompt (dynstack, - SCM_DYNSTACK_TAG_FLAGS (tag), + scm_dynstack_tag_flags (tag), PROMPT_KEY (item), PROMPT_FP (item) + base_fp_offset, PROMPT_SP (item) + base_fp_offset, @@ -714,7 +714,7 @@ scm_dynstack_unwind_frame (scm_t_dynstack *dynstack) tag = dynstack_pop (dynstack, &words); - switch (SCM_DYNSTACK_TAG_TYPE (tag)) + switch (scm_dynstack_tag_type (tag)) { case SCM_DYNSTACK_TYPE_FRAME: return; @@ -726,7 +726,7 @@ scm_dynstack_unwind_frame (scm_t_dynstack *dynstack) scm_t_guard proc = WINDER_PROC (words); void *data = WINDER_DATA (words); clear_scm_t_bits (words, WINDER_WORDS); - if (SCM_DYNSTACK_TAG_FLAGS (tag) & SCM_F_DYNSTACK_WINDER_EXPLICIT) + if (scm_dynstack_tag_flags (tag) & SCM_F_DYNSTACK_WINDER_EXPLICIT) proc (data); continue; } @@ -745,9 +745,9 @@ scm_dynstack_unwind_fluid (scm_t_dynstack *dynstack, scm_thread *thread) size_t len; tag = dynstack_pop (dynstack, &words); - len = SCM_DYNSTACK_TAG_LEN (tag); + len = scm_dynstack_tag_len (tag); - assert (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_WITH_FLUID); + assert (scm_dynstack_tag_type (tag) == SCM_DYNSTACK_TYPE_WITH_FLUID); assert (len == WITH_FLUID_WORDS); scm_swap_fluid (thread, WITH_FLUID_FLUID (words), WITH_FLUID_VALUE_BOX (words)); @@ -762,9 +762,9 @@ scm_dynstack_unwind_dynamic_state (scm_t_dynstack *dynstack, size_t len; tag = dynstack_pop (dynstack, &words); - len = SCM_DYNSTACK_TAG_LEN (tag); + len = scm_dynstack_tag_len (tag); - assert (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_DYNAMIC_STATE); + assert (scm_dynstack_tag_type (tag) == SCM_DYNSTACK_TYPE_DYNAMIC_STATE); assert (len == DYNAMIC_STATE_WORDS); scm_variable_set_x (DYNAMIC_STATE_STATE_BOX (words), diff --git a/libguile/dynstack.h b/libguile/dynstack.h index b2fe015d7..ddd36d310 100644 --- a/libguile/dynstack.h +++ b/libguile/dynstack.h @@ -69,18 +69,36 @@ typedef struct scm_dynstack The tag is a combination of the type of the dynstack item, some flags associated with the item, and the length of the item. See - SCM_MAKE_DYNSTACK_TAG below for the details. + scm_make_dynstack_tag below for the details. This arrangement makes it possible to have variable-length dynstack items, and yet be able to traverse them forwards or backwards. */ #define SCM_DYNSTACK_HEADER_LEN 2 -#define SCM_DYNSTACK_PREV_OFFSET(top) ((top)[-2]) -#define SCM_DYNSTACK_SET_PREV_OFFSET(top, offset) (top)[-2] = (offset) +static inline ptrdiff_t +scm_dynstack_prev_offset (scm_t_bits *top) +{ + return top[-2]; +} -#define SCM_DYNSTACK_TAG(top) ((top)[-1]) -#define SCM_DYNSTACK_SET_TAG(top, tag) (top)[-1] = (tag) +static inline void +scm_dynstack_set_prev_offset (scm_t_bits *top, ptrdiff_t offset) +{ + top[-2] = offset; +} + +static inline scm_t_bits +scm_dynstack_tag (scm_t_bits *top) +{ + return top[-1]; +} + +static inline void +scm_dynstack_set_tag (scm_t_bits *top, scm_t_bits tag) +{ + top[-1] = tag; +} typedef enum { SCM_DYNSTACK_TYPE_NONE = 0, @@ -98,37 +116,84 @@ typedef enum { #define SCM_DYNSTACK_TAG_FLAGS_SHIFT 4 #define SCM_DYNSTACK_TAG_LEN_SHIFT 8 -#define SCM_MAKE_DYNSTACK_TAG(type, flags, len) \ - ((type) | (flags) | ((len) << SCM_DYNSTACK_TAG_LEN_SHIFT)) +static inline scm_t_bits +scm_make_dynstack_tag (scm_t_dynstack_item_type type, scm_t_bits flags, + size_t len) +{ + if (type & ~SCM_DYNSTACK_TAG_TYPE_MASK) + abort (); + if (flags & ~SCM_DYNSTACK_TAG_FLAGS_MASK) + abort (); + + scm_t_bits ret = type; + ret |= flags; + ret |= (len << SCM_DYNSTACK_TAG_LEN_SHIFT); + return ret; +} + +static inline scm_t_dynstack_item_type +scm_dynstack_tag_type (scm_t_bits tag) +{ + return tag & SCM_DYNSTACK_TAG_TYPE_MASK; +} -#define SCM_DYNSTACK_TAG_TYPE(tag) \ - ((tag) & SCM_DYNSTACK_TAG_TYPE_MASK) -#define SCM_DYNSTACK_TAG_FLAGS(tag) \ - ((tag) & SCM_DYNSTACK_TAG_FLAGS_MASK) -#define SCM_DYNSTACK_TAG_LEN(tag) \ - ((tag) >> SCM_DYNSTACK_TAG_LEN_SHIFT) +static inline scm_t_bits +scm_dynstack_tag_flags (scm_t_bits tag) +{ + return tag & SCM_DYNSTACK_TAG_FLAGS_MASK; +} -#define SCM_DYNSTACK_PREV(top) \ - (SCM_DYNSTACK_PREV_OFFSET (top) \ - ? ((top) - SCM_DYNSTACK_PREV_OFFSET (top)) : NULL) -#define SCM_DYNSTACK_NEXT(top) \ - (SCM_DYNSTACK_TAG (top) \ - ? ((top) + SCM_DYNSTACK_TAG_LEN (SCM_DYNSTACK_TAG (top)) \ - + SCM_DYNSTACK_HEADER_LEN) \ - : NULL) +static inline size_t +scm_dynstack_tag_len (scm_t_bits tag) +{ + return tag >> SCM_DYNSTACK_TAG_LEN_SHIFT; +} -#define SCM_DYNSTACK_FIRST(dynstack) \ - ((dynstack)->base + SCM_DYNSTACK_HEADER_LEN) +static inline scm_t_bits * +scm_dynstack_prev (scm_t_bits *top) +{ + ptrdiff_t offset = scm_dynstack_prev_offset (top); + return offset ? top - offset : NULL; +} -#define SCM_DYNSTACK_CAPACITY(dynstack) \ - ((dynstack)->limit - (dynstack)->base) -#define SCM_DYNSTACK_SPACE(dynstack) \ - ((dynstack)->limit - (dynstack)->top) -#define SCM_DYNSTACK_HEIGHT(dynstack) \ - ((dynstack)->top - (dynstack)->base) +static inline scm_t_bits * +scm_dynstack_next (scm_t_bits *top) +{ + scm_t_bits tag = scm_dynstack_tag (top); + return tag + ? top + scm_dynstack_tag_len (tag) + SCM_DYNSTACK_HEADER_LEN + : NULL; +} -#define SCM_DYNSTACK_HAS_SPACE(dynstack, n) \ - (SCM_DYNSTACK_SPACE (dynstack) >= n + SCM_DYNSTACK_HEADER_LEN) +static inline scm_t_bits * +scm_dynstack_first (struct scm_dynstack *dynstack) +{ + return dynstack->base + SCM_DYNSTACK_HEADER_LEN; +} + +static inline size_t +scm_dynstack_capacity (struct scm_dynstack *dynstack) +{ + return dynstack->limit - dynstack->base; +} + +static inline size_t +scm_dynstack_space (struct scm_dynstack *dynstack) +{ + return dynstack->limit - dynstack->top; +} + +static inline size_t +scm_dynstack_height (struct scm_dynstack *dynstack) +{ + return dynstack->top - dynstack->base; +} + +static inline int +scm_dynstack_has_space (struct scm_dynstack *dynstack, size_t n) +{ + return scm_dynstack_space (dynstack) >= n + SCM_DYNSTACK_HEADER_LEN; +} typedef enum { SCM_F_DYNSTACK_FRAME_REWINDABLE = (1 << SCM_DYNSTACK_TAG_FLAGS_SHIFT) diff --git a/libguile/vm.c b/libguile/vm.c index 70781c935..6878a5315 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -1192,13 +1192,13 @@ compose_continuation (scm_thread *thread, SCM cont) { scm_t_bits *walk; - for (walk = SCM_DYNSTACK_FIRST (cp->dynstack); - SCM_DYNSTACK_TAG (walk); - walk = SCM_DYNSTACK_NEXT (walk)) + for (walk = scm_dynstack_first (cp->dynstack); + scm_dynstack_tag (walk); + walk = scm_dynstack_next (walk)) { - scm_t_bits tag = SCM_DYNSTACK_TAG (walk); + scm_t_bits tag = scm_dynstack_tag (walk); - if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT) + if (scm_dynstack_tag_type (tag) == SCM_DYNSTACK_TYPE_PROMPT) scm_dynstack_wind_prompt (&thread->dynstack, walk, old_fp_offset, thread->vm.registers); else @@ -1413,7 +1413,7 @@ abort_to_prompt (scm_thread *thread, uint8_t *saved_mra) { scm_t_dynstack *captured; - captured = scm_dynstack_capture (dynstack, SCM_DYNSTACK_NEXT (prompt)); + captured = scm_dynstack_capture (dynstack, scm_dynstack_next (prompt)); cont = capture_delimited_continuation (thread, vp, fp, saved_mra, registers, captured, thread->vm.registers);