home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
dev
/
oberon-a-1.4ß.lha
/
Oberon-A
/
source
/
oberonsys
/
GC.asm
< prev
next >
Wrap
Assembly Source File
|
1994-08-08
|
14KB
|
350 lines
****************************************************************************
*
* $RCSfile: GC.asm $
* Description: Runtime support for the Oberon-A compiler
*
* Created by: fjc (Frank Copeland)
* $Revision: 1.3 $
* $Author: fjc $
* $Date: 1994/05/16 16:32:13 $
*
* Copyright © 1994, Frank Copeland.
* This file is part of the Oberon-A Library.
* See Oberon-A.doc for conditions of use and distribution.
*
* Log entries are at the end of the file.
*
****************************************************************************
*
* This file contains the MC68000 source code for part of the runtime support
* library of the Oberon-A compiler. It contains the code to implement the
* Oberon-A garbage collector.
*
* Other parts of the runtime system may be found in the other files in this
* directory. The object files resulting from assembling these files are
* concatenated to create OberonSys.lib.
*
* This code is by definition *not* re-entrant and is not suitable for
* creating shared-code libraries.
*
****************************************************************************
;---------------------------------------------------------------------------
; Program unit hunk name
; !! DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING !!
TTL OberonSys
;---------------------------------------------------------------------------
; Imports
INCLUDE "OberonSys.i"
ABSEXECBASE EQU 4
FreeMem EQU -210
;---------------------------------------------------------------------------
; Macros
CALLSYS MACRO
JSR \1(A6)
ENDM
;---------------------------------------------------------------------------
; Defines
SysBit EQU 0
ArrayBit EQU 1
MarkBitB EQU 7
MarkBitL EQU 31
tag EQU -4
size EQU -12
elemSize EQU -16
arrpos EQU -20
PtrTabOffset EQU 36
;---------------------------------------------------------------------------
; PROCEDURE OberonSys_GC ()
;
; A call to this procedure is generated by the compiler when it translates a
; call to SYSTEM.GC. OberonSys_GC implements a mark-and-sweep garbage
; collector. See TechNotes.doc and Memory.doc for a discussion of the
; memory management system and the garbage collector.
;
; This procedure forms the outer loop of the mark phase and OberonSys_Mark
; is the inner loop. It walks the list of global variable descriptors
; generated by the compiler and applies the mark algorithm to each global
; pointer variable. After marking is completed OberonSys_Sweep is called to
; collect the unmarked memory. The global variable descriptors are accessed
; through the offsetPtr variable. They consist of a link field, a pointer
; to the base of the corresponding module's global variables, and an array
; of offsets. The offsetPtr variable is also used to access this array by
; repeatedly incrementing it by the size of an offset (4 bytes). The offset
; array is terminated by a negative value which is initialised so that
; adding it to offsetPtr restores it to point to the base of the descriptor.
;
; VAR
; offsetPtr {A6} :
; POINTER TO UNION
; offsetBlock : RECORD
; link : ADDRESS;
; varBase : ADDRESS;
; END;
; offset : LONGINT;
; END;
; varBase {A4} : ADDRESS;
; ptr {A0} : ADDRESS;
; offset {D7} : LONGINT;
;
;---------------------------------------------------------------------------
SECTION OberonSys,CODE
XDEF OberonSys_GC
OberonSys_GC:
MOVEM.L A4-A5,-(A7) ; (* preserve registers *)
LEA OberonSys_VAR,A5 ; (* load OberonSys_VAR *)
MOVEA.L OS_GCVars(A5),A6 ; offsetPtr := OberonSys.GCVars;
G1:
MOVE.L A6,D0 ; WHILE offsetPtr # NIL DO
BEQ.S G4
MOVEA.L 4(A6),A4 ; varBase := offsetPtr.varBase;
ADDQ.L #8,A6 ; INC (offsetPtr, 8);
G2: ; LOOP
MOVE.L (A6)+,D7 ; offset := offsetPtr.offset;
; INC (offsetPtr, 4)
BMI.S G3 ; IF offset >= 0 THEN
MOVE.L 0(A4,D7.L),D0 ; ptr := mem [varBase + offset];
BEQ.S G2 ; IF (ptr # NIL)
MOVE.L D0,A0
BSET.B #MarkBitB,tag(A0) ; & Unmarked(ptr)
BNE.S G2
BTST.B #SysBit,tag+3(A0) ; & ~SysBlk (ptr) THEN
BNE.S G2
; Already done by BSET above SetMark (ptr);
BSR OberonSys_Mark ; OberonSys_Mark (ptr)
BRA G2 ; END;
G3: ; ELSE
ADDA.L D7,A6 ; offsetPtr := offsetPtr+offset;
SUBQ.L #4,A6 ; (* compensate for increment *)
; EXIT
; END
; END; (* LOOP *)
MOVEA.L (A6),A6 ; offsetPtr := offsetPtr.link
BRA.S G1
G4: ; END; (* WHILE *)
BSR OberonSys_Sweep ; OberonSys_Sweep ()
MOVEM.L (A7)+,A4-A5 ; (* restore registers *)
RTS
;---------------------------------------------------------------------------
;
; PROCEDURE OberonSys_Mark (q {A0} : Pointer)
;
; OberonSys_Mark is a direct implementation of the algorithm described in
; the Oberon Technical Notes, part 5 (see TechNotes.doc). It forms the
; inner loop of the mark phase and assumes that the root pointer variable
; passed in A0 has already been marked. The algorithm has been modified
; slightly to reflect the different tag encodings and memory block formats
; used by Oberon-A.
;
; Address registers A1-A3 and all the data registers are free on entry.
;
; VAR
; n {A1}, t {A2}, tos {A3} : Pointer;
; offset {D0}, tag {A4,D3} : LONGINT;
; qmask {D1}, ntag {D2} : SET;
;
;---------------------------------------------------------------------------
SECTION OberonSys,CODE
OberonSys_Mark:
MOVE.L A4,-(A7) ; (* Create an extra free register *)
BTST.B #ArrayBit,tag+3(A0) ; IF 1 IN q.tag THEN
BEQ.S M1
CLR.L arrpos(A0) ; q.arrpos := 0;
MOVE.L #$80000002,D1 ; qmask := {1, 31}
BRA.S M2
M1: ; ELSE
MOVE.L #$80000000,D1 ; qmask := {31}
M2: ; END;
MOVE.L A0,A2 ; t := q;
MOVE.L tag(A0),D3 ; tag := q.tag - {1, 31} + PtrTabOffset
AND.L #$7FFFFFFD,D3
ADD.L #PtrTabOffset,D3
SUB.L A3,A3 ; tos := NIL;
Loop: ; LOOP {H}
MOVE.L D3,A4 ; offset := mem[tag];
MOVE.L (A4),D0
BPL.S L3 ; IF offset < 0 THEN
MOVE.L D3,D4 ; q.tag := tag + offset + qmask;
ADD.L D0,D4
OR.L D1,D4
MOVE.L D4,tag(A0)
BTST.B #ArrayBit,D1 ; IF 1 IN qmask
BEQ.S L1
MOVE.L elemSize(A0),D4
ADD.L arrpos(A0),D4
CMP.L size(A0),D4 ; & (q.arrpos + q.elemSize # q.size) THEN
BEQ.S L1
MOVE.L elemSize(A0),D4 ; INC(q.arrpos,q.elemSize);
ADD.L D4,arrpos(A0)
ADD.L D0,D3 ; INC(tag, offset + PtrTabOffset - 4);
ADD.L #PtrTabOffset-4,D3
ADD.L elemSize(A0),A2 ; INC(t, q.elemSize)
BRA L5
L1:
MOVE.L A3,D4 ; ELSIF tos = NIL THEN
BEQ Exit ; EXIT
; ELSE
MOVE.L tag(A3),D1 ; qmask := tos.tag;
MOVE.L D1,D3 ; tag := qmask - {1, 31};
AND.L #$7FFFFFFD,D3
AND.L #$80000002,D1 ; qmask := qmask * {1, 31};
MOVE.L A3,A2 ; t := tos;
BTST.B #ArrayBit,D1 ; IF 1 IN qmask THEN
BEQ.S L2
ADD.L arrpos(A3),A2 ; INC (t, tos.arrpos)
L2: ; END;
MO