4 Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers
9 11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode.
10 11/30/94 pcb Tracking all memory usage so we can deallocate it all at once.
11 02/10/96 pcb Added routine to perform a final collection when
12 unloading shared library.
16 /* Boehm, February 15, 1996 2:55 pm PST */
20 #include <Resources.h>
30 // use 'CODE' resource 0 to get exact location of the beginning of global space.
33 unsigned long aboveA5;
34 unsigned long belowA5;
36 unsigned long JTOffset;
37 } *CodeZeroPtr, **CodeZeroHandle;
39 void* GC_MacGetDataStart()
41 CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
43 long belowA5Size = (**code0).belowA5;
44 ReleaseResource((Handle)code0);
45 return (LMGetCurrentA5() - belowA5Size);
47 fprintf(stderr, "Couldn't load the jump table.");
52 /* track the use of temporary memory so it can be freed all at once. */
54 typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
56 struct TemporaryMemoryBlock {
57 TemporaryMemoryHandle nextBlock;
61 static TemporaryMemoryHandle theTemporaryMemory = NULL;
62 static Boolean firstTime = true;
64 void GC_MacFreeTemporaryMemory(void);
66 Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
68 static Boolean firstTime = true;
70 TemporaryMemoryHandle tempMemBlock;
73 tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result);
74 if (tempMemBlock && result == noErr) {
75 HLockHi((Handle)tempMemBlock);
76 tempPtr = (**tempMemBlock).data;
77 if (clearMemory) memset(tempPtr, 0, size);
78 tempPtr = StripAddress(tempPtr);
80 // keep track of the allocated blocks.
81 (**tempMemBlock).nextBlock = theTemporaryMemory;
82 theTemporaryMemory = tempMemBlock;
85 # if !defined(SHARED_LIBRARY_BUILD)
86 // install an exit routine to clean up the memory used at the end.
88 atexit(&GC_MacFreeTemporaryMemory);
96 extern word GC_fo_entries;
98 static void perform_final_collection()
101 word last_fo_entries = 0;
103 /* adjust the stack bottom, because CFM calls us from another stack
105 GC_stackbottom = (ptr_t)&i;
107 /* try to collect and finalize everything in sight */
108 for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) {
109 last_fo_entries = GC_fo_entries;
115 void GC_MacFreeTemporaryMemory()
117 # if defined(SHARED_LIBRARY_BUILD)
118 /* if possible, collect all memory, and invoke all finalizers. */
119 perform_final_collection();
122 if (theTemporaryMemory != NULL) {
123 long totalMemoryUsed = 0;
124 TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
125 while (tempMemBlock != NULL) {
126 TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
127 totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
128 DisposeHandle((Handle)tempMemBlock);
129 tempMemBlock = nextBlock;
131 theTemporaryMemory = NULL;
133 # if !defined(SHARED_LIBRARY_BUILD)
134 if (GC_print_stats) {
135 fprintf(stdout, "[total memory used: %ld bytes.]\n",
137 fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no);
143 #if __option(far_data)
145 void* GC_MacGetDataEnd()
147 CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
149 long aboveA5Size = (**code0).aboveA5;
150 ReleaseResource((Handle)code0);
151 return (LMGetCurrentA5() + aboveA5Size);
153 fprintf(stderr, "Couldn't load the jump table.");
158 #endif /* __option(far_data) */