MacOS.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. MacOS.c
  3. Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers
  4. garbage collector.
  5. <Revision History>
  6. 11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode.
  7. 11/30/94 pcb Tracking all memory usage so we can deallocate it all at once.
  8. 02/10/96 pcb Added routine to perform a final collection when
  9. unloading shared library.
  10. by Patrick C. Beard.
  11. */
  12. /* Boehm, February 15, 1996 2:55 pm PST */
  13. #include <Resources.h>
  14. #include <Memory.h>
  15. #include <LowMem.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #define GC_BUILD
  20. #include "gc.h"
  21. #include "private/gc_priv.h"
  22. /* use 'CODE' resource 0 to get exact location of the beginning of global space. */
  23. typedef struct {
  24. unsigned long aboveA5;
  25. unsigned long belowA5;
  26. unsigned long JTSize;
  27. unsigned long JTOffset;
  28. } *CodeZeroPtr, **CodeZeroHandle;
  29. void* GC_MacGetDataStart(void)
  30. {
  31. CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
  32. if (code0) {
  33. long belowA5Size = (**code0).belowA5;
  34. ReleaseResource((Handle)code0);
  35. return (LMGetCurrentA5() - belowA5Size);
  36. }
  37. fprintf(stderr, "Couldn't load the jump table.");
  38. exit(-1);
  39. return 0;
  40. }
  41. #ifdef USE_TEMPORARY_MEMORY
  42. /* track the use of temporary memory so it can be freed all at once. */
  43. typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
  44. struct TemporaryMemoryBlock {
  45. TemporaryMemoryHandle nextBlock;
  46. char data[];
  47. };
  48. static TemporaryMemoryHandle theTemporaryMemory = NULL;
  49. void GC_MacFreeTemporaryMemory(void);
  50. Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
  51. {
  52. # if !defined(SHARED_LIBRARY_BUILD)
  53. static Boolean firstTime = true;
  54. # endif
  55. OSErr result;
  56. TemporaryMemoryHandle tempMemBlock;
  57. Ptr tempPtr = nil;
  58. tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result);
  59. if (tempMemBlock && result == noErr) {
  60. HLockHi((Handle)tempMemBlock);
  61. tempPtr = (**tempMemBlock).data;
  62. if (clearMemory) memset(tempPtr, 0, size);
  63. tempPtr = StripAddress(tempPtr);
  64. /* keep track of the allocated blocks. */
  65. (**tempMemBlock).nextBlock = theTemporaryMemory;
  66. theTemporaryMemory = tempMemBlock;
  67. }
  68. # if !defined(SHARED_LIBRARY_BUILD)
  69. /* install an exit routine to clean up the memory used at the end. */
  70. if (firstTime) {
  71. atexit(&GC_MacFreeTemporaryMemory);
  72. firstTime = false;
  73. }
  74. # endif
  75. return tempPtr;
  76. }
  77. extern word GC_fo_entries;
  78. static void perform_final_collection(void)
  79. {
  80. unsigned i;
  81. word last_fo_entries = 0;
  82. /* adjust the stack bottom, because CFM calls us from another stack
  83. location. */
  84. GC_stackbottom = (ptr_t)&i;
  85. /* try to collect and finalize everything in sight */
  86. for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) {
  87. last_fo_entries = GC_fo_entries;
  88. GC_gcollect();
  89. }
  90. }
  91. void GC_MacFreeTemporaryMemory(void)
  92. {
  93. # if defined(SHARED_LIBRARY_BUILD)
  94. /* if possible, collect all memory, and invoke all finalizers. */
  95. perform_final_collection();
  96. # endif
  97. if (theTemporaryMemory != NULL) {
  98. # if !defined(SHARED_LIBRARY_BUILD)
  99. long totalMemoryUsed = 0;
  100. # endif
  101. TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
  102. while (tempMemBlock != NULL) {
  103. TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
  104. # if !defined(SHARED_LIBRARY_BUILD)
  105. totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
  106. # endif
  107. DisposeHandle((Handle)tempMemBlock);
  108. tempMemBlock = nextBlock;
  109. }
  110. theTemporaryMemory = NULL;
  111. # if !defined(SHARED_LIBRARY_BUILD)
  112. if (GC_print_stats) {
  113. fprintf(stdout, "[total memory used: %ld bytes.]\n",
  114. totalMemoryUsed);
  115. fprintf(stdout, "[total collections: %lu]\n",
  116. (unsigned long)GC_gc_no);
  117. }
  118. # endif
  119. }
  120. }
  121. #endif /* USE_TEMPORARY_MEMORY */
  122. #if __option(far_data)
  123. void* GC_MacGetDataEnd(void)
  124. {
  125. CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
  126. if (code0) {
  127. long aboveA5Size = (**code0).aboveA5;
  128. ReleaseResource((Handle)code0);
  129. return (LMGetCurrentA5() + aboveA5Size);
  130. }
  131. fprintf(stderr, "Couldn't load the jump table.");
  132. exit(-1);
  133. return 0;
  134. }
  135. #endif /* __option(far_data) */