Explorar o código

Attempt to fix heaptrc fos DOS.

Rika Ichinose hai 2 días
pai
achega
28f6bb4ef1
Modificáronse 1 ficheiros con 59 adicións e 13 borrados
  1. 59 13
      rtl/inc/heaptrc.pp

+ 59 - 13
rtl/inc/heaptrc.pp

@@ -22,6 +22,14 @@ unit heaptrc;
   {$define windows}
 {$endif}
 
+{$if not defined(FPUNONE) and not defined(FPUSOFT)}
+  {$define can_use_ln_in_constants} // :(
+{$endif}
+
+{$if not defined(CPUINT8) and not defined(CPUINT16)}
+  {$define can_use_int32_case} // :(
+{$endif}
+
 // Buggy and does not help: https://gitlab.com/freepascal.org/fpc/source/-/issues/39611.
 // As a workaround, you can wrap this with {$define disable_warnings := ...all of these $warns...} and sprinkle disable_warnings here and there.
 {$warn 4055 off : Conversion between ordinals and pointers is not portable}
@@ -512,28 +520,44 @@ type
   var
     pb: pByte absolute p;
   begin
+{$ifdef can_use_int32_case}
     case v of
       0 .. Ofs2 - 1:
+{$else}
+    if v < Ofs2 then
+{$endif}
         begin
           pb[0] := v;
           result := 1;
-        end;
+        end
+{$ifdef can_use_int32_case};
       Ofs2 .. Ofs3 - 1:
+{$else}
+    else if v < Ofs3 then
+{$endif}
         begin
           dec(v, Ofs2);
           pb[0] := FirstByte2 + v shr 8;
           pb[1] := byte(v);
           result := 2;
-        end;
+        end
+{$ifdef can_use_int32_case};
       Ofs3 .. Ofs4 - 1:
+{$else}
+    else if v < Ofs4 then
+{$endif}
         begin
           dec(v, Ofs3);
           pb[0] := FirstByte3 + v shr 16;
           pb[1] := byte(v shr 8);
           pb[2] := byte(v);
           result := 3;
-        end;
+        end
+{$ifdef can_use_int32_case};
       Ofs4 .. Min5 - 1:
+{$else}
+    else if v < Min5 then
+{$endif}
         begin
           dec(v, Ofs4);
           pb[0] := FirstByte4 + v shr 24;
@@ -541,7 +565,7 @@ type
           pb[2] := byte(v shr 8);
           pb[3] := byte(v);
           result := 4;
-        end;
+        end {$ifdef can_use_int32_case} ; {$endif} { actually this ; is optional even with ‘case’. }
       else
         begin
         {$if sizeof(v) <= sizeof(uint32)}
@@ -556,7 +580,9 @@ type
           unaligned(pUint32(pb + result - 4)^) := uint32(v {$ifdef endian_little} shr (8 * result - 40) {$endif});
         {$else} {$error >64 bits} {$endif}
         end;
-    end;
+{$ifdef can_use_int32_case}
+    end; { closes case .. of }
+{$endif}
   end;
 
   class function VarInt.EnZig(sv: PtrInt): PtrUint;
@@ -630,7 +656,7 @@ type
       n := VarInt.Read(packedTrace, PtrUint(delta));
       inc(packedTrace, n); dec(remaining, n);
     {$push} {$q-,r-} inc(ptrv, VarInt.DeZig(PtrUint(delta))); {$pop}
-      trace[result] := pointer(PtrUint(ptrv));
+      trace[result] := CodePointer(PtrUint(ptrv));
       inc(result);
     end;
   end;
@@ -932,11 +958,18 @@ type
     HeadTailSizes: array[0 .. 15] of uint8 = (0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56);
 
     // Code asumes that HasFullUserRequestBit immediately precedes ExtraInfoIndex, i.e., they can be combined into one index.
