-- IncludesSymTablesImpl.Mesa
-- Last modified by Sandman on July 8, 1980 9:16 AM
-- Last modified by Lewis on October 7, 1980 6:24 PM
-- Copyright Xerox Corporation 1979, 1980
DIRECTORY
AltoDefs USING [PageCount, PageNumber, PageSize],
InlineDefs USING [DIVMOD],
FileLists USING [tablesPages],
IncludesSymTables USING [],
SegmentDefs USING [
DeleteFileSegment, FileHandle, FileSegmentAddress, FileSegmentHandle,
NewFileSegment, Read, SwapIn, Unlock],
SymbolSegment USING [BlockDescriptor, STHeader, VersionID],
Symbols USING [HTIndex, HTRecord, MDIndex],
Storage USING [PagesForWords],
Table USING [Base];
IncludesSymTablesImpl: PROGRAM
IMPORTS FileLists, InlineDefs, SegmentDefs, Storage
EXPORTS IncludesSymTables =
BEGIN
ObsoleteSymbolTable: PUBLIC ERROR = CODE;
SymTablesAlreadyOpen: ERROR = CODE;
SymTablesNotOpen: ERROR = CODE;
mdb: PUBLIC Table.Base;
mdLimit: PUBLIC Symbols.MDIndex;
ssb: PUBLIC STRING;
ht: PUBLIC DESCRIPTOR FOR ARRAY Symbols.HTIndex OF Symbols.HTRecord;
fastAndLarge: BOOLEAN ← TRUE; -- true if one segment for symbols
symFileSeg: SegmentDefs.FileSegmentHandle ← NIL; -- if fastAndLarge
moduleTableFileSeg: SegmentDefs.FileSegmentHandle ← NIL; -- if ~fastAndLarge
stringFileSeg: SegmentDefs.FileSegmentHandle ← NIL;
hashTableFileSeg: SegmentDefs.FileSegmentHandle ← NIL;
moduleTableDesc: SymbolSegment.BlockDescriptor;
stringDesc: SymbolSegment.BlockDescriptor;
hashTableDesc: SymbolSegment.BlockDescriptor;
symTablesOpen: BOOLEAN ← FALSE;
LoadSymTables: PUBLIC PROC [
symFile: SegmentDefs.FileHandle,
symSegBase, symSegSize: AltoDefs.PageNumber] =
BEGIN
IF symTablesOpen THEN ERROR SymTablesAlreadyOpen;
fastAndLarge ← (FileLists.tablesPages < 70) AND (symSegSize < 30);
IF fastAndLarge THEN
LoadSingleSymFileSeg[symFile, symSegBase, symSegSize]
ELSE
LoadSeparateSymFileSegs[symFile, symSegBase];
symTablesOpen ← TRUE;
END;
LoadSingleSymFileSeg: PROC [
symFile: SegmentDefs.FileHandle,
symSegBase, symSegSize: AltoDefs.PageNumber] =
BEGIN OPEN SegmentDefs;
symFileSeg ← NewFileSegment[symFile, symSegBase, symSegSize, Read];
ReadSingleSymFileSeg[];
END;
ReadSingleSymFileSeg: PROC =
BEGIN OPEN SegmentDefs;
header: POINTER TO SymbolSegment.STHeader;
SwapIn[symFileSeg];
header ← FileSegmentAddress[symFileSeg];
IF header.versionIdent # SymbolSegment.VersionID THEN
ERROR ObsoleteSymbolTable[
! UNWIND =>
BEGIN
Unlock[symFileSeg];
DeleteFileSegment[symFileSeg];
symFileSeg ← NIL;
END];
moduleTableDesc ← header.mdBlock;
stringDesc ← header.ssBlock;
hashTableDesc ← header.htBlock;
ht ← DESCRIPTOR[
(FileSegmentAddress[symFileSeg] + hashTableDesc.offset),
hashTableDesc.size/SIZE[Symbols.HTRecord]];
ssb ← FileSegmentAddress[symFileSeg] + stringDesc.offset;
mdb ←
LOOPHOLE[FileSegmentAddress[symFileSeg], Table.Base] +
moduleTableDesc.offset;
mdLimit ← LOOPHOLE[moduleTableDesc.size];
END;
LoadSeparateSymFileSegs: PROC [
symFile: SegmentDefs.FileHandle, symSegBase: AltoDefs.PageNumber] =
BEGIN OPEN SegmentDefs;
symSegHeaderFileSeg: FileSegmentHandle;
header: POINTER TO SymbolSegment.STHeader;
offsetPages: AltoDefs.PageNumber;
offsetInPage: CARDINAL;
modFileSegSize, strFileSegSize, hashFileSegSize: AltoDefs.PageNumber;
symSegHeaderFileSeg ← NewFileSegment[
file: symFile,
base: symSegBase,
pages: Storage.PagesForWords[SIZE[SymbolSegment.STHeader]],
access: Read];
SwapIn[symSegHeaderFileSeg];
header ← FileSegmentAddress[symSegHeaderFileSeg];
IF header.versionIdent # SymbolSegment.VersionID THEN
ERROR ObsoleteSymbolTable[
! UNWIND =>
BEGIN
Unlock[symSegHeaderFileSeg];
DeleteFileSegment[symSegHeaderFileSeg];
symSegHeaderFileSeg ← NIL;
END];
moduleTableDesc ← header.mdBlock;
stringDesc ← header.ssBlock;
hashTableDesc ← header.htBlock;
Unlock[symSegHeaderFileSeg];
DeleteFileSegment[symSegHeaderFileSeg];
[offsetPages, offsetInPage] ← InlineDefs.DIVMOD[ -- hash table
hashTableDesc.offset, AltoDefs.PageSize];
hashFileSegSize ← Storage.PagesForWords[hashTableDesc.size + offsetInPage];
hashTableFileSeg ← NewFileSegment[
symFile, (symSegBase + offsetPages), hashFileSegSize, Read];
[offsetPages, offsetInPage] ← InlineDefs.DIVMOD[ -- string table
stringDesc.offset, AltoDefs.PageSize];
strFileSegSize ← Storage.PagesForWords[stringDesc.size + offsetInPage];
stringFileSeg ← NewFileSegment[
symFile, (symSegBase + offsetPages), strFileSegSize, Read];
[offsetPages, offsetInPage] ← InlineDefs.DIVMOD[ -- module table
moduleTableDesc.offset, AltoDefs.PageSize];
modFileSegSize ← Storage.PagesForWords[moduleTableDesc.size + offsetInPage];
moduleTableFileSeg ← NewFileSegment[
symFile, (symSegBase + offsetPages), modFileSegSize, Read];
ReadSeparateSymFileSegs[];
END;
ReadSeparateSymFileSegs: PROC =
BEGIN OPEN SegmentDefs;
offsetInPage: CARDINAL;
SwapIn[hashTableFileSeg];
offsetInPage ← hashTableDesc.offset MOD AltoDefs.PageSize;
ht ← DESCRIPTOR[
(FileSegmentAddress[hashTableFileSeg] + offsetInPage),
hashTableDesc.size/SIZE[Symbols.HTRecord]];
SwapIn[stringFileSeg];
offsetInPage ← stringDesc.offset MOD AltoDefs.PageSize;
ssb ← FileSegmentAddress[stringFileSeg] + offsetInPage;
SwapIn[moduleTableFileSeg];
offsetInPage ← moduleTableDesc.offset MOD AltoDefs.PageSize;
mdb ←
LOOPHOLE[FileSegmentAddress[moduleTableFileSeg], Table.Base] + offsetInPage;
mdLimit ← LOOPHOLE[moduleTableDesc.size];
END;
ReleaseSymTables: PUBLIC PROC =
BEGIN OPEN SegmentDefs;
IF ~symTablesOpen THEN ERROR SymTablesNotOpen;
IF fastAndLarge THEN
{Unlock[symFileSeg]; DeleteFileSegment[symFileSeg]; symFileSeg ← NIL}
ELSE
BEGIN
Unlock[moduleTableFileSeg];
DeleteFileSegment[moduleTableFileSeg];
Unlock[stringFileSeg];
DeleteFileSegment[stringFileSeg];
Unlock[hashTableFileSeg];
DeleteFileSegment[hashTableFileSeg];
moduleTableFileSeg ← stringFileSeg ← hashTableFileSeg ← NIL;
END;
symTablesOpen ← FALSE;
END;
-- allow symbol table file segments to be swapped out and relocated if
-- necessary during file list table enlargement
UnlockSymFileSegments: PUBLIC PROC =
BEGIN OPEN SegmentDefs;
IF fastAndLarge THEN {IF symFileSeg # NIL THEN Unlock[symFileSeg]}
ELSE
BEGIN
IF moduleTableFileSeg # NIL THEN Unlock[moduleTableFileSeg];
IF stringFileSeg # NIL THEN Unlock[stringFileSeg];
IF hashTableFileSeg # NIL THEN Unlock[hashTableFileSeg];
END;
END;
-- swap in (possibly relocated) symbol table file segments
ReloadSymFileSegments: PUBLIC PROC =
BEGIN
IF fastAndLarge THEN {IF symFileSeg # NIL THEN ReadSingleSymFileSeg[]}
ELSE
IF moduleTableFileSeg # NIL AND stringFileSeg # NIL
AND hashTableFileSeg # NIL THEN
ReadSeparateSymFileSegs[];
END;
END.