[BACK]Return to gc_alloc.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc / include

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>