Chez Scheme GC: simplify make parallel sweeper object exchange
Make the exchange of objects by parallel sweepers --- which is needed when an object being swept by one thread refers to an object owner by another thread --- much simpler and slightly faster. The original design of exchanging memory regions didn't really work out, and it had degrenerated to essentially exchanging objects. Explicitly exchanging objects instead of regions makes the GC simpler, because received objects can be just added to the regular sweep stack, and less additional space<->type correspondence is needed.
This commit is contained in:
parent
1a1bad4e90
commit
449f01b55d
|
@ -84,6 +84,10 @@ LZ4Sources=../lz4/lib/lz4.h ../lz4/lib/lz4frame.h \
|
|||
../lz4/lib/lz4.c ../lz4/lib/lz4frame.c \
|
||||
../lz4/lib/lz4hc.c ../lz4/lib/xxhash.c
|
||||
|
||||
.PHONY: run
|
||||
run:
|
||||
env SCHEMEHEAPDIRS=../boot/$m/ ../bin/$m/scheme $(ARGS)
|
||||
|
||||
clean:
|
||||
rm -f *.$o ${mdclean}
|
||||
rm -f Make.out
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -666,13 +666,6 @@ void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
|||
printf("!!! inconsistent thread NEXT %p and BASE %p\n",
|
||||
TO_VOIDP(tgc->next_loc[g][s]), TO_VOIDP(tgc->base_loc[g][s]));
|
||||
}
|
||||
if ((tgc->remote_range_end != (ptr)0)
|
||||
|| (tgc->remote_range_start != (ptr)(uptr)-1)) {
|
||||
S_checkheap_errors += 1;
|
||||
printf("!!! nonempty thread REMOTERANGE %p-%p\n",
|
||||
TO_VOIDP(tgc->remote_range_start),
|
||||
TO_VOIDP(tgc->remote_range_end));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1022,7 +1015,7 @@ void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
|||
|
||||
if (S_checkheap_errors) {
|
||||
printf("heap check failed%s\n", (aftergc ? " after gc" : ""));
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,11 +163,7 @@ ptr S_create_thread_object(who, p_tc) const char *who; ptr p_tc; {
|
|||
|
||||
tgc->during_alloc = 0;
|
||||
tgc->sweeper = main_sweeper_index;
|
||||
tgc->remote_range_start = (ptr)(uptr)-1;
|
||||
tgc->remote_range_end = (ptr)0;
|
||||
tgc->pending_ephemerons = (ptr)0;
|
||||
tgc->ranges_to_send = NULL;
|
||||
tgc->ranges_received = NULL;
|
||||
for (i = 0; i < (int)DIRTY_SEGMENT_LISTS; i++)
|
||||
tgc->dirty_segments[i] = NULL;
|
||||
tgc->thread = (ptr)0;
|
||||
|
|
|
@ -464,14 +464,6 @@ typedef struct {
|
|||
#define AS_IMPLICIT_ATOMIC(T, X) X
|
||||
#endif
|
||||
|
||||
typedef struct remote_range {
|
||||
ISPC s;
|
||||
IGEN g;
|
||||
ptr start, end;
|
||||
struct thread_gc *tgc;
|
||||
struct remote_range *next;
|
||||
} remote_range;
|
||||
|
||||
typedef struct thread_gc {
|
||||
ptr tc;
|
||||
ptr thread; /* set only when collecting */
|
||||
|
@ -497,12 +489,16 @@ typedef struct thread_gc {
|
|||
int sweep_change;
|
||||
|
||||
int sweeper; /* parallel GC: sweeper thread identity */
|
||||
|
||||
struct thread_gc *remote_range_tgc;
|
||||
ptr remote_range_start;
|
||||
ptr remote_range_end;
|
||||
remote_range *ranges_to_send; /* modified only by owning sweeper */
|
||||
remote_range *ranges_received; /* modified with sweeper mutex held */
|
||||
|
||||
/* modified only by owning sweeper; contains ptr and thread_gc* */
|
||||
ptr send_remote_sweep_stack;
|
||||
ptr send_remote_sweep_stack_start;
|
||||
ptr send_remote_sweep_stack_limit;
|
||||
|
||||
/* modified with sweeper mutex held; contains just ptr */
|
||||
ptr receive_remote_sweep_stack;
|
||||
ptr receive_remote_sweep_stack_start;
|
||||
ptr receive_remote_sweep_stack_limit;
|
||||
|
||||
seginfo *dirty_segments[DIRTY_SEGMENT_LISTS];
|
||||
|
||||
|
|
|
@ -444,6 +444,9 @@ prettyclean:
|
|||
clean: prettyclean
|
||||
rm -f Make.out
|
||||
|
||||
.PHONY: run
|
||||
run:
|
||||
env SCHEMEHEAPDIRS=../boot/$m/ ../bin/$m/scheme $(ARGS)
|
||||
|
||||
### rules for generating various experr files
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@
|
|||
;; A stack segment has a single owner, so it's ok for us
|
||||
;; to sweep the stack content, even though it's on a
|
||||
;; remote segment relative to the current sweeper.
|
||||
(RECORD_REMOTE_RANGE _tgc_ _ _size_ s_si)]
|
||||
(RECORD_REMOTE s_si)]
|
||||
[else
|
||||
(set! (continuation-stack _)
|
||||
(copy_stack _tgc_
|
||||
|
@ -794,7 +794,7 @@
|
|||
(SEGMENT_IS_LOCAL v_si val))
|
||||
(trace-symcode symbol-pvalue val)]
|
||||
[else
|
||||
(RECORD_REMOTE_RANGE _tgc_ _ _size_ v_si)])]
|
||||
(RECORD_REMOTE v_si)])]
|
||||
[off (trace-symcode symbol-pvalue val)])]
|
||||
[else
|
||||
(trace-symcode symbol-pvalue val)]))
|
||||
|
@ -869,7 +869,7 @@
|
|||
(trace-record-type-pm num rtd)]
|
||||
[else
|
||||
;; Try again in the bignum's sweeper
|
||||
(RECORD_REMOTE_RANGE _tgc_ _ _size_ pm_si)
|
||||
(RECORD_REMOTE pm_si)
|
||||
(set! num S_G.zero_length_bignum)])]
|
||||
[off
|
||||
(trace-record-type-pm num rtd)])]
|
||||
|
@ -1110,7 +1110,7 @@
|
|||
(trace-pure (* (ENTRYNONCOMPACTLIVEMASKADDR oldret)))
|
||||
(set! num (ENTRYLIVEMASK oldret))]
|
||||
[else
|
||||
(RECORD_REMOTE_RANGE _tgc_ _ _size_ n_si)
|
||||
(RECORD_REMOTE n_si)
|
||||
(set! num S_G.zero_length_bignum)])])
|
||||
(let* ([index : iptr (BIGLEN num)])
|
||||
(while
|
||||
|
@ -1140,7 +1140,7 @@
|
|||
[(sweep sweep-in-old)
|
||||
(define x_si : seginfo* (SegInfo (ptr_get_segment c_p)))
|
||||
(when (-> x_si old_space)
|
||||
(relocate_code c_p x_si _ _size_)
|
||||
(relocate_code c_p x_si)
|
||||
(case-mode
|
||||
[sweep-in-old]
|
||||
[else
|
||||
|
@ -1222,7 +1222,7 @@
|
|||
(find_gc_room _tgc_ space_data from_g typemod n t)
|
||||
(memcpy_aligned (TO_VOIDP t) (TO_VOIDP oldt) n))])]
|
||||
[else
|
||||
(RECORD_REMOTE_RANGE _tgc_ _ _size_ t_si)])))
|
||||
(RECORD_REMOTE t_si)])))
|
||||
(set! (reloc-table-code t) _)
|
||||
(set! (code-reloc _) t)])
|
||||
(S_record_code_mod (-> _tgc_ tc) (cast uptr (TO_PTR (& (code-data _ 0)))) (cast uptr (code-length _)))]
|
||||
|
@ -1526,15 +1526,20 @@
|
|||
"return si->generation;")]
|
||||
[(sweep)
|
||||
(code-block
|
||||
"FLUSH_REMOTE_BLOCK"
|
||||
(and (lookup 'maybe-backreferences? config #f)
|
||||
"PUSH_BACKREFERENCE(p)")
|
||||
(body)
|
||||
(and (lookup 'maybe-backreferences? config #f)
|
||||
"POP_BACKREFERENCE()")
|
||||
"FLUSH_REMOTE(tgc, p);"
|
||||
(and (lookup 'as-dirty? config #f)
|
||||
"return youngest;"))]
|
||||
[(sweep-in-old)
|
||||
(body)]
|
||||
(code-block
|
||||
"FLUSH_REMOTE_BLOCK"
|
||||
(body)
|
||||
"ASSERT_EMPTY_FLUSH_REMOTE();")]
|
||||
[(measure)
|
||||
(body)]
|
||||
[(self-test)
|
||||
|
@ -2215,27 +2220,19 @@
|
|||
|
||||
(define (relocate-statement purity e config)
|
||||
(define mode (lookup 'mode config))
|
||||
(define (get-start) (expression '_ config))
|
||||
(define (get-size) (cond
|
||||
[(lookup 'early-rtd? config #f)
|
||||
(expression '(size_record_inst (UNFIX (record-type-size (record-type _)))) config)]
|
||||
[(lookup 'early-code? config #f)
|
||||
(expression '(size_closure (CODEFREE (CLOSCODE _))) config)]
|
||||
[else
|
||||
(expression '_size_ config)]))
|
||||
(case mode
|
||||
[(vfasl-sweep)
|
||||
(format "vfasl_relocate(vfi, &~a);" e)]
|
||||
[(sweep-in-old)
|
||||
(if (eq? purity 'pure)
|
||||
(format "relocate_pure(&~a, ~a, ~a);" e (get-start) (get-size))
|
||||
(format "relocate_indirect(~a, ~a, ~a);" e (get-start) (get-size)))]
|
||||
(format "relocate_pure(&~a);" e)
|
||||
(format "relocate_indirect(~a);" e))]
|
||||
[else
|
||||
(if (lookup 'as-dirty? config #f)
|
||||
(begin
|
||||
(when (eq? purity 'pure) (error 'relocate-statement "pure as dirty?"))
|
||||
(format "relocate_dirty(&~a, youngest, ~a, ~a);" e (get-start) (get-size)))
|
||||
(format "relocate_~a(&~a~a, ~a, ~a);" purity e (if (eq? purity 'impure) ", from_g" "") (get-start) (get-size)))]))
|
||||
(format "relocate_dirty(&~a, youngest);" e))
|
||||
(format "relocate_~a(&~a~a);" purity e (if (eq? purity 'impure) ", from_g" "")))]))
|
||||
|
||||
(define (measure-statement e)
|
||||
(code
|
||||
|
|
Loading…
Reference in New Issue
Block a user