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

Annotation of OpenXM_contrib2/asir2000/gc/include/new_gc_alloc.h, Revision 1.3

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 revision of gc_alloc.h for SGI STL versions > 3.0
                     16: // Unlike earlier versions, it supplements the standard "alloc.h"
                     17: // instead of replacing it.
                     18: //
                     19: // This is sloppy about variable names used in header files.
                     20: // It also doesn't yet understand the new header file names or
                     21: // namespaces.
                     22: //
1.3     ! noro       23: // This assumes the collector has been compiled with -DATOMIC_UNCOLLECTABLE.
        !            24: // The user should also consider -DREDIRECT_MALLOC=GC_uncollectable_malloc,
        !            25: // to ensure that object allocated through malloc are traced.
1.1       noro       26: //
                     27: // Some of this could be faster in the explicit deallocation case.
                     28: // In particular, we spend too much time clearing objects on the
                     29: // free lists.  That could be avoided.
                     30: //
                     31: // This uses template classes with static members, and hence does not work
                     32: // with g++ 2.7.2 and earlier.
                     33: //
                     34: // Unlike its predecessor, this one simply defines
                     35: //     gc_alloc
                     36: //     single_client_gc_alloc
                     37: //     traceable_alloc
                     38: //     single_client_traceable_alloc
                     39: //
                     40: // It does not redefine alloc.  Nor does it change the default allocator,
                     41: // though the user may wish to do so.  (The argument against changing
                     42: // the default allocator is that it may introduce subtle link compatibility
                     43: // problems.  The argument for changing it is that the usual default
                     44: // allocator is usually a very bad choice for a garbage collected environment.)
                     45: //
1.3     ! noro       46: // This code assumes that the collector itself has been compiled with a
        !            47: // compiler that defines __STDC__ .
        !            48: //
1.1       noro       49:
                     50: #ifndef GC_ALLOC_H
                     51:
                     52: #include "gc.h"
1.3     ! noro       53: #include <stack>  // A more portable way to get stl_alloc.h .
1.1       noro       54:
                     55: #define GC_ALLOC_H
                     56:
                     57: #include <stddef.h>
                     58: #include <string.h>
                     59:
                     60: // The following need to match collector data structures.
                     61: // We can't include gc_priv.h, since that pulls in way too much stuff.
                     62: // This should eventually be factored out into another include file.
                     63:
                     64: extern "C" {
                     65:     extern void ** const GC_objfreelist_ptr;
                     66:     extern void ** const GC_aobjfreelist_ptr;
                     67:     extern void ** const GC_uobjfreelist_ptr;
                     68:     extern void ** const GC_auobjfreelist_ptr;
                     69:
                     70:     extern void GC_incr_words_allocd(size_t words);
                     71:     extern void GC_incr_mem_freed(size_t words);
                     72:
                     73:     extern char * GC_generic_malloc_words_small(size_t word, int kind);
                     74: }
                     75:
                     76: // Object kinds; must match PTRFREE, NORMAL, UNCOLLECTABLE, and
                     77: // AUNCOLLECTABLE in gc_priv.h.
                     78:
                     79: enum { GC_PTRFREE = 0, GC_NORMAL = 1, GC_UNCOLLECTABLE = 2,
                     80:        GC_AUNCOLLECTABLE = 3 };
                     81:
                     82: enum { GC_max_fast_bytes = 255 };
                     83:
                     84: enum { GC_bytes_per_word = sizeof(char *) };
                     85:
                     86: enum { GC_byte_alignment = 8 };
                     87:
                     88: enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word };
                     89:
                     90: inline void * &GC_obj_link(void * p)
                     91: {   return *(void **)p;  }
                     92:
                     93: // Compute a number of words >= n+1 bytes.
                     94: // The +1 allows for pointers one past the end.
                     95: inline size_t GC_round_up(size_t n)
                     96: {
                     97:     return ((n + GC_byte_alignment)/GC_byte_alignment)*GC_word_alignment;
                     98: }
                     99:
                    100: // The same but don't allow for extra byte.
                    101: inline size_t GC_round_up_uncollectable(size_t n)
                    102: {
                    103:     return ((n + GC_byte_alignment - 1)/GC_byte_alignment)*GC_word_alignment;
                    104: }
                    105:
                    106: template <int dummy>
                    107: class GC_aux_template {
                    108: public:
                    109:   // File local count of allocated words.  Occasionally this is
                    110:   // added into the global count.  A separate count is necessary since the
                    111:   // real one must be updated with a procedure call.
                    112:   static size_t GC_words_recently_allocd;
                    113:
                    114:   // Same for uncollectable mmory.  Not yet reflected in either
                    115:   // GC_words_recently_allocd or GC_non_gc_bytes.
                    116:   static size_t GC_uncollectable_words_recently_allocd;
                    117:
                    118:   // Similar counter for explicitly deallocated memory.
                    119:   static size_t GC_mem_recently_freed;
                    120:
                    121:   // Again for uncollectable memory.
                    122:   static size_t GC_uncollectable_mem_recently_freed;
                    123:
                    124:   static void * GC_out_of_line_malloc(size_t nwords, int kind);
                    125: };
                    126:
                    127: template <int dummy>
                    128: size_t GC_aux_template<dummy>::GC_words_recently_allocd = 0;
                    129:
                    130: template <int dummy>
                    131: size_t GC_aux_template<dummy>::GC_uncollectable_words_recently_allocd = 0;
                    132:
                    133: template <int dummy>
                    134: size_t GC_aux_template<dummy>::GC_mem_recently_freed = 0;
                    135:
                    136: template <int dummy>
                    137: size_t GC_aux_template<dummy>::GC_uncollectable_mem_recently_freed = 0;
                    138:
                    139: template <int dummy>
                    140: void * GC_aux_template<dummy>::GC_out_of_line_malloc(size_t nwords, int kind)
                    141: {
                    142:     GC_words_recently_allocd += GC_uncollectable_words_recently_allocd;
                    143:     GC_non_gc_bytes +=
                    144:                 GC_bytes_per_word * GC_uncollectable_words_recently_allocd;
                    145:     GC_uncollectable_words_recently_allocd = 0;
                    146:
                    147:     GC_mem_recently_freed += GC_uncollectable_mem_recently_freed;
                    148:     GC_non_gc_bytes -=
                    149:                 GC_bytes_per_word * GC_uncollectable_mem_recently_freed;
                    150:     GC_uncollectable_mem_recently_freed = 0;
                    151:
                    152:     GC_incr_words_allocd(GC_words_recently_allocd);
                    153:     GC_words_recently_allocd = 0;
                    154:
                    155:     GC_incr_mem_freed(GC_mem_recently_freed);
                    156:     GC_mem_recently_freed = 0;
                    157:
                    158:     return GC_generic_malloc_words_small(nwords, kind);
                    159: }
                    160:
                    161: typedef GC_aux_template<0> GC_aux;
                    162:
                    163: // A fast, single-threaded, garbage-collected allocator
                    164: // We assume the first word will be immediately overwritten.
                    165: // In this version, deallocation is not a noop, and explicit
                    166: // deallocation is likely to help performance.
                    167: template <int dummy>
                    168: class single_client_gc_alloc_template {
                    169:     public:
                    170:        static void * allocate(size_t n)
                    171:         {
                    172:            size_t nwords = GC_round_up(n);
                    173:            void ** flh;
                    174:            void * op;
                    175:
                    176:            if (n > GC_max_fast_bytes) return GC_malloc(n);
                    177:            flh = GC_objfreelist_ptr + nwords;
                    178:            if (0 == (op = *flh)) {
                    179:                return GC_aux::GC_out_of_line_malloc(nwords, GC_NORMAL);
                    180:            }
                    181:            *flh = GC_obj_link(op);
                    182:            GC_aux::GC_words_recently_allocd += nwords;
                    183:            return op;
                    184:         }
                    185:        static void * ptr_free_allocate(size_t n)
                    186:         {
                    187:            size_t nwords = GC_round_up(n);
                    188:            void ** flh;
                    189:            void * op;
                    190:
                    191:            if (n > GC_max_fast_bytes) return GC_malloc_atomic(n);
                    192:            flh = GC_aobjfreelist_ptr + nwords;
                    193:            if (0 == (op = *flh)) {
                    194:                return GC_aux::GC_out_of_line_malloc(nwords, GC_PTRFREE);
                    195:            }
                    196:            *flh = GC_obj_link(op);
                    197:            GC_aux::GC_words_recently_allocd += nwords;
                    198:            return op;
                    199:         }
                    200:        static void deallocate(void *p, size_t n)
                    201:        {
                    202:             size_t nwords = GC_round_up(n);
                    203:             void ** flh;
                    204:
                    205:            if (n > GC_max_fast_bytes)  {
                    206:                GC_free(p);
                    207:            } else {
                    208:                flh = GC_objfreelist_ptr + nwords;
                    209:                GC_obj_link(p) = *flh;
                    210:                memset((char *)p + GC_bytes_per_word, 0,
                    211:                       GC_bytes_per_word * (nwords - 1));
                    212:                *flh = p;
                    213:                GC_aux::GC_mem_recently_freed += nwords;
                    214:            }
                    215:        }
                    216:        static void ptr_free_deallocate(void *p, size_t n)
                    217:        {
                    218:             size_t nwords = GC_round_up(n);
                    219:             void ** flh;
                    220:
                    221:            if (n > GC_max_fast_bytes) {
                    222:                GC_free(p);
                    223:            } else {
                    224:                flh = GC_aobjfreelist_ptr + nwords;
                    225:                GC_obj_link(p) = *flh;
                    226:                *flh = p;
                    227:                GC_aux::GC_mem_recently_freed += nwords;
                    228:            }
                    229:        }
                    230: };
                    231:
                    232: typedef single_client_gc_alloc_template<0> single_client_gc_alloc;
                    233:
                    234: // Once more, for uncollectable objects.
                    235: template <int dummy>
                    236: class single_client_traceable_alloc_template {
                    237:     public:
                    238:        static void * allocate(size_t n)
                    239:         {
                    240:            size_t nwords = GC_round_up_uncollectable(n);
                    241:            void ** flh;
                    242:            void * op;
                    243:
                    244:            if (n > GC_max_fast_bytes) return GC_malloc_uncollectable(n);
                    245:            flh = GC_uobjfreelist_ptr + nwords;
                    246:            if (0 == (op = *flh)) {
                    247:                return GC_aux::GC_out_of_line_malloc(nwords, GC_UNCOLLECTABLE);
                    248:            }
                    249:            *flh = GC_obj_link(op);
                    250:            GC_aux::GC_uncollectable_words_recently_allocd += nwords;
                    251:            return op;
                    252:         }
                    253:        static void * ptr_free_allocate(size_t n)
                    254:         {
                    255:            size_t nwords = GC_round_up_uncollectable(n);
                    256:            void ** flh;
                    257:            void * op;
                    258:
                    259:            if (n > GC_max_fast_bytes) return GC_malloc_atomic_uncollectable(n);
                    260:            flh = GC_auobjfreelist_ptr + nwords;
                    261:            if (0 == (op = *flh)) {
                    262:                return GC_aux::GC_out_of_line_malloc(nwords, GC_AUNCOLLECTABLE);
                    263:            }
                    264:            *flh = GC_obj_link(op);
                    265:            GC_aux::GC_uncollectable_words_recently_allocd += nwords;
                    266:            return op;
                    267:         }
                    268:        static void deallocate(void *p, size_t n)
                    269:        {
                    270:             size_t nwords = GC_round_up_uncollectable(n);
                    271:             void ** flh;
                    272:
                    273:            if (n > GC_max_fast_bytes)  {
                    274:                GC_free(p);
                    275:            } else {
                    276:                flh = GC_uobjfreelist_ptr + nwords;
                    277:                GC_obj_link(p) = *flh;
                    278:                *flh = p;
                    279:                GC_aux::GC_uncollectable_mem_recently_freed += nwords;
                    280:            }
                    281:        }
                    282:        static void ptr_free_deallocate(void *p, size_t n)
                    283:        {
                    284:             size_t nwords = GC_round_up_uncollectable(n);
                    285:             void ** flh;
                    286:
                    287:            if (n > GC_max_fast_bytes) {
                    288:                GC_free(p);
                    289:            } else {
                    290:                flh = GC_auobjfreelist_ptr + nwords;
                    291:                GC_obj_link(p) = *flh;
                    292:                *flh = p;
                    293:                GC_aux::GC_uncollectable_mem_recently_freed += nwords;
                    294:            }
                    295:        }
                    296: };
                    297:
                    298: typedef single_client_traceable_alloc_template<0> single_client_traceable_alloc;
                    299:
                    300: template < int dummy >
                    301: class gc_alloc_template {
                    302:     public:
                    303:        static void * allocate(size_t n) { return GC_malloc(n); }
                    304:        static void * ptr_free_allocate(size_t n)
                    305:                { return GC_malloc_atomic(n); }
                    306:        static void deallocate(void *, size_t) { }
                    307:        static void ptr_free_deallocate(void *, size_t) { }
                    308: };
                    309:
                    310: typedef gc_alloc_template < 0 > gc_alloc;
                    311:
                    312: template < int dummy >
                    313: class traceable_alloc_template {
                    314:     public:
                    315:        static void * allocate(size_t n) { return GC_malloc_uncollectable(n); }
                    316:        static void * ptr_free_allocate(size_t n)
                    317:                { return GC_malloc_atomic_uncollectable(n); }
                    318:        static void deallocate(void *p, size_t) { GC_free(p); }
                    319:        static void ptr_free_deallocate(void *p, size_t) { GC_free(p); }
                    320: };
                    321:
                    322: typedef traceable_alloc_template < 0 > traceable_alloc;
                    323:
                    324: // We want to specialize simple_alloc so that it does the right thing
                    325: // for all pointerfree types.  At the moment there is no portable way to
                    326: // even approximate that.  The following approximation should work for
