| /** | |
| * Contains the internal GC interface. | |
| * | |
| * Copyright: Copyright Digital Mars 2016. | |
| * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). | |
| * Authors: Walter Bright, Sean Kelly, Jeremy DeHaan | |
| */ | |
| /* Copyright Digital Mars 2016. | |
| * Distributed under the Boost Software License, Version 1.0. | |
| * (See accompanying file LICENSE or copy at | |
| * http://www.boost.org/LICENSE_1_0.txt) | |
| */ | |
| module core.gc.gcinterface; | |
| import core.thread.threadbase : ThreadBase; | |
| static import core.memory; | |
| alias BlkAttr = core.memory.GC.BlkAttr; | |
| alias BlkInfo = core.memory.GC.BlkInfo; | |
| alias RootIterator = int delegate(scope int delegate(ref Root) nothrow dg); | |
| alias RangeIterator = int delegate(scope int delegate(ref Range) nothrow dg); | |
| struct Root | |
| { | |
| void* proot; | |
| alias proot this; | |
| } | |
| struct Range | |
| { | |
| void* pbot; | |
| void* ptop; | |
| TypeInfo ti; // should be tail const, but doesn't exist for references | |
| alias pbot this; // only consider pbot for relative ordering (opCmp) | |
| bool opEquals(const scope Range rhs) nothrow const { return pbot == rhs.pbot; } | |
| } | |
| interface GC | |
| { | |
| /** | |
| * | |
| */ | |
| void enable(); | |
| /** | |
| * | |
| */ | |
| void disable(); | |
| /** | |
| * | |
| */ | |
| void collect() nothrow; | |
| /** | |
| * minimize free space usage | |
| */ | |
| void minimize() nothrow; | |
| /** | |
| * | |
| */ | |
| uint getAttr(void* p) nothrow; | |
| /** | |
| * | |
| */ | |
| uint setAttr(void* p, uint mask) nothrow; | |
| /** | |
| * | |
| */ | |
| uint clrAttr(void* p, uint mask) nothrow; | |
| /** | |
| * | |
| */ | |
| void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow; | |
| /* | |
| * | |
| */ | |
| BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow; | |
| /* | |
| * | |
| */ | |
| void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow; | |
| /* | |
| * | |
| */ | |
| void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow; | |
| /** | |
| * Attempt to in-place enlarge the memory block pointed to by p by at least | |
| * minsize bytes, up to a maximum of maxsize additional bytes. | |
| * This does not attempt to move the memory block (like realloc() does). | |
| * | |
| * Returns: | |
| * 0 if could not extend p, | |
| * total size of entire memory block if successful. | |
| */ | |
| size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow; | |
| /** | |
| * | |
| */ | |
| size_t reserve(size_t size) nothrow; | |
| /** | |
| * | |
| */ | |
| void free(void* p) nothrow @nogc; | |
| /** | |
| * Determine the base address of the block containing p. If p is not a gc | |
| * allocated pointer, return null. | |
| */ | |
| void* addrOf(void* p) nothrow @nogc; | |
| /** | |
| * Determine the allocated size of pointer p. If p is an interior pointer | |
| * or not a gc allocated pointer, return 0. | |
| */ | |
| size_t sizeOf(void* p) nothrow @nogc; | |
| /** | |
| * Determine the base address of the block containing p. If p is not a gc | |
| * allocated pointer, return null. | |
| */ | |
| BlkInfo query(void* p) nothrow; | |
| /** | |
| * Retrieve statistics about garbage collection. | |
| * Useful for debugging and tuning. | |
| */ | |
| core.memory.GC.Stats stats() @safe nothrow @nogc; | |
| /** | |
| * Retrieve profile statistics about garbage collection. | |
| * Useful for debugging and tuning. | |
| */ | |
| core.memory.GC.ProfileStats profileStats() @safe nothrow @nogc; | |
| /** | |
| * add p to list of roots | |
| */ | |
| void addRoot(void* p) nothrow @nogc; | |
| /** | |
| * remove p from list of roots | |
| */ | |
| void removeRoot(void* p) nothrow @nogc; | |
| /** | |
| * | |
| */ | |
| @property RootIterator rootIter() @nogc; | |
| /** | |
| * add range to scan for roots | |
| */ | |
| void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc; | |
| /** | |
| * remove range | |
| */ | |
| void removeRange(void* p) nothrow @nogc; | |
| /** | |
| * | |
| */ | |
| @property RangeIterator rangeIter() @nogc; | |
| /** | |
| * run finalizers | |
| */ | |
| void runFinalizers(const scope void[] segment) nothrow; | |
| /* | |
| * | |
| */ | |
| bool inFinalizer() nothrow @nogc @safe; | |
| /** | |
| * Returns the number of bytes allocated for the current thread | |
| * since program start. It is the same as | |
| * GC.stats().allocatedInCurrentThread, but faster. | |
| */ | |
| ulong allocatedInCurrentThread() nothrow; | |
| // ARRAY FUNCTIONS | |
| /** | |
| * Get the current used capacity of an array block. | |
| * | |
| * Note that this is only needed if you are about to change the array used | |
| * size and need to deal with the memory that is about to go away. For | |
| * appending or shrinking arrays that have no destructors, you probably | |
| * don't need this function. | |
| * | |
| * Params: | |
| * ptr = The pointer to check. This can be an interior pointer, but if it | |
| * is beyond the end of the used space, the return value may not be | |
| * valid. | |
| * atomic = The value is fetched atomically (for shared arrays) | |
| * Returns: | |
| * Current array slice, or null if the pointer does not point to a valid | |
| * appendable GC block. | |
| */ | |
| void[] getArrayUsed(void *ptr, bool atomic = false) nothrow; | |
| /** | |
| * Expand the array used size in place. | |
| * | |
| * Used for appending and expanding the length of the array slice. If the | |
| * operation can be performed without reallocating, the function succeeds. | |
| * Newly expanded data is not initialized. Slices that do not point at | |
| * expandable GC blocks cannot be affected, and this function will always | |
| * return false. | |
| * | |
| * Params: | |
| * slice = the slice to attempt expanding in place. | |
| * newUsed = the size that should be stored as used. | |
| * atomic = if true, the array may be shared between threads, and this | |
| * operation should be done atomically. | |
| * Returns: true if successful. | |
| */ | |
| bool expandArrayUsed(void[] slice, size_t newUsed, bool atomic = false) nothrow @safe; | |
| /** | |
| * Expand the array capacity in place. | |
| * | |
| * Used for reserving space that can be used for appending. If the | |
| * operation can be performed without reallocating, the function succeeds. | |
| * The used size is not changed. Slices that do not point at expandable GC | |
| * blocks cannot be affected, and this function will always return zero. | |
| * | |
| * Params: | |
| * slice = the slice to attempt reserving capacity for. | |
| * request = the requested size to expand to. Includes the existing data. | |
| * Passing a value less than the current array size will result in no | |
| * changes, but will return the current capacity. | |
| * atomic = The array may be shared between threads, and this operation | |
| * should be done atomically. | |
| * | |
| * Returns: | |
| * Resulting capacity size or 0 if the operation could not be performed. | |
| */ | |
| size_t reserveArrayCapacity(void[] slice, size_t request, bool atomic = false) nothrow @safe; | |
| /** | |
| * Shrink used space of a slice in place. | |
| * | |
| * Unlike the other array functions, the array slice passed in is the | |
| * target slice, and the existing used space is passed separately. This is | |
| * to discourage code that ends up with a slice to dangling valid data. | |
| * | |
| * If slice.ptr[0 .. existingUsed] does not point to the end of a valid GC | |
| * appendable slice, then the operation fails. | |
| * | |
| * Params: | |
| * slice = The proposed valid slice data. | |
| * existingUsed = The amount of data in the block (starting at slice.ptr) | |
| * that is currently valid in the array. If this amount does not match | |
| * the current used size, the operation fails. | |
| * atomic = The slice may be shared between threads, and the operation | |
| * should be atomic. | |
| * Returns: true if successful. | |
| */ | |
| bool shrinkArrayUsed(void[] slice, size_t existingUsed, bool atomic = false) nothrow; | |
| /** | |
| * Prepare a thread for use with the GC after the GC is initialized. Note | |
| * that you can register an initThread function to call before the GC is | |
| * initialized, see core.gc.registry. | |
| * | |
| * This function is always called *from* the thread as it is being started, | |
| * before any static initializers. The thread object parameter may not yet | |
| * be registered as `ThreadBase.getThis()`, as this is called before that | |
| * happens. | |
| */ | |
| void initThread(ThreadBase thread) nothrow @nogc; | |
| /** | |
| * Clean up any GC related data from the thread before it exits. There is | |
| * no equivalent of this function as a hook before the GC is initialized. | |
| * That is, the thread init function called before the GC is initialized | |
| * (from the registry hook) should assume this function may not be called | |
| * on termination if the GC is never initialized. | |
| * | |
| * This function is only called from a thread that was started from the D | |
| * runtime, and is terminating. The GC can assume the thread is still in | |
| * the list of running threads and can be paused for a GC cycle. This is | |
| * not called for the main thread which initialized the GC. | |
| */ | |
| void cleanupThread(ThreadBase thread) nothrow @nogc; | |
| } |