]>
Commit | Line | Data |
---|---|---|
73ffefd0 TT |
1 | /* |
2 | MacOS.c | |
3 | ||
4 | Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers | |
5 | garbage collector. | |
6 | ||
7 | <Revision History> | |
8 | ||
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. | |
13 | ||
14 | by Patrick C. Beard. | |
15 | */ | |
16 | /* Boehm, February 15, 1996 2:55 pm PST */ | |
17 | ||
18 | #include <Resources.h> | |
19 | #include <Memory.h> | |
20 | #include <LowMem.h> | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | ||
25 | #include "gc.h" | |
26 | #include "gc_priv.h" | |
27 | ||
28 | // use 'CODE' resource 0 to get exact location of the beginning of global space. | |
29 | ||
30 | typedef struct { | |
31 | unsigned long aboveA5; | |
32 | unsigned long belowA5; | |
33 | unsigned long JTSize; | |
34 | unsigned long JTOffset; | |
35 | } *CodeZeroPtr, **CodeZeroHandle; | |
36 | ||
37 | void* GC_MacGetDataStart() | |
38 | { | |
39 | CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); | |
40 | if (code0) { | |
41 | long belowA5Size = (**code0).belowA5; | |
42 | ReleaseResource((Handle)code0); | |
43 | return (LMGetCurrentA5() - belowA5Size); | |
44 | } | |
45 | fprintf(stderr, "Couldn't load the jump table."); | |
46 | exit(-1); | |
47 | return 0; | |
48 | } | |
49 | ||
50 | /* track the use of temporary memory so it can be freed all at once. */ | |
51 | ||
52 | typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle; | |
53 | ||
54 | struct TemporaryMemoryBlock { | |
55 | TemporaryMemoryHandle nextBlock; | |
56 | char data[]; | |
57 | }; | |
58 | ||
59 | static TemporaryMemoryHandle theTemporaryMemory = NULL; | |
60 | static Boolean firstTime = true; | |
61 | ||
62 | void GC_MacFreeTemporaryMemory(void); | |
63 | ||
64 | Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory) | |
65 | { | |
66 | static Boolean firstTime = true; | |
67 | OSErr result; | |
68 | TemporaryMemoryHandle tempMemBlock; | |
69 | Ptr tempPtr = nil; | |
70 | ||
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); | |
77 | ||
78 | // keep track of the allocated blocks. | |
79 | (**tempMemBlock).nextBlock = theTemporaryMemory; | |
80 | theTemporaryMemory = tempMemBlock; | |
81 | } | |
82 | ||
83 | # if !defined(SHARED_LIBRARY_BUILD) | |
84 | // install an exit routine to clean up the memory used at the end. | |
85 | if (firstTime) { | |
86 | atexit(&GC_MacFreeTemporaryMemory); | |
87 | firstTime = false; | |
88 | } | |
89 | # endif | |
90 | ||
91 | return tempPtr; | |
92 | } | |
93 | ||
94 | extern word GC_fo_entries; | |
95 | ||
96 | static void perform_final_collection() | |
97 | { | |
98 | unsigned i; | |
99 | word last_fo_entries = 0; | |
100 | ||
101 | /* adjust the stack bottom, because CFM calls us from another stack | |
102 | location. */ | |
103 | GC_stackbottom = (ptr_t)&i; | |
104 | ||
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; | |
108 | GC_gcollect(); | |
109 | } | |
110 | } | |
111 | ||
112 | ||
113 | void GC_MacFreeTemporaryMemory() | |
114 | { | |
115 | # if defined(SHARED_LIBRARY_BUILD) | |
116 | /* if possible, collect all memory, and invoke all finalizers. */ | |
117 | perform_final_collection(); | |
118 | # endif | |
119 | ||
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; | |
128 | } | |
129 | theTemporaryMemory = NULL; | |
130 | ||
131 | # if !defined(SILENT) && !defined(SHARED_LIBRARY_BUILD) | |
132 | fprintf(stdout, "[total memory used: %ld bytes.]\n", | |
133 | totalMemoryUsed); | |
134 | fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no); | |
135 | # endif | |
136 | } | |
137 | } | |
20bbd3cd TT |
138 | |
139 | #if __option(far_data) | |
140 | ||
141 | void* GC_MacGetDataEnd() | |
142 | { | |
143 | CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); | |
144 | if (code0) { | |
145 | long aboveA5Size = (**code0).aboveA5; | |
146 | ReleaseResource((Handle)code0); | |
147 | return (LMGetCurrentA5() + aboveA5Size); | |
148 | } | |
149 | fprintf(stderr, "Couldn't load the jump table."); | |
150 | exit(-1); | |
151 | return 0; | |
152 | } | |
153 | ||
154 | #endif /* __option(far_data) */ |