Mercurial > emacs
comparison gc/MacOS.c @ 51488:5de98dce4bd1
*** empty log message ***
author | Dave Love <fx@gnu.org> |
---|---|
date | Thu, 05 Jun 2003 17:49:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
51487:01d68b199093 | 51488:5de98dce4bd1 |
---|---|
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 } | |
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) */ |