[t][TT #1119] Convert t/op/bitwise.t to PIR
[parrot.git] / src / gc / gc_inf.c
blobd986ae4537d9da12882ff6da09579a5c805ed636
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/gc/gc_inf.c - A demonstration of an infinite memory garbage collector
9 =head1 DESCRIPTION
11 This code implements an example of a bare-bones "infinite memory" garbage
12 collector. This is a learning tool only to demonstrate how to implement the
13 GC API in a new core. DO NOT USE THIS CORE ANYWHERE FOR ANY REASON.
15 Because this core never frees memory, some functionality is missing and some
16 tests will fail: Tests for timely destruction, tests involving IO that is
17 not manually flushed (the GC never calls the destroy VTABLE, so things never
18 get flushed/closed automatically), etc. This is by design and should not be
19 considered a "bug" or an "error". It is just a fact of life for such a
20 minimalist core.
22 To enable this core, change the settings in include/parrot/settings.h. Set
24 PARROT_GC_SUBSYSEM == 3
26 to activate this core.
28 =cut
32 #include "parrot/parrot.h"
33 #include "gc_private.h"
35 /* HEADERIZER HFILE: src/gc/gc_private.h */
37 /* HEADERIZER BEGIN: static */
38 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
40 static void gc_inf_add_free_object(SHIM_INTERP,
41 ARGMOD(Fixed_Size_Pool *pool),
42 ARGIN(void *to_add))
43 __attribute__nonnull__(2)
44 __attribute__nonnull__(3)
45 FUNC_MODIFIES(*pool);
47 static void gc_inf_alloc_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
48 __attribute__nonnull__(2)
49 FUNC_MODIFIES(*pool);
51 PARROT_CANNOT_RETURN_NULL
52 static void * gc_inf_get_free_object(SHIM_INTERP,
53 ARGMOD(Fixed_Size_Pool *pool))
54 __attribute__nonnull__(2)
55 FUNC_MODIFIES(*pool);
57 static void gc_inf_mark_and_sweep(SHIM_INTERP, UINTVAL flags);
58 static void gc_inf_more_traceable_objects(SHIM_INTERP,
59 ARGMOD(Fixed_Size_Pool *pool))
60 __attribute__nonnull__(2)
61 FUNC_MODIFIES(*pool);
63 static void gc_inf_pool_init(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
64 __attribute__nonnull__(2)
65 FUNC_MODIFIES(*pool);
67 #define ASSERT_ARGS_gc_inf_add_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
68 PARROT_ASSERT_ARG(pool) \
69 , PARROT_ASSERT_ARG(to_add))
70 #define ASSERT_ARGS_gc_inf_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
71 PARROT_ASSERT_ARG(pool))
72 #define ASSERT_ARGS_gc_inf_get_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
73 PARROT_ASSERT_ARG(pool))
74 #define ASSERT_ARGS_gc_inf_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
75 #define ASSERT_ARGS_gc_inf_more_traceable_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
76 PARROT_ASSERT_ARG(pool))
77 #define ASSERT_ARGS_gc_inf_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
78 PARROT_ASSERT_ARG(pool))
79 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
80 /* HEADERIZER END: static */
84 =head1 Functions
86 =over 4
88 =item C<static void gc_inf_mark_and_sweep(PARROT_INTERP, UINTVAL flags)>
90 This function would perform a GC run, if we needed to. Luckily we have
91 infinite memory!
93 This function is called from the GC API function C<Parrot_gc_mark_and_sweep>.
95 Flags can be a combination of these values:
97 GC_finish_FLAG
98 GC_lazy_FLAG
99 GC_trace_stack_FLAG
101 =cut
105 static void
106 gc_inf_mark_and_sweep(SHIM_INTERP, UINTVAL flags)
108 ASSERT_ARGS(gc_inf_mark_and_sweep)
109 UNUSED(flags);
114 =item C<static void gc_inf_add_free_object(PARROT_INTERP, Fixed_Size_Pool *pool,
115 void *to_add)>
117 Manually frees a chunk of memory. Normally this would return the memory
118 to the free list of the pool, but in this case we just return it to the
121 This function is called from places like C<Parrot_gc_free_pmc_header> and
122 related manual freeing functions. Some cores will also use it internally to
123 add items to the freelist from a freshly allocated arena.
125 =cut
129 static void
130 gc_inf_add_free_object(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool),
131 ARGIN(void *to_add))
133 ASSERT_ARGS(gc_inf_add_free_object)
134 if (to_add)
135 free(to_add);
140 =item C<static void * gc_inf_get_free_object(PARROT_INTERP, Fixed_Size_Pool
141 *pool)>
143 Gets a new object from the pool. Each pool specifies an object size in
144 C<pool->object_size> so we can use that number to make the allocation. For
145 GCs that manage their own memory through the use of arenas or similar
146 structures, we can use this basic algorithm here:
148 1) Check if we have any items on the free list and allocate one from there
149 if so.
150 2) Do a GC run to try and free up new items, and allocate a newly freed
151 item if one becomes available
152 3) Allocate a new arena from the OS and allocate a new item from there.
154 This function is called from GC API functions like
155 C<Parrot_Gc_get_new_pmc_header>
157 =cut
161 PARROT_CANNOT_RETURN_NULL
162 static void *
163 gc_inf_get_free_object(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
165 ASSERT_ARGS(gc_inf_get_free_object)
166 return calloc(pool->object_size, 1);
171 =item C<static void gc_inf_alloc_objects(PARROT_INTERP, Fixed_Size_Pool *pool)>
173 Allocates a new arena of objects from the system. This function is only
174 really used internally by the core, the API functions don't need to call
175 it directly. However, this function is necessary because we may have
176 different behaviors for certain pools, so we can't allocate for all of them
177 in the same way. We will need to have a new "alloc_objects" function
178 for each special case pool.
180 =cut
184 static void
185 gc_inf_alloc_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
187 ASSERT_ARGS(gc_inf_alloc_objects)
188 UNUSED(pool);
193 =item C<static void gc_inf_more_traceable_objects(PARROT_INTERP, Fixed_Size_Pool
194 *pool)>
196 Would normally try to find new traceable objects by first running a GC sweep
197 and then allocating a new arena from the system. Neither of these are
198 necessary in the infinite memory collector.
200 This function is only used internally to the core, and is not called directly
201 from the GC API. Different pools may have special requirements so multiple
202 "more_traceable_objects" functions may need to be written and used.
204 =cut
208 static void
209 gc_inf_more_traceable_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
211 ASSERT_ARGS(gc_inf_more_traceable_objects)
212 UNUSED(pool);
217 =item C<static void gc_inf_pool_init(PARROT_INTERP, Fixed_Size_Pool *pool)>
219 Initializes the function pointers in a new pool. When a new pool is created
220 we assign several function pointers to it for managing memory in the pool.
221 In this way we can treat different pools differently if they have special
222 management needs. In general all PObj-like pools are treated the same.
224 This function is mostly called from the function C<initialize_fixed_size_pools>
225 in F<src/gc/mark_sweep.c> at Parrot startup.
227 =cut
231 static void
232 gc_inf_pool_init(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
234 ASSERT_ARGS(gc_inf_pool_init)
235 pool->add_free_object = gc_inf_add_free_object;
236 pool->get_free_object = gc_inf_get_free_object;
237 pool->alloc_objects = gc_inf_alloc_objects;
238 pool->more_objects = gc_inf_more_traceable_objects;
243 =item C<void Parrot_gc_inf_init(PARROT_INTERP)>
245 Initializes the infinite memory collector. Installs the necessary function
246 pointers into the Memory_Pools structure. The two most important are the
247 C<mark_and_sweep> and C<pool_init> functions. C<finalize_gc_system> function
248 will be called at Parrot exit and will shut down the GC system if things
249 need to be flushed/closed/deactivated/freed/etc. It can be set to NULL if no
250 finalization is necessary.
252 =cut
256 void
257 Parrot_gc_inf_init(PARROT_INTERP)
259 ASSERT_ARGS(Parrot_gc_inf_init)
261 interp->gc_sys->do_gc_mark = gc_inf_mark_and_sweep;
262 interp->gc_sys->finalize_gc_system = NULL;
263 interp->gc_sys->init_pool = gc_inf_pool_init;
269 =back
271 =cut
276 * Local variables:
277 * c-file-style: "parrot"
278 * End:
279 * vim: expandtab shiftwidth=4: