generational gc and compiler relocation fixes
parent
41b5a344b8
commit
3b5855a195
|
@ -6,6 +6,10 @@
|
||||||
<magnus--> http://www.caddr.com/macho/archives/sbcl-devel/2005-3/4764.html
|
<magnus--> http://www.caddr.com/macho/archives/sbcl-devel/2005-3/4764.html
|
||||||
<magnus--> http://clozure.com/cgi-bin/viewcvs.cgi/ccl/lisp-kernel/lisp-exceptions.c?rev=1.9&content-type=text/vnd.viewcvs-markup
|
<magnus--> http://clozure.com/cgi-bin/viewcvs.cgi/ccl/lisp-kernel/lisp-exceptions.c?rev=1.9&content-type=text/vnd.viewcvs-markup
|
||||||
|
|
||||||
|
- simplifier:
|
||||||
|
- dead loads not optimized out
|
||||||
|
- kill tag-fixnum/untag-fixnum
|
||||||
|
- \ foo where foo is parsing is not printed readably
|
||||||
- faster layout
|
- faster layout
|
||||||
- tiled window manager
|
- tiled window manager
|
||||||
- c primitive arrays: or just specialized arrays
|
- c primitive arrays: or just specialized arrays
|
||||||
|
@ -17,6 +21,8 @@
|
||||||
- sleep word
|
- sleep word
|
||||||
- update docs
|
- update docs
|
||||||
- redo new compiler backend for PowerPC
|
- redo new compiler backend for PowerPC
|
||||||
|
- type predicates: : foo? type 7 eq? ;
|
||||||
|
- remove 'not' word, and move t?/f? to kernel
|
||||||
|
|
||||||
- plugin: supportsBackspace
|
- plugin: supportsBackspace
|
||||||
- if external factor is down, don't add tons of random shit to the
|
- if external factor is down, don't add tons of random shit to the
|
||||||
|
|
|
@ -13,7 +13,7 @@ kernel lists namespaces prettyprint stdio words ;
|
||||||
|
|
||||||
: compiling ( word -- word parameter )
|
: compiling ( word -- word parameter )
|
||||||
check-architecture
|
check-architecture
|
||||||
"Compiling " write dup . flush
|
"Compiling " write dup word. terpri flush
|
||||||
dup word-def ;
|
dup word-def ;
|
||||||
|
|
||||||
GENERIC: (compile) ( word -- )
|
GENERIC: (compile) ( word -- )
|
||||||
|
@ -43,7 +43,7 @@ M: compound (compile) ( word -- )
|
||||||
"compile" get [ word compile ] when ; parsing
|
"compile" get [ word compile ] when ; parsing
|
||||||
|
|
||||||
: cannot-compile ( word error -- )
|
: cannot-compile ( word error -- )
|
||||||
"Cannot compile " write swap . print-error ;
|
"Cannot compile " write swap word. terpri print-error ;
|
||||||
|
|
||||||
: try-compile ( word -- )
|
: try-compile ( word -- )
|
||||||
[ compile ] [ [ cannot-compile ] when* ] catch ;
|
[ compile ] [ [ cannot-compile ] when* ] catch ;
|
||||||
|
@ -52,7 +52,7 @@ M: compound (compile) ( word -- )
|
||||||
|
|
||||||
: decompile ( word -- )
|
: decompile ( word -- )
|
||||||
dup compiled? [
|
dup compiled? [
|
||||||
"Decompiling " write dup . flush
|
"Decompiling " write dup word. terpri flush
|
||||||
[ word-primitive ] keep set-word-primitive
|
[ word-primitive ] keep set-word-primitive
|
||||||
] [
|
] [
|
||||||
drop
|
drop
|
||||||
|
|
|
@ -5,7 +5,7 @@ USING: alien compiler inference kernel kernel-internals lists
|
||||||
math memory namespaces words ;
|
math memory namespaces words ;
|
||||||
|
|
||||||
\ alien-invoke [
|
\ alien-invoke [
|
||||||
uncons load-library 2dup rel-dlsym-16/16 dlsym compile-call-far
|
uncons load-library 2dup 1 rel-dlsym dlsym compile-call-far
|
||||||
] "generator" set-word-prop
|
] "generator" set-word-prop
|
||||||
|
|
||||||
: stack-size 8 + 16 align ;
|
: stack-size 8 + 16 align ;
|
||||||
|
@ -16,7 +16,7 @@ math memory namespaces words ;
|
||||||
] "generator" set-word-prop
|
] "generator" set-word-prop
|
||||||
|
|
||||||
#unbox [
|
#unbox [
|
||||||
uncons f 2dup rel-dlsym-16/16 dlsym compile-call-far
|
uncons f 2dup 1 rel-dlsym dlsym compile-call-far
|
||||||
3 1 rot stack@ STW
|
3 1 rot stack@ STW
|
||||||
] "generator" set-word-prop
|
] "generator" set-word-prop
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ math memory namespaces words ;
|
||||||
] "generator" set-word-prop
|
] "generator" set-word-prop
|
||||||
|
|
||||||
#box [
|
#box [
|
||||||
f 2dup rel-dlsym-16/16 dlsym compile-call-far
|
f 2dup 1 rel-dlsym dlsym compile-call-far
|
||||||
] "generator" set-word-prop
|
] "generator" set-word-prop
|
||||||
|
|
||||||
#cleanup [
|
#cleanup [
|
||||||
|
|
|
@ -46,14 +46,14 @@ words ;
|
||||||
|
|
||||||
: compile-call-label ( label -- )
|
: compile-call-label ( label -- )
|
||||||
dup primitive? [
|
dup primitive? [
|
||||||
dup rel-primitive-16/16 word-xt compile-call-far
|
dup 1 rel-primitive word-xt compile-call-far
|
||||||
] [
|
] [
|
||||||
0 BL relative-24
|
0 BL relative-24
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
#call-label [
|
#call-label [
|
||||||
! Hack: length of instruction sequence that follows
|
! Hack: length of instruction sequence that follows
|
||||||
rel-address-16/16 compiled-offset 20 + 18 LOAD32
|
0 1 rel-address compiled-offset 20 + 18 LOAD32
|
||||||
1 1 -16 STWU
|
1 1 -16 STWU
|
||||||
18 1 20 STW
|
18 1 20 STW
|
||||||
0 B relative-24
|
0 B relative-24
|
||||||
|
@ -66,7 +66,7 @@ words ;
|
||||||
|
|
||||||
: compile-jump-label ( label -- )
|
: compile-jump-label ( label -- )
|
||||||
dup primitive? [
|
dup primitive? [
|
||||||
dup rel-primitive-16/16 word-xt compile-jump-far
|
dup 1 rel-primitive word-xt compile-jump-far
|
||||||
] [
|
] [
|
||||||
0 B relative-24
|
0 B relative-24
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
@ -94,7 +94,7 @@ words ;
|
||||||
18 18 1 SRAWI
|
18 18 1 SRAWI
|
||||||
! The value 24 is a magic number. It is the length of the
|
! The value 24 is a magic number. It is the length of the
|
||||||
! instruction sequence that follows to be generated.
|
! instruction sequence that follows to be generated.
|
||||||
rel-address-16/16 compiled-offset 24 + 19 LOAD32
|
0 1 rel-address compiled-offset 24 + 19 LOAD32
|
||||||
18 18 19 ADD
|
18 18 19 ADD
|
||||||
18 18 0 LWZ
|
18 18 0 LWZ
|
||||||
18 MTLR
|
18 MTLR
|
||||||
|
|
|
@ -11,34 +11,20 @@ SYMBOL: relocation-table
|
||||||
|
|
||||||
: relocating compiled-offset cell - rel, ;
|
: relocating compiled-offset cell - rel, ;
|
||||||
|
|
||||||
: rel-primitive ( word rel/abs -- )
|
: rel-type, ( rel/abs 16/16 type -- )
|
||||||
#! If flag is true; relative.
|
swap 8 shift bitor swap 16 shift bitor rel, ;
|
||||||
0 1 ? rel, relocating word-primitive rel, ;
|
|
||||||
|
|
||||||
: rel-dlsym ( name dll rel/abs -- )
|
: rel-primitive ( word relative 16/16 -- )
|
||||||
#! If flag is true; relative.
|
0 rel-type, relocating word-primitive rel, ;
|
||||||
2 3 ? rel, relocating cons intern-literal rel, ;
|
|
||||||
|
|
||||||
: rel-address ( rel/abs -- )
|
: rel-dlsym ( name dll rel/abs 16/16 -- )
|
||||||
|
1 rel-type, relocating cons intern-literal rel, ;
|
||||||
|
|
||||||
|
: rel-address ( rel/abs 16/16 -- )
|
||||||
#! Relocate address just compiled. If flag is true,
|
#! Relocate address just compiled. If flag is true,
|
||||||
#! relative, and there is nothing to do.
|
#! relative, and there is nothing to do.
|
||||||
[ 4 rel, relocating 0 rel, ] unless ;
|
over [ 2drop ] [ 2 rel-type, relocating 0 rel, ] ifte ;
|
||||||
|
|
||||||
: rel-word ( word rel/abs -- )
|
: rel-word ( word rel/abs 16/16 -- )
|
||||||
#! If flag is true; relative.
|
#! If flag is true; relative.
|
||||||
over primitive? [ rel-primitive ] [ nip rel-address ] ifte ;
|
over primitive? [ rel-primitive ] [ nip rel-address ] ifte ;
|
||||||
|
|
||||||
! PowerPC relocations
|
|
||||||
|
|
||||||
: rel-primitive-16/16 ( word -- )
|
|
||||||
#! This is called before a sequence like
|
|
||||||
#! 19 LOAD32
|
|
||||||
#! 19 MTCTR
|
|
||||||
#! BCTR
|
|
||||||
5 rel, compiled-offset rel, word-primitive rel, ;
|
|
||||||
|
|
||||||
: rel-dlsym-16/16 ( name dll -- )
|
|
||||||
6 rel, compiled-offset rel, cons intern-literal rel, ;
|
|
||||||
|
|
||||||
: rel-address-16/16 ( -- )
|
|
||||||
7 rel, compiled-offset rel, 0 rel, ;
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ M: vreg v>operand vreg-n { EAX ECX EDX } nth ;
|
||||||
M: %prologue generate-node drop ;
|
M: %prologue generate-node drop ;
|
||||||
|
|
||||||
: compile-c-call ( symbol dll -- )
|
: compile-c-call ( symbol dll -- )
|
||||||
2dup dlsym CALL t rel-dlsym ;
|
2dup dlsym CALL 1 0 rel-dlsym ;
|
||||||
|
|
||||||
M: %call generate-node ( vop -- )
|
M: %call generate-node ( vop -- )
|
||||||
vop-label dup postpone-word CALL ;
|
vop-label dup postpone-word CALL ;
|
||||||
|
@ -58,7 +58,7 @@ M: %dispatch generate-node ( vop -- )
|
||||||
! Multiply by 4 to get a jump table offset
|
! Multiply by 4 to get a jump table offset
|
||||||
dup 2 SHL
|
dup 2 SHL
|
||||||
! Add to jump table base
|
! Add to jump table base
|
||||||
dup HEX: ffff ADD just-compiled >r f rel-address
|
dup HEX: ffff ADD just-compiled >r 0 0 rel-address
|
||||||
! Jump to jump table entry
|
! Jump to jump table entry
|
||||||
unit JMP
|
unit JMP
|
||||||
! Align for better performance
|
! Align for better performance
|
||||||
|
|
|
@ -7,7 +7,7 @@ memory sequences words ;
|
||||||
: rel-cs ( -- )
|
: rel-cs ( -- )
|
||||||
#! Add an entry to the relocation table for the 32-bit
|
#! Add an entry to the relocation table for the 32-bit
|
||||||
#! immediate just compiled.
|
#! immediate just compiled.
|
||||||
"cs" f f rel-dlsym ;
|
"cs" f 0 0 rel-dlsym ;
|
||||||
|
|
||||||
: CS ( -- [ address ] ) "cs" f dlsym unit ;
|
: CS ( -- [ address ] ) "cs" f dlsym unit ;
|
||||||
: CS> ( register -- ) CS MOV rel-cs ;
|
: CS> ( register -- ) CS MOV rel-cs ;
|
||||||
|
@ -34,7 +34,7 @@ M: %immediate-d generate-node ( vop -- )
|
||||||
vop-literal [ ESI ] swap address MOV ;
|
vop-literal [ ESI ] swap address MOV ;
|
||||||
|
|
||||||
: load-indirect ( dest literal -- )
|
: load-indirect ( dest literal -- )
|
||||||
intern-literal unit MOV f rel-address ;
|
intern-literal unit MOV 0 0 rel-address ;
|
||||||
|
|
||||||
M: %indirect generate-node ( vop -- )
|
M: %indirect generate-node ( vop -- )
|
||||||
#! indirect load of a literal through a table
|
#! indirect load of a literal through a table
|
||||||
|
|
|
@ -49,7 +49,7 @@ TUPLE: relative word where to ;
|
||||||
: just-compiled compiled-offset 4 - ;
|
: just-compiled compiled-offset 4 - ;
|
||||||
|
|
||||||
C: relative ( word -- )
|
C: relative ( word -- )
|
||||||
over t rel-word
|
over 1 0 rel-word
|
||||||
[ set-relative-word ] keep
|
[ set-relative-word ] keep
|
||||||
[ just-compiled swap set-relative-where ] keep
|
[ just-compiled swap set-relative-where ] keep
|
||||||
[ compiled-offset swap set-relative-to ] keep ;
|
[ compiled-offset swap set-relative-to ] keep ;
|
||||||
|
@ -71,7 +71,7 @@ C: absolute ( word -- )
|
||||||
[ just-compiled swap set-absolute-where ] keep ;
|
[ just-compiled swap set-absolute-where ] keep ;
|
||||||
|
|
||||||
: absolute ( word -- )
|
: absolute ( word -- )
|
||||||
dup f rel-word <absolute> deferred-xt ;
|
dup 0 0 rel-word <absolute> deferred-xt ;
|
||||||
|
|
||||||
: >absolute dup absolute-word compiled-xt swap absolute-where ;
|
: >absolute dup absolute-word compiled-xt swap absolute-where ;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ hashtables errors sequences vectors ;
|
||||||
#! Internal allocation function. Do not call it directly,
|
#! Internal allocation function. Do not call it directly,
|
||||||
#! since you can fool the runtime and corrupt memory by
|
#! since you can fool the runtime and corrupt memory by
|
||||||
#! specifying an incorrect size.
|
#! specifying an incorrect size.
|
||||||
<tuple> [ 0 swap set-array-nth ] keep ;
|
<tuple> [ 2 set-slot ] keep ;
|
||||||
|
|
||||||
: class-tuple 2 slot ; inline
|
: class-tuple 2 slot ; inline
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,10 @@ USE: kernel
|
||||||
USE: math
|
USE: math
|
||||||
USE: test
|
USE: test
|
||||||
USE: math-internals
|
USE: math-internals
|
||||||
|
USE: namespaces
|
||||||
|
|
||||||
|
! Four fibonacci implementations, each one slower than the
|
||||||
|
! previous.
|
||||||
|
|
||||||
: fixnum-fib ( n -- nth fibonacci number )
|
: fixnum-fib ( n -- nth fibonacci number )
|
||||||
dup 1 fixnum<= [
|
dup 1 fixnum<= [
|
||||||
|
@ -36,3 +40,18 @@ TUPLE: box i ;
|
||||||
] ifte ; compiled
|
] ifte ; compiled
|
||||||
|
|
||||||
[ << box f 9227465 >> ] [ << box f 34 >> tuple-fib ] unit-test
|
[ << box f 9227465 >> ] [ << box f 34 >> tuple-fib ] unit-test
|
||||||
|
|
||||||
|
SYMBOL: n
|
||||||
|
: namespace-fib ( n -- n )
|
||||||
|
[
|
||||||
|
n set
|
||||||
|
n get 1 <= [
|
||||||
|
1
|
||||||
|
] [
|
||||||
|
n get 1 - namespace-fib
|
||||||
|
n get 2 - namespace-fib
|
||||||
|
+
|
||||||
|
] ifte
|
||||||
|
] with-scope ; compiled
|
||||||
|
|
||||||
|
[ 9227465 ] [ 34 namespace-fib ] unit-test
|
||||||
|
|
|
@ -87,7 +87,7 @@ SYMBOL: failures
|
||||||
"buffer" ,
|
"buffer" ,
|
||||||
] when
|
] when
|
||||||
|
|
||||||
cpu "unknown" = "compile" get and [
|
cpu "unknown" = not "compile" get and [
|
||||||
[
|
[
|
||||||
"io/buffer" "compiler/optimizer"
|
"io/buffer" "compiler/optimizer"
|
||||||
"compiler/simple"
|
"compiler/simple"
|
||||||
|
@ -95,7 +95,7 @@ SYMBOL: failures
|
||||||
"compiler/generic" "compiler/bail-out"
|
"compiler/generic" "compiler/bail-out"
|
||||||
"compiler/linearizer" "compiler/intrinsics"
|
"compiler/linearizer" "compiler/intrinsics"
|
||||||
] %
|
] %
|
||||||
] unless
|
] when
|
||||||
|
|
||||||
[
|
[
|
||||||
"benchmark/empty-loop" "benchmark/fac"
|
"benchmark/empty-loop" "benchmark/fac"
|
||||||
|
|
|
@ -18,6 +18,8 @@ INLINE void collect_card(CARD *ptr, CELL here)
|
||||||
|
|
||||||
while(card_scan < card_end && card_scan < here)
|
while(card_scan < card_end && card_scan < here)
|
||||||
card_scan = collect_next(card_scan);
|
card_scan = collect_next(card_scan);
|
||||||
|
|
||||||
|
cards_scanned++;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void collect_gen_cards(CELL gen)
|
INLINE void collect_gen_cards(CELL gen)
|
||||||
|
@ -48,8 +50,9 @@ void unmark_cards(CELL from, CELL to)
|
||||||
|
|
||||||
void clear_cards(CELL from, CELL to)
|
void clear_cards(CELL from, CELL to)
|
||||||
{
|
{
|
||||||
CARD *ptr = ADDR_TO_CARD(generations[from].base);
|
/* NOTE: reverse order due to heap layout. */
|
||||||
CARD *last_card = ADDR_TO_CARD(generations[to].limit);
|
CARD *last_card = ADDR_TO_CARD(generations[from].limit);
|
||||||
|
CARD *ptr = ADDR_TO_CARD(generations[to].base);
|
||||||
for(; ptr < last_card; ptr++)
|
for(; ptr < last_card; ptr++)
|
||||||
clear_card(ptr);
|
clear_card(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,10 +274,10 @@ void factorbug(void)
|
||||||
else if(strcmp(cmd,"i") == 0)
|
else if(strcmp(cmd,"i") == 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Call frame:\n");
|
fprintf(stderr,"Call frame:\n");
|
||||||
dump_cell(callframe);
|
print_obj(callframe);
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
fprintf(stderr,"Executing:\n");
|
fprintf(stderr,"Executing:\n");
|
||||||
dump_cell(executing);
|
print_obj(executing);
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
}
|
}
|
||||||
else if(strcmp(cmd,"e") == 0)
|
else if(strcmp(cmd,"e") == 0)
|
||||||
|
|
67
native/gc.c
67
native/gc.c
|
@ -44,7 +44,7 @@ void init_arena(CELL young_size, CELL aging_size)
|
||||||
for(i = GC_GENERATIONS - 2; i >= 0; i--)
|
for(i = GC_GENERATIONS - 2; i >= 0; i--)
|
||||||
alloter = init_zone(&generations[i],young_size,alloter);
|
alloter = init_zone(&generations[i],young_size,alloter);
|
||||||
|
|
||||||
clear_cards(TENURED,NURSERY);
|
clear_cards(NURSERY,TENURED);
|
||||||
|
|
||||||
if(alloter != heap_start + total_size)
|
if(alloter != heap_start + total_size)
|
||||||
fatal_error("Oops",alloter);
|
fatal_error("Oops",alloter);
|
||||||
|
@ -52,6 +52,8 @@ void init_arena(CELL young_size, CELL aging_size)
|
||||||
allot_profiling = false;
|
allot_profiling = false;
|
||||||
heap_scan = false;
|
heap_scan = false;
|
||||||
gc_time = 0;
|
gc_time = 0;
|
||||||
|
minor_collections = 0;
|
||||||
|
cards_scanned = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_roots(void)
|
void collect_roots(void)
|
||||||
|
@ -78,18 +80,6 @@ void collect_roots(void)
|
||||||
copy_handle(&userenv[i]);
|
copy_handle(&userenv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* follow a chain of forwarding pointers */
|
|
||||||
CELL resolve_forwarding(CELL untagged, CELL tag)
|
|
||||||
{
|
|
||||||
CELL header = get(untagged);
|
|
||||||
/* another forwarding pointer */
|
|
||||||
if(TAG(header) == GC_COLLECTED)
|
|
||||||
return resolve_forwarding(UNTAG(header),tag);
|
|
||||||
/* we've found the destination */
|
|
||||||
else
|
|
||||||
return RETAG(untagged,tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a pointer to oldspace, copy it to newspace. */
|
/* Given a pointer to oldspace, copy it to newspace. */
|
||||||
INLINE void *copy_untagged_object(void *pointer, CELL size)
|
INLINE void *copy_untagged_object(void *pointer, CELL size)
|
||||||
{
|
{
|
||||||
|
@ -103,12 +93,7 @@ INLINE void *copy_untagged_object(void *pointer, CELL size)
|
||||||
|
|
||||||
INLINE CELL copy_object_impl(CELL pointer)
|
INLINE CELL copy_object_impl(CELL pointer)
|
||||||
{
|
{
|
||||||
CELL newpointer;
|
CELL newpointer = (CELL)copy_untagged_object((void*)UNTAG(pointer),
|
||||||
|
|
||||||
if(pointer < collecting_generation)
|
|
||||||
critical_error("asked to copy object outside collected generation",pointer);
|
|
||||||
|
|
||||||
newpointer = (CELL)copy_untagged_object((void*)UNTAG(pointer),
|
|
||||||
object_size(pointer));
|
object_size(pointer));
|
||||||
|
|
||||||
/* install forwarding pointer */
|
/* install forwarding pointer */
|
||||||
|
@ -117,6 +102,23 @@ INLINE CELL copy_object_impl(CELL pointer)
|
||||||
return newpointer;
|
return newpointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* follow a chain of forwarding pointers */
|
||||||
|
CELL resolve_forwarding(CELL untagged, CELL tag)
|
||||||
|
{
|
||||||
|
CELL header = get(untagged);
|
||||||
|
/* another forwarding pointer */
|
||||||
|
if(TAG(header) == GC_COLLECTED)
|
||||||
|
return resolve_forwarding(UNTAG(header),tag);
|
||||||
|
/* we've found the destination */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CELL pointer = RETAG(untagged,tag);
|
||||||
|
if(should_copy(untagged))
|
||||||
|
pointer = RETAG(copy_object_impl(pointer),tag);
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Given a pointer to a tagged pointer to oldspace, copy it to newspace.
|
Given a pointer to a tagged pointer to oldspace, copy it to newspace.
|
||||||
If the object has already been copied, return the forwarding
|
If the object has already been copied, return the forwarding
|
||||||
|
@ -202,7 +204,8 @@ void reset_generations(CELL from, CELL to)
|
||||||
|
|
||||||
void begin_gc(CELL gen)
|
void begin_gc(CELL gen)
|
||||||
{
|
{
|
||||||
collecting_generation = generations[gen].base;
|
collecting_gen = gen;
|
||||||
|
collecting_gen_start = generations[gen].base;
|
||||||
|
|
||||||
if(gen == TENURED)
|
if(gen == TENURED)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +237,12 @@ void end_gc(CELL gen)
|
||||||
unmark_cards(TENURED,TENURED);
|
unmark_cards(TENURED,TENURED);
|
||||||
/* all generations except tenured space are
|
/* all generations except tenured space are
|
||||||
now empty */
|
now empty */
|
||||||
reset_generations(TENURED - 1,NURSERY);
|
reset_generations(NURSERY,TENURED - 1);
|
||||||
|
|
||||||
|
fprintf(stderr,"*** Major GC (%ld minor, %ld cards)\n",
|
||||||
|
minor_collections,cards_scanned);
|
||||||
|
minor_collections = 0;
|
||||||
|
cards_scanned = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -245,7 +253,9 @@ void end_gc(CELL gen)
|
||||||
unmark_cards(gen + 1,gen + 1);
|
unmark_cards(gen + 1,gen + 1);
|
||||||
/* all generations up to and including the one
|
/* all generations up to and including the one
|
||||||
collected are now empty */
|
collected are now empty */
|
||||||
reset_generations(gen,NURSERY);
|
reset_generations(NURSERY,gen);
|
||||||
|
|
||||||
|
minor_collections++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +318,18 @@ are also reachable via the GC roots. */
|
||||||
void maybe_garbage_collection(void)
|
void maybe_garbage_collection(void)
|
||||||
{
|
{
|
||||||
if(nursery.here > nursery.alarm)
|
if(nursery.here > nursery.alarm)
|
||||||
garbage_collection(NURSERY);
|
{
|
||||||
|
CELL gen = NURSERY;
|
||||||
|
while(gen < TENURED)
|
||||||
|
{
|
||||||
|
ZONE *z = &generations[gen + 1];
|
||||||
|
if(z->here < z->alarm)
|
||||||
|
break;
|
||||||
|
gen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
garbage_collection(gen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void primitive_gc_time(void)
|
void primitive_gc_time(void)
|
||||||
|
|
16
native/gc.h
16
native/gc.h
|
@ -37,16 +37,20 @@ CELL init_zone(ZONE *z, CELL size, CELL base);
|
||||||
|
|
||||||
void init_arena(CELL young_size, CELL aging_size);
|
void init_arena(CELL young_size, CELL aging_size);
|
||||||
|
|
||||||
|
/* statistics */
|
||||||
s64 gc_time;
|
s64 gc_time;
|
||||||
|
CELL minor_collections;
|
||||||
|
CELL cards_scanned;
|
||||||
|
|
||||||
/* only meaningful during a GC */
|
/* only meaningful during a GC */
|
||||||
CELL collecting_generation;
|
CELL collecting_gen;
|
||||||
|
CELL collecting_gen_start;
|
||||||
|
|
||||||
/* test if the pointer is in generation being collected, or a younger one.
|
/* test if the pointer is in generation being collected, or a younger one.
|
||||||
init_arena() arranges things so that the older generations are first,
|
init_arena() arranges things so that the older generations are first,
|
||||||
so we have to check that the pointer occurs after the beginning of
|
so we have to check that the pointer occurs after the beginning of
|
||||||
the requested generation. */
|
the requested generation. */
|
||||||
#define COLLECTING_GEN(ptr) (collecting_generation <= ptr)
|
#define COLLECTING_GEN(ptr) (collecting_gen_start <= ptr)
|
||||||
|
|
||||||
/* #define GC_DEBUG */
|
/* #define GC_DEBUG */
|
||||||
|
|
||||||
|
@ -56,6 +60,14 @@ INLINE void gc_debug(char* msg, CELL x) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE bool should_copy(CELL untagged)
|
||||||
|
{
|
||||||
|
if(collecting_gen == TENURED)
|
||||||
|
return !in_zone(newspace,untagged);
|
||||||
|
else
|
||||||
|
return(in_zone(&prior,untagged) || COLLECTING_GEN(untagged));
|
||||||
|
}
|
||||||
|
|
||||||
CELL copy_object(CELL pointer);
|
CELL copy_object(CELL pointer);
|
||||||
#define COPY_OBJECT(lvalue) if(COLLECTING_GEN(lvalue)) lvalue = copy_object(lvalue)
|
#define COPY_OBJECT(lvalue) if(COLLECTING_GEN(lvalue)) lvalue = copy_object(lvalue)
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,6 @@ INLINE CELL relocate_data_next(CELL relocating)
|
||||||
CELL size = CELLS;
|
CELL size = CELLS;
|
||||||
CELL cell = get(relocating);
|
CELL cell = get(relocating);
|
||||||
|
|
||||||
allot_barrier(relocating);
|
|
||||||
|
|
||||||
if(headerp(cell))
|
if(headerp(cell))
|
||||||
{
|
{
|
||||||
size = untagged_object_size(relocating);
|
size = untagged_object_size(relocating);
|
||||||
|
@ -69,6 +67,7 @@ void relocate_data()
|
||||||
if(relocating >= tenured.here)
|
if(relocating >= tenured.here)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
allot_barrier(relocating);
|
||||||
relocating = relocate_data_next(relocating);
|
relocating = relocate_data_next(relocating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ CELL get_rel_symbol(F_REL* rel)
|
||||||
|
|
||||||
INLINE CELL compute_code_rel(F_REL *rel, CELL original)
|
INLINE CELL compute_code_rel(F_REL *rel, CELL original)
|
||||||
{
|
{
|
||||||
switch(rel->type)
|
switch(REL_TYPE(rel))
|
||||||
{
|
{
|
||||||
case F_PRIMITIVE:
|
case F_PRIMITIVE:
|
||||||
return primitive_to_xt(rel->argument);
|
return primitive_to_xt(rel->argument);
|
||||||
|
@ -133,7 +132,7 @@ INLINE CELL relocate_code_next(CELL relocating)
|
||||||
CELL original;
|
CELL original;
|
||||||
CELL new_value;
|
CELL new_value;
|
||||||
|
|
||||||
if(rel->risc16_16)
|
if(REL_16_16(rel))
|
||||||
original = reloc_get_16_16(rel->offset);
|
original = reloc_get_16_16(rel->offset);
|
||||||
else
|
else
|
||||||
original = get(rel->offset);
|
original = get(rel->offset);
|
||||||
|
@ -143,10 +142,10 @@ INLINE CELL relocate_code_next(CELL relocating)
|
||||||
code_fixup(&rel->offset);
|
code_fixup(&rel->offset);
|
||||||
new_value = compute_code_rel(rel,original);
|
new_value = compute_code_rel(rel,original);
|
||||||
|
|
||||||
if(rel->relative)
|
if(REL_RELATIVE(rel))
|
||||||
new_value -= (rel->offset + CELLS);
|
new_value -= (rel->offset + CELLS);
|
||||||
|
|
||||||
if(rel->risc16_16)
|
if(REL_16_16(rel))
|
||||||
reloc_set_16_16(rel->offset,new_value);
|
reloc_set_16_16(rel->offset,new_value);
|
||||||
else
|
else
|
||||||
put(rel->offset,new_value);
|
put(rel->offset,new_value);
|
||||||
|
|
|
@ -21,13 +21,17 @@ typedef enum {
|
||||||
F_CARDS
|
F_CARDS
|
||||||
} F_RELTYPE;
|
} F_RELTYPE;
|
||||||
|
|
||||||
|
/* the rel type is built like a cell to avoid endian-specific code in
|
||||||
|
the compiler */
|
||||||
|
#define REL_TYPE(r) ((r)->type & 0xff)
|
||||||
|
/* on PowerPC, some values are stored in the high 16 bits of a pair
|
||||||
|
of consecutive cells */
|
||||||
|
#define REL_16_16(r) ((r)->type & 0xff00)
|
||||||
|
#define REL_RELATIVE(r) ((r)->type & 0xff0000)
|
||||||
|
|
||||||
/* code relocation consists of a table of entries for each fixup */
|
/* code relocation consists of a table of entries for each fixup */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 type;
|
CELL type;
|
||||||
u8 relative;
|
|
||||||
/* on PowerPC, some values are stored in the high 16 bits of a pair
|
|
||||||
of consecutive cells */
|
|
||||||
u8 risc16_16;
|
|
||||||
CELL offset;
|
CELL offset;
|
||||||
CELL argument;
|
CELL argument;
|
||||||
} F_REL;
|
} F_REL;
|
||||||
|
|
Loading…
Reference in New Issue