fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / docs / memory_internals.pod
blob2393f23d2af77bf09e055e885c6e27087633d7a8
1 # Copyright (C) 2001-2009, Parrot Foundation.
2 # $Id$
4 =head1 NAME
6 docs/memory_internals.pod - Memory Internals
8 =head1 ABSTRACT
10 This document tries to explain the internals of the Parrot memory subsystem,
11 and the data structures related to memory management and garbage collection.
13 =head1 OVERVIEW
15 All allocated items are managed in memory pools. Memory pools hold collections
16 of similar items, items of the same data type and usually of the same size.
17 These can be roughly divided into two kinds: pools holding fixed sized items
18 and pools holding variable sized items.
20 A pool is organized as a linked list of big chunks, called I<Arenas>. Each
21 Arena holds and manages a set number of items of a single size and shape.
23 =head2 Abbreviations used here
25 =over 4
27 =item * GC
29 Garbage collector. A garbage collector is a system that finds memory objects
30 that are not being used by the system, and frees them automatically. Garbage
31 collection is broken into two distinct phases: the I<mark phase> that searches
32 for unreferenced objects, and the I<sweep phase> that frees all dead objects.
34 =item * DOD
36 Dead object detection, a deprecated term that refers to the I<mark phase>
37 of the garbage collector.
39 =back
41 By scanning through all the interpreter's registers, stacks and the processor
42 stack, all objects that are detected by the garbage collector are marked as
43 alive. Objects in all pools not alive at the end of the mark phase are
44 considered dead and are collected.
46 See F<docs/pdds/pdd09_gc.pod> for details about the garbage collector system.
48 =head1 Top down: the interpreter
50 A overall layout of the interpreter's memory management looks like so:
52     typedef struct Interp {
53         ...
54         struct Memory_Pools *mem_pools;
55         ...
56     } Interp;
58 All object-like things that get allocated during the execution of parrot
59 bytecode are managed from the C<mem_pools> member of the interpreter
60 structure.
62 =head1 Memory Pools
64 C<struct Memory_Pools> holds pointers to a variety of different kinds of managed
65 memory. A simplification looks similar to this:
67     typedef struct Memory_Pools {
68         struct Var_Size_Pool *memory_pool;
69         ...
70         struct Fixed_Size_Pool * header_pool;
71         struct Fixed_Size_Pool ** sized_pools;
72     } Memory_Pools;
74 C<memory_pool> and C<header_pool> are variable and fixed sized pool pointers
75 respectively. These are just two examples, there are other C<Var_Size_Pool>s
76 and C<Fixed_Size_Pool>s in the Parrot system. Pools of type
77 C<struct Var_Size_Pool> are for variable-size objects, such as constant string
78 buffers. Pools of type C<struct Fixed_Size_Pool> are for fixed-size objects
79 such as headers or PMCs.
81 =head1 Fixed sized items
83 Fixed-size items are either objects by themselves, like a C<PMC>, or are
84 header structures of variable-sized objects like C<STRING>.  The general
85 object of this kind is a buffer-like object, which consists of a
86 C<Buffer> or a C<PObj> header at the beginning connected to a variable-sized
87 memory block for data.
89 Buffer-like objects of the same size are maintained in the list of
90 C<sized_pools>, which manage objects of the same size in one slot.
92 Every garbage collector must supply 4 function pointers: an initialization
93 routine, a de-initialization routine, a function to initialize a new memory
94 pool, and a function to initiate a garbage collection run. Every pool also
95 requires the garbage collector to supply 4 additional function pointers: a
96 function to allocate a new arena for the pool, a function to find more items
97 (possibly through running the garbage collector, or allocating objects
98 otherwise), a function to add an unused item to the free list, and a function
99 to retrieve a new free item from the pool.
101 Every pool maintains a list of unused items within the pool, called the
102 C<free_list> When there is need for a new object it is taken off the free
103 list, and when it stops being used, it will be put back on the free list
104 again. GC mark determines which objects are not being used, and GC sweep
105 adds those unused items back to the free list.
107 If the free list is empty then a GC run could be initiated. This may be
108 able to find some dead objects and free them up for immediate reuse.
109 However, if there are no objects that can be immediately recycled, a new
110 arena will be allocated.
112 Arenas, which contain the fixed-sized items used by Parrot, are never returned
113 to the operating system, even if they are empty. In the future, this behavior
114 may change, however. Variable-sized buffers may be returned when they are no
115 longer being used.
117 =head2 General structure of a buffer-like item
119     struct parrot_object_t {
120         unsigned flags;
121         ...
122     } PObj;
124 The flags field may contain a series of flags which indicate the type, status,
125 configuration, and special requirements of each item. C<Buffer>s, C<PMC>s, and
126 C<PObj>s all have this basic field in common.
128 C<PMC>s and C<Buffer>s each have an additional field which contain a pointer
129 to a block of data.
131 =head2 GC-related PObj flags
133 Only three flags need to be checked during a mark run: C<PObj_live_FLAG>,
134 C<PObj_on_free_list_FLAG>, and C<PObj_is_special_PMC_FLAG>.  Normally these
135 flags are stored in C<PObj-E<gt>flags>, meaning that each PMC must be accessed
136 during the mark run.
138 F<pobj.h> provides macros to facilitate referencing individual object flags:
139 C<gc_flag_SET>, C<gc_flag_CLEAR> and C<gc_flag_TEST>. They make up a portable
140 way of manipulating the GC-relevant object flags.
142 =head1 Variable sized items
144 Variable-sized items do not exist by themselves, they are always wrapped by
145 a buffer structure that contains a pointer to the data information about them.
146 The variable-sized data items are managed in two different pools: the
147 C<memory_pool>, which contains a general mish-mash of data types, and the
148 C<constant_string_pool> which contains immutable string buffers used by
149 programs running on Parrot.
151 Here, different memory allocation schemes jump in:
153 =head2 Copying GC
155 A C<memory_pool> gets allocated in big blocks, namely a C<Memory_Block>.
156 When some part is needed, e.g. to store a string, this part is carved out of
157 the memory block, until this block is used up. If no more space is available in
158 this memory block, a special copying garbage collection (GC) is started.
159 This copies all living items of all used memory blocks into one new block,
160 which holds thereafter only used items tightly packed together.
162 The old memory blocks, containing sparse unused parts and used parts already
163 copied to the new place, are then unused altogether and get C<free()>ed
164 thereafter. When GC doesn't provide enough free space needed for a new item,
165 a new block is added to the memory pool.
167 This also implies that buffers are moved around during their life. Users of
168 these buffers are therefore not allowed to hold pointers to buffers over pieces
169 of code that might trigger a GC run, like C<Parrot_allocate()> or
170 C<Parrot_str_compare()>.
172 =head2 Defragmenting allocator
174 An alternative to the above is to use a memory allocator, which is as fast as
175 the above and does reuse C<free()>ed items in a memory-conserving way.
176 Actually, the malloc implementations in some systems' F<libc> efficiently
177 provide this, such as the glibc malloc based on Doug Lea's allocator.
179 Using this allocator, all variable sized items are just allocated via a plain
180 C<malloc()> call, or resized with C<realloc()>, and after they lose their
181 existence (ie when the mark phase detects that the managing buffer header is no
182 longer in use) they are C<free()>ed. That's all. The underlying allocator
183 collects these pieces, coalesces them if possible to form bigger pieces, and
184 then puts them on free lists, sorted by size.  Eventually, when a new
185 allocation request arrives, it may give them back to Parrot.
187 So here, the variable length C<memory_pool> is unused. You can consider this
188 pool to live inside the allocator. Buffers allocated this way don't move
189 around, except when reallocated, of course.
191 The F<Configure.pl> option C<--gc> allows one to use either method.
193 =head2 Buffer_Tail and COW
195 Both implementations have the same problem to solve: C<STRING>s that get
196 copied, or parts of strings as the result of a substr() call, do not allocate
197 new space in the memory pool to hold this string or part of string. They just
198 use a C<new_string_header()> and set up a pointer (C<strstart>) pointing
199 somewhere into the original string and remember the used length there in
200 C<bufused>.
202 This is all OK, as long as the original and the lazy copy of the string are not
203 modified. So that's well-known and called COW (copy on write). We don't have
204 to make a copy of the buffer until one of the copies tries to modify it. In
205 practice, strings often get copied from place to place but do not often get
206 modified, so this optimization saves us a lot of time.
208 Now, during GC (or freeing buffers) the problem arises: to whom does this
209 string belong? You shouldn't copy the same string to different places, thus
210 rendering COW to a noop, nor are you allowed to free this same string more then
211 once. Both allocation schemes therefore use a part of the allocated string to
212 do this bookkeeping.
214 The C<malloc()>/C<free()> approach stores a refcount at C<bufstart>. During the
215 mark phase all dead users increment the refcount, living users set it to an
216 huge value.  When freeing the buffer, the string is only freed if the refcount
217 reaches zero.
219 =head1 Simplified Figure
221                          +--------------+
222       +--------------<---| Memory Pools |<---------+
223       |                  +--------------+---+      |
224       |                                     |      |
225       |         +------+    +-----------+   |  +=============+
226       |         | S0   |<---| Registers |<--)--| Interpreter |
227       |         +------+    +-----------+   |  +=============+
228       |     +---| S1   |                    |
229       |     |   +------+                    +----------+
230  +-------+  |                                          |
231  | Blk 1 |--)-->+----------+    +--------------+   +---------+
232  +-------+  |   | Buffer 1 |    | OnestringAno |   | Block 1 |
233  | Blk 2 |  |   +----------+    | therstring.. |   +---------+
234  +-------+  |   | Buffer 2 |    | ..String...  |<--| Block 2 |
235  | .     |  |   +----------+    +--------------+   +---------+
236  +-------+  |   | ...      |        ^    ^         | ...     |
237 Fixed Size  |   +----------+        |    |         +---------+
238    Pool     +-->| Buffer N |--------+----+        Var Size Pool
239                 +----------+
240                  Buffer          Memory Block
242 Now consider that the I<Interpreter> shall be a C<PMC> living in C<Buffer X>
243 of the underlying interpreter and is currently running F<perldoc
244 docs/memory_internals.pod>, and then redo this figure, with all the blanks
245 filled in.
247 =head1 FILES
249 src/gc/api.c, src/gc/gc_private.h, pobj.h, mark_sweep.[ch],
250 alloc_resources.[ch], string.[ch]. Other garbage collector
251 implementations may use separate files as well.
253 =head1 BUGS
255 To minimize this bugs section - please patch this document and keep it up to
256 date - thanks.
258 =head1 AUTHOR
260 Leopold Tötsch C<lt@toetsch.at>
262 =head1 VERSION
264 0.1.1 June 2008