Compacting Symbol Tables
After each module is compiled the symbol tables are compacted to remove unused space.
Procedure JoinSymbolTablesAndCreateUnit;
Var ReferencedUnitRecord: PReferencedModulesBlockRecord;
SymbolsSize: LongRec;
Block: TSymbolTable;
UnitHeader: PUnitHeader;
CurrentPointer: PChar;
Function AdjustCurrentPointerToNextParagraph: Word;
begin
AdjustCurrentPointerToNextParagraph := Seg (CurrentPointer^);
FillChar (CurrentPointer^, (16 - Ofs (CurrentPointer^)) and $000F, 0);
Inc (CurrentPointer, (16 - Ofs (CurrentPointer^)) and $000F);
CurrentPointer := Ptr (Seg (CurrentPointer^) + Ofs (CurrentPointer^) shr 4, 0);
end;
begin
ReferencedUnitRecord := Ptr (SymbolTable [stReferencedModules].Segment, 0);
While ReferencedUnitRecord <> SymbolTable [stReferencedModules].Ptr do
begin
ReferencedUnitRecord^.ModuleSegment := 0;
Inc (PChar (ReferencedUnitRecord), ReferencedUnitRecord^.UnitName.Len + 5);
end;
SymbolsSize.Long := 0;
For Block := stMain to stSourceLineCodeOffsets do
Inc (SymbolsSize.Long, SymbolTable [Block].UsedSize);
If SymbolsSize.WordH <> 0 then Error (TooManySymbols);
If SymbolsSize.WordL > $FFF0 then Error (TooManySymbols);
UnitHeader := Ptr (SymbolTable [stMain].Segment, 0);
CurrentPointer := SymbolTable [stMain].Ptr;
For Block := stProcedures to stSourceLineCodeOffsets do
begin
UnitHeader^.BlockOffset [Block] := Ofs (CurrentPointer^);
MoveBackward (Ptr (SymbolTable [Block].Segment, 0)^, CurrentPointer^, SymbolTable [Block].UsedSize);
Inc (CurrentPointer, SymbolTable [Block].UsedSize);
end;
SymbolTable [stMain].UsedSize := Ofs (CurrentPointer^);
UnitHeader^.JoinedBlockSize := Ofs (CurrentPointer^);
For Block := st11 to stTypedConstantsReferences do
UnitHeader^.BlockSize [Block] := SymbolTable [Block].UsedSize;
UnitHeader^.SizeOfVariablesInDataSegment := SizeOfVariablesInDataSegment;
AdjustCurrentPointerToNextParagraph;
For Block := st11 to stTypedConstantsReferences do
begin
MoveBackward (Ptr (SymbolTable [Block].Segment, 0)^, CurrentPointer^, SymbolTable [Block].UsedSize);
Inc (CurrentPointer, SymbolTable [Block].UsedSize);
SymbolTable [Block].Segment := AdjustCurrentPointerToNextParagraph;
end;
HeapPtr := CurrentPointer;
end;