1.2       noro      327: // SGI compilers, and recent versions of g++.
1.1       noro      328:
                    329: # define __GC_SPECIALIZE(T,alloc) \
                    330: class simple_alloc<T, alloc> { \
                    331: public: \
                    332:     static T *allocate(size_t n) \
                    333:        { return 0 == n? 0 : \
                    334:                         (T*) alloc::ptr_free_allocate(n * sizeof (T)); } \
                    335:     static T *allocate(void) \
                    336:        { return (T*) alloc::ptr_free_allocate(sizeof (T)); } \
                    337:     static void deallocate(T *p, size_t n) \
                    338:        { if (0 != n) alloc::ptr_free_deallocate(p, n * sizeof (T)); } \
                    339:     static void deallocate(T *p) \
                    340:        { alloc::ptr_free_deallocate(p, sizeof (T)); } \
                    341: };
                    342:
1.3     ! noro      343: __STL_BEGIN_NAMESPACE
        !           344:
1.1       noro      345: __GC_SPECIALIZE(char, gc_alloc)
                    346: __GC_SPECIALIZE(int, gc_alloc)
                    347: __GC_SPECIALIZE(unsigned, gc_alloc)
                    348: __GC_SPECIALIZE(float, gc_alloc)
                    349: __GC_SPECIALIZE(double, gc_alloc)
                    350:
                    351: __GC_SPECIALIZE(char, traceable_alloc)
                    352: __GC_SPECIALIZE(int, traceable_alloc)
                    353: __GC_SPECIALIZE(unsigned, traceable_alloc)
                    354: __GC_SPECIALIZE(float, traceable_alloc)
                    355: __GC_SPECIALIZE(double, traceable_alloc)
                    356:
                    357: __GC_SPECIALIZE(char, single_client_gc_alloc)
                    358: __GC_SPECIALIZE(int, single_client_gc_alloc)
                    359: __GC_SPECIALIZE(unsigned, single_client_gc_alloc)
                    360: __GC_SPECIALIZE(float, single_client_gc_alloc)
                    361: __GC_SPECIALIZE(double, single_client_gc_alloc)
                    362:
                    363: __GC_SPECIALIZE(char, single_client_traceable_alloc)
                    364: __GC_SPECIALIZE(int, single_client_traceable_alloc)
                    365: __GC_SPECIALIZE(unsigned, single_client_traceable_alloc)
                    366: __GC_SPECIALIZE(float, single_client_traceable_alloc)
                    367: __GC_SPECIALIZE(double, single_client_traceable_alloc)
