[t][TT #1119] Convert t/op/bitwise.t to PIR
[parrot.git] / src / gc / gc_private.h
blobae2a9427c67a535f1b4fcd29eddb47e80e2deaec
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/gc/gc_private.h - private header file for the GC subsystem
9 =head1 DESCRIPTION
11 This is a private header file for the GC subsystem. It contains definitions
12 that are only for use in the GC and don't need to be included in the rest of
13 Parrot.
16 #ifndef PARROT_GC_PRIVATE_H_GUARD
17 #define PARROT_GC_PRIVATE_H_GUARD
19 #include "parrot/settings.h"
21 #if ! DISABLE_GC_DEBUG
22 /* Set when walking the system stack. Defined in src/gc/system.c */
23 extern int CONSERVATIVE_POINTER_CHASING;
24 #endif
26 #ifdef __ia64__
28 # include <ucontext.h>
29 extern void *flush_reg_store(void);
30 # define BACKING_STORE_BASE 0x80000fff80000000
32 # ifdef __hpux
33 # include <sys/pstat.h>
34 # include <ia64/sys/inline.h>
35 # endif /* __hpux */
37 #endif /* __ia64__ */
39 /* the percent of used Arena items at which to trace next time through */
40 #define GC_DEBUG_REPLENISH_LEVEL_FACTOR 0.0
41 #define GC_DEBUG_UNITS_PER_ALLOC_GROWTH_FACTOR 1
42 #define REPLENISH_LEVEL_FACTOR 0.3
44 /* this factor is totally arbitrary, but gives good timings for stress.pasm */
45 #define UNITS_PER_ALLOC_GROWTH_FACTOR 1.75
47 #define POOL_MAX_BYTES 65536 * 128
49 #define PMC_HEADERS_PER_ALLOC 4096 * 10 / sizeof (PMC)
50 #define BUFFER_HEADERS_PER_ALLOC 4096 / sizeof (Buffer)
51 #define STRING_HEADERS_PER_ALLOC 4096 * 20 / sizeof (STRING)
53 #define CONSTANT_PMC_HEADERS_PER_ALLOC 4096 / sizeof (PMC)
54 #define GET_SIZED_POOL_IDX(x) ((x) / sizeof (void *))
55 #define GC_NUM_INITIAL_FIXED_SIZE_POOLS 128
58 /* these values are used for the attribute allocator */
59 #define GC_ATTRIB_POOLS_HEADROOM 8
60 #define GC_FIXED_SIZE_POOL_SIZE 4096
62 /* Use the lazy allocator. Since it amortizes arena allocation costs, turn
63 this on at the same time that you increase the size of allocated arenas.
64 increase *_HEADERS_PER_ALLOC and GC_FIXED_SIZE_POOL_SIZE to be large
65 enough to satisfy most startup costs. */
66 #define GC_USE_LAZY_ALLOCATOR 1
68 /* Set to 1 if we want to use the fixed-size allocator. Set to 0 if we want
69 to allocate these things using mem_sys_allocate instead */
70 #define GC_USE_FIXED_SIZE_ALLOCATOR 1
72 /* We're using this here to add an additional pointer to a PObj without
73 having to actually add an entire pointer to every PObj-alike structure
74 in Parrot. Astute observers may notice that if the PObj is comprised of
75 only an INTVAL, then there are some systems where sizeof(PObj*) can be
76 larger then sizeof(PObj), thus creating overflow. However PObjs are never
77 used by themselves, things like PMCs and STRINGs are cast to PObj in the
78 GC, so we should have plenty of space. */
79 typedef struct GC_MS_PObj_Wrapper {
80 size_t flags;
81 struct GC_MS_PObj_Wrapper * next_ptr;
82 } GC_MS_PObj_Wrapper;
85 typedef enum _gc_sys_type_enum {
86 MS, /*mark and sweep*/
87 INF /*infinite memory core*/
88 } gc_sys_type_enum;
90 typedef struct GC_Subsystem {
91 /* Which GC subsystem are we using? See PARROT_GC_DEFAULT_TYPE in
92 * include/parrot/settings.h for possible values */
93 gc_sys_type_enum sys_type;
95 /** Function hooks that each subsystem MUST provide */
96 void (*do_gc_mark)(PARROT_INTERP, UINTVAL flags);
97 void (*finalize_gc_system) (PARROT_INTERP);
98 void (*init_pool)(PARROT_INTERP, struct Fixed_Size_Pool *);
100 /*Function hooks that GC systems can CHOOSE to provide if they need them
101 *These will be called via the GC API functions Parrot_gc_func_name
102 *e.g. read barrier && write barrier hooks can go here later ...*/
104 /* Holds system-specific data structures
105 * unused right now, but this is where it should go if we need them ...
106 union {
107 } gc_private;
109 } GC_Subsystem;
111 typedef struct Memory_Block {
112 size_t free;
113 size_t size;
114 struct Memory_Block *prev;
115 struct Memory_Block *next;
116 char *start;
117 char *top;
118 } Memory_Block;
120 typedef struct Variable_Size_Pool {
121 Memory_Block *top_block;
122 void (*compact)(PARROT_INTERP, struct Variable_Size_Pool *);
123 size_t minimum_block_size;
124 size_t total_allocated; /* total bytes allocated to this pool */
125 size_t guaranteed_reclaimable; /* bytes that can definitely be reclaimed*/
126 size_t possibly_reclaimable; /* bytes that can possibly be reclaimed
127 * (above plus COW-freed bytes) */
128 FLOATVAL reclaim_factor; /* minimum percentage we will reclaim */
129 } Variable_Size_Pool;
131 typedef struct Fixed_Size_Arena {
132 size_t used;
133 size_t total_objects;
134 struct Fixed_Size_Arena *prev;
135 struct Fixed_Size_Arena *next;
136 void *start_objects;
137 } Fixed_Size_Arena;
139 typedef struct PMC_Attribute_Free_List {
140 struct PMC_Attribute_Free_List * next;
141 } PMC_Attribute_Free_List;
143 typedef struct PMC_Attribute_Arena {
144 struct PMC_Attribute_Arena * next;
145 struct PMC_Attribute_Arena * prev;
146 } PMC_Attribute_Arena;
148 typedef struct PMC_Attribute_Pool {
149 size_t attr_size;
150 size_t total_objects;
151 size_t objects_per_alloc;
152 size_t num_free_objects;
153 PMC_Attribute_Free_List * free_list;
154 PMC_Attribute_Arena * top_arena;
155 #if GC_USE_LAZY_ALLOCATOR
156 PMC_Attribute_Free_List * newfree;
157 PMC_Attribute_Free_List * newlast;
158 #endif
159 } PMC_Attribute_Pool;
161 /* Tracked resource pool */
162 typedef struct Fixed_Size_Pool {
164 struct Variable_Size_Pool *mem_pool;
165 /* Size in bytes of an individual pool item. This size may include
166 * a GC-system specific GC header. */
167 size_t object_size;
169 size_t start_arena_memory;
170 size_t end_arena_memory;
172 Fixed_Size_Arena *last_Arena;
173 GC_MS_PObj_Wrapper * free_list;
174 size_t num_free_objects; /* number of resources in the free pool */
175 size_t total_objects;
177 PARROT_OBSERVER const char *name;
179 size_t objects_per_alloc;
181 int skip;
182 size_t replenish_level;
184 add_free_object_fn_type add_free_object; /* adds a free object to
185 the pool's free list */
186 get_free_object_fn_type get_free_object; /* gets and removes a free
187 object from the pool's
188 free list */
189 alloc_objects_fn_type alloc_objects; /* allocates more objects */
190 alloc_objects_fn_type more_objects;
191 gc_object_fn_type gc_object;
193 /* Contains GC system-specific data structures ... unused at the moment,
194 * but this is where it should go when we need it ...
195 union {
196 } gc_private;
199 #if GC_USE_LAZY_ALLOCATOR
200 void *newfree;
201 void *newlast;
202 #endif
204 } Fixed_Size_Pool;
206 typedef struct Memory_Pools {
207 Variable_Size_Pool *memory_pool;
208 Variable_Size_Pool *constant_string_pool;
209 struct Fixed_Size_Pool *string_header_pool;
210 struct Fixed_Size_Pool *pmc_pool;
211 struct Fixed_Size_Pool *constant_pmc_pool;
212 struct Fixed_Size_Pool *constant_string_header_pool;
213 struct Fixed_Size_Pool **sized_header_pools;
214 size_t num_sized;
216 PMC_Attribute_Pool **attrib_pools;
217 size_t num_attribs;
220 /** statistics for GC **/
221 size_t gc_mark_runs; /* Number of times we've done a mark run*/
222 size_t gc_lazy_mark_runs; /* Number of successful lazy mark runs */
223 size_t gc_collect_runs; /* Number of times we've done a memory
224 compaction */
225 size_t mem_allocs_since_last_collect; /* The number of memory
226 * allocations from the
227 * system since the last
228 * compaction run */
229 size_t header_allocs_since_last_collect; /* The number of header
230 * blocks allocated from
231 * the system since the last
232 * GC run */
233 size_t memory_allocated; /* The total amount of
234 * allocatable memory
235 * allocated. Doesn't count
236 * memory for headers or
237 * internal structures or
238 * anything */
239 UINTVAL memory_collected; /* Total amount of memory copied
240 during collection */
241 UINTVAL num_early_gc_PMCs; /* how many PMCs want immediate destruction */
242 UINTVAL num_early_PMCs_seen; /* how many such PMCs has GC seen */
243 PMC* gc_mark_start; /* first PMC marked during a GC run */
244 PMC* gc_mark_ptr; /* last PMC marked during a GC run */
245 PMC* gc_trace_ptr; /* last PMC trace_children was called on */
246 int lazy_gc; /* flag that indicates whether we should stop
247 when we've seen all impatient PMCs */
249 * GC blocking
251 UINTVAL gc_mark_block_level; /* How many outstanding GC block
252 requests are there? */
253 UINTVAL gc_sweep_block_level; /* How many outstanding GC block
254 requests are there? */
256 * private data for the GC subsystem
258 void * gc_private; /* gc subsystem data */
259 } Memory_Pools;
262 /* HEADERIZER BEGIN: src/gc/system.c */
263 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
265 void trace_system_areas(PARROT_INTERP)
266 __attribute__nonnull__(1);
268 #define ASSERT_ARGS_trace_system_areas __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
269 PARROT_ASSERT_ARG(interp))
270 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
271 /* HEADERIZER END: src/gc/system.c */
273 /* HEADERIZER BEGIN: src/gc/mark_sweep.c */
274 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
276 PARROT_WARN_UNUSED_RESULT
277 INTVAL contained_in_pool(PARROT_INTERP,
278 ARGIN(const Fixed_Size_Pool *pool),
279 ARGIN(const void *ptr))
280 __attribute__nonnull__(1)
281 __attribute__nonnull__(2)
282 __attribute__nonnull__(3);
284 PARROT_WARN_UNUSED_RESULT
285 PARROT_CANNOT_RETURN_NULL
286 Fixed_Size_Pool * get_bufferlike_pool(PARROT_INTERP, size_t buffer_size)
287 __attribute__nonnull__(1);
289 PARROT_IGNORABLE_RESULT
290 int /*@alt void@*/
291 header_pools_iterate_callback(PARROT_INTERP,
292 int flag,
293 ARGIN_NULLOK(void *arg),
294 NOTNULL(pool_iter_fn func))
295 __attribute__nonnull__(1)
296 __attribute__nonnull__(4);
298 void initialize_fixed_size_pools(PARROT_INTERP)
299 __attribute__nonnull__(1);
301 void mark_special(PARROT_INTERP, ARGIN(PMC *obj))
302 __attribute__nonnull__(1)
303 __attribute__nonnull__(2);
305 void Parrot_add_to_free_list(PARROT_INTERP,
306 ARGMOD(Fixed_Size_Pool *pool),
307 ARGMOD(Fixed_Size_Arena *arena))
308 __attribute__nonnull__(1)
309 __attribute__nonnull__(2)
310 __attribute__nonnull__(3)
311 FUNC_MODIFIES(*pool)
312 FUNC_MODIFIES(*arena);
314 void Parrot_append_arena_in_pool(PARROT_INTERP,
315 ARGMOD(Fixed_Size_Pool *pool),
316 ARGMOD(Fixed_Size_Arena *new_arena),
317 size_t size)
318 __attribute__nonnull__(1)
319 __attribute__nonnull__(2)
320 __attribute__nonnull__(3)
321 FUNC_MODIFIES(*pool)
322 FUNC_MODIFIES(*new_arena);
324 void Parrot_gc_clear_live_bits(PARROT_INTERP,
325 ARGIN(const Fixed_Size_Pool *pool))
326 __attribute__nonnull__(1)
327 __attribute__nonnull__(2);
329 PARROT_CANNOT_RETURN_NULL
330 PMC_Attribute_Pool * Parrot_gc_get_attribute_pool(PARROT_INTERP,
331 size_t attrib_size)
332 __attribute__nonnull__(1);
334 PARROT_CANNOT_RETURN_NULL
335 void * Parrot_gc_get_attributes_from_pool(PARROT_INTERP,
336 ARGMOD(PMC_Attribute_Pool * pool))
337 __attribute__nonnull__(1)
338 __attribute__nonnull__(2)
339 FUNC_MODIFIES(* pool);
341 void Parrot_gc_initialize_fixed_size_pools(PARROT_INTERP,
342 size_t init_num_pools)
343 __attribute__nonnull__(1);
345 void Parrot_gc_run_init(PARROT_INTERP)
346 __attribute__nonnull__(1);
348 void Parrot_gc_sweep_pool(PARROT_INTERP, ARGMOD(Fixed_Size_Pool *pool))
349 __attribute__nonnull__(1)
350 __attribute__nonnull__(2)
351 FUNC_MODIFIES(*pool);
353 int Parrot_gc_trace_root(PARROT_INTERP, Parrot_gc_trace_type trace)
354 __attribute__nonnull__(1);
356 #define ASSERT_ARGS_contained_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
357 PARROT_ASSERT_ARG(interp) \
358 , PARROT_ASSERT_ARG(pool) \
359 , PARROT_ASSERT_ARG(ptr))
360 #define ASSERT_ARGS_get_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
361 PARROT_ASSERT_ARG(interp))
362 #define ASSERT_ARGS_header_pools_iterate_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
363 PARROT_ASSERT_ARG(interp) \
364 , PARROT_ASSERT_ARG(func))
365 #define ASSERT_ARGS_initialize_fixed_size_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
366 PARROT_ASSERT_ARG(interp))
367 #define ASSERT_ARGS_mark_special __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
368 PARROT_ASSERT_ARG(interp) \
369 , PARROT_ASSERT_ARG(obj))
370 #define ASSERT_ARGS_Parrot_add_to_free_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
371 PARROT_ASSERT_ARG(interp) \
372 , PARROT_ASSERT_ARG(pool) \
373 , PARROT_ASSERT_ARG(arena))
374 #define ASSERT_ARGS_Parrot_append_arena_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
375 PARROT_ASSERT_ARG(interp) \
376 , PARROT_ASSERT_ARG(pool) \
377 , PARROT_ASSERT_ARG(new_arena))
378 #define ASSERT_ARGS_Parrot_gc_clear_live_bits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
379 PARROT_ASSERT_ARG(interp) \
380 , PARROT_ASSERT_ARG(pool))
381 #define ASSERT_ARGS_Parrot_gc_get_attribute_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
382 PARROT_ASSERT_ARG(interp))
383 #define ASSERT_ARGS_Parrot_gc_get_attributes_from_pool \
384 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
385 PARROT_ASSERT_ARG(interp) \
386 , PARROT_ASSERT_ARG(pool))
387 #define ASSERT_ARGS_Parrot_gc_initialize_fixed_size_pools \
388 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
389 PARROT_ASSERT_ARG(interp))
390 #define ASSERT_ARGS_Parrot_gc_run_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
391 PARROT_ASSERT_ARG(interp))
392 #define ASSERT_ARGS_Parrot_gc_sweep_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
393 PARROT_ASSERT_ARG(interp) \
394 , PARROT_ASSERT_ARG(pool))
395 #define ASSERT_ARGS_Parrot_gc_trace_root __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
396 PARROT_ASSERT_ARG(interp))
397 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
398 /* HEADERIZER END: src/gc/mark_sweep.c */
400 /* HEADERIZER BEGIN: src/gc/pools.c */
401 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
403 PARROT_WARN_UNUSED_RESULT
404 PARROT_CANNOT_RETURN_NULL
405 Fixed_Size_Pool * get_bufferlike_pool(PARROT_INTERP, size_t buffer_size)
406 __attribute__nonnull__(1);
408 PARROT_IGNORABLE_RESULT
409 int /*@alt void@*/
410 header_pools_iterate_callback(PARROT_INTERP,
411 int flag,
412 ARGIN_NULLOK(void *arg),
413 NOTNULL(pool_iter_fn func))
414 __attribute__nonnull__(1)
415 __attribute__nonnull__(4);
417 void initialize_fixed_size_pools(PARROT_INTERP)
418 __attribute__nonnull__(1);
420 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
421 /* HEADERIZER END: src/gc/pools.c */
423 /* HEADERIZER BEGIN: src/gc/alloc_resources.c */
424 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
426 PARROT_CANNOT_RETURN_NULL
427 PARROT_WARN_UNUSED_RESULT
428 char * aligned_mem(ARGIN(const Buffer *buffer), ARGIN(char *mem))
429 __attribute__nonnull__(1)
430 __attribute__nonnull__(2);
432 PARROT_PURE_FUNCTION
433 PARROT_WARN_UNUSED_RESULT
434 size_t aligned_size(ARGIN(const Buffer *buffer), size_t len)
435 __attribute__nonnull__(1);
437 PARROT_CONST_FUNCTION
438 PARROT_WARN_UNUSED_RESULT
439 size_t aligned_string_size(size_t len);
441 void check_buffer_ptr(
442 ARGMOD(Buffer * pobj),
443 ARGMOD(Variable_Size_Pool * pool))
444 __attribute__nonnull__(1)
445 __attribute__nonnull__(2)
446 FUNC_MODIFIES(* pobj)
447 FUNC_MODIFIES(* pool);
449 void compact_pool(PARROT_INTERP, ARGMOD(Variable_Size_Pool *pool))
450 __attribute__nonnull__(1)
451 __attribute__nonnull__(2)
452 FUNC_MODIFIES(*pool);
454 void initialize_var_size_pools(PARROT_INTERP)
455 __attribute__nonnull__(1);
457 PARROT_MALLOC
458 PARROT_CANNOT_RETURN_NULL
459 void * mem_allocate(PARROT_INTERP,
460 size_t size,
461 ARGMOD(Variable_Size_Pool *pool))
462 __attribute__nonnull__(1)
463 __attribute__nonnull__(3)
464 FUNC_MODIFIES(*pool);
466 void merge_pools(
467 ARGMOD(Variable_Size_Pool *dest),
468 ARGMOD(Variable_Size_Pool *source))
469 __attribute__nonnull__(1)
470 __attribute__nonnull__(2)
471 FUNC_MODIFIES(*dest)
472 FUNC_MODIFIES(*source);
474 #define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
475 PARROT_ASSERT_ARG(buffer) \
476 , PARROT_ASSERT_ARG(mem))
477 #define ASSERT_ARGS_aligned_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
478 PARROT_ASSERT_ARG(buffer))
479 #define ASSERT_ARGS_aligned_string_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
480 #define ASSERT_ARGS_check_buffer_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
481 PARROT_ASSERT_ARG(pobj) \
482 , PARROT_ASSERT_ARG(pool))
483 #define ASSERT_ARGS_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
484 PARROT_ASSERT_ARG(interp) \
485 , PARROT_ASSERT_ARG(pool))
486 #define ASSERT_ARGS_initialize_var_size_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
487 PARROT_ASSERT_ARG(interp))
488 #define ASSERT_ARGS_mem_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
489 PARROT_ASSERT_ARG(interp) \
490 , PARROT_ASSERT_ARG(pool))
491 #define ASSERT_ARGS_merge_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
492 PARROT_ASSERT_ARG(dest) \
493 , PARROT_ASSERT_ARG(source))
494 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
495 /* HEADERIZER END: src/gc/alloc_resources.c */
497 /* GC subsystem init functions */
498 /* HEADERIZER BEGIN: src/gc/gc_ms.c */
499 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
501 void Parrot_gc_ms_init(PARROT_INTERP)
502 __attribute__nonnull__(1);
504 #define ASSERT_ARGS_Parrot_gc_ms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
505 PARROT_ASSERT_ARG(interp))
506 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
507 /* HEADERIZER END: src/gc/gc_ms.c */
509 /* HEADERIZER BEGIN: src/gc/gc_inf.c */
510 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
512 void Parrot_gc_inf_init(PARROT_INTERP)
513 __attribute__nonnull__(1);
515 #define ASSERT_ARGS_Parrot_gc_inf_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
516 PARROT_ASSERT_ARG(interp))
517 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
518 /* HEADERIZER END: src/gc/gc_inf.c */
520 #endif /* PARROT_GC_PRIVATE_H_GUARD */
525 * Local variables:
526 * c-file-style: "parrot"
527 * End:
528 * vim: expandtab shiftwidth=4: