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

Annotation of OpenXM_contrib/gc/gc_alloc.h, Revision 1.1

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

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