소스 검색

* 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 년 전
부모
커밋
345713c1fa
1개의 변경된 파일47개의 추가작업 그리고 11개의 파일을 삭제
  1. 47 11
      compiler/owomflib.pas

+ 47 - 11
compiler/owomflib.pas

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