Skip to content

Commit

Permalink
Expose functions to enable pushing of custom proc and ranges
Browse files Browse the repository at this point in the history
(cherry-pick of d0a8081 from Unity-Technologies/bdwgc)

The new API functions are: GC_push_proc, GC_custom_push_proc and
GC_custom_push_range.

* include/gc/gc_mark.h (GC_push_proc, GC_custom_push_proc,
GC_custom_push_range): New public function declaration.
* include/private/gc_pmark.h (GC_signal_mark_stack_overflow): Do not
declare.
* include/private/gc_pmark.h (GC_push_obj): Use GC_custom_push_proc().
* typd_mlc.c (GC_typed_mark_proc): Likewise.
* mark.c (GC_signal_mark_stack_overflow): Define as STATIC instead of
GC_INNER.
* mark.c [PARALLEL_MARK] (GC_steal_mark_stack): Store a value to
top->mse_start before to top->mse_descr.w.
* mark.c (GC_push_all): Reformat comment; rename b to bottom and t to
top in comment.
* mark.c (GC_custom_push_range, GC_custom_push_proc, GC_push_proc):
Implement.
* tests/gctest.c [GC_PTHREADS && CPPCHECK] (main): Reference
GC_custom_push_range and GC_push_proc as UNTESTED.

Co-authored-by: Ivan Maidanski <[email protected]>
  • Loading branch information
joncham and ivmai committed Feb 26, 2024
1 parent 5fba9ce commit 7fc3e07
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 24 deletions.
12 changes: 12 additions & 0 deletions include/gc/gc_mark.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ GC_API struct GC_ms_entry * GC_CALL GC_mark_and_push(void * /* obj */,
&& (GC_word)(obj) < (GC_word)GC_greatest_plausible_heap_addr ? \
GC_mark_and_push(obj, msp, lim, src) : (msp))

GC_API void GC_CALL GC_push_proc(GC_word /* descr */, void * /* obj */);

GC_API struct GC_ms_entry * GC_CALL GC_custom_push_proc(GC_word /* descr */,
void * /* obj */,
struct GC_ms_entry * /* mark_stack_top */,
struct GC_ms_entry * /* mark_stack_limit */);

GC_API struct GC_ms_entry * GC_CALL GC_custom_push_range(void * /* bottom */,
void * /* top */,
struct GC_ms_entry * /* mark_stack_top */,
struct GC_ms_entry * /* mark_stack_limit */);

/* The size of the header added to objects allocated through the */
/* GC_debug routines. Defined as a function so that client mark */
/* procedures do not need to be recompiled for the collector library */
Expand Down
10 changes: 2 additions & 8 deletions include/private/gc_pmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,15 @@ GC_EXTERN unsigned GC_n_mark_procs;
*/
#endif /* PARALLEL_MARK */

GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp);

/* Push the object obj with corresponding heap block header hhdr onto */
/* the mark stack. Returns the updated mark_stack_top value. */
GC_INLINE mse * GC_push_obj(ptr_t obj, hdr * hhdr, mse * mark_stack_top,
mse * mark_stack_limit)
{
GC_ASSERT(!HBLK_IS_FREE(hhdr));
if (!IS_PTRFREE(hhdr)) {
mark_stack_top++;
if ((word)mark_stack_top >= (word)mark_stack_limit) {
mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top);
}
mark_stack_top -> mse_start = obj;
mark_stack_top -> mse_descr.w = hhdr -> hb_descr;
mark_stack_top = GC_custom_push_proc(hhdr -> hb_descr, obj,
mark_stack_top, mark_stack_limit);
}
return mark_stack_top;
}
Expand Down
53 changes: 44 additions & 9 deletions mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ GC_INNER void GC_invalidate_mark_state(void)
GC_mark_stack_top = GC_mark_stack-1;
}

GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp)
STATIC mse * GC_signal_mark_stack_overflow(mse *msp)
{
GC_mark_state = MS_INVALID;
# ifdef PARALLEL_MARK
Expand Down Expand Up @@ -986,8 +986,8 @@ STATIC mse * GC_steal_mark_stack(mse * low, mse * high, mse * local,
/* More than one thread may get this entry, but that's only */
/* a minor performance problem. */
++top;
top -> mse_descr.w = descr;
top -> mse_start = p -> mse_start;
top -> mse_descr.w = descr;
GC_ASSERT((descr & GC_DS_TAGS) != GC_DS_LENGTH /* 0 */
|| descr < GC_greatest_real_heap_addr-GC_least_real_heap_addr
|| (word)(p -> mse_start + descr)
Expand Down Expand Up @@ -1313,13 +1313,10 @@ GC_INNER void GC_mark_init(void)
alloc_mark_stack(INITIAL_MARK_STACK_SIZE);
}

/*
* Push all locations between b and t onto the mark stack.
* b is the first location to be checked. t is one past the last
* location to be checked.
* Should only be used if there is no possibility of mark stack
* overflow.
*/
/* Push all locations between bottom and top onto the mark stack. */
/* bottom is the first location to be checked; top is one past the */
/* last location to be checked. Should only be used if there is */
/* no possibility of mark stack overflow. */
GC_API void GC_CALL GC_push_all(void *bottom, void *top)
{
mse * mark_stack_top;
Expand All @@ -1342,6 +1339,44 @@ GC_API void GC_CALL GC_push_all(void *bottom, void *top)
GC_mark_stack_top = mark_stack_top;
}

GC_API struct GC_ms_entry * GC_CALL GC_custom_push_range(void *bottom,
void *top,
struct GC_ms_entry *mark_stack_top,
struct GC_ms_entry *mark_stack_limit)
{
word length;

bottom = PTRT_ROUNDUP_BY_MASK(bottom, ALIGNMENT-1);
top = (void *)((word)top & ~(word)(ALIGNMENT-1));
if ((word)bottom >= (word)top) return mark_stack_top;

length = (word)top - (word)bottom;
# if GC_DS_TAGS > ALIGNMENT - 1
length = (length + GC_DS_TAGS) & ~(word)GC_DS_TAGS; /* round up */
# endif
return GC_custom_push_proc(length | GC_DS_LENGTH, bottom, mark_stack_top,
mark_stack_limit);
}

GC_API struct GC_ms_entry * GC_CALL GC_custom_push_proc(GC_word descr,
void *obj, struct GC_ms_entry *mark_stack_top,
struct GC_ms_entry *mark_stack_limit)
{
mark_stack_top++;
if ((word)mark_stack_top >= (word)mark_stack_limit) {
mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top);
}
mark_stack_top -> mse_start = (ptr_t)obj;
mark_stack_top -> mse_descr.w = descr;
return mark_stack_top;
}

GC_API void GC_CALL GC_push_proc(GC_word descr, void *obj)
{
GC_mark_stack_top = GC_custom_push_proc(descr, obj, GC_mark_stack_top,
GC_mark_stack_limit);
}

#ifndef GC_DISABLE_INCREMENTAL

/* Analogous to the above, but push only those pages h with */
Expand Down
2 changes: 2 additions & 0 deletions tests/gctest.c
Original file line number Diff line number Diff line change
Expand Up @@ -2787,6 +2787,8 @@ int main(void)
# endif
# endif
# if defined(CPPCHECK)
UNTESTED(GC_custom_push_range);
UNTESTED(GC_push_proc);
UNTESTED(GC_register_altstack);
# endif /* CPPCHECK */

Expand Down
11 changes: 4 additions & 7 deletions typd_mlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,10 @@ STATIC mse *GC_CALLBACK GC_typed_mark_proc(word *addr, mse *mark_stack_top,
/* stack. Thus we never do too much work at once. Note that */
/* we also can't overflow the mark stack unless we actually */
/* mark something. */
mark_stack_top++;
if ((word)mark_stack_top >= (word)mark_stack_limit) {
mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top);
}
mark_stack_top -> mse_start = (ptr_t)(addr + CPP_WORDSZ);
mark_stack_top -> mse_descr.w =
GC_MAKE_PROC(GC_typed_mark_proc_index, env + 1);
mark_stack_top = GC_custom_push_proc(
GC_MAKE_PROC(GC_typed_mark_proc_index, env + 1),
&addr[CPP_WORDSZ], mark_stack_top,
mark_stack_limit);
}
return mark_stack_top;
}
Expand Down

0 comments on commit 7fc3e07

Please sign in to comment.