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