Use mmap to allocate cells and mprotect to watch them
[software/dgc/naive.git] / gc / gc.d
1 /**
2  * Naive Garbage Collector implementation.
3  *
4  * This module implements a Naive Garbage Collector. The idea behind this
5  * implementation is to document all the bookkeeping and considerations that
6  * have to be taken in order to implement a garbage collector for D.
7  *
8  * The garbage collector algorithm itself is extremely simple to make it
9  * easier to focus on the specifics of D. A completely naive mark and sweep
10  * algorithm is used, with a recursive mark phase. The code is extremely
11  * inefficient in order to keep it clean, and easy to read and understand.
12  *
13  * The implementation is split in several modules to ease the reading even
14  * more. All architecture/compiler specific code is done in the arch module,
15  * in order to avoid confusing version statements all over the places. The
16  * cell module has all the code related to the memory cells header. dynarray
17  * is another support module which holds the implementation of a simple
18  * dynamic array used to store root pointers and ranges. The list module holds
19  * a simple singly linked list (of cells) implementation to store the live and
20  * free lists. Finally, the iface module is the one with the C interface to
21  * comply with the Tango/Druntime GC specification.
22  *
23  * Copyright: Public Domain
24  * License:   Public Domain
25  * Authors:   Leandro Lucarella <llucax@gmail.com>
26  */
27
28 module gc.gc;
29
30 private:
31
32 // Internal imports
33 import gc.cell: Cell, BlkAttr, op_apply_ptr_range;
34 import gc.list: List;
35 import gc.dynarray: DynArray;
36 import gc.arch: push_registers, pop_registers;
37
38 // Standard imports
39 import cstring = tango.stdc.string;
40 import mman = tango.stdc.posix.sys.mman;
41 // XXX: missing in Tango 0.99.8 for Linux
42 extern (C) int mprotect(void*, size_t, int);
43
44 // Debug imports
45
46 /*
47  * These are external functions coming from the D/Tango runtime. It's pretty
48  * intuitive what they do based on their names, for more details please
49  * refer to the functions documentation.
50  */
51 alias void delegate(void*, void*) mark_function;
52 extern (C) void onOutOfMemoryError();
53 extern (C) void rt_finalize(void* p, bool det=true);
54 extern (C) void rt_scanStaticData(mark_function mark);
55 extern (C) void thread_init();
56 extern (C) bool thread_needLock();
57 extern (C) void thread_suspendAll();
58 extern (C) void thread_resumeAll();
59 extern (C) void thread_scanAll(mark_function mark, void* stack_top=null);
60
61 /**
62  * A range of memory that should be scanned for pointers.
63  *
64  * This object is iterable, yielding a pointer (void*) for each iteration.
65  */
66 struct RootRange
67 {
68
69     /// Beginning of the memory range
70     void* from;
71
72     /// End of the memory range
73     void* to;
74
75     /// Iterate over a memory range applying dg to its elements
76     int opApply(int delegate(ref void*) dg)
77     {
78         return op_apply_ptr_range(this.from, this.to, dg);
79     }
80
81 }
82
83
84 package:
85
86
87 /**
88  * Information on a block of memory.
89  *
90  * This is part of the GC specification, it's used for the query() method.
91  *
92  * Standards: Tango/Druntime specs
93  */
94 struct BlkInfo
95 {
96
97     /// Base address of the block
98     void* base;
99
100     /// Size of the block (this is the total capacity, not the requested size)
101     size_t size;
102
103     /**
104      * Memory block attributes
105      *
106      * See_Also: cell.BlkAttr for possible values
107      */
108     uint attr;
109
110 }
111
112
113 /**
114  * GC implementation.
115  *
116  * This object contains the whole GC implementation. This is instantiated in
117  * the iface module as a global variable to provide the GC services.
118  *
119  * This implementation is designed to be extremely simple. The algorithm
120  * implemented is the most basic stop-the-world mark-sweep known.
121  *
122  * Memory is organized in cells. Each cell has a header where all the
123  * bookkeeping information is stored (like the mark bit, cell attributes,
124  * capacity, etc.), and the memory allocated for the requested memory itself.
125  *
126  * Two lists of cells are kept: free list and live list.
127  *
128  * The free list store cells known not to be referenced by the program. The
129  * live list stores cells that were referenced by the program at the end of
130  * the last collection (and just allocated cells).
131  *
132  * The root set is composed by several elements:
133  *
134  * $(UL
135  *      $(LI Static data)
136  *      $(LI Threads stack)
137  *      $(LI Registers)
138  *      $(LI Root pointers)
139  *      $(LI Root ranges)
140  * )
141  *
142  * Root pointers and ranges are user-defined.
143  *
144  * See_Also:
145  *
146  *  $(UL
147  *      $(LI cell.Cell for the cell header layout)
148  *      $(LI collect() for the main collection algorithm)
149  *      $(LI )
150  * )
151  *
152  */
153 struct GC
154 {
155
156 private:
157
158     /// List of free cells.
159     List free_list;
160
161     /// List of live cells.
162     List live_list;
163
164     /// Single root pointers.
165     DynArray!(void*) root_pointers;
166
167     /// Root ranges.
168     DynArray!(RootRange) root_ranges;
169
170     /**
171      * "Flag" to indicate when the GC is disabled.
172      *
173      * This is a number because calls to enable() and disable() can be
174      * recursive. The number of calls to enable() should match the number of
175      * calls to disable(), though, if you want the GC to be effectively
176      * enabled again.
177      */
178     uint disabled = 0;
179
180     /**
181      * Remove the mark bit to all the live cells.
182      *
183      * This is done before starting the mark phase.
184      *
185      * See_Also:
186      *
187      *  $(UL
188      *      $(LI collect() for the main collect algorithm)
189      *      $(LI mark_all() for details on the marking phase)
190      *  )
191      */
192     void unmark()
193     {
194         foreach (cell; this.live_list)
195             cell.marked = false;
196     }
197
198     /**
199      * Mark all live data (pausing all threads)
200      *
201      * This methods start marking following all the known roots:
202      *
203      *  $(UL
204      *      $(LI Static data)
205      *      $(LI Threads stack)
206      *      $(LI Registers)
207      *      $(LI Root pointers)
208      *      $(LI Root ranges)
209      *  )
210      *
211      * Note that the registers are pushed into the stack to get scanned.
212      *
213      * This is the complete mark phase. The algorithm roughly does:
214      *
215      *  $(OL
216      *      $(LI Push registers into the stack)
217      *      $(LI Pause all threads (but the current one, of course))
218      *      $(LI Scan the static data)
219      *      $(LI Scan all threads stack)
220      *      $(LI Scan the root pointers and ranges)
221      *      $(LI Resume all threads)
222      *      $(LI Pop the registers from the stack)
223      *  )
224      *
225      *
226      * See_Also:
227      *
228      *  $(UL
229      *      $(LI collect() for the main collect algorithm)
230      *      $(LI mark() for details on the marking algorithm)
231      *      $(LI sweep() for details on the sweep phase)
232      *  )
233      */
234     void mark_all()
235     {
236         void* stack_top;
237         mixin (push_registers("stack_top"));
238         thread_suspendAll();
239         rt_scanStaticData(&mark_range);
240         thread_scanAll(&mark_range, stack_top);
241         foreach (ptr; this.root_pointers) {
242             this.mark(ptr);
243         }
244         foreach (range; this.root_ranges) {
245             this.mark_range(range.from, range.to);
246         }
247         thread_resumeAll();
248         mixin (pop_registers("stack_top"));
249     }
250
251     /**
252      * Wrapper for mark() over a range, needed by some runtime functions.
253      *
254      * This function is used as a delegate to be passed to rt_scanStaticData()
255      * and thread_scanAll(), because they expect a function taking 2 pointers.
256      *
257      * This extremely inefficient on purpose. The goal of this implementation
258      * is simplicity, nor performance.
259      *
260      * See_Also:
261      *  $(UL
262      *      $(LI mark() for details on the marking algorithm)
263      *  )
264      */
265     void mark_range(void* from, void* to)
266     {
267         foreach (ptr; RootRange(from, to))
268             mark(ptr);
269     }
270
271     /**
272      * Mark all cells accessible from a pointer.
273      *
274      * This is the mark algorithm itself. It's recursive and dumb as a log. No
275      * care is taken in regards to stack overflows. This is the first example
276      * in text books.
277      *
278      * Marking is done with all threads stopped.
279      *
280      * See_Also:
281      *  $(UL
282      *      $(LI collect() for the main collect algorithm)
283      *      $(LI mark_all() for details on the marking phase)
284      *      $(LI sweep() for details on the sweep phase)
285      *  )
286      */
287     void mark(void* ptr)
288     {
289         Cell* cell = Cell.from_ptr(this.addrOf(ptr));
290         if (cell is null)
291             return;
292         if (!cell.marked) {
293             cell.marked = true;
294             if (cell.has_pointers) {
295                 foreach (ptr; *cell)
296                     mark(ptr);
297             }
298         }
299     }
300
301     /**
302      * Move unreferenced live objects to the free list (calling finalizers).
303      *
304      * This is the sweep phase. It's very simple, it just searches the live
305      * list and move unmarked cells to the free list. This function is in
306      * charge of calling finalizers too, through the rt_finalize() runtime
307      * function.
308      *
309      * Sweeping is done concurrently with the mutator threads.
310      *
311      * See_Also:
312      *  $(UL
313      *      $(LI collect() for the main collect algorithm)
314      *      $(LI mark_all() for details on the marking phase)
315      *  )
316      */
317     void sweep()
318     {
319         foreach (cell; this.live_list) {
320             if (!cell.marked) {
321                 this.live_list.unlink(cell);
322                 if (cell.has_finalizer)
323                     rt_finalize(cell.ptr, false);
324                 // Forbid the mutator read/write cell data
325                 int r = mprotect(cast(byte*) cell + 4096, cell.capacity,
326                         mman.PROT_NONE);
327                 assert (r != -1);
328                 this.free_list.link(cell);
329             }
330         }
331     }
332
333
334 public:
335
336     /**
337      * Initialize the GC.
338      *
339      * This initializes the thread library too, as requested by the
340      * Tango/Druntime specs.
341      */
342     void init()
343     {
344         this.disabled = 0;
345         thread_init();
346     }
347
348     /**
349      * Terminate the GC.
350      *
351      * Finalization of unreferenced cells is not mandatory by the specs.
352      * This implementation guarantees that all finalizers are called, at least
353      * at program exit (i.e. at GC termination).
354      *
355      * The specs says that "objects referenced from the data segment never get
356      * collected by the GC". While this is true for this implementation,
357      * finalizers are called for objects referenced from the data segment at
358      * program exit.
359      *
360      * There could be some problems with this, in very strange situations. For
361      * a more complete discussion about the topic please take a look at the
362      * bug 2858: http://d.puremagic.com/issues/show_bug.cgi?id=2858
363      */
364     void term()
365     {
366         foreach (cell; this.live_list)
367             if (cell.has_finalizer)
368                 rt_finalize(cell.ptr, false);
369         // Let the OS free the memory on exit.
370     }
371
372     /**
373      * Enable the GC.
374      *
375      * When the GC is enabled, a collection is triggered when malloc() can't
376      * find room in the free list to fulfill the requested size.
377      *
378      * enable() and disable() can be called recursively. The number of calls
379      * to enable() should match the number of calls to disable(), though, if
380      * you want the GC to be effectively enabled again.
381      *
382      * See_Also: disable()
383      */
384     void enable()
385     {
386         assert (this.disabled > 0);
387         this.disabled--;
388     }
389
390     /**
391      * Disable the GC.
392      *
393      * See_Also: enable()
394      */
395     void disable()
396     {
397         this.disabled++;
398         assert (this.disabled > 0);
399     }
400
401     /**
402      * Run a GC collection in order to find unreferenced objects.
403      *
404      * This is the simplest stop-the-world mark-sweep algorithm ever. It first
405      * removes the mark bit from all the live cells, then it marks the cells
406      * that are reachable through the root set (static data, stack, registers
407      * and custom root), and finally sweeps the live list looking for unmarked
408      * cells to free.
409      *
410      * The world is stopped only for the mark phase.
411      *
412      * See_Also:
413      *  $(UL
414      *      $(LI mark_all() for details on the marking phase)
415      *      $(LI sweep() for details on the sweep phase)
416      *  )
417      */
418     void collect()
419     {
420         this.unmark();
421         this.mark_all();
422         this.sweep();
423     }
424
425     /**
426      * Minimize free space usage.
427      *
428      * This method returns to the OS memory that is not longer used by
429      * the program. Usually calling this method manually is not
430      * necessary, because unused cells are recycled for future
431      * allocations. But if there is some small part of the program that
432      * requires a lot of memory and it's known that it won't be used
433      * further, calling this can reduce the memory footprint of the program
434      * considerably (at the expense of some performance lost in future
435      * allocations).
436      *
437      * This implementation just return to the OS all the cells in the free
438      * list.
439      */
440     void minimize()
441     {
442         foreach (cell; this.free_list) {
443             this.free_list.unlink(cell);
444             Cell.free(cell);
445         }
446     }
447
448     /**
449      * Get attributes associated to the cell pointed by ptr.
450      *
451      * Attributes is a bitmap that can have these values:
452      *
453      *  $(UL
454      *      $(LI 1: The object stored in the cell has to be finalized)
455      *      $(LI 2: The cell should not be scanned for pointers)
456      *      $(LI 4: The cell should not be moved during a collection
457      *           (unimplemented))
458      *  )
459      *
460      * See_Also: cell.BlkAttr, setAttr(), clrAttr()
461      */
462     uint getAttr(void* ptr)
463     {
464         auto cell = this.live_list.find(ptr);
465         if (cell !is null)
466             return cell.attr;
467         return 0;
468     }
469
470     /**
471      * Set the attributes of the cell pointed by ptr.
472      *
473      * All bits present in attr are set, other bits are untouched. The old
474      * attributes are returned.
475      *
476      * See_Also: cell.BlkAttr, getAttr(), clrAttr()
477      */
478     uint setAttr(void* ptr, uint attr)
479     {
480         auto cell = this.live_list.find(ptr);
481         if (cell !is null) {
482             auto old = cell.attr;
483             cell.attr |= attr;
484             return cell.attr;
485         }
486         return 0;
487     }
488
489     /**
490      * Clear the attributes of the cell pointed by ptr.
491      *
492      * All bits present in attr are cleared, other bits are untouched. The old
493      * attributes are returned.
494      *
495      * See_Also: cell.BlkAttr, getAttr(), setAttr()
496      */
497     uint clrAttr(void* ptr, uint attr)
498     {
499         auto cell = this.live_list.find(ptr);
500         if (cell !is null) {
501             auto old = cell.attr;
502             cell.attr &= ~attr;
503             return cell.attr;
504         }
505         return 0;
506     }
507
508     /**
509      * Allocate memory.
510      *
511      * This is the main allocator of the GC. The algorithm is really
512      * simple. It does a first-fit search in the free list, if no free cell is
513      * found with enough room, it runs a collection and retry (unless the GC
514      * is disabled). If there is no room still, it uses C malloc to allocate
515      * a new cell. If all that fails, then onOutOfMemoryError() runtime
516      * function is called to handle the error.
517      *
518      * attr are the attributes to associate to the new cell (see getAttr() for
519      * details).
520      */
521     void* malloc(size_t size, uint attr=0)
522     {
523         if (size == 0)
524             return null;
525
526         // Find a free cell in the free list with enough space
527         auto cell = this.free_list.pop(size);
528         if (cell !is null)
529             goto reuse;
530
531         // No room in the free list found, if the GC is enabled, trigger
532         // a collection and try again
533         if (!this.disabled) {
534             this.collect();
535             cell = this.free_list.pop(size);
536             if (cell !is null)
537                 goto reuse;
538         }
539
540         // No luck still, allocate a new cell
541         cell = Cell.alloc(size, attr);
542         if (cell !is null)
543             goto link;
544
545         // No memory
546         onOutOfMemoryError();
547
548         return null;
549
550     reuse:
551         // Allow the mutator to read/write cell data
552         int r = mprotect(cast(byte*) cell + 4096, cell.capacity,
553                 mman.PROT_READ | mman.PROT_WRITE);
554         assert (r != -1);
555         cell.size = size;
556         cell.attr = cast(BlkAttr) attr;
557
558     link:
559         this.live_list.link(cell);
560
561         return cell.ptr;
562     }
563
564     /**
565      * Allocate memory (set memory to zero).
566      *
567      * Same as malloc() but set the allocated memory cell to zero.
568      */
569     void* calloc(size_t size, uint attr=0)
570     {
571         if (size == 0)
572             return null;
573
574         void* ptr = this.malloc(size, attr);
575
576         if (ptr !is null) // in case onOutOfMemoryError didn't throw
577             cstring.memset(ptr, 0, size);
578
579         return ptr;
580     }
581
582     /**
583      * Reallocate memory.
584      *
585      * This implementation is very simple, if size less or equals than the
586      * cells capacity, the cell's size is changed and the same address is
587      * returned. Otherwise a new cell is allocated using malloc() (this can
588      * trigger a collection), the contents are moved and the old cell is freed.
589      *
590      * attr has the same meaning as in malloc().
591      */
592     void* realloc(void* ptr, size_t size, uint attr=0)
593     {
594         debug (gc_malloc) printf("gc.realloc(%p, %u, %u)\n", ptr, size, attr);
595
596         // Undercover malloc()
597         if (ptr is null)
598             return this.malloc(size, attr);
599
600         // Undercover free()
601         if (size == 0) {
602             this.free(ptr);
603             return null;
604         }
605
606         auto cell = this.live_list.find(ptr);
607         assert (cell !is null);
608
609         // We have enough capacity already, just change the size
610         if (cell.capacity >= size) {
611             debug (gc_malloc)
612                 printf("gc.realloc() - cell has %zu capacity, no need to "
613                         "realloc\n", cell.capacity);
614             cell.size = size;
615             return cell.ptr;
616         }
617
618         // We need to move the cell because of the lack of capacity, find
619         // a free cell with the requested capacity (at least)
620         ptr = this.malloc(size, attr);
621         if (ptr is null) // in case onOutOfMemoryError didn't throw
622             return null;
623         Cell* new_cell = Cell.from_ptr(ptr);
624         assert (new_cell !is null);
625
626         // Move cell attributes and contents
627         new_cell.attr = cell.attr;
628         cstring.memcpy(new_cell.ptr, cell.ptr, cell.size);
629
630         // Free the old cell
631         this.free(cell);
632
633         return new_cell.ptr;
634     }
635
636     /**
637      * Attempt to in-place enlarge a memory block pointed to by ptr.
638      *
639      * The memory should be enlarged to at least min_size beyond its current
640      * capacity, up to a maximum of max_size. This does not attempt to move
641      * the memory block (like realloc() does).
642      *
643      * Returns:
644      *  0 if could not extend ptr, total size of entire memory block if
645      *  successful.
646      */
647     size_t extend(void* ptr, size_t min_size, size_t max_size)
648     {
649         assert (min_size <= max_size);
650         // There is no possible extension of the capacity for this
651         // implementation.
652         return 0;
653     }
654
655     /**
656      * Reserve memory to anticipate memory allocations.
657      *
658      * This implementation is really dumb, a single cell is allocated with
659      * size bytes. If 2 malloc()s follow a call to reserve(size), requesting
660      * size/2 bytes each, one allocation will still be done (and half the
661      * memory of the first malloc will be wasted =). Since this is a trivial
662      * implementation, we don't care about this.
663      *
664      * The actual number of bytes reserved are returned, or 0 on error.
665      */
666     size_t reserve(size_t size)
667     {
668         assert (size > 0);
669         auto cell = Cell.alloc(size);
670         if (cell is null)
671             return 0;
672         // Forbid the mutator read/write cell data
673         int r = mprotect(cast(byte*) cell + 4096, cell.capacity,
674                 mman.PROT_NONE);
675         assert (r != -1);
676         this.free_list.link(cell);
677         return cell.capacity;
678     }
679
680     /**
681      * Free unused memory.
682      *
683      * This method tells the GC that a cell is not longer used. The GC doesn't
684      * perform any connectivity check, if the cell was referenced by others,
685      * nasty things will happen (much like C/C++).
686      *
687      * Note that finalizers are not called by this method. Finalizers are
688      * called by the runtime when the delete operator is used, and the delete
689      * operator calls this method through the runtime.
690      */
691     void free(void* ptr)
692     {
693         debug (gc_malloc) printf("gc.free(%p)\n", ptr);
694
695         if (ptr is null)
696             return;
697
698         auto cell = this.live_list.pop(ptr);
699         assert (cell !is null);
700
701         // Forbid the mutator read/write cell data
702         int r = mprotect(cast(byte*) cell + 4096, cell.capacity,
703                 mman.PROT_NONE);
704         assert (r != -1);
705
706         this.free_list.link(cell);
707     }
708
709     /**
710      * Get the base address of an interior pointer into the GC heap.
711      *
712      * If ptr is not pointing into the GC heap null is returned.
713      */
714     void* addrOf(void* ptr)
715     {
716         if (ptr is null)
717             return null;
718
719         bool in_range(Cell* cell)
720         {
721             return ptr >= cell.ptr && ptr < (cell.ptr + cell.size);
722         }
723
724         auto cell = this.live_list.find(&in_range);
725         if (cell !is null)
726             return cell.ptr;
727
728         return null;
729     }
730
731     /**
732      * Return the real size (capacity) for the cell pointed to by ptr.
733      *
734      * ptr should be the base address of a heap allocated object, interior
735      * pointers are not supported (use addrOf() if you have an interior
736      * pointer). If this is not true, this method returns 0.
737      *
738      * realloc(ptr, sizeOf(ptr), attr) is guaranteed not to allocate/move
739      * memory.
740      */
741     size_t sizeOf(void* ptr)
742     {
743         auto cell = this.live_list.find(ptr);
744         if (cell !is null)
745             return cell.capacity;
746         return 0;
747     }
748
749     /**
750      * Get information about the cell pointed to by ptr.
751      *
752      * ptr should be the base address of a heap allocated object, interior
753      * pointers are not supported (use addrOf() if you have an interior
754      * pointer). If this is not true, this method returns BlkInfo.init.
755      *
756      * See BlkInfo for the information provided by this method.
757      */
758     BlkInfo query(void* ptr)
759     {
760         BlkInfo blk_info;
761
762         auto cell = this.live_list.find(ptr);
763         if (cell !is null) {
764             blk_info.base = cell.ptr;
765             blk_info.size = cell.capacity;
766             blk_info.attr = cell.attr;
767         }
768
769         return blk_info;
770     }
771
772     /**
773      * Add a root pointer to the root set.
774      *
775      * This method can be used to register new root to the GC heap. This is
776      * only needed when the user has custom memory that has pointers into the
777      * GC heap (for example for interfacing with C programs, which allocates
778      * memory using malloc() directly).
779      *
780      * See_Also: removeRoot(), addRange(), removeRange()
781      */
782     void addRoot(void* ptr)
783     {
784         this.root_pointers.append(ptr);
785     }
786
787     /**
788      * Add a root range to the root set.
789      *
790      * This method can be used to register new root range (a memory chunk
791      * that should be scanned for pointers into the GC heap). This is
792      * only needed when the user has custom memory that has pointers into the
793      * GC heap (for example for interfacing with C programs, which allocates
794      * memory using malloc() directly).
795      *
796      * Pointers will be scanned assuming they are aligned.
797      *
798      * See_Also: removeRange(), addRoot(), removeRoot()
799      */
800     void addRange(void* ptr, size_t size)
801     {
802         this.root_ranges.append(RootRange(ptr, ptr + size));
803     }
804
805     /**
806      * Remove a root pointer from the root set.
807      *
808      * ptr has to be previously registered using addRoot(), otherwise the
809      * results are undefined.
810      *
811      * See_Also: addRoot(), addRange(), removeRange()
812      */
813     void removeRoot(void* ptr)
814     {
815         this.root_pointers.remove(ptr);
816     }
817
818     /**
819      * Remove a root range from the root set.
820      *
821      * ptr has to be previously registered using addRange(), otherwise the
822      * results are undefined.
823      *
824      * See_Also: addRange(), addRoot(), removeRoot()
825      */
826     void removeRange(void* ptr)
827     {
828         this.root_ranges.remove_if((ref RootRange range) {
829                     return range.from is ptr;
830                 });
831     }
832
833 } // struct GC
834
835 // vim: set et sw=4 sts=4 :