TempAlloc

A struct to allocate memory in a strictly first-in last-out order for things like scratch space. Technically, memory can safely escape the scope in which it was allocated. However, this is a very bad idea unless being done within the private API of a class, struct or nested function, where it can be guaranteed that LIFO will not be violated.

Under the hood, this works by allocating large blocks (currently 4 MB) from the GC, and sub-allocating these as a stack. Very large allocations (currently > 4MB) are simply performed on the heap. There are two ways to free memory: Calling TempAlloc.free() frees the last allocated block. Calling TempAlloc.frameFree() frees all memory allocated since the last call to TempAlloc.frameInit().

All allocations are aligned on 16-byte boundaries using padding, since on x86, 16-byte alignment is necessary to make SSE2 work. Note, however, that this is implemented based on the assumption that the GC allocates using 16-byte alignment (which appears to be true in druntime.)

Members

Static functions

frameFree
void frameFree()

Frees all memory allocated by TempAlloc since the last call to * frameInit().

frameFree
void frameFree(State stateCopy)

Same as frameFree() but uses stateCopy cached on stack by caller * to avoid a thread-local storage lookup. Strictly a speed hack.

frameInit
State frameInit()

Initializes a frame, i.e. marks the current allocation position. * Memory past the position at which this was last called will be * freed when frameFree() is called. Returns a reference to the * State class in case the caller wants to cache it for speed.

frameInit
State frameInit(State stateCopy)

Same as frameInit() but uses stateCopy cached on stack by caller * to avoid a thread-local storage lookup. Strictly a speed hack.

free
void free()

Frees the last piece of memory allocated by TempAlloc. Since * all memory must be allocated and freed in strict LIFO order, * there's no need to pass a pointer in. All bookkeeping for figuring * out what to free is done internally.

free
void free(State stateCopy)

Same as free() but uses stateCopy cached on stack by caller * to avoid a thread-local storage lookup. Strictly a speed hack.

getState
State getState()

Allows caller to cache the state class on the stack and pass it in as a * parameter. This is ugly, but results in a speed boost that can be * significant in some cases because it avoids a thread-local storage * lookup. Also used internally.

malloc
void* malloc(size_t nbytes)

Allocates nbytes bytes on the TempAlloc stack. NOT safe for real-time * programming, since if there's not enough space on the current block, * a new one will automatically be created. Also, very large objects * (currently over 4MB) will simply be heap-allocated. * * Bugs: Memory allocated by TempAlloc is not scanned by the GC. * This is necessary for performance and to avoid false pointer issues. * Do not store the only reference to a GC-allocated object in * TempAlloc-allocated memory.

malloc
void* malloc(size_t nbytes, State stateCopy)

Same as malloc() but uses stateCopy cached on stack by caller * to avoid a thread-local storage lookup. Strictly a speed hack.

opCall
void* opCall(T args)

Purely a convenience overload, forwards arguments to TempAlloc.malloc().

Meta