From b4e36608da2f842c9910b018d5a86033dbe9e93d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 5 Oct 2009 05:27:49 -0500 Subject: [PATCH] compiler.cfg: remove _gc instruction, it doesn't need to exist, and change GC checks to ensure that the right amount of space is available instead of blindly checking for 1Kb --- .../build-stack-frame.factor | 2 +- basis/compiler/cfg/gc-checks/gc-checks.factor | 21 ++++++++++++++++--- .../cfg/instructions/instructions.factor | 6 +----- .../cfg/intrinsics/allot/allot.factor | 5 ++++- .../linear-scan/assignment/assignment.factor | 10 +++++---- .../cfg/linearization/linearization.factor | 15 ------------- .../stacks/uninitialized/uninitialized.factor | 2 +- basis/compiler/codegen/codegen.factor | 4 ++-- basis/cpu/architecture/architecture.factor | 2 +- basis/cpu/ppc/ppc.factor | 5 ++--- basis/cpu/x86/x86.factor | 4 ++-- vm/data_gc.cpp | 4 ++-- vm/data_gc.hpp | 5 ----- 13 files changed, 40 insertions(+), 45 deletions(-) diff --git a/basis/compiler/cfg/build-stack-frame/build-stack-frame.factor b/basis/compiler/cfg/build-stack-frame/build-stack-frame.factor index 90992fcc96..b5510c7142 100644 --- a/basis/compiler/cfg/build-stack-frame/build-stack-frame.factor +++ b/basis/compiler/cfg/build-stack-frame/build-stack-frame.factor @@ -25,7 +25,7 @@ M: stack-frame-insn compute-stack-frame* M: ##call compute-stack-frame* word>> sub-primitive>> [ frame-required? on ] unless ; -M: _gc compute-stack-frame* +M: ##gc compute-stack-frame* frame-required? on stack-frame new swap tagged-values>> length cells >>gc-root-size request-stack-frame ; diff --git a/basis/compiler/cfg/gc-checks/gc-checks.factor b/basis/compiler/cfg/gc-checks/gc-checks.factor index 21a60768ea..5d3c79e40f 100644 --- a/basis/compiler/cfg/gc-checks/gc-checks.factor +++ b/basis/compiler/cfg/gc-checks/gc-checks.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel sequences assocs fry -cpu.architecture +cpu.architecture layouts compiler.cfg.rpo compiler.cfg.registers compiler.cfg.instructions @@ -17,11 +17,26 @@ IN: compiler.cfg.gc-checks : blocks-with-gc ( cfg -- bbs ) 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 -- ) - dup '[ + dup dup '[ 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 ] change-instructions drop ; diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index b6881b61b6..6b61cb53cb 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -672,7 +672,7 @@ use: src1/int-rep src2/int-rep ; INSN: ##gc 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 temp: temp1/int-rep temp2/int-rep @@ -740,10 +740,6 @@ use: src1/int-rep src2/int-rep ; TUPLE: spill-slot { n integer } ; C: spill-slot -INSN: _gc -temp: temp1 temp2 -literal: data-values tagged-values uninitialized-locs ; - ! These instructions operate on machine registers and not ! virtual registers INSN: _spill diff --git a/basis/compiler/cfg/intrinsics/allot/allot.factor b/basis/compiler/cfg/intrinsics/allot/allot.factor index 6ad5450bfc..8283299ea8 100644 --- a/basis/compiler/cfg/intrinsics/allot/allot.factor +++ b/basis/compiler/cfg/intrinsics/allot/allot.factor @@ -55,6 +55,9 @@ IN: compiler.cfg.intrinsics.allot ] [ node emit-primitive ] if ] ; +: expand-(byte-array)? ( obj -- ? ) + dup integer? [ 0 1024 between? ] [ drop f ] if ; + : expand-? ( obj -- ? ) dup integer? [ 0 32 between? ] [ drop f ] if ; @@ -69,7 +72,7 @@ IN: compiler.cfg.intrinsics.allot [ byte-array store-length ] [ ds-push ] [ ] tri ; : emit-(byte-array) ( node -- ) - dup node-input-infos first literal>> dup expand-? + dup node-input-infos first literal>> dup expand-(byte-array)? [ nip emit-allot-byte-array drop ] [ drop emit-primitive ] if ; :: emit- ( node -- ) diff --git a/basis/compiler/cfg/linear-scan/assignment/assignment.factor b/basis/compiler/cfg/linear-scan/assignment/assignment.factor index 8959add822..f69db1deea 100644 --- a/basis/compiler/cfg/linear-scan/assignment/assignment.factor +++ b/basis/compiler/cfg/linear-scan/assignment/assignment.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel math assocs namespaces sequences heaps fry make combinators sets locals arrays -cpu.architecture +cpu.architecture layouts compiler.cfg compiler.cfg.def-use compiler.cfg.liveness @@ -117,8 +117,6 @@ RENAMING: assign [ vreg>reg ] [ vreg>reg ] [ vreg>reg ] M: vreg-insn assign-registers-in-insn [ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ; -! TODO: needs tagged-rep - : trace-on-gc ( assoc -- assoc' ) ! When a GC occurs, virtual registers which contain tagged data ! are traced by the GC. Outputs a sequence physical registers. @@ -141,12 +139,16 @@ M: vreg-insn assign-registers-in-insn ] assoc-each ] { } 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 ! Since ##gc is always the first instruction in a block, the set of ! values live at the ##gc is just live-in. dup call-next-method 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 ; M: insn assign-registers-in-insn drop ; diff --git a/basis/compiler/cfg/linearization/linearization.factor b/basis/compiler/cfg/linearization/linearization.factor index 31a4247206..34ae7f8cc6 100755 --- a/basis/compiler/cfg/linearization/linearization.factor +++ b/basis/compiler/cfg/linearization/linearization.factor @@ -97,21 +97,6 @@ M: ##dispatch linearize-insn [ successors>> [ block-number _dispatch-label ] each ] 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 ) [ [ diff --git a/basis/compiler/cfg/stacks/uninitialized/uninitialized.factor b/basis/compiler/cfg/stacks/uninitialized/uninitialized.factor index ce0e98de5f..0bed759e52 100644 --- a/basis/compiler/cfg/stacks/uninitialized/uninitialized.factor +++ b/basis/compiler/cfg/stacks/uninitialized/uninitialized.factor @@ -9,7 +9,7 @@ IN: compiler.cfg.stacks.uninitialized ! Consider the following sequence of instructions: ! ##inc-d 2 -! _gc +! ##gc ! ##replace ... D 0 ! ##replace ... D 1 ! The GC check runs before stack locations 0 and 1 have been initialized, diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index 05f50771f6..121f09a5a8 100755 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -271,10 +271,10 @@ M: object load-gc-root drop %load-gc-root ; : load-data-regs ( data-regs -- ) [ first3 %reload ] each ; -M: _gc generate-insn +M: ##gc generate-insn "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 ] [ data-values>> save-data-regs ] [ [ tagged-values>> ] [ temp1>> ] bi save-gc-roots ] diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index 0fb69120da..5ce16ad731 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -317,7 +317,7 @@ HOOK: %allot cpu ( dst size class temp -- ) HOOK: %write-barrier cpu ( src card# table -- ) ! 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: %load-gc-root cpu ( gc-root register -- ) HOOK: %call-gc cpu ( gc-root-count temp1 -- ) diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor index f604efe64d..9394e864f0 100644 --- a/basis/cpu/ppc/ppc.factor +++ b/basis/cpu/ppc/ppc.factor @@ -446,12 +446,11 @@ M:: ppc %write-barrier ( src card# table -- ) src card# deck-bits SRWI table scratch-reg card# STBX ; -M:: ppc %check-nursery ( label temp1 temp2 -- ) +M:: ppc %check-nursery ( label size temp1 temp2 -- ) temp2 load-zone-ptr temp1 temp2 cell LWZ temp2 temp2 3 cells LWZ - ! add ALLOT_BUFFER_ZONE to here - temp1 temp1 1024 ADDI + temp1 temp1 size ADDI ! is here >= end? temp1 0 temp2 CMP label BLE ; diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index 7c025707fc..fa5d99101b 100644 --- a/basis/cpu/x86/x86.factor +++ b/basis/cpu/x86/x86.factor @@ -410,10 +410,10 @@ M:: x86 %write-barrier ( src card# table -- ) table table [] MOV table card# [+] card-mark MOV ; -M:: x86 %check-nursery ( label temp1 temp2 -- ) +M:: x86 %check-nursery ( label size temp1 temp2 -- ) temp1 load-zone-ptr temp2 temp1 cell [+] MOV - temp2 1024 ADD + temp2 size ADD temp1 temp1 3 cells [+] MOV temp2 temp1 CMP label JLE ; diff --git a/vm/data_gc.cpp b/vm/data_gc.cpp index 679eec01f7..60195f89d5 100755 --- a/vm/data_gc.cpp +++ b/vm/data_gc.cpp @@ -738,10 +738,10 @@ object *factor_vm::allot_object(header header, cell size) object *obj; - if(nursery.size - allot_buffer_zone > size) + if(nursery.size > size) { /* 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); cell h = nursery.here; diff --git a/vm/data_gc.hpp b/vm/data_gc.hpp index 0f098b877d..2a74568b66 100755 --- a/vm/data_gc.hpp +++ b/vm/data_gc.hpp @@ -58,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); }