Port gc_is_stack_obj to a macro

This avoids function calls and can improve performance in extreme cases.
This commit is contained in:
Justin Ethier 2019-09-26 17:24:27 -04:00
parent a18ba5eaf8
commit f7e6c11108
4 changed files with 32 additions and 20 deletions

31
gc.c
View file

@ -1863,28 +1863,29 @@ void gc_sum_pending_writes(gc_thread_data * thd, int locked)
}
}
/**
* @brief Determine if object lives on the thread's stack
* @param thd Mutator's thread data
* @param obj Object to inspect
* @return True if `obj` is on the mutator's stack, false otherwise
*/
int gc_is_stack_obj(gc_thread_data * thd, object obj)
{
char tmp;
object low_limit = &tmp;
object high_limit = thd->stack_start;
return (stack_overflow(low_limit, obj) && stack_overflow(obj, high_limit));
}
// /**
// * @brief Determine if object lives on the thread's stack
// * @param thd Mutator's thread data
// * @param obj Object to inspect
// * @return True if `obj` is on the mutator's stack, false otherwise
// */
// int gc_is_stack_obj(gc_thread_data * thd, object obj)
// {
// char tmp;
// object low_limit = &tmp;
// object high_limit = thd->stack_start;
// return (stack_overflow(low_limit, obj) && stack_overflow(obj, high_limit));
// }
/**
* @brief Helper function for `gc_mut_update`
*/
static void mark_stack_or_heap_obj(gc_thread_data * thd, object obj, int locked)
{
char tmp;
if (!is_object_type(obj) || type_of(obj) == boolean_tag) {
return;
} else if (gc_is_stack_obj(thd, obj)) {
} else if (gc_is_stack_obj(&tmp, thd, obj)) {
// Set object to be marked after moved to heap by next GC.
// This avoids having to recursively examine the stack now,
// which we have to do anyway during minor GC.
@ -2937,7 +2938,7 @@ void gc_mutator_thread_runnable(gc_thread_data * thd, object result, object mayb
// Check if obj was copied while we slept
if (maybe_copied &&
is_object_type(maybe_copied) &&
gc_is_stack_obj(thd, maybe_copied) &&
gc_is_stack_obj(&stack_limit, thd, maybe_copied) &&
type_of(maybe_copied) == forward_tag) {
gc_recopy_obj(maybe_copied, thd);
}

View file

@ -395,7 +395,16 @@ void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base,
long stack_size);
void gc_thread_data_free(gc_thread_data * thd);
// Prototypes for mutator/collector:
int gc_is_stack_obj(gc_thread_data * thd, object obj);
/**
* @brief Determine if object lives on the thread's stack
* @param low_limit Temporary object at the current "end" of the stack
* @param thd Mutator's thread data
* @param obj Object to inspect
* @return True if `obj` is on the mutator's stack, false otherwise
*/
#define gc_is_stack_obj(low_limit, thd, obj) \
(stack_overflow(((object)low_limit), ((object)obj)) && \
stack_overflow(((object)obj), ((object)((gc_thread_data *)thd)->stack_start)))
void gc_mut_update(gc_thread_data * thd, object old_obj, object value);
void gc_mut_cooperate(gc_thread_data * thd, int buf_len);
void gc_mark_gray(gc_thread_data * thd, object obj);

View file

@ -101,7 +101,7 @@
atomic atm;
atomic_type tmp;
Cyc_verify_immutable(data, obj); // TODO: verify obj is not on local stack???
if (gc_is_stack_obj(data, obj)){
if (gc_is_stack_obj(&tmp, data, obj)){
Cyc_rt_raise2(data, \"Atom cannot contain a thread-local object\", obj);
}
tmp.hdr.mark = gc_color_red;
@ -157,9 +157,10 @@
(define-c compare-and-set!
"(void *data, int argc, closure _, object k, object obj, object oldval, object newval)"
" atomic a;
char tmp;
Cyc_check_atomic(data, obj);
Cyc_verify_immutable(data, newval);
if (gc_is_stack_obj(data, obj)){
if (gc_is_stack_obj(&tmp, data, obj)){
Cyc_rt_raise2(data, \"Atom cannot contain a thread-local object\", obj);
}
a = (atomic) obj;

View file

@ -487,13 +487,14 @@ void Cyc_set_globals_changed(gc_thread_data *thd)
void add_mutation(void *data, object var, int index, object value)
{
gc_thread_data *thd = (gc_thread_data *) data;
char tmp;
// No need to track for minor GC purposes unless we are mutating
// a heap variable to point to a stack var.
//
// If var is on stack we'll get it anyway in minor GC,
// and if value is on heap we don't care (no chance of heap pointing to nursery)
if (!gc_is_stack_obj(data, var) && gc_is_stack_obj(data, value)) {
if (!gc_is_stack_obj(&tmp, data, var) && gc_is_stack_obj(&tmp, data, value)) {
thd->mutations = vpbuffer_add(thd->mutations,
&(thd->mutation_buflen),
thd->mutation_count,
@ -5777,7 +5778,7 @@ void Cyc_make_shared_object(void *data, object k, object obj)
object buf[1];
int tmp, *heap_grown = &tmp;
if (!is_object_type(obj) || // Immediates do not have to be moved
!gc_is_stack_obj(data, obj)) { // Not thread-local, assume already on heap
!gc_is_stack_obj(&tmp, data, obj)) { // Not thread-local, assume already on heap
return_closcall1(data, k, obj);
}