Annotation of OpenXM_contrib2/asir2000/gc/include/gc_alloc.h, Revision 1.5
1.1 noro 1: /*
2: * Copyright (c) 1996-1998 by Silicon Graphics. 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: */
13:
14: //
15: // This is a C++ header file that is intended to replace the SGI STL
1.2 noro 16: // alloc.h. This assumes SGI STL version < 3.0.
1.1 noro 17: //
18: // This assumes the collector has been compiled with -DATOMIC_UNCOLLECTABLE
19: // and -DALL_INTERIOR_POINTERS. We also recommend
20: // -DREDIRECT_MALLOC=GC_uncollectable_malloc.
21: //
22: // Some of this could be faster in the explicit deallocation case. In particular,
23: // we spend too much time clearing objects on the free lists. That could be avoided.
24: //
25: // This uses template classes with static members, and hence does not work
26: // with g++ 2.7.2 and earlier.
27: //
1.3 noro 28: // This code assumes that the collector itself has been compiled with a
29: // compiler that defines __STDC__ .
30: //
1.1 noro 31:
32: #include "gc.h"
33:
34: #ifndef GC_ALLOC_H
35:
36: #define GC_ALLOC_H
37: #define __ALLOC_H // Prevent inclusion of the default version. Ugly.
38: #define __SGI_STL_ALLOC_H
39: #define __SGI_STL_INTERNAL_ALLOC_H
40:
41: #ifndef __ALLOC
42: # define __ALLOC alloc
43: #endif
44:
45: #include <stddef.h>
46: #include <string.h>
47:
48: // The following is just replicated from the conventional SGI alloc.h:
49:
50: template<class T, class alloc>
51: class simple_alloc {
52:
53: public:
54: static T *allocate(size_t n)
55: { return 0 == n? 0 : (T*) alloc::allocate(n * sizeof (T)); }
56: static T *allocate(void)
57: { return (T*) alloc::allocate(sizeof (T)); }
58: static void deallocate(T *p, size_t n)
59: { if (0 != n) alloc::deallocate(p, n * sizeof (T)); }
60: static void deallocate(T *p)
61: { alloc::deallocate(p, sizeof (T)); }
62: };
63:
64: #include "gc.h"
65:
66: // The following need to match collector data structures.
67: // We can't include gc_priv.h, since that pulls in way too much stuff.
68: // This should eventually be factored out into another include file.
69:
70: extern "C" {
71: extern void ** const GC_objfreelist_ptr;
72: extern void ** const GC_aobjfreelist_ptr;
73: extern void ** const GC_uobjfreelist_ptr;
74: extern void ** const GC_auobjfreelist_ptr;
75:
76: extern void GC_incr_words_allocd(size_t words);
77: extern void GC_incr_mem_freed(size_t words);
78:
79: extern char * GC_generic_malloc_words_small(size_t word, int kind);
80: }
81:
82: // Object kinds; must match PTRFREE, NORMAL, UNCOLLECTABLE, and
83: // AUNCOLLECTABLE in gc_priv.h.
84:
85: enum { GC_PTRFREE = 0, GC_NORMAL = 1, GC_UNCOLLECTABLE = 2,
86: GC_AUNCOLLECTABLE = 3 };
87:
88: enum { GC_max_fast_bytes = 255 };
89:
90: enum { GC_bytes_per_word = sizeof(char *) };
91:
92: enum { GC_byte_alignment = 8 };
93:
94: enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word };
95:
96: inline void * &GC_obj_link(void * p)
97: { return *(void **)p; }
98:
99: // Compute a number of words >= n+1 bytes.
100: // The +1 allows for pointers one past the end.
101: inline size_t GC_round_up(size_t n)
102: {
103: return ((n + GC_byte_alignment)/GC_byte_alignment)*GC_word_alignment;
104: }
105:
106: // The same but don't allow for extra byte.
107: inline size_t GC_round_up_uncollectable(size_t n)
108: {
109: return ((n + GC_byte_alignment - 1)/GC_byte_alignment)*GC_word_alignment;
110: }
111:
112: template <int dummy>
113: class GC_aux_template {
114: public:
115: // File local count of allocated words. Occasionally this is
116: // added into the global count. A separate count is necessary since the
117: // real one must be updated with a procedure call.
118: static size_t GC_words_recently_allocd;
119:
120: // Same for uncollectable mmory. Not yet reflected in either
121: // GC_words_recently_allocd or GC_non_gc_bytes.
122: static size_t GC_uncollectable_words_recently_allocd;
123:
124: // Similar counter for explicitly deallocated memory.
125: static size_t GC_mem_recently_freed;
126:
127: // Again for uncollectable memory.
128: static size_t GC_uncollectable_mem_recently_freed;
129:
130: static void * GC_out_of_line_malloc(size_t nwords, int kind);
131: };
132:
133: template <int dummy>
134: size_t GC_aux_template<dummy>::GC_words_recently_allocd = 0;
135:
136: template <int dummy>
137: size_t GC_aux_template<dummy>::GC_uncollectable_words_recently_allocd = 0;
138:
139: template <int dummy>
140: size_t GC_aux_template<dummy>::GC_mem_recently_freed = 0;
141:
142: template <int dummy>
143: size_t GC_aux_template<dummy>::GC_uncollectable_mem_recently_freed = 0;
144:
145: template <int dummy>
146: void * GC_aux_template<dummy>::GC_out_of_line_malloc(size_t nwords, int kind)
147: {
148: GC_words_recently_allocd += GC_uncollectable_words_recently_allocd;
149: GC_non_gc_bytes +=
150: GC_bytes_per_word * GC_uncollectable_words_recently_allocd;
151: GC_uncollectable_words_recently_allocd = 0;
152:
153: GC_mem_recently_freed += GC_uncollectable_mem_recently_freed;
154: GC_non_gc_bytes -=
155: GC_bytes_per_word * GC_uncollectable_mem_recently_freed;
156: GC_uncollectable_mem_recently_freed = 0;
157:
158: GC_incr_words_allocd(GC_words_recently_allocd);
159: GC_words_recently_allocd = 0;
160:
161: GC_incr_mem_freed(GC_mem_recently_freed);
162: GC_mem_recently_freed = 0;
163:
164: return GC_generic_malloc_words_small(nwords, kind);
165: }
166:
167: typedef GC_aux_template<0> GC_aux;
168:
169: // A fast, single-threaded, garbage-collected allocator
170: // We assume the first word will be immediately overwritten.
171: // In this version, deallocation is not a noop, and explicit
172: // deallocation is likely to help performance.
173: template <int dummy>
174: class single_client_gc_alloc_template {
175: public:
176: static void * allocate(size_t n)
177: {
178: size_t nwords = GC_round_up(n);
179: void ** flh;
180: void * op;
181:
182: if (n > GC_max_fast_bytes) return GC_malloc(n);
183: flh = GC_objfreelist_ptr + nwords;
184: if (0 == (op = *flh)) {
185: return GC_aux::GC_out_of_line_malloc(nwords, GC_NORMAL);
186: }
187: *flh = GC_obj_link(op);
188: GC_aux::GC_words_recently_allocd += nwords;
189: return op;
190: }
191: static void * ptr_free_allocate(size_t n)
192: {
193: size_t nwords = GC_round_up(n);
194: void ** flh;
195: void * op;
196:
197: if (n > GC_max_fast_bytes) return GC_malloc_atomic(n);
198: flh = GC_aobjfreelist_ptr + nwords;
199: if (0 == (op = *flh)) {
200: return GC_aux::GC_out_of_line_malloc(nwords, GC_PTRFREE);
201: }
202: *flh = GC_obj_link(op);
203: GC_aux::GC_words_recently_allocd += nwords;
204: return op;
205: }
206: static void deallocate(void *p, size_t n)
207: {
208: size_t nwords = GC_round_up(n);
209: void ** flh;
210:
211: if (n > GC_max_fast_bytes) {
212: GC_free(p);
213: } else {
214: flh = GC_objfreelist_ptr + nwords;
215: GC_obj_link(p) = *flh;
216: memset((char *)p + GC_bytes_per_word, 0,
217: GC_bytes_per_word * (nwords - 1));
218: *flh = p;
219: GC_aux::GC_mem_recently_freed += nwords;
220: }
221: }
222: static void ptr_free_deallocate(void *p, size_t n)
223: {
224: size_t nwords = GC_round_up(n);
225: void ** flh;
226:
227: if (n > GC_max_fast_bytes) {
228: GC_free(p);
229: } else {
230: flh = GC_aobjfreelist_ptr + nwords;
231: GC_obj_link(p) = *flh;
232: *flh = p;
233: GC_aux::GC_mem_recently_freed += nwords;
234: }
235: }
236: };
237:
238: typedef single_client_gc_alloc_template<0> single_client_gc_alloc;
239:
240: // Once more, for uncollectable objects.
241: template <int dummy>
242: class single_client_alloc_template {
243: public:
244: static void * allocate(size_t n)
245: {
246: size_t nwords = GC_round_up_uncollectable(n);
247: void ** flh;
248: void * op;
249:
250: if (n > GC_max_fast_bytes) return GC_malloc_uncollectable(n);
251: flh = GC_uobjfreelist_ptr + nwords;
252: if (0 == (op = *flh)) {
253: return GC_aux::GC_out_of_line_malloc(nwords, GC_UNCOLLECTABLE);
254: }
255: *flh = GC_obj_link(op);
256: GC_aux::GC_uncollectable_words_recently_allocd += nwords;
257: return op;
258: }
259: static void * ptr_free_allocate(size_t n)
260: {
261: size_t nwords = GC_round_up_uncollectable(n);
262: void ** flh;
263: void * op;
264:
265: if (n > GC_max_fast_bytes) return GC_malloc_atomic_uncollectable(n);
266: flh = GC_auobjfreelist_ptr + nwords;
267: if (0 == (op = *flh)) {
268: return GC_aux::GC_out_of_line_malloc(nwords, GC_AUNCOLLECTABLE);
269: }
270: *flh = GC_obj_link(op);
271: GC_aux::GC_uncollectable_words_recently_allocd += nwords;
272: return op;
273: }
274: static void deallocate(void *p, size_t n)
275: {
276: size_t nwords = GC_round_up_uncollectable(n);
277: void ** flh;
278:
279: if (n > GC_max_fast_bytes) {
280: GC_free(p);
281: } else {
282: flh = GC_uobjfreelist_ptr + nwords;
283: GC_obj_link(p) = *flh;
284: *flh = p;
285: GC_aux::GC_uncollectable_mem_recently_freed += nwords;
286: }
287: }
288: static void ptr_free_deallocate(void *p, size_t n)
289: {
290: size_t nwords = GC_round_up_uncollectable(n);
291: void ** flh;
292:
293: if (n > GC_max_fast_bytes) {
294: GC_free(p);
295: } else {
296: flh = GC_auobjfreelist_ptr + nwords;
297: GC_obj_link(p) = *flh;
298: *flh = p;
299: GC_aux::GC_uncollectable_mem_recently_freed += nwords;
300: }
301: }
302: };
303:
304: typedef single_client_alloc_template<0> single_client_alloc;
305:
306: template < int dummy >
307: class gc_alloc_template {
308: public:
309: static void * allocate(size_t n) { return GC_malloc(n); }
310: static void * ptr_free_allocate(size_t n)
311: { return GC_malloc_atomic(n); }
312: static void deallocate(void *, size_t) { }
313: static void ptr_free_deallocate(void *, size_t) { }
314: };
315:
316: typedef gc_alloc_template < 0 > gc_alloc;
317:
318: template < int dummy >
319: class alloc_template {
320: public:
321: static void * allocate(size_t n) { return GC_malloc_uncollectable(n); }
322: static void * ptr_free_allocate(size_t n)
323: { return GC_malloc_atomic_uncollectable(n); }
324: static void deallocate(void *p, size_t) { GC_free(p); }
325: static void ptr_free_deallocate(void *p, size_t) { GC_free(p); }
326: };
327:
328: typedef alloc_template < 0 > alloc;
329:
330: #ifdef _SGI_SOURCE
331:
332: // We want to specialize simple_alloc so that it does the right thing
333: // for all pointerfree types. At the moment there is no portable way to
334: // even approximate that. The following approximation should work for
335: // SGI compilers, and perhaps some others.
336:
337: # define __GC_SPECIALIZE(T,alloc) \
338: class simple_alloc<T, alloc> { \
339: public: \
340: static T *allocate(size_t n) \
341: { return 0 == n? 0 : \
342: (T*) alloc::ptr_free_allocate(n * sizeof (T)); } \
343: static T *allocate(void) \
344: { return (T*) alloc::ptr_free_allocate(sizeof (T)); } \
345: static void deallocate(T *p, size_t n) \
346: { if (0 != n) alloc::ptr_free_deallocate(p, n * sizeof (T)); } \
347: static void deallocate(T *p) \
348: { alloc::ptr_free_deallocate(p, sizeof (T)); } \
349: };
350:
351: __GC_SPECIALIZE(char, gc_alloc)
352: __GC_SPECIALIZE(int, gc_alloc)
353: __GC_SPECIALIZE(unsigned, gc_alloc)
354: __GC_SPECIALIZE(float, gc_alloc)
355: __GC_SPECIALIZE(double, gc_alloc)
356:
357: __GC_SPECIALIZE(char, alloc)
358: __GC_SPECIALIZE(int, alloc)
359: __GC_SPECIALIZE(unsigned, alloc)
360: __GC_SPECIALIZE(float, alloc)
361: __GC_SPECIALIZE(double, alloc)
362:
363: __GC_SPECIALIZE(char, single_client_gc_alloc)
364: __GC_SPECIALIZE(int, single_client_gc_alloc)
365: __GC_SPECIALIZE(unsigned, single_client_gc_alloc)
366: __GC_SPECIALIZE(float, single_client_gc_alloc)
367: __GC_SPECIALIZE(double, single_client_gc_alloc)
368:
369: __GC_SPECIALIZE(char, single_client_alloc)
370: __GC_SPECIALIZE(int, single_client_alloc)
371: __GC_SPECIALIZE(unsigned, single_client_alloc)
372: __GC_SPECIALIZE(float, single_client_alloc)
373: __GC_SPECIALIZE(double, single_client_alloc)
374:
375: #ifdef __STL_USE_STD_ALLOCATORS
376:
377: ???copy stuff from stl_alloc.h or remove it to a different file ???
378:
379: #endif /* __STL_USE_STD_ALLOCATORS */
380:
381: #endif /* _SGI_SOURCE */
382:
383: #endif /* GC_ALLOC_H */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>