Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
3.8 KiB

  1. /*****************************************************************************
  2. *
  3. * gc.c
  4. *
  5. * The garbage-collector.
  6. *
  7. *****************************************************************************/
  8. #include "m4.h"
  9. #ifndef Gc
  10. /*****************************************************************************
  11. *
  12. * WalkPv
  13. *
  14. * Mark an arbitrary object.
  15. *
  16. *****************************************************************************/
  17. void STDCALL
  18. WalkPv(PVOID pv)
  19. {
  20. if (pv) {
  21. PAR par = parPv(pv);
  22. Assert(par->tm == g_tmNow - 1);
  23. par->tm = g_tmNow;
  24. AssertPar(par); /* This catches double-references */
  25. }
  26. }
  27. /*****************************************************************************
  28. *
  29. * WalkPtok
  30. *
  31. * Walk a token. The token itself is not walked, but its contents are.
  32. * (Because tokens are typically embedded inside other objects.)
  33. *
  34. *****************************************************************************/
  35. void STDCALL
  36. WalkPtok(PTOK ptok)
  37. {
  38. if (ptok) {
  39. if (!fStaticPtok(ptok)) {
  40. Assert(fHeapPtok(ptok));
  41. WalkPv(ptchPtok(ptok));
  42. }
  43. }
  44. }
  45. /*****************************************************************************
  46. *
  47. * WalkPval
  48. *
  49. * Walk a value.
  50. *
  51. *****************************************************************************/
  52. void STDCALL
  53. WalkPval(PVAL pval)
  54. {
  55. if (pval) {
  56. WalkPv(pval);
  57. WalkPtok(&pval->tok);
  58. }
  59. }
  60. /*****************************************************************************
  61. *
  62. * WalkPmac
  63. *
  64. * Walk a macro.
  65. *
  66. *****************************************************************************/
  67. void STDCALL
  68. WalkPmac(PMAC pmac)
  69. {
  70. if (pmac) {
  71. PVAL pval;
  72. WalkPv(pmac);
  73. WalkPtok(&pmac->tokName);
  74. for (pval = pmac->pval; pval; pval = pval->pvalPrev) {
  75. WalkPval(pval);
  76. }
  77. }
  78. }
  79. /*****************************************************************************
  80. *
  81. * WalkPstm
  82. *
  83. * Walk a stream.
  84. *
  85. * The compiler knows how to optimize tail recursion.
  86. *
  87. *****************************************************************************/
  88. void STDCALL
  89. WalkPstm(PSTM pstm)
  90. {
  91. if (pstm) {
  92. WalkPv(pstm);
  93. WalkPv(pstm->ptchMin);
  94. WalkPv(pstm->ptchName);
  95. WalkPstm(pstm->pstmNext);
  96. }
  97. }
  98. /*****************************************************************************
  99. *
  100. * WalkPdiv
  101. *
  102. * Walk a diversion.
  103. *
  104. *****************************************************************************/
  105. void STDCALL
  106. WalkPdiv(PDIV pdiv)
  107. {
  108. if (pdiv) {
  109. WalkPv(pdiv);
  110. WalkPv(pdiv->ptchMin);
  111. WalkPv(pdiv->ptchName);
  112. }
  113. }
  114. /*****************************************************************************
  115. *
  116. * Sweep
  117. *
  118. * Sweep through memory, looking for garbage.
  119. *
  120. *****************************************************************************/
  121. void STDCALL
  122. Sweep(void)
  123. {
  124. PAR par;
  125. for (par = parHead->parNext; par != parHead; par = par->parNext) {
  126. Assert(par->tm == g_tmNow); /* Memory should have been walked! */
  127. }
  128. }
  129. /*****************************************************************************
  130. *
  131. * Gc
  132. *
  133. * The garbage collector is mark-and-sweep.
  134. *
  135. * Walk all the root objects, recursing into sub-objects, until everything
  136. * is marked with the current (fake) timestamp. Then walk through the
  137. * memory arenas. Anything not marked with the current timestamp is garbage.
  138. *
  139. *****************************************************************************/
  140. TM g_tmNow;
  141. void STDCALL
  142. Gc(void)
  143. {
  144. g_tmNow++;
  145. if (mphashpmac) {
  146. WalkPv(mphashpmac);
  147. EachMacroOp(WalkPmac);
  148. }
  149. WalkPv(rgtokArgv);
  150. WalkPv(rgcellEstack);
  151. WalkPstm(g_pstmCur);
  152. WalkPdiv(g_pdivArg);
  153. WalkPdiv(g_pdivExp);
  154. WalkPdiv(g_pdivOut);
  155. WalkPdiv(g_pdivErr);
  156. WalkPdiv(g_pdivNul);
  157. Sweep();
  158. }
  159. #endif