]>
Commit | Line | Data |
---|---|---|
73ffefd0 TT |
1 | /* |
2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. | |
3 | * | |
4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED | |
5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. | |
6 | * | |
7 | * Permission is hereby granted to use or copy this program | |
8 | * for any purpose, provided the above notices are retained on all copies. | |
9 | * Permission to modify the code and to distribute modified code is granted, | |
10 | * provided the above notices are retained, and a notice that the code was | |
11 | * modified is included with the above copyright notice. | |
12 | */ | |
9110a741 | 13 | # include "private/gc_priv.h" |
73ffefd0 TT |
14 | |
15 | # ifdef PCR | |
16 | /* | |
17 | * Note that POSIX PCR requires an ANSI C compiler. Hence we are allowed | |
18 | * to make the same assumption here. | |
19 | * We wrap all of the allocator functions to avoid questions of | |
20 | * compatibility between the prototyped and nonprototyped versions of the f | |
21 | */ | |
22 | # include "config/PCR_StdTypes.h" | |
23 | # include "mm/PCR_MM.h" | |
24 | # include <errno.h> | |
25 | ||
26 | # define MY_MAGIC 17L | |
27 | # define MY_DEBUGMAGIC 42L | |
28 | ||
29 | void * GC_AllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear ) | |
30 | { | |
31 | if (ptrFree) { | |
32 | void * result = (void *)GC_malloc_atomic(size); | |
33 | if (clear && result != 0) BZERO(result, size); | |
34 | return(result); | |
35 | } else { | |
36 | return((void *)GC_malloc(size)); | |
37 | } | |
38 | } | |
39 | ||
40 | void * GC_DebugAllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear ) | |
41 | { | |
42 | if (ptrFree) { | |
43 | void * result = (void *)GC_debug_malloc_atomic(size, __FILE__, | |
44 | __LINE__); | |
45 | if (clear && result != 0) BZERO(result, size); | |
46 | return(result); | |
47 | } else { | |
48 | return((void *)GC_debug_malloc(size, __FILE__, __LINE__)); | |
49 | } | |
50 | } | |
51 | ||
52 | # define GC_ReallocProc GC_realloc | |
53 | void * GC_DebugReallocProc(void * old_object, size_t new_size_in_bytes) | |
54 | { | |
55 | return(GC_debug_realloc(old_object, new_size_in_bytes, __FILE__, __LINE__)); | |
56 | } | |
57 | ||
58 | # define GC_FreeProc GC_free | |
59 | # define GC_DebugFreeProc GC_debug_free | |
60 | ||
61 | typedef struct { | |
62 | PCR_ERes (*ed_proc)(void *p, size_t size, PCR_Any data); | |
63 | GC_bool ed_pointerfree; | |
64 | PCR_ERes ed_fail_code; | |
65 | PCR_Any ed_client_data; | |
66 | } enumerate_data; | |
67 | ||
68 | void GC_enumerate_block(h, ed) | |
69 | register struct hblk *h; | |
70 | enumerate_data * ed; | |
71 | { | |
72 | register hdr * hhdr; | |
73 | register int sz; | |
74 | word *p; | |
75 | word * lim; | |
76 | ||
77 | hhdr = HDR(h); | |
78 | sz = hhdr -> hb_sz; | |
79 | if (sz >= 0 && ed -> ed_pointerfree | |
80 | || sz <= 0 && !(ed -> ed_pointerfree)) return; | |
81 | if (sz < 0) sz = -sz; | |
82 | lim = (word *)(h+1) - sz; | |
83 | p = (word *)h; | |
84 | do { | |
85 | if (PCR_ERes_IsErr(ed -> ed_fail_code)) return; | |
86 | ed -> ed_fail_code = | |
87 | (*(ed -> ed_proc))(p, WORDS_TO_BYTES(sz), ed -> ed_client_data); | |
88 | p+= sz; | |
89 | } while (p <= lim); | |
90 | } | |
91 | ||
92 | struct PCR_MM_ProcsRep * GC_old_allocator = 0; | |
93 | ||
94 | PCR_ERes GC_EnumerateProc( | |
95 | PCR_Bool ptrFree, | |
96 | PCR_ERes (*proc)(void *p, size_t size, PCR_Any data), | |
97 | PCR_Any data | |
98 | ) | |
99 | { | |
100 | enumerate_data ed; | |
101 | ||
102 | ed.ed_proc = proc; | |
103 | ed.ed_pointerfree = ptrFree; | |
104 | ed.ed_fail_code = PCR_ERes_okay; | |
105 | ed.ed_client_data = data; | |
106 | GC_apply_to_all_blocks(GC_enumerate_block, &ed); | |
107 | if (ed.ed_fail_code != PCR_ERes_okay) { | |
108 | return(ed.ed_fail_code); | |
109 | } else { | |
110 | /* Also enumerate objects allocated by my predecessors */ | |
111 | return((*(GC_old_allocator->mmp_enumerate))(ptrFree, proc, data)); | |
112 | } | |
113 | } | |
114 | ||
115 | void GC_DummyFreeProc(void *p) {} | |
116 | ||
117 | void GC_DummyShutdownProc(void) {} | |
118 | ||
119 | struct PCR_MM_ProcsRep GC_Rep = { | |
120 | MY_MAGIC, | |
121 | GC_AllocProc, | |
122 | GC_ReallocProc, | |
123 | GC_DummyFreeProc, /* mmp_free */ | |
124 | GC_FreeProc, /* mmp_unsafeFree */ | |
125 | GC_EnumerateProc, | |
126 | GC_DummyShutdownProc /* mmp_shutdown */ | |
127 | }; | |
128 | ||
129 | struct PCR_MM_ProcsRep GC_DebugRep = { | |
130 | MY_DEBUGMAGIC, | |
131 | GC_DebugAllocProc, | |
132 | GC_DebugReallocProc, | |
133 | GC_DummyFreeProc, /* mmp_free */ | |
134 | GC_DebugFreeProc, /* mmp_unsafeFree */ | |
135 | GC_EnumerateProc, | |
136 | GC_DummyShutdownProc /* mmp_shutdown */ | |
137 | }; | |
138 | ||
139 | GC_bool GC_use_debug = 0; | |
140 | ||
141 | void GC_pcr_install() | |
142 | { | |
143 | PCR_MM_Install((GC_use_debug? &GC_DebugRep : &GC_Rep), &GC_old_allocator); | |
144 | } | |
145 | ||
146 | PCR_ERes | |
147 | PCR_GC_Setup(void) | |
148 | { | |
149 | return PCR_ERes_okay; | |
150 | } | |
151 | ||
152 | PCR_ERes | |
153 | PCR_GC_Run(void) | |
154 | { | |
155 | ||
156 | if( !PCR_Base_TestPCRArg("-nogc") ) { | |
157 | GC_quiet = ( PCR_Base_TestPCRArg("-gctrace") ? 0 : 1 ); | |
158 | GC_use_debug = (GC_bool)PCR_Base_TestPCRArg("-debug_alloc"); | |
159 | GC_init(); | |
160 | if( !PCR_Base_TestPCRArg("-nogc_incremental") ) { | |
161 | /* | |
162 | * awful hack to test whether VD is implemented ... | |
163 | */ | |
164 | if( PCR_VD_Start( 0, NIL, 0) != PCR_ERes_FromErr(ENOSYS) ) { | |
165 | GC_enable_incremental(); | |
166 | } | |
167 | } | |
168 | } | |
169 | return PCR_ERes_okay; | |
170 | } | |
171 | ||
9110a741 BM |
172 | void GC_push_thread_structures(void) |
173 | { | |
174 | /* PCR doesn't work unless static roots are pushed. Can't get here. */ | |
175 | ABORT("In GC_push_thread_structures()"); | |
176 | } | |
177 | ||
73ffefd0 | 178 | # endif |