Text preview for : SymbolCache.mesa_Oct77.pdf part of xerox SymbolCache.mesa Oct77 xerox mesa 3.0_1977 listing SymbolCache.mesa_Oct77.pdf



Back to : SymbolCache.mesa_Oct77.pd | Home

symbolcache.mESA 24-0CT-77 10:55:07 Page 1


-- file SymbolCache.Mesa
-- last modified by Satterthwaite on August 26, 1977 9:23 PM
DIRECTORY
AltoDefs: FROM "altodefs",
ControlDefs: FROM "controldefs",
SegmentDefs: fROM "segmentdefs",
SymDefs: FROM "symdefs",
SymbolTable: FROM "symboltable",
TableDefs: FROM "tabledefs",
SymbolTableDefs: FROM "symboltabledefs":
DEFINITIONS FROM SymbolTableDefs:
SymbolCache: PROGRAM
IMPORTS
sO: Symbol Table. sl: SymbolTable, s2: SymbolTable, s3: SymbolTable,
SegmentDefs
EXPORTS SymbolTableDefs
SHARES ControlDefs, SymbolTableDefs =
BEGIN
OPEN SegmentDefs:
-- public interface
NoSymbolTable: PUBLIC SIGNAL [FileSegmentHandle] = CODE:
TableForFrame: PUBLIC PROCEDURE [frame: ControlDefs.FrameHandle] RETURNS [SymbolTableHandle]
BEGIN
symbolseg: FileSegmentHandle = frame.accesslink.symbolsegment:
IF symbolseg : NIL THEN ERROR NoSymbolTable[frame.accesslink.codesegment]:
IF symbolseg.class # symbols THEN ERROR:
RETURN [SymbolTableHandle[symbolseg]]
END:
TableForSegment: PUBLIC PROCEDURE [seg: FileSegmentHandle] RETURNS [SymbolTableHandle]
BEGIN
IF seg : NIL OR seg.class # symbols THEN ERROR NoSymbolTable[seg]:
RETURN [SymbolTableHandle[seg]]
END:
SegmentForTable: PUBLIC PROCEDURE [table: SymbolTablefiandle] RETURNS [FileSegmentHandle]
BEGIN
RETURN [table.segment]
END:

TooManySymbolTables: PUBLIC SIGNAL [handle: SymbolTablefiandle] = CODE:
SymbolBuffersFull: PUBLIC SIGNAL = CODE:
IllegalSymbolBase: PUBLIC SIGNAL [base: SymbolTableBase] = CODE:
AcquireSymbolTable: PUBLIC PROCEDURE [handle: SymbolTableHandle] RETURNS [base: SymbolTableBase]
BEGIN
i: STMapIndex;
-- repeat on failure
DO
.. strover;
DO
IF stmap[i].stlink : NIL
THEN
BEGIN strover .. i:
stmap[i].sllink .. MakeCacheEntry[handle]:
base" slmap[i].slbase;
InstallTable[base. stmap[i].stl ink.symheader]:
RrTURN
END:
i .. IF joIAST[STMapIndex] TIIfN fIRST[STMapIndex] ELSE i+1:
If I = strover TllfN EXIT:
rNDIOOP:
SIGNAl TooManySymbolTablos[handle]:
fNOIOOP:
fND:
HpleaseSymbolTable: PUBLIC PROCfDURE [base: SymbolTabloBase]
B[GIN
i: SfMapIndex .. slrover:
symbolcache.mESA 24-0CT-77 18:56:07 Page 2


DO
IF stmap[1].stbase = base AND stmap[1].st11nk # NIL
THEN
BEGIN strover ~ 1;
FreeCacheEntry[stmap[1].stlink]; stmap[i].st11nk ~ NIL:
RETURN
END;
i ~ IF i=FIRST[STMapIndex] THEN LAST[STMapIndex] ELSE 1-1:
IF 1 = strover THEN EXIT:
ENDLOOP;
SIGNAL IllegalSymbo18ase[base]; RETURN
END;

cachepagelimit: INTEGER ~ 0;
SymbolCacheSize: PUBLI~ PROCEDURE RETURNS [pages: INTEGER]
BEGIN
pages ~ cachepagelimit; RETURN
END;
SetSymbolCacheSize: PUBLIC PROCEDURE [pages: INTEGER]
BEGIN
cachepagel imit ~ MAX[pages. 0];
trimcache[cachepage11mit];
RETURN
END;
suspended: BOOLEAN:
SuspendSymbolCache: PUBLIC PROCEDURE
BEGIN
node: CachePointer;
tr imcache[O];
suspended ~ TRUE;
FOR node ~ header.next. node. next UNTIL node = free
DO Unlock[node.table]; SwapOut[node.table] ENr.LOOP;
RETURN
END:
RestartSymbolCache: PUBLIC PROCEDURE
BEGIN
node: CachePointer:
i: STMapIndex:
IF -suspended THEN ERROR;
FOR node ~ header.next. node. next UNTIL node = free
DO
SwapIn[node.table]:
node.symheader ~ FileSegmentAddress[node.table]:
ENDLOOP:
FOR i IN STMapIndex
DO
IF stmap[i].stlink # NIL
THEN
BEGIN
SetBases[stmap[i].stbase. stmap[i].stlink.symheader]:
s~nap[i].stbase.notifier[stmap[i].stbase]:
END:
ENDLOOP:
suspended ~ FALSE:
RETURN
END:

internal cache management
CacheNode: TYPE = RECORD[
prevo next: CachePointer.
table: SymbolTablefiandle.
symheader: POINTER.
rercoun t: INTEGER]:
CachePointer: TYP[ = POINTFR TO CacheNode:
STMapTndex: TYPE = TNTffirR [0 .. 4);
symbolcache.mESA 24-0CT-77 18:55:07 Page 3


stmap: ARRAY STMapIndex OF RECORD[
stbase: SymbolTableBase,
stlink: CachePointer]:
strover: STMapIndex:
header, free, flushed: CachePointer:
CacheNodes: INTEGER = 7:
cachedpages: INTEGER;
IncompatibleSymbolTable: ERROR = CODE:

MakeCacheEntry: PROCEDURE [handle: SymbolTableHandle] RETURNS [node: CachePointer] =
BEGIN
FOR node ~ header.next, node.next UNTIL node = free
DO
IF node.table = handle THEN GO TO allocated;
REPEAT
allocated => NULL;
FINISHED =>
BEGIN
FOR node ~ free, node. next UNTIL node = flushed
DO
IF node.table = handle THEN GO TO unflushed:
REPEAT
unflushed =>
BEGIN
movenode[ node, free]:
IF flushed = free
THEN RemoveSwapStrategy[@flushstrategy];
END;
FINISHED =>
BEGIN
trimcache[cachepagelimit];
node ~ GetFlushedNode[];
SwapIn[handle
!InvalidFP =) ERROR NoSymbolTable[handle]:
InsufficientVM =)
IF free # flushed THEN
BEGIN FlushATable[]; RESUME END];
cachedpages ~ cachedpages + handle.pages;
node.table ~ handle;
node.symheader ~ FileSegmentAddress[handle]:
movenode[node, free];
END;
ENDLOOP:
movenode[node, free];
END;
ENDLOOP;
node.refcount ~ node.refcount+l; RETURN
END;
freeCacheEntry: PROCEDURE [node: CachePointer]
BEGIN
np: INTEGER;
slot: CachePointer;
SELECT (node.refcount ~ node.refcount-1) FROM
=0 =)
BEGIN
slot ~ free; np ~ node.table.pages;
IF 3