mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-16 01:07:34 +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
|
// * @brief Determine if object lives on the thread's stack
|
||||||
* @param thd Mutator's thread data
|
// * @param thd Mutator's thread data
|
||||||
* @param obj Object to inspect
|
// * @param obj Object to inspect
|
||||||
* @return True if `obj` is on the mutator's stack, false otherwise
|
// * @return True if `obj` is on the mutator's stack, false otherwise
|
||||||
*/
|
// */
|
||||||
int gc_is_stack_obj(gc_thread_data * thd, object obj)
|
// int gc_is_stack_obj(gc_thread_data * thd, object obj)
|
||||||
{
|
// {
|
||||||
char tmp;
|
// char tmp;
|
||||||
object low_limit = &tmp;
|
// object low_limit = &tmp;
|
||||||
object high_limit = thd->stack_start;
|
// object high_limit = thd->stack_start;
|
||||||
return (stack_overflow(low_limit, obj) && stack_overflow(obj, high_limit));
|
// return (stack_overflow(low_limit, obj) && stack_overflow(obj, high_limit));
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper function for `gc_mut_update`
|
* @brief Helper function for `gc_mut_update`
|
||||||
*/
|
*/
|
||||||
static void mark_stack_or_heap_obj(gc_thread_data * thd, object obj, int locked)
|
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) {
|
if (!is_object_type(obj) || type_of(obj) == boolean_tag) {
|
||||||
return;
|
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.
|
// Set object to be marked after moved to heap by next GC.
|
||||||
// This avoids having to recursively examine the stack now,
|
// This avoids having to recursively examine the stack now,
|
||||||
// which we have to do anyway during minor GC.
|
// 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
|
// Check if obj was copied while we slept
|
||||||
if (maybe_copied &&
|
if (maybe_copied &&
|
||||||
is_object_type(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) {
|
type_of(maybe_copied) == forward_tag) {
|
||||||
gc_recopy_obj(maybe_copied, thd);
|
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);
|
long stack_size);
|
||||||
void gc_thread_data_free(gc_thread_data * thd);
|
void gc_thread_data_free(gc_thread_data * thd);
|
||||||
// Prototypes for mutator/collector:
|
// 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_update(gc_thread_data * thd, object old_obj, object value);
|
||||||
void gc_mut_cooperate(gc_thread_data * thd, int buf_len);
|
void gc_mut_cooperate(gc_thread_data * thd, int buf_len);
|
||||||
void gc_mark_gray(gc_thread_data * thd, object obj);
|
void gc_mark_gray(gc_thread_data * thd, object obj);
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
atomic atm;
|
atomic atm;
|
||||||
atomic_type tmp;
|
atomic_type tmp;
|
||||||
Cyc_verify_immutable(data, obj); // TODO: verify obj is not on local stack???
|
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);
|
Cyc_rt_raise2(data, \"Atom cannot contain a thread-local object\", obj);
|
||||||
}
|
}
|
||||||
tmp.hdr.mark = gc_color_red;
|
tmp.hdr.mark = gc_color_red;
|
||||||
|
@ -157,9 +157,10 @@
|
||||||
(define-c compare-and-set!
|
(define-c compare-and-set!
|
||||||
"(void *data, int argc, closure _, object k, object obj, object oldval, object newval)"
|
"(void *data, int argc, closure _, object k, object obj, object oldval, object newval)"
|
||||||
" atomic a;
|
" atomic a;
|
||||||
|
char tmp;
|
||||||
Cyc_check_atomic(data, obj);
|
Cyc_check_atomic(data, obj);
|
||||||
Cyc_verify_immutable(data, newval);
|
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);
|
Cyc_rt_raise2(data, \"Atom cannot contain a thread-local object\", obj);
|
||||||
}
|
}
|
||||||
a = (atomic) 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)
|
void add_mutation(void *data, object var, int index, object value)
|
||||||
{
|
{
|
||||||
gc_thread_data *thd = (gc_thread_data *) data;
|
gc_thread_data *thd = (gc_thread_data *) data;
|
||||||
|
char tmp;
|
||||||
|
|
||||||
// No need to track for minor GC purposes unless we are mutating
|
// No need to track for minor GC purposes unless we are mutating
|
||||||
// a heap variable to point to a stack var.
|
// a heap variable to point to a stack var.
|
||||||
//
|
//
|
||||||
// If var is on stack we'll get it anyway in minor GC,
|
// 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)
|
// 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->mutations = vpbuffer_add(thd->mutations,
|
||||||
&(thd->mutation_buflen),
|
&(thd->mutation_buflen),
|
||||||
thd->mutation_count,
|
thd->mutation_count,
|
||||||
|
@ -5777,7 +5778,7 @@ void Cyc_make_shared_object(void *data, object k, object obj)
|
||||||
object buf[1];
|
object buf[1];
|
||||||
int tmp, *heap_grown = &tmp;
|
int tmp, *heap_grown = &tmp;
|
||||||
if (!is_object_type(obj) || // Immediates do not have to be moved
|
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);
|
return_closcall1(data, k, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue