mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-15 16:57:35 +02:00
Port gc_is_stack_obj to a macro
This avoids function calls and can improve performance in extreme cases.
This commit is contained in:
parent
a18ba5eaf8
commit
f7e6c11108
4 changed files with 32 additions and 20 deletions
31
gc.c
31
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue