2 * This module contains a minimal garbage collector implementation according to
3 * Tango requirements. This library is mostly intended to serve as an example,
4 * but it is usable in applications which do not rely on a garbage collector
5 * to clean up memory (ie. when dynamic array resizing is not used, and all
6 * memory allocated with 'new' is freed deterministically with 'delete').
8 * Please note that block attribute data must be tracked, or at a minimum, the
9 * FINALIZE bit must be tracked for any allocated memory block because calling
10 * rt_finalize on a non-object block can result in an access violation. In the
11 * allocator below, this tracking is done via a leading uint bitmask. A real
12 * allocator may do better to store this data separately, similar to the basic
13 * GC normally used by Tango.
15 * Copyright: Public Domain
17 * Authors: Leandro Lucarella
22 // TODO: explain why the functions return strings to use as string mixins
25 * Small hack to define the string alias if not defined
27 * Tango don't define this alias in object.d, but Phobos 1 and 2 does.
29 // XXX: this doesnt work:
30 // static if (!is(string))
31 // alias char[] string;
32 // See: http://d.puremagic.com/issues/show_bug.cgi?id=2848
37 * Functions dependant on the direction in which the stack grows
39 * By default, stack is considered to grow down, as in x86 architectures.
42 version = STACK_GROWS_DOWN;
44 bool stack_smaller(void* ptr1, void* ptr2)
46 version (STACK_GROWS_DOWN)
52 // Functions to push/pop registers into/from the stack
58 * GCC has an intrinsic function that does the job of pushing the registers
59 * into the stack, we use that function if available because it should work
60 * in all GCC supported architectures.
63 string push_registers(string sp_name)
66 __builtin_unwind_init();
67 " ~ sp_name ~ " = &" ~ sp_name ~ ";
71 string pop_registers(string sp_name)
81 * For X86 PUSHAD/POPAD are not used because they are too fragile to
82 * compiler optimizations (like ommitting the frame pointer).
84 * This method should work safely with all optimizations because it doesn't
85 * works behind the compilers back.
88 string push_registers(string sp_name)
91 size_t eax, ecx, edx, ebx, ebp, esi, edi;
101 mov " ~ sp_name ~ "[EBP], ESP;
106 string pop_registers(string sp_name)
112 else version (X86_64)
116 * See X86 comment above.
119 string push_registers(string sp_name)
122 size_t rax, rbx, rcx, rdx, rbp, rsi, rdi,
123 r10, r11, r12, r13, r14, r15;
139 movq " ~ sp_name ~ "[RBP], RSP;
144 string pop_registers(string sp_name)
150 else // Unkown compiler/architecture
153 pragma(msg, "Don't know how to push registers into the stack for this "
154 "compiler/architecture");
155 static assert(false);
159 // vim: set et sw=4 sts=4 :