Browse Source

* refactored omf library writing, so that the whole library is written in
TOmfLibObjectWrite.WriteLib, after determining the page size (currently still
fixed to 512 bytes). Prerequisite for OMF lib page size optimization.

git-svn-id: trunk@39194 -

nickysn 7 years ago
parent
commit
345713c1fa
1 changed files with 47 additions and 11 deletions
  1. 47 11
      compiler/owomflib.pas

+ 47 - 11
compiler/owomflib.pas

@@ -69,7 +69,7 @@ type
     FPageSize: Integer;
     FPageSize: Integer;
     FLibName: string;
     FLibName: string;
     FLibData: TDynamicArray;
     FLibData: TDynamicArray;
-    FObjStartPage: Word;
+    FFooterPos: LongWord;
     FDictionary: TFPHashObjectList;
     FDictionary: TFPHashObjectList;
     FObjectModules: TFPObjectList;
     FObjectModules: TFPObjectList;
     FCurrentModule: TOmfLibObjectModule;
     FCurrentModule: TOmfLibObjectModule;
@@ -77,6 +77,7 @@ type
 
 
     procedure WriteHeader(DictStart: DWord; DictBlocks: Word);
     procedure WriteHeader(DictStart: DWord; DictBlocks: Word);
     procedure WriteFooter;
     procedure WriteFooter;
+    function TryPageSize(aPageSize: Integer): Boolean;
     procedure WriteLib;
     procedure WriteLib;
     function WriteDictionary: Word;
     function WriteDictionary: Word;
     function TryWriteDictionaryWithSize(nblocks: Word): Boolean;
     function TryWriteDictionaryWithSize(nblocks: Word): Boolean;
@@ -131,7 +132,7 @@ implementation
 
 
     uses
     uses
       SysUtils,
       SysUtils,
-      cstreams,
+      cstreams,cutils,
       verbose,
       verbose,
       omfbase;
       omfbase;
 
 
@@ -195,8 +196,6 @@ implementation
         FDictionary:=TFPHashObjectList.Create;
         FDictionary:=TFPHashObjectList.Create;
         FObjectModules:=TFPObjectList.Create(True);
         FObjectModules:=TFPObjectList.Create(True);
         FCurrentModule:=nil;
         FCurrentModule:=nil;
-        { header is at page 0, so first module starts at page 1 }
-        FObjStartPage:=1;
       end;
       end;
 
 
 
 
@@ -215,7 +214,6 @@ implementation
       begin
       begin
         FCurrentModule:=TOmfLibObjectModule.Create(fn);
         FCurrentModule:=TOmfLibObjectModule.Create(fn);
         FCurrentModuleIndex:=FObjectModules.Add(FCurrentModule);
         FCurrentModuleIndex:=FObjectModules.Add(FCurrentModule);
-        FCurrentModule.PageNum:=FObjStartPage;
         createfile:=true;
         createfile:=true;
         fobjsize:=0;
         fobjsize:=0;
       end;
       end;
@@ -226,7 +224,6 @@ implementation
         RawRec: TOmfRawRecord;
         RawRec: TOmfRawRecord;
         ObjHeader: TOmfRecord_THEADR;
         ObjHeader: TOmfRecord_THEADR;
       begin
       begin
-        FLibData.seek(FObjStartPage*FPageSize);
         FCurrentModule.ObjData.seek(0);
         FCurrentModule.ObjData.seek(0);
         RawRec:=TOmfRawRecord.Create;
         RawRec:=TOmfRawRecord.Create;
         repeat
         repeat
@@ -239,11 +236,8 @@ implementation
               TOmfLibDictionaryEntry.Create(FDictionary,ModName2DictEntry(ObjHeader.ModuleName),FCurrentModuleIndex);
               TOmfLibDictionaryEntry.Create(FDictionary,ModName2DictEntry(ObjHeader.ModuleName),FCurrentModuleIndex);
               ObjHeader.Free;
               ObjHeader.Free;
             end;
             end;
