MacOS.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #include "gc.h"
  20. #include "gc_priv.h"
  21. // use 'CODE' resource 0 to get exact location of the beginning of global space.
  22. typedef struct {
  23. unsigned long aboveA5;
  24. unsigned long belowA5;
  25. unsigned long JTSize;
  26. unsigned long JTOffset;
  27. } *CodeZeroPtr, **CodeZeroHandle;
  28. void* GC_MacGetDataStart()
  29. {
  30. CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
  31. if (code0) {
  32. long belowA5Size = (**code0).belowA5;
  33. ReleaseResource((Handle)code0);
  34. return (LMGetCurrentA5() - belowA5Size);
  35. }
  36. fprintf(stderr, "Couldn't load the jump table.");
  37. exit(-1);
  38. return 0;
  39. }
  40. /* track the use of temporary memory so it can be freed all at once. */
  41. typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
  42. struct TemporaryMemoryBlock {
  43. TemporaryMemoryHandle nextBlock;
  44. char data[];
  45. };
  46. static TemporaryMemoryHandle theTemporaryMemory = NULL;
  47. static Boolean firstTime = true;
  48. void GC_MacFreeTemporaryMemory(void);
  49. Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
  50. {
  51. static Boolean firstTime = true;
  52. OSErr result;
  53. TemporaryMemoryHandle tempMemBlock;
  54. Ptr tempPtr = nil;
  55. tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result);
  56. if (tempMemBlock && result == noErr) {
  57. HLockHi((Handle)tempMemBlock);
  58. tempPtr = (**tempMemBlock).data;
  59. if (clearMemory) memset(tempPtr, 0, size);
  60. tempPtr = StripAddress(tempPtr);
  61. // keep track of the allocated blocks.
  62. (**tempMemBlock).nextBlock = theTemporaryMemory;
  63. theTemporaryMemory = tempMemBlock;
  64. }
  65. # if !defined(SHARED_LIBRARY_BUILD)
  66. // install an exit routine to clean up the memory used at the end.
  67. if (firstTime) {
  68. atexit(&GC_MacFreeTemporaryMemory);
  69. firstTime = false;
  70. }
  71. # endif
  72. return tempPtr;
  73. }
  74. extern word GC_fo_entries;
  75. static void perform_final_collection()
  76. {
  77. unsigned i;
  78. word last_fo_entries = 0;
  79. /* adjust the stack bottom, because CFM calls us from another stack
  80. location. */
  81. GC_stackbottom = (ptr_t)&i;
  82. /* try to collect and finalize everything in sight */
  83. for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) {
  84. last_fo_entries = GC_fo_entries;
  85. GC_gcollect();
  86. }
  87. }
  88. void GC_MacFreeTemporaryMemory()
  89. {
  90. # if defined(SHARED_LIBRARY_BUILD)
  91. /* if possible, collect all memory, and invoke all finalizers. */
  92. perform_final_collection();
  93. # endif
  94. if (theTemporaryMemory != NULL) {
  95. long totalMemoryUsed = 0;
  96. TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
  97. while (tempMemBlock != NULL) {
  98. TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
  99. totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
  100. DisposeHandle((Handle)tempMemBlock);
  101. tempMemBlock = nextBlock;
  102. }
  103. theTemporaryMemory = NULL;
  104. # if !defined(SILENT) && !defined(SHARED_LIBRARY_BUILD)
  105. fprintf(stdout, "[total memory used: %ld bytes.]\n",
  106. totalMemoryUsed);
  107. fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no);
  108. # endif
  109. }
  110. }
  111. #if __option(far_data)
  112. void* GC_MacGetDataEnd()
  113. {
  114. CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
  115. if (code0) {
  116. long aboveA5Size = (**code0).aboveA5;
  117. ReleaseResource((Handle)code0);
  118. return (LMGetCurrentA5() + aboveA5Size);
  119. }
  120. fprintf(stderr, "Couldn't load the jump table.");
  121. exit(-1);
  122. return 0;
  123. }
  124. #endif /* __option(far_data) */