Merge branch 'master' of git://factorcode.org/git/factor
commit
23288da694
1
Makefile
1
Makefile
|
@ -60,6 +60,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
|
||||||
vm/strings.o \
|
vm/strings.o \
|
||||||
vm/tuples.o \
|
vm/tuples.o \
|
||||||
vm/utilities.o \
|
vm/utilities.o \
|
||||||
|
vm/vm.o \
|
||||||
vm/words.o \
|
vm/words.o \
|
||||||
vm/write_barrier.o
|
vm/write_barrier.o
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ M: stack-frame-insn compute-stack-frame*
|
||||||
M: ##call compute-stack-frame*
|
M: ##call compute-stack-frame*
|
||||||
word>> sub-primitive>> [ frame-required? on ] unless ;
|
word>> sub-primitive>> [ frame-required? on ] unless ;
|
||||||
|
|
||||||
M: _gc compute-stack-frame*
|
M: ##gc compute-stack-frame*
|
||||||
frame-required? on
|
frame-required? on
|
||||||
stack-frame new swap tagged-values>> length cells >>gc-root-size
|
stack-frame new swap tagged-values>> length cells >>gc-root-size
|
||||||
request-stack-frame ;
|
request-stack-frame ;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel sequences assocs fry
|
USING: accessors kernel sequences assocs fry
|
||||||
cpu.architecture
|
cpu.architecture layouts
|
||||||
compiler.cfg.rpo
|
compiler.cfg.rpo
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
|
@ -17,11 +17,26 @@ IN: compiler.cfg.gc-checks
|
||||||
: blocks-with-gc ( cfg -- bbs )
|
: blocks-with-gc ( cfg -- bbs )
|
||||||
post-order [ insert-gc-check? ] filter ;
|
post-order [ insert-gc-check? ] filter ;
|
||||||
|
|
||||||
|
GENERIC: allocation-size* ( insn -- n )
|
||||||
|
|
||||||
|
M: ##allot allocation-size* size>> ;
|
||||||
|
|
||||||
|
M: ##box-alien allocation-size* drop 4 cells ;
|
||||||
|
|
||||||
|
M: ##box-displaced-alien allocation-size* drop 4 cells ;
|
||||||
|
|
||||||
|
: allocation-size ( bb -- n )
|
||||||
|
instructions>> [ ##allocation? ] filter [ allocation-size* ] sigma ;
|
||||||
|
|
||||||
: insert-gc-check ( bb -- )
|
: insert-gc-check ( bb -- )
|
||||||
dup '[
|
dup dup '[
|
||||||
int-rep next-vreg-rep
|
int-rep next-vreg-rep
|
||||||
int-rep next-vreg-rep
|
int-rep next-vreg-rep
|
||||||
f f _ uninitialized-locs \ ##gc new-insn
|
_ allocation-size
|
||||||
|
f
|
||||||
|
f
|
||||||
|
_ uninitialized-locs
|
||||||
|
\ ##gc new-insn
|
||||||
prefix
|
prefix
|
||||||
] change-instructions drop ;
|
] change-instructions drop ;
|
||||||
|
|
||||||
|
|
|
@ -672,7 +672,7 @@ use: src1/int-rep src2/int-rep ;
|
||||||
|
|
||||||
INSN: ##gc
|
INSN: ##gc
|
||||||
temp: temp1/int-rep temp2/int-rep
|
temp: temp1/int-rep temp2/int-rep
|
||||||
literal: data-values tagged-values uninitialized-locs ;
|
literal: size data-values tagged-values uninitialized-locs ;
|
||||||
|
|
||||||
INSN: ##save-context
|
INSN: ##save-context
|
||||||
temp: temp1/int-rep temp2/int-rep
|
temp: temp1/int-rep temp2/int-rep
|
||||||
|
@ -740,10 +740,6 @@ use: src1/int-rep src2/int-rep ;
|
||||||
TUPLE: spill-slot { n integer } ;
|
TUPLE: spill-slot { n integer } ;
|
||||||
C: <spill-slot> spill-slot
|
C: <spill-slot> spill-slot
|
||||||
|
|
||||||
INSN: _gc
|
|
||||||
temp: temp1 temp2
|
|
||||||
literal: data-values tagged-values uninitialized-locs ;
|
|
||||||
|
|
||||||
! These instructions operate on machine registers and not
|
! These instructions operate on machine registers and not
|
||||||
! virtual registers
|
! virtual registers
|
||||||
INSN: _spill
|
INSN: _spill
|
||||||
|
|
|
@ -55,6 +55,9 @@ IN: compiler.cfg.intrinsics.allot
|
||||||
] [ node emit-primitive ] if
|
] [ node emit-primitive ] if
|
||||||
] ;
|
] ;
|
||||||
|
|
||||||
|
: expand-(byte-array)? ( obj -- ? )
|
||||||
|
dup integer? [ 0 1024 between? ] [ drop f ] if ;
|
||||||
|
|
||||||
: expand-<byte-array>? ( obj -- ? )
|
: expand-<byte-array>? ( obj -- ? )
|
||||||
dup integer? [ 0 32 between? ] [ drop f ] if ;
|
dup integer? [ 0 32 between? ] [ drop f ] if ;
|
||||||
|
|
||||||
|
@ -69,7 +72,7 @@ IN: compiler.cfg.intrinsics.allot
|
||||||
[ byte-array store-length ] [ ds-push ] [ ] tri ;
|
[ byte-array store-length ] [ ds-push ] [ ] tri ;
|
||||||
|
|
||||||
: emit-(byte-array) ( node -- )
|
: emit-(byte-array) ( node -- )
|
||||||
dup node-input-infos first literal>> dup expand-<byte-array>?
|
dup node-input-infos first literal>> dup expand-(byte-array)?
|
||||||
[ nip emit-allot-byte-array drop ] [ drop emit-primitive ] if ;
|
[ nip emit-allot-byte-array drop ] [ drop emit-primitive ] if ;
|
||||||
|
|
||||||
:: emit-<byte-array> ( node -- )
|
:: emit-<byte-array> ( node -- )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel math assocs namespaces sequences heaps
|
USING: accessors kernel math assocs namespaces sequences heaps
|
||||||
fry make combinators sets locals arrays
|
fry make combinators sets locals arrays
|
||||||
cpu.architecture
|
cpu.architecture layouts
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.def-use
|
compiler.cfg.def-use
|
||||||
compiler.cfg.liveness
|
compiler.cfg.liveness
|
||||||
|
@ -117,8 +117,6 @@ RENAMING: assign [ vreg>reg ] [ vreg>reg ] [ vreg>reg ]
|
||||||
M: vreg-insn assign-registers-in-insn
|
M: vreg-insn assign-registers-in-insn
|
||||||
[ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ;
|
[ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ;
|
||||||
|
|
||||||
! TODO: needs tagged-rep
|
|
||||||
|
|
||||||
: trace-on-gc ( assoc -- assoc' )
|
: trace-on-gc ( assoc -- assoc' )
|
||||||
! When a GC occurs, virtual registers which contain tagged data
|
! When a GC occurs, virtual registers which contain tagged data
|
||||||
! are traced by the GC. Outputs a sequence physical registers.
|
! are traced by the GC. Outputs a sequence physical registers.
|
||||||
|
@ -141,12 +139,16 @@ M: vreg-insn assign-registers-in-insn
|
||||||
] assoc-each
|
] assoc-each
|
||||||
] { } make ;
|
] { } make ;
|
||||||
|
|
||||||
|
: gc-root-offsets ( registers -- alist )
|
||||||
|
! Outputs a sequence of { offset register/spill-slot } pairs
|
||||||
|
[ length iota [ cell * ] map ] keep zip ;
|
||||||
|
|
||||||
M: ##gc assign-registers-in-insn
|
M: ##gc assign-registers-in-insn
|
||||||
! Since ##gc is always the first instruction in a block, the set of
|
! Since ##gc is always the first instruction in a block, the set of
|
||||||
! values live at the ##gc is just live-in.
|
! values live at the ##gc is just live-in.
|
||||||
dup call-next-method
|
dup call-next-method
|
||||||
basic-block get register-live-ins get at
|
basic-block get register-live-ins get at
|
||||||
[ trace-on-gc >>tagged-values ] [ spill-on-gc >>data-values ] bi
|
[ trace-on-gc gc-root-offsets >>tagged-values ] [ spill-on-gc >>data-values ] bi
|
||||||
drop ;
|
drop ;
|
||||||
|
|
||||||
M: insn assign-registers-in-insn drop ;
|
M: insn assign-registers-in-insn drop ;
|
||||||
|
|
|
@ -97,21 +97,6 @@ M: ##dispatch linearize-insn
|
||||||
[ successors>> [ block-number _dispatch-label ] each ]
|
[ successors>> [ block-number _dispatch-label ] each ]
|
||||||
bi* ;
|
bi* ;
|
||||||
|
|
||||||
: gc-root-offsets ( registers -- alist )
|
|
||||||
! Outputs a sequence of { offset register/spill-slot } pairs
|
|
||||||
[ length iota [ cell * ] map ] keep zip ;
|
|
||||||
|
|
||||||
M: ##gc linearize-insn
|
|
||||||
nip
|
|
||||||
{
|
|
||||||
[ temp1>> ]
|
|
||||||
[ temp2>> ]
|
|
||||||
[ data-values>> ]
|
|
||||||
[ tagged-values>> gc-root-offsets ]
|
|
||||||
[ uninitialized-locs>> ]
|
|
||||||
} cleave
|
|
||||||
_gc ;
|
|
||||||
|
|
||||||
: linearize-basic-blocks ( cfg -- insns )
|
: linearize-basic-blocks ( cfg -- insns )
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
|
|
|
@ -9,7 +9,7 @@ IN: compiler.cfg.stacks.uninitialized
|
||||||
|
|
||||||
! Consider the following sequence of instructions:
|
! Consider the following sequence of instructions:
|
||||||
! ##inc-d 2
|
! ##inc-d 2
|
||||||
! _gc
|
! ##gc
|
||||||
! ##replace ... D 0
|
! ##replace ... D 0
|
||||||
! ##replace ... D 1
|
! ##replace ... D 1
|
||||||
! The GC check runs before stack locations 0 and 1 have been initialized,
|
! The GC check runs before stack locations 0 and 1 have been initialized,
|
||||||
|
|
|
@ -271,10 +271,10 @@ M: object load-gc-root drop %load-gc-root ;
|
||||||
|
|
||||||
: load-data-regs ( data-regs -- ) [ first3 %reload ] each ;
|
: load-data-regs ( data-regs -- ) [ first3 %reload ] each ;
|
||||||
|
|
||||||
M: _gc generate-insn
|
M: ##gc generate-insn
|
||||||
"no-gc" define-label
|
"no-gc" define-label
|
||||||
{
|
{
|
||||||
[ [ "no-gc" get ] dip [ temp1>> ] [ temp2>> ] bi %check-nursery ]
|
[ [ "no-gc" get ] dip [ size>> ] [ temp1>> ] [ temp2>> ] tri %check-nursery ]
|
||||||
[ [ uninitialized-locs>> ] [ temp1>> ] bi wipe-locs ]
|
[ [ uninitialized-locs>> ] [ temp1>> ] bi wipe-locs ]
|
||||||
[ data-values>> save-data-regs ]
|
[ data-values>> save-data-regs ]
|
||||||
[ [ tagged-values>> ] [ temp1>> ] bi save-gc-roots ]
|
[ [ tagged-values>> ] [ temp1>> ] bi save-gc-roots ]
|
||||||
|
|
|
@ -317,7 +317,7 @@ HOOK: %allot cpu ( dst size class temp -- )
|
||||||
HOOK: %write-barrier cpu ( src card# table -- )
|
HOOK: %write-barrier cpu ( src card# table -- )
|
||||||
|
|
||||||
! GC checks
|
! GC checks
|
||||||
HOOK: %check-nursery cpu ( label temp1 temp2 -- )
|
HOOK: %check-nursery cpu ( label size temp1 temp2 -- )
|
||||||
HOOK: %save-gc-root cpu ( gc-root register -- )
|
HOOK: %save-gc-root cpu ( gc-root register -- )
|
||||||
HOOK: %load-gc-root cpu ( gc-root register -- )
|
HOOK: %load-gc-root cpu ( gc-root register -- )
|
||||||
HOOK: %call-gc cpu ( gc-root-count temp1 -- )
|
HOOK: %call-gc cpu ( gc-root-count temp1 -- )
|
||||||
|
|
|
@ -446,12 +446,11 @@ M:: ppc %write-barrier ( src card# table -- )
|
||||||
src card# deck-bits SRWI
|
src card# deck-bits SRWI
|
||||||
table scratch-reg card# STBX ;
|
table scratch-reg card# STBX ;
|
||||||
|
|
||||||
M:: ppc %check-nursery ( label temp1 temp2 -- )
|
M:: ppc %check-nursery ( label size temp1 temp2 -- )
|
||||||
temp2 load-zone-ptr
|
temp2 load-zone-ptr
|
||||||
temp1 temp2 cell LWZ
|
temp1 temp2 cell LWZ
|
||||||
temp2 temp2 3 cells LWZ
|
temp2 temp2 3 cells LWZ
|
||||||
! add ALLOT_BUFFER_ZONE to here
|
temp1 temp1 size ADDI
|
||||||
temp1 temp1 1024 ADDI
|
|
||||||
! is here >= end?
|
! is here >= end?
|
||||||
temp1 0 temp2 CMP
|
temp1 0 temp2 CMP
|
||||||
label BLE ;
|
label BLE ;
|
||||||
|
|
|
@ -410,10 +410,10 @@ M:: x86 %write-barrier ( src card# table -- )
|
||||||
table table [] MOV
|
table table [] MOV
|
||||||
table card# [+] card-mark <byte> MOV ;
|
table card# [+] card-mark <byte> MOV ;
|
||||||
|
|
||||||
M:: x86 %check-nursery ( label temp1 temp2 -- )
|
M:: x86 %check-nursery ( label size temp1 temp2 -- )
|
||||||
temp1 load-zone-ptr
|
temp1 load-zone-ptr
|
||||||
temp2 temp1 cell [+] MOV
|
temp2 temp1 cell [+] MOV
|
||||||
temp2 1024 ADD
|
temp2 size ADD
|
||||||
temp1 temp1 3 cells [+] MOV
|
temp1 temp1 3 cells [+] MOV
|
||||||
temp2 temp1 CMP
|
temp2 temp1 CMP
|
||||||
label JLE ;
|
label JLE ;
|
||||||
|
|
|
@ -119,8 +119,10 @@ CONSTANT: zero-matrix4
|
||||||
TYPED:: m4^n ( m: matrix4 n: fixnum -- m^n: matrix4 )
|
TYPED:: m4^n ( m: matrix4 n: fixnum -- m^n: matrix4 )
|
||||||
identity-matrix4 n [ m m4. ] times ;
|
identity-matrix4 n [ m m4. ] times ;
|
||||||
|
|
||||||
|
: vmerge-diagonal* ( x y -- h t )
|
||||||
|
[ vmerge-head ] [ swap vmerge-tail ] 2bi ; inline
|
||||||
: vmerge-diagonal ( x -- h t )
|
: vmerge-diagonal ( x -- h t )
|
||||||
0.0 float-4-with [ vmerge-head ] [ swap vmerge-tail ] 2bi ; inline
|
0.0 float-4-with vmerge-diagonal* ; inline
|
||||||
|
|
||||||
TYPED: diagonal-matrix4 ( diagonal: float-4 -- matrix: matrix4 )
|
TYPED: diagonal-matrix4 ( diagonal: float-4 -- matrix: matrix4 )
|
||||||
[ vmerge-diagonal [ vmerge-diagonal ] bi@ ] make-matrix4 ;
|
[ vmerge-diagonal [ vmerge-diagonal ] bi@ ] make-matrix4 ;
|
||||||
|
@ -133,23 +135,22 @@ TYPED: transpose-matrix4 ( matrix: matrix4 -- matrix: matrix4 )
|
||||||
|
|
||||||
: scale-matrix4 ( factors -- matrix )
|
: scale-matrix4 ( factors -- matrix )
|
||||||
[ float-4{ t t t f } ] dip float-4{ 0.0 0.0 0.0 1.0 } v?
|
[ float-4{ t t t f } ] dip float-4{ 0.0 0.0 0.0 1.0 } v?
|
||||||
diagonal-matrix4 ;
|
diagonal-matrix4 ; inline
|
||||||
|
|
||||||
: ortho-matrix4 ( factors -- matrix )
|
: ortho-matrix4 ( factors -- matrix )
|
||||||
float-4{ 1.0 1.0 1.0 1.0 } swap v/ scale-matrix4 ; inline
|
float-4{ 1.0 1.0 1.0 1.0 } swap v/ scale-matrix4 ; inline
|
||||||
|
|
||||||
TYPED:: translation-matrix4 ( offset: float-4 -- matrix: matrix4 )
|
TYPED:: translation-matrix4 ( offset: float-4 -- matrix: matrix4 )
|
||||||
matrix4 (struct) :> c
|
[
|
||||||
|
float-4{ 1.0 1.0 1.0 1.0 } :> diagonal
|
||||||
|
|
||||||
float-4{ 0.0 0.0 0.0 1.0 } :> c4
|
offset 0 float-4-with vmerge
|
||||||
float-4{ t t t f } offset c4 v? :> offset'
|
[ 0 float-4-with swap vmerge ] bi@ drop :> z :> y :> x
|
||||||
|
|
||||||
offset' { 3 3 3 0 } vshuffle float-4{ t f f t } vbitand
|
diagonal y vmerge-diagonal*
|
||||||
offset' { 3 3 3 1 } vshuffle float-4{ f t f t } vbitand
|
[ x vmerge-diagonal* ]
|
||||||
offset' { 3 3 3 2 } vshuffle float-4{ f f t t } vbitand
|
[ z vmerge-diagonal* ] bi*
|
||||||
c4
|
] make-matrix4 ;
|
||||||
|
|
||||||
c set-rows ;
|
|
||||||
|
|
||||||
TYPED:: rotation-matrix4 ( axis: float-4 theta: float -- matrix: matrix4 )
|
TYPED:: rotation-matrix4 ( axis: float-4 theta: float -- matrix: matrix4 )
|
||||||
! x*x + c*(1.0 - x*x) x*y*(1.0 - c) - s*z x*z*(1.0 - c) + s*y 0
|
! x*x + c*(1.0 - x*x) x*y*(1.0 - c) - s*z x*z*(1.0 - c) + s*y 0
|
||||||
|
@ -188,16 +189,13 @@ TYPED:: rotation-matrix4 ( axis: float-4 theta: float -- matrix: matrix4 )
|
||||||
diagonal-m triangle-m m4+ ;
|
diagonal-m triangle-m m4+ ;
|
||||||
|
|
||||||
TYPED:: frustum-matrix4 ( xy: float-4 near: float far: float -- matrix: matrix4 )
|
TYPED:: frustum-matrix4 ( xy: float-4 near: float far: float -- matrix: matrix4 )
|
||||||
matrix4 (struct) :> c
|
[
|
||||||
|
near near near far + 2 near far * * float-4-boa ! num
|
||||||
|
float-4{ t t f f } xy near far - float-4-with v? ! denom
|
||||||
|
v/ :> fov
|
||||||
|
|
||||||
near near near far + 2 near far * * float-4-boa :> num
|
fov 0.0 float-4-with vmerge-head vmerge-diagonal
|
||||||
float-4{ t t f f } xy near far - float-4-with v? :> denom
|
fov float-4{ f f t t } vand
|
||||||
num denom v/ :> fov
|
|
||||||
|
|
||||||
fov { 0 0 0 0 } vshuffle float-4{ t f f f } vbitand
|
|
||||||
fov { 1 1 1 1 } vshuffle float-4{ f t f f } vbitand
|
|
||||||
fov { 2 2 2 3 } vshuffle float-4{ f f t t } vbitand
|
|
||||||
float-4{ 0.0 0.0 -1.0 0.0 }
|
float-4{ 0.0 0.0 -1.0 0.0 }
|
||||||
|
] make-matrix4 ;
|
||||||
c set-rows ;
|
|
||||||
|
|
||||||
|
|
|
@ -12,18 +12,16 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
|
||||||
data(data_),
|
data(data_),
|
||||||
growing_data_heap(growing_data_heap_),
|
growing_data_heap(growing_data_heap_),
|
||||||
collecting_gen(collecting_gen_),
|
collecting_gen(collecting_gen_),
|
||||||
|
collecting_aging_again(false),
|
||||||
start_time(current_micros()) { }
|
start_time(current_micros()) { }
|
||||||
|
|
||||||
gc_state::~gc_state() { }
|
gc_state::~gc_state() { }
|
||||||
|
|
||||||
/* If a generation fills up, throw this error. It is caught in garbage_collection() */
|
|
||||||
struct generation_full_condition { };
|
|
||||||
|
|
||||||
/* Given a pointer to oldspace, copy it to newspace */
|
/* Given a pointer to oldspace, copy it to newspace */
|
||||||
object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
|
object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
|
||||||
{
|
{
|
||||||
if(current_gc->newspace->here + size >= current_gc->newspace->end)
|
if(current_gc->newspace->here + size >= current_gc->newspace->end)
|
||||||
throw generation_full_condition();
|
longjmp(current_gc->gc_unwind,1);
|
||||||
|
|
||||||
object *newpointer = allot_zone(current_gc->newspace,size);
|
object *newpointer = allot_zone(current_gc->newspace,size);
|
||||||
|
|
||||||
|
@ -502,7 +500,6 @@ void factor_vm::begin_gc(cell requested_bytes)
|
||||||
|
|
||||||
void factor_vm::end_gc()
|
void factor_vm::end_gc()
|
||||||
{
|
{
|
||||||
|
|
||||||
gc_stats *s = &stats[current_gc->collecting_gen];
|
gc_stats *s = &stats[current_gc->collecting_gen];
|
||||||
|
|
||||||
cell gc_elapsed = (current_micros() - current_gc->start_time);
|
cell gc_elapsed = (current_micros() - current_gc->start_time);
|
||||||
|
@ -545,10 +542,34 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
|
||||||
|
|
||||||
/* Keep trying to GC higher and higher generations until we don't run out
|
/* Keep trying to GC higher and higher generations until we don't run out
|
||||||
of space */
|
of space */
|
||||||
for(;;)
|
if(setjmp(current_gc->gc_unwind))
|
||||||
{
|
{
|
||||||
try
|
/* We come back here if a generation is full */
|
||||||
|
|
||||||
|
/* We have no older generations we can try collecting, so we
|
||||||
|
resort to growing the data heap */
|
||||||
|
if(current_gc->collecting_tenured_p())
|
||||||
{
|
{
|
||||||
|
current_gc->growing_data_heap = true;
|
||||||
|
|
||||||
|
/* see the comment in unmark_marked() */
|
||||||
|
code->unmark_marked();
|
||||||
|
}
|
||||||
|
/* we try collecting aging space twice before going on to
|
||||||
|
collect tenured */
|
||||||
|
else if(data->have_aging_p()
|
||||||
|
&& current_gc->collecting_gen == data->aging()
|
||||||
|
&& !current_gc->collecting_aging_again)
|
||||||
|
{
|
||||||
|
current_gc->collecting_aging_again = true;
|
||||||
|
}
|
||||||
|
/* Collect the next oldest generation */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current_gc->collecting_gen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
begin_gc(requested_bytes);
|
begin_gc(requested_bytes);
|
||||||
|
|
||||||
/* Initialize chase pointer */
|
/* Initialize chase pointer */
|
||||||
|
@ -585,37 +606,6 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
|
||||||
update_dirty_code_blocks();
|
update_dirty_code_blocks();
|
||||||
|
|
||||||
/* GC completed without any generations filling up; finish up */
|
/* GC completed without any generations filling up; finish up */
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch(const generation_full_condition &c)
|
|
||||||
{
|
|
||||||
/* We come back here if a generation is full */
|
|
||||||
|
|
||||||
/* We have no older generations we can try collecting, so we
|
|
||||||
resort to growing the data heap */
|
|
||||||
if(current_gc->collecting_tenured_p())
|
|
||||||
{
|
|
||||||
current_gc->growing_data_heap = true;
|
|
||||||
|
|
||||||
/* see the comment in unmark_marked() */
|
|
||||||
code->unmark_marked();
|
|
||||||
}
|
|
||||||
/* we try collecting aging space twice before going on to
|
|
||||||
collect tenured */
|
|
||||||
else if(data->have_aging_p()
|
|
||||||
&& current_gc->collecting_gen == data->aging()
|
|
||||||
&& !current_gc->collecting_aging_again)
|
|
||||||
{
|
|
||||||
current_gc->collecting_aging_again = true;
|
|
||||||
}
|
|
||||||
/* Collect the next oldest generation */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current_gc->collecting_gen++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end_gc();
|
end_gc();
|
||||||
|
|
||||||
delete current_gc;
|
delete current_gc;
|
||||||
|
@ -748,10 +738,10 @@ object *factor_vm::allot_object(header header, cell size)
|
||||||
|
|
||||||
object *obj;
|
object *obj;
|
||||||
|
|
||||||
if(nursery.size - allot_buffer_zone > size)
|
if(nursery.size > size)
|
||||||
{
|
{
|
||||||
/* If there is insufficient room, collect the nursery */
|
/* If there is insufficient room, collect the nursery */
|
||||||
if(nursery.here + allot_buffer_zone + size > nursery.end)
|
if(nursery.here + size > nursery.end)
|
||||||
garbage_collection(data->nursery(),false,true,0);
|
garbage_collection(data->nursery(),false,true,0);
|
||||||
|
|
||||||
cell h = nursery.here;
|
cell h = nursery.here;
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct gc_state {
|
||||||
/* GC start time, for benchmarking */
|
/* GC start time, for benchmarking */
|
||||||
u64 start_time;
|
u64 start_time;
|
||||||
|
|
||||||
|
jmp_buf gc_unwind;
|
||||||
|
|
||||||
explicit gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_);
|
explicit gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_);
|
||||||
~gc_state();
|
~gc_state();
|
||||||
|
|
||||||
|
@ -56,11 +58,6 @@ struct gc_state {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* We leave this many bytes free at the top of the nursery so that inline
|
|
||||||
allocation (which does not call GC because of possible roots in volatile
|
|
||||||
registers) does not run out of memory */
|
|
||||||
static const cell allot_buffer_zone = 1024;
|
|
||||||
|
|
||||||
VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm);
|
VM_C_API void inline_gc(cell *gc_roots_base, cell gc_roots_size, factor_vm *myvm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ struct startargs {
|
||||||
|
|
||||||
factor_vm *new_factor_vm()
|
factor_vm *new_factor_vm()
|
||||||
{
|
{
|
||||||
factor_vm *newvm = new factor_vm;
|
factor_vm *newvm = new factor_vm();
|
||||||
register_vm_with_thread(newvm);
|
register_vm_with_thread(newvm);
|
||||||
thread_vms[thread_id()] = newvm;
|
thread_vms[thread_id()] = newvm;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace factor
|
||||||
template<typename Array> cell array_capacity(Array *array)
|
template<typename Array> cell array_capacity(Array *array)
|
||||||
{
|
{
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
assert(array->h.hi_tag() == T::type_number);
|
assert(array->h.hi_tag() == Array::type_number);
|
||||||
#endif
|
#endif
|
||||||
return array->capacity >> TAG_BITS;
|
return array->capacity >> TAG_BITS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe)
|
||||||
else
|
else
|
||||||
signal_callstack_top = NULL;
|
signal_callstack_top = NULL;
|
||||||
|
|
||||||
switch (e->ExceptionCode) {
|
switch (e->ExceptionCode)
|
||||||
|
{
|
||||||
case EXCEPTION_ACCESS_VIOLATION:
|
case EXCEPTION_ACCESS_VIOLATION:
|
||||||
signal_fault_addr = e->ExceptionInformation[1];
|
signal_fault_addr = e->ExceptionInformation[1];
|
||||||
c->EIP = (cell)factor::memory_signal_handler_impl;
|
c->EIP = (cell)factor::memory_signal_handler_impl;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "master.hpp"
|
||||||
|
|
||||||
|
namespace factor
|
||||||
|
{
|
||||||
|
|
||||||
|
factor_vm::factor_vm() { }
|
||||||
|
|
||||||
|
}
|
|
@ -535,7 +535,6 @@ struct factor_vm
|
||||||
//code_heap
|
//code_heap
|
||||||
heap *code;
|
heap *code;
|
||||||
unordered_map<heap_block *, char *> forwarding;
|
unordered_map<heap_block *, char *> forwarding;
|
||||||
typedef void (factor_vm::*code_heap_iterator)(code_block *compiled);
|
|
||||||
|
|
||||||
void init_code_heap(cell size);
|
void init_code_heap(cell size);
|
||||||
bool in_code_heap_p(cell ptr);
|
bool in_code_heap_p(cell ptr);
|
||||||
|
@ -743,16 +742,7 @@ struct factor_vm
|
||||||
void call_fault_handler(exception_type_t exception, exception_data_type_t code, MACH_EXC_STATE_TYPE *exc_state, MACH_THREAD_STATE_TYPE *thread_state, MACH_FLOAT_STATE_TYPE *float_state);
|
void call_fault_handler(exception_type_t exception, exception_data_type_t code, MACH_EXC_STATE_TYPE *exc_state, MACH_THREAD_STATE_TYPE *thread_state, MACH_FLOAT_STATE_TYPE *float_state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
factor_vm()
|
factor_vm();
|
||||||
: profiling_p(false),
|
|
||||||
secure_gc(false),
|
|
||||||
gc_off(false),
|
|
||||||
fep_disabled(false),
|
|
||||||
full_output(false),
|
|
||||||
max_pic_size(0)
|
|
||||||
{
|
|
||||||
memset(this,0,sizeof(this)); // just to make sure
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue