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 */
18 #include <Resources.h>
28 // use 'CODE' resource 0 to get exact location of the beginning of global space.
31 unsigned long aboveA5
;
32 unsigned long belowA5
;
34 unsigned long JTOffset
;
35 } *CodeZeroPtr
, **CodeZeroHandle
;
37 void* GC_MacGetDataStart()
39 CodeZeroHandle code0
= (CodeZeroHandle
)GetResource('CODE', 0);
41 long belowA5Size
= (**code0
).belowA5
;
42 ReleaseResource((Handle
)code0
);
43 return (LMGetCurrentA5() - belowA5Size
);
45 fprintf(stderr
, "Couldn't load the jump table.");
50 /* track the use of temporary memory so it can be freed all at once. */
52 typedef struct TemporaryMemoryBlock TemporaryMemoryBlock
, **TemporaryMemoryHandle
;
54 struct TemporaryMemoryBlock
{
55 TemporaryMemoryHandle nextBlock
;
59 static TemporaryMemoryHandle theTemporaryMemory
= NULL
;
60 static Boolean firstTime
= true;
62 void GC_MacFreeTemporaryMemory(void);
64 Ptr
GC_MacTemporaryNewPtr(size_t size
, Boolean clearMemory
)
66 static Boolean firstTime
= true;
68 TemporaryMemoryHandle tempMemBlock
;
71 tempMemBlock
= (TemporaryMemoryHandle
)TempNewHandle(size
+ sizeof(TemporaryMemoryBlock
), &result
);
72 if (tempMemBlock
&& result
== noErr
) {
73 HLockHi((Handle
)tempMemBlock
);
74 tempPtr
= (**tempMemBlock
).data
;
75 if (clearMemory
) memset(tempPtr
, 0, size
);
76 tempPtr
= StripAddress(tempPtr
);
78 // keep track of the allocated blocks.
79 (**tempMemBlock
).nextBlock
= theTemporaryMemory
;
80 theTemporaryMemory
= tempMemBlock
;
83 # if !defined(SHARED_LIBRARY_BUILD)
84 // install an exit routine to clean up the memory used at the end.
86 atexit(&GC_MacFreeTemporaryMemory
);
94 extern word GC_fo_entries
;
96 static void perform_final_collection()
99 word last_fo_entries
= 0;
101 /* adjust the stack bottom, because CFM calls us from another stack
103 GC_stackbottom
= (ptr_t
)&i
;
105 /* try to collect and finalize everything in sight */
106 for (i
= 0; i
< 2 || GC_fo_entries
< last_fo_entries
; i
++) {
107 last_fo_entries
= GC_fo_entries
;
113 void GC_MacFreeTemporaryMemory()
115 # if defined(SHARED_LIBRARY_BUILD)
116 /* if possible, collect all memory, and invoke all finalizers. */
117 perform_final_collection();
120 if (theTemporaryMemory
!= NULL
) {
121 long totalMemoryUsed
= 0;
122 TemporaryMemoryHandle tempMemBlock
= theTemporaryMemory
;
123 while (tempMemBlock
!= NULL
) {
124 TemporaryMemoryHandle nextBlock
= (**tempMemBlock
).nextBlock
;
125 totalMemoryUsed
+= GetHandleSize((Handle
)tempMemBlock
);
126 DisposeHandle((Handle
)tempMemBlock
);
127 tempMemBlock
= nextBlock
;
129 theTemporaryMemory
= NULL
;
131 # if !defined(SILENT) && !defined(SHARED_LIBRARY_BUILD)
132 fprintf(stdout
, "[total memory used: %ld bytes.]\n",
134 fprintf(stdout
, "[total collections: %ld.]\n", GC_gc_no
);