-- 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.