copying-gc.red 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. %
  2. % GC.RED - Copying 2-space garbage collector for PSL
  3. %
  4. % Author: Eric Benson
  5. % Computer Science Dept.
  6. % University of Utah
  7. % Date: 30 November 1981
  8. % Copyright (c) 1981 Eric Benson
  9. %
  10. % Edit by Cris Perdue, 16 Feb 1983 1409-PST
  11. % Removed external declaration of HeapPreviousLast (the only occurrence)
  12. % Now using "known-free-space" function and heap-warn-level
  13. % Sets HeapTrapped to NIL now.
  14. % Added check of Heap!-Warn!-Level after %Reclaim.
  15. % <PSL.KERNEL>COPYING-GC.RED.6, 4-Oct-82 17:56:49, Edit by BENSON
  16. % Added GCTime!*
  17. fluid '(!*GC GCKnt!* GCTime!* Heap!-Warn!-Level);
  18. LoadTime
  19. << GCKnt!* := 0;
  20. GCTime!* := 0;
  21. !*GC := T;
  22. LispVar Heap!-Warn!-Level := 1000
  23. >>;
  24. on SysLisp;
  25. CompileTime <<
  26. syslsp smacro procedure PointerTagP X;
  27. X > PosInt and X < Code;
  28. syslsp smacro procedure WithinOldHeapPointer X;
  29. X >= !%chipmunk!-kludge OldHeapLowerBound
  30. and X <= !%chipmunk!-kludge OldHeapLast;
  31. syslsp smacro procedure Mark X;
  32. MkItem(Forward, X);
  33. syslsp smacro procedure Marked X;
  34. Tag X eq Forward;
  35. syslsp smacro procedure MarkID X;
  36. Field(SymNam X, TagStartingBit, TagBitLength) := Forward;
  37. syslsp smacro procedure MarkedID X;
  38. Tag SymNam X eq Forward;
  39. syslsp smacro procedure ClearIDMark X;
  40. Field(SymNam X, TagStartingBit, TagBitLength) := STR;
  41. flag('(CopyFromAllBases CopyFromRange CopyFromBase CopyItem CopyItem1
  42. MarkAndCopyFromID MakeIDFreeList GCStats),
  43. 'InternalFunction);
  44. >>;
  45. external WVar ST, StackLowerBound,
  46. BndStkLowerBound, BndStkPtr,
  47. HeapLast, HeapLowerBound, HeapUpperBound,
  48. OldHeapLast, OldHeapLowerBound, OldHeapUpperBound
  49. HeapTrapped;
  50. internal WVar StackLast, OldTime, OldSize;
  51. syslsp procedure Reclaim();
  52. !%Reclaim();
  53. syslsp procedure !%Reclaim();
  54. begin scalar Tmp1, Tmp2;
  55. if LispVar !*GC then ErrorPrintF "*** Garbage collection starting";
  56. BeforeGCSystemHook();
  57. StackLast := MakeAddressFromStackPointer AdjustStackPointer(ST,
  58. -FrameSize());
  59. OldTime := TimC();
  60. OldSize := HeapLast - HeapLowerBound;
  61. LispVar GCKnt!* := LispVar GCKnt!* + 1;
  62. OldHeapLast := HeapLast;
  63. HeapLast := OldHeapLowerBound;
  64. Tmp1 := HeapLowerBound;
  65. Tmp2 := HeapUpperBound;
  66. HeapLowerBound := OldHeapLowerBound;
  67. HeapUpperBound := OldHeapUpperBound;
  68. OldHeapLowerBound := Tmp1;
  69. OldHeapUpperBound := Tmp2;
  70. CopyFromAllBases();
  71. MakeIDFreeList();
  72. AfterGCSystemHook();
  73. OldTime := TimC() - OldTime;
  74. LispVar GCTime!* := Plus2(LispVar GCTime!*, OldTime);
  75. if LispVar !*GC then GCStats();
  76. HeapTrapped := NIL;
  77. if IntInf Known!-Free!-Space() < IntInf (LispVar Heap!-Warning!-Level) then
  78. ContinuableError(99, "Heap space low", NIL)
  79. >>;
  80. syslsp procedure MarkAndCopyFromID X;
  81. % SymNam has to be copied before marking, since the mark destroys the tag
  82. % No problem since it's only a string, can't reference itself.
  83. << CopyFromBase &SymNam X;
  84. MarkID X;
  85. CopyFromBase &SymPrp X;
  86. CopyFromBase &SymVal X >>;
  87. syslsp procedure CopyFromAllBases();
  88. begin scalar LastSymbol, B;
  89. MarkAndCopyFromID 128; % Mark NIL first
  90. for I := 0 step 1 until 127 do
  91. if not MarkedID I then MarkAndCopyFromID I;
  92. for I := 0 step 1 until MaxObArray do
  93. << B := ObArray I;
  94. if B > 0 and not MarkedID B then MarkAndCopyFromID B >>;
  95. B := BndStkLowerBound;
  96. while << B := AdjustBndStkPtr(B, 1);
  97. B <= BndStkPtr >> do
  98. CopyFromBase B;
  99. for I := StackLowerBound step StackDirection*AddressingUnitsPerItem
  100. until StackLast do
  101. CopyFromBase I;
  102. end;
  103. syslsp procedure CopyFromRange(Lo, Hi);
  104. begin scalar X, I;
  105. X := Lo;
  106. I := 0;
  107. while X <= Hi do
  108. << CopyFromBase X;
  109. I := I + 1;
  110. X := &Lo[I] >>;
  111. end;
  112. syslsp procedure CopyFromBase P;
  113. @P := CopyItem @P;
  114. syslsp procedure CopyItem X;
  115. begin scalar Typ, Info, Hdr;
  116. Typ := Tag X;
  117. if not PointerTagP Typ then return
  118. << if Typ = ID and not null X then % don't follow NIL, for speed
  119. << Info := IDInf X;
  120. if not MarkedID Info then MarkAndCopyFromID Info >>;
  121. X >>;
  122. Info := Inf X;
  123. if not WithinOldHeapPointer Info then return X;
  124. Hdr := @Info;
  125. if Marked Hdr then return MkItem(Typ, Inf Hdr);
  126. return CopyItem1 X;
  127. end;
  128. syslsp procedure CopyItem1 S; % Copier for GC
  129. begin scalar NewS, Len, Ptr, StripS;
  130. return case Tag S of
  131. PAIR:
  132. << Ptr := car S;
  133. Rplaca(S, Mark(NewS := GtHeap PairPack()));
  134. NewS[1] := CopyItem cdr S;
  135. NewS[0] := CopyItem Ptr;
  136. MkPAIR NewS >>;
  137. STR:
  138. << @StrInf S := Mark(NewS := CopyString S);
  139. NewS >>;
  140. VECT:
  141. << StripS := VecInf S;
  142. Len := VecLen StripS;
  143. @StripS := Mark(Ptr := GtVECT Len);
  144. for I := 0 step 1 until Len do
  145. VecItm(Ptr, I) := CopyItem VecItm(StripS, I);
  146. MkVEC Ptr >>;
  147. EVECT:
  148. << StripS := VecInf S;
  149. Len := VecLen StripS;
  150. @StripS := Mark(Ptr := GtVECT Len);
  151. for I := 0 step 1 until Len do
  152. VecItm(Ptr, I) := CopyItem VecItm(StripS, I);
  153. MkItem(EVECT, Ptr) >>;
  154. WRDS, FIXN, FLTN, BIGN:
  155. << Ptr := Tag S;
  156. @Inf S := Mark(NewS := CopyWRDS S);
  157. MkItem(Ptr, NewS) >>;
  158. default:
  159. FatalError "Unexpected tag found during garbage collection";
  160. end;
  161. end;
  162. syslsp procedure MakeIDFreeList();
  163. begin scalar Previous;
  164. for I := 0 step 1 until 128 do
  165. ClearIDMark I;
  166. Previous := 129;
  167. while MarkedID Previous and Previous <= MaxSymbols do
  168. << ClearIDMark Previous;
  169. Previous := Previous + 1 >>;
  170. if Previous >= MaxSymbols then
  171. NextSymbol := 0
  172. else
  173. NextSymbol := Previous; % free list starts here
  174. for I := Previous + 1 step 1 until MaxSymbols do
  175. if MarkedID I then ClearIDMark I
  176. else
  177. << SymNam Previous := I;
  178. Previous := I >>;
  179. SymNam Previous := 0; % end of free list
  180. end;
  181. syslsp procedure GCStats();
  182. << ErrorPrintF("*** GC %w: time %d ms, %d recovered, %d free",
  183. LispVar GCKnt!*, OldTime,
  184. (OldSize - (HeapLast - HeapLowerBound))/AddressingUnitsPerItem,
  185. Known!-Free!-Space() ) >>;
  186. off SysLisp;
  187. END;