diff --git a/gc.c b/gc.c index e492082d..93401c33 100644 --- a/gc.c +++ b/gc.c @@ -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); } diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 8a3a5156..75f25b2d 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -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); diff --git a/libs/cyclone/concurrent.sld b/libs/cyclone/concurrent.sld index 913f8a5c..13837836 100644 --- a/libs/cyclone/concurrent.sld +++ b/libs/cyclone/concurrent.sld @@ -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; diff --git a/runtime.c b/runtime.c index 911ebdff..462309fd 100644 --- a/runtime.c +++ b/runtime.c @@ -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); }