1.3     ! noro      368:
        !           369: __STL_END_NAMESPACE
1.1       noro      370:
                    371: #ifdef __STL_USE_STD_ALLOCATORS
                    372:
                    373: __STL_BEGIN_NAMESPACE
                    374:
                    375: template <class _T>
                    376: struct _Alloc_traits<_T, gc_alloc >
                    377: {
                    378:   static const bool _S_instanceless = true;
                    379:   typedef simple_alloc<_T, gc_alloc > _Alloc_type;
                    380:   typedef __allocator<_T, gc_alloc > allocator_type;
                    381: };
                    382:
                    383: inline bool operator==(const gc_alloc&,
                    384:                        const gc_alloc&)
                    385: {
                    386:   return true;
                    387: }
                    388:
                    389: inline bool operator!=(const gc_alloc&,
                    390:                        const gc_alloc&)
                    391: {
                    392:   return false;
                    393: }
                    394:
                    395: template <class _T>
                    396: struct _Alloc_traits<_T, single_client_gc_alloc >
                    397: {
                    398:   static const bool _S_instanceless = true;
                    399:   typedef simple_alloc<_T, single_client_gc_alloc > _Alloc_type;
                    400:   typedef __allocator<_T, single_client_gc_alloc > allocator_type;
                    401: };
                    402:
                    403: inline bool operator==(const single_client_gc_alloc&,
                    404:                        const single_client_gc_alloc&)
                    405: {
                    406:   return true;
                    407: }
                    408:
                    409: inline bool operator!=(const single_client_gc_alloc&,
                    410:                        const single_client_gc_alloc&)
                    411: {
                    412:   return false;
                    413: }
                    414:
                    415: template <class _T>
                    416: struct _Alloc_traits<_T, traceable_alloc >
                    417: {
                    418:   static const bool _S_instanceless = true;
                    419:   typedef simple_alloc<_T, traceable_alloc > _Alloc_type;
                    420:   typedef __allocator<_T, traceable_alloc > allocator_type;
                    421: };
                    422:
                    423: inline bool operator==(const traceable_alloc&,
                    424:                        const traceable_alloc&)
                    425: {
                    426:   return true;
                    427: }
                    428:
                    429: inline bool operator!=(const traceable_alloc&,
                    430:                        const traceable_alloc&)
                    431: {
                    432:   return false;
                    433: }
                    434:
                    435: template <class _T>
                    436: struct _Alloc_traits<_T, single_client_traceable_alloc >
                    437: {
                    438:   static const bool _S_instanceless = true;
                    439:   typedef simple_alloc<_T, single_client_traceable_alloc > _Alloc_type;
                    440:   typedef __allocator<_T, single_client_traceable_alloc > allocator_type;
                    441: };
                    442:
                    443: inline bool operator==(const single_client_traceable_alloc&,
                    444:                        const single_client_traceable_alloc&)
                    445: {
                    446:   return true;
                    447: }
                    448:
                    449: inline bool operator!=(const single_client_traceable_alloc&,
                    450:                        const single_client_traceable_alloc&)
                    451: {
                    452:   return false;
                    453: }
                    454:
                    455: __STL_END_NAMESPACE
                    456:
                    457: #endif /* __STL_USE_STD_ALLOCATORS */
                    458:
                    459: #endif /* GC_ALLOC_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>