-    HasFullUserRequestShift = 0;                                HasFullUserRequestBit = 1 shl HasFullUserRequestShift;
-    ExtraInfoIndexShift = HasFullUserRequestShift + 1;             ExtraInfoIndexBits = 1 + trunc(ln(MaxExtraInfos) / ln(2) + Eps);      ExtraInfoIndexMask = 1 shl ExtraInfoIndexBits - 1;
-    FreelistIndexMask = ExtraInfoIndexMask shl 1 or 1;
-    TailSizeIndexShift = ExtraInfoIndexShift + ExtraInfoIndexBits; TailSizeIndexBits = 1 + trunc(ln(High(HeadTailSizes)) / ln(2) + Eps); TailSizeIndexMask = 1 shl TailSizeIndexBits - 1;
-    HeadSizeIndexShift = TailSizeIndexShift + TailSizeIndexBits;   HeadSizeIndexBits = 1 + trunc(ln(High(HeadTailSizes)) / ln(2) + Eps); HeadSizeIndexMask = 1 shl HeadSizeIndexBits - 1;
+    HasFullUserRequestShift = 0;
+    HasFullUserRequestBit = 1 shl HasFullUserRequestShift;
+    ExtraInfoIndexShift = HasFullUserRequestShift + 1;
+    ExtraInfoIndexBits = {$ifdef can_use_ln_in_constants} 1 + trunc(ln(MaxExtraInfos) / ln(2) + Eps) {$else} 2 {$endif}; {$if ExtraInfoIndexBits <> 2} {$error fix the hardcoded constant} {$endif}
+    ExtraInfoIndexMask = 1 shl ExtraInfoIndexBits - 1;
+    FreelistIndexMask = ExtraInfoIndexMask shl 1 or 1; // Mask for merged ExtraInfoIndex:HasFullUserRequestBit.
+    TailSizeIndexShift = ExtraInfoIndexShift + ExtraInfoIndexBits;
+    TailSizeIndexBits = {$ifdef can_use_ln_in_constants} 1 + trunc(ln(High(HeadTailSizes)) / ln(2) + Eps) {$else} 4 {$endif}; {$if TailSizeIndexBits <> 4} {$error fix the hardcoded constant} {$endif}
+    TailSizeIndexMask = 1 shl TailSizeIndexBits - 1;
+    HeadSizeIndexShift = TailSizeIndexShift + TailSizeIndexBits;
+    HeadSizeIndexBits = {$ifdef can_use_ln_in_constants} 1 + trunc(ln(High(HeadTailSizes)) / ln(2) + Eps) {$else} 4 {$endif}; {$if HeadSizeIndexBits <> 4} {$error fix the hardcoded constant} {$endif}
+    HeadSizeIndexMask = 1 shl HeadSizeIndexBits - 1;
     ReallocatingShift = HeadSizeIndexShift + HeadSizeIndexBits; ReallocatingBit = 1 shl ReallocatingShift;
     ReportedShift = ReallocatingShift + 1;                      ReportedBit = 1 shl ReportedShift;
     UserSizeRequestShift = ReportedShift + 1;
@@ -1035,7 +1068,7 @@ type
     procedure FreeAllToFreeItems(cf: CheckFlags); // For finalization.
     function AllocateNode(info: SizeUint): pNode;
     procedure FreeNode(n: pNode; var freeBatch: PrevMgrToFreeBatch; cf: CheckFlags);
-    class function CfSkipFrames(cf: CheckFlags): SizeUint; static;
+    class function CfSkipFrames(cf: CheckFlags): SizeUint; static; inline;
 
     function DoGetMem(size: PtrUint): pointer;
     function DoFreeMem(p: pointer; size: PtrUint): PtrUint;
@@ -1331,10 +1364,23 @@ var
     freeBatch.Add(n^.userPtr - HeadTailSizes[info shr HeadSizeIndexShift and HeadSizeIndexMask] * HeadSizeUnit, cf);
   end;
 
+type
+  HeapTracerCheckFlags = HeapTracer.CheckFlags;
+
   class function HeapTracer.CfSkipFrames(cf: CheckFlags): SizeUint;
+{$if sizeof(HeapTracerCheckFlags) = sizeof(uint32)}
   begin
     result := PopCnt(uint32(cf * CheckFlagsThatMeanFramesUninterestingInBacktraces));
   end;
+{$else}
+  var
+    f: CheckFlag;
+  begin
+    result := 0;
+    for f in cf * CheckFlagsThatMeanFramesUninterestingInBacktraces do
+      inc(result);
+  end;
+{$endif}
 
   function HeapTracer.DoGetMem(size: PtrUint): pointer;
   var
@@ -2150,7 +2196,7 @@ end;
         exit;
       end;
     end;
-  {$I+}
+  {$pop}
     outfp := @ownOutfp;
     needCloseOutfp := true;
     for i := 0 to ParamCount do