-          RawRec.WriteTo(FLibData);
         until RawRec.RecordType in [RT_MODEND,RT_MODEND32];
         until RawRec.RecordType in [RT_MODEND,RT_MODEND32];
         RawRec.Free;
         RawRec.Free;
-        { calculate start page of next module }
-        FObjStartPage:=(FLibData.Pos+FPageSize-1) div FPageSize;
         fobjsize:=0;
         fobjsize:=0;
       end;
       end;
 
 
@@ -287,7 +281,7 @@ implementation
         Footer: TOmfRecord_LIBEND;
         Footer: TOmfRecord_LIBEND;
         RawRec: TOmfRawRecord;
         RawRec: TOmfRawRecord;
       begin
       begin
-        FLibData.seek(FObjStartPage*FPageSize);
+        FLibData.seek(FFooterPos);
         Footer:=TOmfRecord_LIBEND.Create;
         Footer:=TOmfRecord_LIBEND.Create;
         Footer.CalculatePaddingBytes(FLibData.Pos);
         Footer.CalculatePaddingBytes(FLibData.Pos);
         RawRec:=TOmfRawRecord.Create;
         RawRec:=TOmfRawRecord.Create;
@@ -297,18 +291,60 @@ implementation
         RawRec.Free;
         RawRec.Free;
       end;
       end;
 
 
+    function TOmfLibObjectWriter.TryPageSize(aPageSize: Integer): Boolean;
+      var
+        I: Integer;
+        CurrentPage: Integer;
+        CurrentPos: LongWord;
+        pow: longint;
+      begin
+        if not IsPowerOf2(aPageSize,pow) then
+          internalerror(2018060701);
+        if (pow<4) or (pow>15) then
+          internalerror(2018060702);
+        FPageSize:=aPageSize;
+        { header is at page 0, so first module starts at page 1 }
+        CurrentPage:=1;
+        for I:=0 to FObjectModules.Count-1 do
+          with TOmfLibObjectModule(FObjectModules[I]) do
+            begin
+              if CurrentPage>high(word) then
+                exit(False);
+              PageNum:=CurrentPage;
+              { calculate next page }
+              CurrentPos:=CurrentPage*FPageSize+ObjData.Size;
+              CurrentPage:=(CurrentPos+FPageSize-1) div FPageSize;
+            end;
+        FFooterPos:=CurrentPage*FPageSize;
+        Result:=True;
+      end;
+
     procedure TOmfLibObjectWriter.WriteLib;
     procedure TOmfLibObjectWriter.WriteLib;
       var
       var
         libf: TCCustomFileStream;
         libf: TCCustomFileStream;
-        DictStart: LongWord;
+        DictStart, bytes: LongWord;
         DictBlocks: Word;
         DictBlocks: Word;
+        I: Integer;
+        buf: array [0..1023] of Byte;
       begin
       begin
+        TryPageSize(512);
         libf:=CFileStreamClass.Create(FLibName,fmCreate);
         libf:=CFileStreamClass.Create(FLibName,fmCreate);
         if CStreamError<>0 then
         if CStreamError<>0 then
           begin
           begin
             Message1(exec_e_cant_create_archivefile,FLibName);
             Message1(exec_e_cant_create_archivefile,FLibName);
             exit;
             exit;
           end;
           end;
+        for I:=0 to FObjectModules.Count-1 do
+          with TOmfLibObjectModule(FObjectModules[I]) do
+            begin
+              FLibData.seek(PageNum*FPageSize);
+              ObjData.seek(0);
+              while ObjData.Pos<ObjData.size do
+                begin
+                  bytes:=ObjData.read(buf,Min(SizeOf(buf),ObjData.size-ObjData.Pos));
+                  FLibData.write(buf,bytes);
+                end;
+            end;
         WriteFooter;
         WriteFooter;
         DictStart:=FLibData.Pos;
         DictStart:=FLibData.Pos;
         DictBlocks:=WriteDictionary;
         DictBlocks:=WriteDictionary;