"Fossies" - the Fresh Open Source Software Archive

Member "dmd2/src/druntime/src/gc/impl/manual/gc.d" (20 Nov 2020, 6355 Bytes) of package /linux/misc/dmd.2.094.2.linux.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) D source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /**
    2  * This module contains a minimal garbage collector implementation according to
    3  * published requirements.  This library is mostly intended to serve as an
    4  * example, but it is usable in applications which do not rely on a garbage
    5  * collector to clean up memory (ie. when dynamic array resizing is not used,
    6  * and all memory allocated with 'new' is freed deterministically with
    7  * 'delete').
    8  *
    9  * Please note that block attribute data must be tracked, or at a minimum, the
   10  * FINALIZE bit must be tracked for any allocated memory block because calling
   11  * rt_finalize on a non-object block can result in an access violation.  In the
   12  * allocator below, this tracking is done via a leading uint bitmask.  A real
   13  * allocator may do better to store this data separately, similar to the basic
   14  * GC.
   15  *
   16  * Copyright: Copyright Sean Kelly 2005 - 2016.
   17  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
   18  * Authors:   Sean Kelly
   19  */
   20 
   21 /*          Copyright Sean Kelly 2005 - 2016.
   22  * Distributed under the Boost Software License, Version 1.0.
   23  *    (See accompanying file LICENSE or copy at
   24  *          http://www.boost.org/LICENSE_1_0.txt)
   25  */
   26 module gc.impl.manual.gc;
   27 
   28 import core.gc.gcinterface;
   29 
   30 import rt.util.container.array;
   31 
   32 import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;
   33 static import core.memory;
   34 
   35 extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */
   36 
   37 // register GC in C constructor (_STI_)
   38 extern(C) pragma(crt_constructor) void _d_register_manual_gc()
   39 {
   40     import core.gc.registry;
   41     registerGCFactory("manual", &initialize);
   42 }
   43 
   44 private GC initialize()
   45 {
   46     import core.stdc.string: memcpy;
   47 
   48     auto p = cstdlib.malloc(__traits(classInstanceSize, ManualGC));
   49     if (!p)
   50         onOutOfMemoryError();
   51 
   52     auto init = typeid(ManualGC).initializer();
   53     assert(init.length == __traits(classInstanceSize, ManualGC));
   54     auto instance = cast(ManualGC) memcpy(p, init.ptr, init.length);
   55     instance.__ctor();
   56 
   57     return instance;
   58 }
   59 
   60 class ManualGC : GC
   61 {
   62     Array!Root roots;
   63     Array!Range ranges;
   64 
   65     this()
   66     {
   67     }
   68 
   69     ~this()
   70     {
   71         // TODO: cannot free as memory is overwritten and
   72         //  the monitor is still read in rt_finalize (called by destroy)
   73         // cstdlib.free(cast(void*) this);
   74     }
   75 
   76     void enable()
   77     {
   78     }
   79 
   80     void disable()
   81     {
   82     }
   83 
   84     void collect() nothrow
   85     {
   86     }
   87 
   88     void collectNoStack() nothrow
   89     {
   90     }
   91 
   92     void minimize() nothrow
   93     {
   94     }
   95 
   96     uint getAttr(void* p) nothrow
   97     {
   98         return 0;
   99     }
  100 
  101     uint setAttr(void* p, uint mask) nothrow
  102     {
  103         return 0;
  104     }
  105 
  106     uint clrAttr(void* p, uint mask) nothrow
  107     {
  108         return 0;
  109     }
  110 
  111     void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
  112     {
  113         void* p = cstdlib.malloc(size);
  114 
  115         if (size && p is null)
  116             onOutOfMemoryError();
  117         return p;
  118     }
  119 
  120     BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow
  121     {
  122         BlkInfo retval;
  123         retval.base = malloc(size, bits, ti);
  124         retval.size = size;
  125         retval.attr = bits;
  126         return retval;
  127     }
  128 
  129     void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
  130     {
  131         void* p = cstdlib.calloc(1, size);
  132 
  133         if (size && p is null)
  134             onOutOfMemoryError();
  135         return p;
  136     }
  137 
  138     void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
  139     {
  140         p = cstdlib.realloc(p, size);
  141 
  142         if (size && p is null)
  143             onOutOfMemoryError();
  144         return p;
  145     }
  146 
  147     size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
  148     {
  149         return 0;
  150     }
  151 
  152     size_t reserve(size_t size) nothrow
  153     {
  154         return 0;
  155     }
  156 
  157     void free(void* p) nothrow @nogc
  158     {
  159         cstdlib.free(p);
  160     }
  161 
  162     /**
  163      * Determine the base address of the block containing p.  If p is not a gc
  164      * allocated pointer, return null.
  165      */
  166     void* addrOf(void* p) nothrow @nogc
  167     {
  168         return null;
  169     }
  170 
  171     /**
  172      * Determine the allocated size of pointer p.  If p is an interior pointer
  173      * or not a gc allocated pointer, return 0.
  174      */
  175     size_t sizeOf(void* p) nothrow @nogc
  176     {
  177         return 0;
  178     }
  179 
  180     /**
  181      * Determine the base address of the block containing p.  If p is not a gc
  182      * allocated pointer, return null.
  183      */
  184     BlkInfo query(void* p) nothrow
  185     {
  186         return BlkInfo.init;
  187     }
  188 
  189     core.memory.GC.Stats stats() nothrow
  190     {
  191         return typeof(return).init;
  192     }
  193 
  194     core.memory.GC.ProfileStats profileStats() nothrow
  195     {
  196         return typeof(return).init;
  197     }
  198 
  199     void addRoot(void* p) nothrow @nogc
  200     {
  201         roots.insertBack(Root(p));
  202     }
  203 
  204     void removeRoot(void* p) nothrow @nogc
  205     {
  206         foreach (ref r; roots)
  207         {
  208             if (r is p)
  209             {
  210                 r = roots.back;
  211                 roots.popBack();
  212                 return;
  213             }
  214         }
  215         assert(false);
  216     }
  217 
  218     @property RootIterator rootIter() return @nogc
  219     {
  220         return &rootsApply;
  221     }
  222 
  223     private int rootsApply(scope int delegate(ref Root) nothrow dg)
  224     {
  225         foreach (ref r; roots)
  226         {
  227             if (auto result = dg(r))
  228                 return result;
  229         }
  230         return 0;
  231     }
  232 
  233     void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc
  234     {
  235         ranges.insertBack(Range(p, p + sz, cast() ti));
  236     }
  237 
  238     void removeRange(void* p) nothrow @nogc
  239     {
  240         foreach (ref r; ranges)
  241         {
  242             if (r.pbot is p)
  243             {
  244                 r = ranges.back;
  245                 ranges.popBack();
  246                 return;
  247             }
  248         }
  249         assert(false);
  250     }
  251 
  252     @property RangeIterator rangeIter() return @nogc
  253     {
  254         return &rangesApply;
  255     }
  256 
  257     private int rangesApply(scope int delegate(ref Range) nothrow dg)
  258     {
  259         foreach (ref r; ranges)
  260         {
  261             if (auto result = dg(r))
  262                 return result;
  263         }
  264         return 0;
  265     }
  266 
  267     void runFinalizers(const scope void[] segment) nothrow
  268     {
  269     }
  270 
  271     bool inFinalizer() nothrow
  272     {
  273         return false;
  274     }
  275 
  276     ulong allocatedInCurrentThread() nothrow
  277     {
  278         return typeof(return).init;
  279     }
  280 }