fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / gc / api.c
bloba6397aabb043a9e7c9fb0a1ad5636a54bfa2ab54
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/gc/api.c - general Parrot API for GC functions
9 =head1 DESCRIPTION
11 This file implements the external-facing API for Parrot's garbage collector.
12 The collector itself is composed of various interchangable cores that each
13 may operate very differently internally. The functions in this file can be used
14 throughout Parrot without having to be concerned about the internal operations
15 of the GC. This is documented in PDD 9 with supplementary notes in
16 F<docs/memory_internals.pod>.
18 =head1 GC OVERVIEW
20 The GC is broken into a number of different files that each represent different
21 components.
23 =over 4
25 =item F<src/gc/api.c>
27 This is the main API file which provides access to functions which are used by
28 the rest of Parrot core. In the long term, only the functions provided in this
29 file should be visible to files outside the src/gc/ directory. Because this
30 represents a public-facing API, the functions in this file are not related by
31 theme.
33 =item F<src/gc/alloc_memory.c>
35 This file provides a number of functions and macros for allocating memory from
36 the OS. These are typically wrapper functions with error-handling capabilities
37 over malloc, calloc, or realloc.
39 =item F<src/gc/alloc_register.c>
41 This file implements the custom management and interface logic for
42 Parrot_Context structures. The functions in this file are publicly available
43 and are used throughout Parrot core for interacting with contexts and registers
45 =item F<src/gc/alloc_resources.c>
47 This file implements handling logic for strings and arbitrary-sized memory
48 buffers. String storage is managed by special Variable_Size_Pool structures, and use
49 a separate compacting garbage collector to keep track of them.
51 =item F<src/gc/incremental_ms.c>
53 =item F<src/gc/generational_ms.c>
55 =item F<src/gc/gc_ms.c>
57 These files are the individual GC cores which implement the primary tracing
58 and sweeping logic. gc_ms.c is the mark & sweep collector core which is used in
59 Parrot by default. generational_ms.c is an experimental and incomplete
60 generational core. incremental_ms.c is an experimental and incomplete
61 incremental collector core.
63 =item F<src/gc/mark_sweep.c>
65 This file implements some routines that are commonly needed by the various GC
66 cores and provide an abstraction layer that a GC core can use to interact with
67 some of the architecture of Parrot.
69 =item F<src/gc/system.c>
71 This file implements logic for tracing processor registers and the system stack.
72 Here there be dragons.
74 =item F<src/gc/malloc.c>
76 =item F<src/gc/malloc_trace.c>
78 These two files implement various unused features, including a custom malloc
79 implementation, and malloc wrappers for various purposes. These are unused.
81 =back
84 =head1 FUNCTIONS
86 =over 4
88 =cut
92 #define GC_C_SOURCE
93 #include "parrot/parrot.h"
94 #include "parrot/gc_api.h"
95 #include "gc_private.h"
97 /* HEADERIZER HFILE: include/parrot/gc_api.h */
99 /* HEADERIZER BEGIN: static */
100 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
102 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
103 /* HEADERIZER END: static */
105 #if ! DISABLE_GC_DEBUG
107 #endif
111 =item C<void Parrot_gc_mark_PObj_alive(PARROT_INTERP, PObj *obj)>
113 Marks the PObj as "alive" for the Garbage Collector. Takes a pointer to a PObj,
114 and performs necessary marking to ensure the PMC and its direct children nodes
115 are marked alive. Implementation is generally dependant on the particular
116 garbage collector in use.
118 Previously known as C<pobject_lives>.
120 =cut
124 PARROT_EXPORT
125 void
126 Parrot_gc_mark_PObj_alive(PARROT_INTERP, ARGMOD(PObj *obj))
128 ASSERT_ARGS(Parrot_gc_mark_PObj_alive)
129 /* TODO: Have each core register a ->pobject_lives function pointer in the
130 Memory_Pools struct, and call that pointer directly instead of having a messy
131 set of #if preparser conditions. */
133 /* if object is live or on free list return */
134 if (PObj_is_live_or_free_TESTALL(obj))
135 return;
137 /* mark it live */
138 PObj_live_SET(obj);
140 /* if object is a PMC and contains buffers or PMCs, then attach the PMC
141 * to the chained mark list. */
142 if (PObj_is_PMC_TEST(obj)) {
143 PMC * const p = (PMC *)obj;
145 if (PObj_is_special_PMC_TEST(obj))
146 interp->gc_sys->mark_special(interp, p);
148 else if (PMC_metadata(p))
149 Parrot_gc_mark_PMC_alive(interp, PMC_metadata(p));
155 =item C<void Parrot_gc_mark_PMC_alive_fun(PARROT_INTERP, PMC *obj)>
157 A type safe wrapper of Parrot_gc_mark_PObj_alive for PMC.
159 =cut
163 PARROT_EXPORT
164 void
165 Parrot_gc_mark_PMC_alive_fun(PARROT_INTERP, ARGMOD_NULLOK(PMC *obj))
167 ASSERT_ARGS(Parrot_gc_mark_PMC_alive_fun)
168 if (!PMC_IS_NULL(obj)) {
169 PARROT_ASSERT(PObj_is_PMC_TEST(obj));
171 if (PObj_is_live_or_free_TESTALL(obj))
172 return;
174 /* mark it live */
175 PObj_live_SET(obj);
177 /* if object is a PMC and contains buffers or PMCs, then attach the PMC
178 * to the chained mark list. */
179 if (PObj_is_special_PMC_TEST(obj)) {
180 if (PObj_custom_mark_TEST(obj))
181 VTABLE_mark(interp, obj);
184 if (PMC_metadata(obj))
185 Parrot_gc_mark_PMC_alive(interp, PMC_metadata(obj));
191 =item C<void Parrot_gc_mark_STRING_alive_fun(PARROT_INTERP, STRING *obj)>
193 A type safe wrapper of Parrot_gc_mark_PObj_alive for STRING.
195 =cut
199 PARROT_EXPORT
200 void
201 Parrot_gc_mark_STRING_alive_fun(SHIM_INTERP, ARGMOD_NULLOK(STRING *obj))
203 ASSERT_ARGS(Parrot_gc_mark_STRING_alive_fun)
204 if (!STRING_IS_NULL(obj)) {
205 PARROT_ASSERT(PObj_is_string_TEST(obj));
207 /* mark it live */
208 PObj_live_SET(obj);
214 =item C<void Parrot_gc_initialize(PARROT_INTERP, void *stacktop)>
216 Initializes the memory allocator and the garbage collection subsystem.
217 Calls the initialization function associated with each collector, which
218 is determined at compile time.
220 The "stacktop" parameter is required; it provides an upper bound for
221 stack scanning during a garbage collection run.
223 =cut
227 void
228 Parrot_gc_initialize(PARROT_INTERP, ARGIN(void *stacktop))
230 ASSERT_ARGS(Parrot_gc_initialize)
232 interp->lo_var_ptr = stacktop;
234 /*Call appropriate initialization function for GC subsystem*/
235 switch (interp->gc_sys->sys_type) {
236 case MS:
237 Parrot_gc_ms_init(interp);
238 break;
239 case INF:
240 Parrot_gc_inf_init(interp);
241 break;
242 default:
243 /*die horribly because of invalid GC core specified*/
244 break;
247 /* Assertions that GC subsystem has complete API */
248 PARROT_ASSERT(interp->gc_sys->do_gc_mark);
249 PARROT_ASSERT(interp->gc_sys->compact_string_pool);
251 /* It should be mandatory. But there is abstraction leak in */
252 /* mark_foo_alive. */
253 /* PARROT_ASSERT(interp->gc_sys->mark_special); */
255 PARROT_ASSERT(interp->gc_sys->allocate_pmc_header);
256 PARROT_ASSERT(interp->gc_sys->free_pmc_header);
258 PARROT_ASSERT(interp->gc_sys->allocate_string_header);
259 PARROT_ASSERT(interp->gc_sys->free_string_header);
261 PARROT_ASSERT(interp->gc_sys->allocate_bufferlike_header);
262 PARROT_ASSERT(interp->gc_sys->free_bufferlike_header);
264 PARROT_ASSERT(interp->gc_sys->allocate_pmc_attributes);
265 PARROT_ASSERT(interp->gc_sys->free_pmc_attributes);
267 PARROT_ASSERT(interp->gc_sys->allocate_string_storage);
268 PARROT_ASSERT(interp->gc_sys->reallocate_string_storage);
270 PARROT_ASSERT(interp->gc_sys->allocate_buffer_storage);
271 PARROT_ASSERT(interp->gc_sys->reallocate_buffer_storage);
273 PARROT_ASSERT(interp->gc_sys->allocate_fixed_size_storage);
274 PARROT_ASSERT(interp->gc_sys->free_fixed_size_storage);
276 PARROT_ASSERT(interp->gc_sys->allocate_memory_chunk);
277 PARROT_ASSERT(interp->gc_sys->reallocate_memory_chunk);
278 PARROT_ASSERT(interp->gc_sys->allocate_memory_chunk_with_interior_pointers);
279 PARROT_ASSERT(interp->gc_sys->reallocate_memory_chunk_with_interior_pointers);
280 PARROT_ASSERT(interp->gc_sys->free_memory_chunk);
282 PARROT_ASSERT(interp->gc_sys->get_gc_info);
287 =item C<void Parrot_gc_finalize(PARROT_INTERP)>
289 Finalize the GC system, if the current GC core has defined a finalization
290 routine.
292 =cut
296 void
297 Parrot_gc_finalize(PARROT_INTERP)
299 ASSERT_ARGS(Parrot_gc_finalize)
300 if (interp->gc_sys->finalize_gc_system)
301 interp->gc_sys->finalize_gc_system(interp);
303 mem_internal_free(interp->gc_sys);
304 interp->gc_sys = NULL;
310 =item C<PMC * Parrot_gc_new_pmc_header(PARROT_INTERP, UINTVAL flags)>
312 Gets a new PMC header from the PMC pool's free list. Guaranteed to return a
313 valid PMC object or else Parrot will throw an exception. Sets the necessary
314 flags for the objects and initializes the PMC data pointer to C<NULL>.
316 =cut
320 PARROT_WARN_UNUSED_RESULT
321 PARROT_CANNOT_RETURN_NULL
322 PMC *
323 Parrot_gc_new_pmc_header(PARROT_INTERP, UINTVAL flags)
325 ASSERT_ARGS(Parrot_gc_new_pmc_header)
326 PMC * const pmc = interp->gc_sys->allocate_pmc_header(interp, flags);
328 if (!pmc)
329 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
330 "Parrot VM: PMC allocation failed!\n");
332 PObj_get_FLAGS(pmc) = PObj_is_PMC_FLAG|flags;
333 pmc->vtable = NULL;
334 PMC_data(pmc) = NULL;
335 PMC_metadata(pmc) = PMCNULL;
337 return pmc;
342 =item C<void Parrot_gc_free_pmc_header(PARROT_INTERP, PMC *pmc)>
344 Adds the given PMC to the free list for later reuse.
346 =cut
350 void
351 Parrot_gc_free_pmc_header(PARROT_INTERP, ARGMOD(PMC *pmc))
353 ASSERT_ARGS(Parrot_gc_free_pmc_header)
354 interp->gc_sys->free_pmc_header(interp, pmc);
359 =item C<STRING * Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)>
361 Returns a new C<STRING> header from the string pool or the constant string
362 pool. Sets default flags on the string object: C<PObj_is_string_FLAG> and
363 C<PObj_is_COWable_FLAG>. Initializes the data field of the string buffer to
364 C<NULL>.
366 =cut
370 PARROT_CANNOT_RETURN_NULL
371 PARROT_WARN_UNUSED_RESULT
372 STRING *
373 Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)
375 ASSERT_ARGS(Parrot_gc_new_string_header)
377 STRING * const string = interp->gc_sys->allocate_string_header(interp, flags);
378 if (!string)
379 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
380 "Parrot VM: STRING allocation failed!\n");
382 string->strstart = NULL;
383 PObj_get_FLAGS(string) |=
384 flags | PObj_is_string_FLAG | PObj_is_COWable_FLAG;
386 return string;
391 =item C<void Parrot_gc_free_string_header(PARROT_INTERP, STRING *s)>
393 Adds the given STRING to the free list for later reuse.
395 =cut
399 void
400 Parrot_gc_free_string_header(PARROT_INTERP, ARGMOD(STRING *s))
402 ASSERT_ARGS(Parrot_gc_free_string_header)
403 interp->gc_sys->free_string_header(interp, s);
408 =item C<Buffer * Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size)>
410 Returns a new buffer-like header from the appropriate sized pool.
411 A "bufferlike object" is an object that is considered to be isomorphic to the
412 PObj, so it will participate in normal GC. At the moment these are only used
413 to create ListChunk objects in src/list.c.
415 =cut
419 PARROT_CANNOT_RETURN_NULL
420 PARROT_WARN_UNUSED_RESULT
421 Buffer *
422 Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size)
424 ASSERT_ARGS(Parrot_gc_new_bufferlike_header)
425 return interp->gc_sys->allocate_bufferlike_header(interp, size);
430 =item C<void Parrot_gc_free_bufferlike_header(PARROT_INTERP, Buffer *obj, size_t
431 size)>
433 Free a bufferlike header that is not being used, so that Parrot can recycle
434 it and use it again.
436 =cut
440 void
441 Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD(Buffer *obj),
442 size_t size)
444 ASSERT_ARGS(Parrot_gc_free_bufferlike_header)
445 interp->gc_sys->free_bufferlike_header(interp, obj, size);
450 =item C<void Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP, Buffer
451 *buffer, size_t size)>
453 Allocates a chunk of memory of at least size C<size> for the given Buffer.
454 buffer is guaranteed to be properly aligned for things like C<FLOATVALS>,
455 so the size may be rounded up or down to guarantee that this alignment holds.
457 =cut
461 void
462 Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP,
463 ARGOUT(Buffer *buffer), size_t size)
465 ASSERT_ARGS(Parrot_gc_allocate_buffer_storage_aligned)
466 interp->gc_sys->allocate_buffer_storage(interp, buffer, size);
471 =item C<void Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, Buffer *buffer,
472 size_t newsize)>
474 Reallocate the Buffer's buffer memory to the given size. The
475 allocated buffer will not shrink. If the buffer was allocated with
476 L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
477 all reallocation, the new buffer might have moved and the additional
478 memory is not cleared.
480 =cut
484 void
485 Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer),
486 size_t newsize)
488 ASSERT_ARGS(Parrot_gc_reallocate_buffer_storage)
489 interp->gc_sys->reallocate_buffer_storage(interp, buffer, newsize);
494 =item C<void Parrot_gc_allocate_string_storage(PARROT_INTERP, STRING *str,
495 size_t size)>
497 Allocate the STRING's buffer memory to the given size. The allocated
498 buffer maybe slightly bigger than the given C<size>. This function
499 sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
500 is B<not> changed.
502 =cut
506 void
507 Parrot_gc_allocate_string_storage(PARROT_INTERP, ARGOUT(STRING *str),
508 size_t size)
510 ASSERT_ARGS(Parrot_gc_allocate_string_storage)
511 interp->gc_sys->allocate_string_storage(interp, str, size);
516 =item C<void Parrot_gc_reallocate_string_storage(PARROT_INTERP, STRING *str,
517 size_t newsize)>
519 Reallocate the STRING's buffer memory to the given size. The allocated
520 buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
521 new buffer location, C<str-E<gt>bufused> is B<not> changed.
523 =cut
527 void
528 Parrot_gc_reallocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str),
529 size_t newsize)
531 ASSERT_ARGS(Parrot_gc_reallocate_string_storage)
532 interp->gc_sys->reallocate_string_storage(interp, str, newsize);
537 =item C<void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, PMC *pmc)>
539 Allocates a new attribute structure for a PMC if it has the auto_attrs flag
540 set.
542 =cut
546 PARROT_CANNOT_RETURN_NULL
547 void *
548 Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
550 ASSERT_ARGS(Parrot_gc_allocate_pmc_attributes)
551 return interp->gc_sys->allocate_pmc_attributes(interp, pmc);
556 =item C<void Parrot_gc_free_pmc_attributes(PARROT_INTERP, PMC *pmc)>
558 Deallocates an attibutes structure from a PMC if it has the auto_attrs
559 flag set.
563 void
564 Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
566 ASSERT_ARGS(Parrot_gc_free_pmc_attributes)
567 interp->gc_sys->free_pmc_attributes(interp, pmc);
572 =item C<void * Parrot_gc_allocate_fixed_size_storage(PARROT_INTERP, size_t
573 size)>
575 Allocates a fixed-size chunk of memory for use. This memory is not manually
576 managed and needs to be freed with C<Parrot_gc_free_fixed_size_storage>
580 PARROT_CANNOT_RETURN_NULL
581 void *
582 Parrot_gc_allocate_fixed_size_storage(PARROT_INTERP, size_t size)
584 ASSERT_ARGS(Parrot_gc_allocate_fixed_size_storage)
585 return interp->gc_sys->allocate_fixed_size_storage(interp, size);
590 =item C<void Parrot_gc_free_fixed_size_storage(PARROT_INTERP, size_t size, void
591 *data)>
593 Manually deallocates fixed size storage allocated with
594 C<Parrot_gc_allocate_fixed_size_storage>
598 void
599 Parrot_gc_free_fixed_size_storage(PARROT_INTERP, size_t size, ARGMOD(void *data))
601 ASSERT_ARGS(Parrot_gc_free_fixed_size_storage)
602 interp->gc_sys->free_fixed_size_storage(interp, size, data);
607 =item C<void * Parrot_gc_allocate_memory_chunk(PARROT_INTERP, size_t size)>
609 =item C<void * Parrot_gc_reallocate_memory_chunk(PARROT_INTERP, void *data,
610 size_t newsize)>
612 =item C<void Parrot_gc_free_memory_chunk(PARROT_INTERP, void *data)>
614 =item C<void *
615 Parrot_gc_allocate_memory_chunk_with_interior_pointers(PARROT_INTERP, size_t
616 size)>
618 =item C<void *
619 Parrot_gc_reallocate_memory_chunk_with_interior_pointers(PARROT_INTERP, void
620 *data, size_t newsize, size_t oldsize)>
622 TODO Write docu.
626 PARROT_EXPORT
627 PARROT_CANNOT_RETURN_NULL
628 void *
629 Parrot_gc_allocate_memory_chunk(PARROT_INTERP, size_t size)
631 ASSERT_ARGS(Parrot_gc_allocate_memory_chunk)
632 return interp->gc_sys->allocate_memory_chunk(interp, size);
635 PARROT_EXPORT
636 PARROT_CANNOT_RETURN_NULL
637 void *
638 Parrot_gc_reallocate_memory_chunk(PARROT_INTERP, ARGFREE(void *data), size_t newsize)
640 ASSERT_ARGS(Parrot_gc_reallocate_memory_chunk)
641 return interp->gc_sys->reallocate_memory_chunk(interp, data, newsize);
644 PARROT_EXPORT
645 PARROT_CANNOT_RETURN_NULL
646 void
647 Parrot_gc_free_memory_chunk(PARROT_INTERP, ARGIN_NULLOK(void *data))
649 ASSERT_ARGS(Parrot_gc_free_memory_chunk)
650 interp->gc_sys->free_memory_chunk(interp, data);
654 PARROT_EXPORT
655 PARROT_CANNOT_RETURN_NULL
656 void *
657 Parrot_gc_allocate_memory_chunk_with_interior_pointers(PARROT_INTERP, size_t size)
659 ASSERT_ARGS(Parrot_gc_allocate_memory_chunk_with_interior_pointers)
660 return interp->gc_sys->allocate_memory_chunk_with_interior_pointers(interp, size);
663 PARROT_EXPORT
664 PARROT_CANNOT_RETURN_NULL
665 void *
666 Parrot_gc_reallocate_memory_chunk_with_interior_pointers(PARROT_INTERP,
667 ARGFREE(void *data), size_t newsize, size_t oldsize)
669 ASSERT_ARGS(Parrot_gc_reallocate_memory_chunk_with_interior_pointers)
670 return interp->gc_sys->reallocate_memory_chunk_with_interior_pointers(interp,
671 data, newsize, oldsize);
677 =item C<void Parrot_gc_mark_and_sweep(PARROT_INTERP, UINTVAL flags)>
679 Calls the configured garbage collector to find and reclaim unused
680 headers. Performs a complete mark & sweep run of the GC.
682 =cut
686 void
687 Parrot_gc_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
689 ASSERT_ARGS(Parrot_gc_mark_and_sweep)
690 interp->gc_sys->do_gc_mark(interp, flags);
695 =item C<void Parrot_gc_compact_memory_pool(PARROT_INTERP)>
697 Compact string pool if supported by GC.
699 =cut
703 void
704 Parrot_gc_compact_memory_pool(PARROT_INTERP)
706 ASSERT_ARGS(Parrot_gc_compact_memory_pool)
707 interp->gc_sys->compact_string_pool(interp);
712 =item C<void Parrot_gc_destroy_child_interp(Interp *dest_interp, Interp
713 *source_interp)>
715 Merges the header pools of C<source_interp> into those of C<dest_interp>.
716 (Used to deal with shared objects left after interpreter destruction.)
718 =cut
722 void
723 Parrot_gc_destroy_child_interp(ARGMOD(Interp *dest_interp),
724 ARGIN(Interp *source_interp))
726 ASSERT_ARGS(Parrot_gc_destroy_child_interp)
727 if (dest_interp->gc_sys->destroy_child_interp)
728 dest_interp->gc_sys->destroy_child_interp(dest_interp, source_interp);
733 =item C<int Parrot_gc_active_sized_buffers(PARROT_INTERP)>
735 Returns the number of actively used sized buffers.
737 =cut
742 Parrot_gc_active_sized_buffers(PARROT_INTERP)
744 ASSERT_ARGS(Parrot_gc_active_sized_buffers)
745 return interp->gc_sys->get_gc_info(interp, ACTIVE_BUFFERS);
750 =item C<int Parrot_gc_total_sized_buffers(PARROT_INTERP)>
752 Returns the total number of sized buffers that we are managing.
754 =cut
759 Parrot_gc_total_sized_buffers(PARROT_INTERP)
761 ASSERT_ARGS(Parrot_gc_total_sized_buffers)
762 return interp->gc_sys->get_gc_info(interp, TOTAL_BUFFERS);
767 =item C<int Parrot_gc_active_pmcs(PARROT_INTERP)>
769 Return the number of actively used PMCs.
771 =cut
776 Parrot_gc_active_pmcs(PARROT_INTERP)
778 ASSERT_ARGS(Parrot_gc_active_pmcs)
779 return interp->gc_sys->get_gc_info(interp, ACTIVE_PMCS);
784 =item C<int Parrot_gc_total_pmcs(PARROT_INTERP)>
786 Return the total number of PMCs that we are managing.
788 =cut
793 Parrot_gc_total_pmcs(PARROT_INTERP)
795 ASSERT_ARGS(Parrot_gc_total_pmcs)
796 return interp->gc_sys->get_gc_info(interp, TOTAL_PMCS);
801 =item C<size_t Parrot_gc_count_mark_runs(PARROT_INTERP)>
803 Return the number of mark runs the GC has performed.
805 =item C<size_t Parrot_gc_count_collect_runs(PARROT_INTERP)>
807 Return the number of collect runs the GC has performed.
809 =item C<size_t Parrot_gc_count_lazy_mark_runs(PARROT_INTERP)>
811 Return the number of lazy mark runs the GC has performed.
813 =item C<size_t Parrot_gc_total_memory_allocated(PARROT_INTERP)>
815 Return the total number of memory allocations made by the GC.
817 =item C<size_t Parrot_gc_headers_alloc_since_last_collect(PARROT_INTERP)>
819 Return the number of new headers allocated since the last collection run.
821 =item C<size_t Parrot_gc_mem_alloc_since_last_collect(PARROT_INTERP)>
823 Return the number of memory allocations made since the last collection run.
825 =item C<UINTVAL Parrot_gc_total_copied(PARROT_INTERP)>
827 =item C<UINTVAL Parrot_gc_impatient_pmcs(PARROT_INTERP)>
829 Returns the number of PMCs that are marked as needing timely destruction.
833 size_t
834 Parrot_gc_count_mark_runs(PARROT_INTERP)
836 ASSERT_ARGS(Parrot_gc_count_mark_runs)
837 return interp->gc_sys->get_gc_info(interp, GC_MARK_RUNS);
840 size_t
841 Parrot_gc_count_collect_runs(PARROT_INTERP)
843 ASSERT_ARGS(Parrot_gc_count_collect_runs)
844 return interp->gc_sys->get_gc_info(interp, GC_COLLECT_RUNS);
847 size_t
848 Parrot_gc_count_lazy_mark_runs(PARROT_INTERP)
850 ASSERT_ARGS(Parrot_gc_count_lazy_mark_runs)
851 return interp->gc_sys->get_gc_info(interp, GC_LAZY_MARK_RUNS);
854 size_t
855 Parrot_gc_total_memory_allocated(PARROT_INTERP)
857 ASSERT_ARGS(Parrot_gc_total_memory_allocated)
858 return interp->gc_sys->get_gc_info(interp, TOTAL_MEM_ALLOC);
861 size_t
862 Parrot_gc_headers_alloc_since_last_collect(PARROT_INTERP)
864 ASSERT_ARGS(Parrot_gc_headers_alloc_since_last_collect)
865 return interp->gc_sys->get_gc_info(interp, HEADER_ALLOCS_SINCE_COLLECT);
868 size_t
869 Parrot_gc_mem_alloc_since_last_collect(PARROT_INTERP)
871 ASSERT_ARGS(Parrot_gc_mem_alloc_since_last_collect)
872 return interp->gc_sys->get_gc_info(interp, MEM_ALLOCS_SINCE_COLLECT);
875 UINTVAL
876 Parrot_gc_total_copied(PARROT_INTERP)
878 ASSERT_ARGS(Parrot_gc_total_copied)
879 return interp->gc_sys->get_gc_info(interp, TOTAL_COPIED);
882 UINTVAL
883 Parrot_gc_impatient_pmcs(PARROT_INTERP)
885 ASSERT_ARGS(Parrot_gc_impatient_pmcs)
886 return interp->gc_sys->get_gc_info(interp, IMPATIENT_PMCS);
891 =item C<void Parrot_block_GC_mark(PARROT_INTERP)>
893 Blocks the GC from performing its mark phase.
895 =item C<void Parrot_unblock_GC_mark(PARROT_INTERP)>
897 Unblocks the GC mark.
899 =item C<void Parrot_block_GC_sweep(PARROT_INTERP)>
901 Blocks the GC from performing its sweep phase.
903 =item C<void Parrot_unblock_GC_sweep(PARROT_INTERP)>
905 Unblocks GC sweep.
907 =item C<unsigned int Parrot_is_blocked_GC_mark(PARROT_INTERP)>
909 Determines if the GC mark is currently blocked.
911 =item C<unsigned int Parrot_is_blocked_GC_sweep(PARROT_INTERP)>
913 Determines if the GC sweep is currently blocked.
915 =item C<void Parrot_gc_completely_unblock(PARROT_INTERP)>
917 Completely unblock the GC mark and sweep. This is only used at interpreter
918 destruction, using it anywhere else will cause problems.
920 =cut
924 PARROT_EXPORT
925 void
926 Parrot_block_GC_mark(PARROT_INTERP)
928 ASSERT_ARGS(Parrot_block_GC_mark)
929 if (interp->gc_sys->block_mark)
930 interp->gc_sys->block_mark(interp);
933 PARROT_EXPORT
934 void
935 Parrot_unblock_GC_mark(PARROT_INTERP)
937 ASSERT_ARGS(Parrot_unblock_GC_mark)
938 if (interp->gc_sys->unblock_mark)
939 interp->gc_sys->unblock_mark(interp);
942 PARROT_EXPORT
943 void
944 Parrot_block_GC_sweep(PARROT_INTERP)
946 ASSERT_ARGS(Parrot_block_GC_sweep)
947 if (interp->gc_sys->block_sweep)
948 interp->gc_sys->block_sweep(interp);
951 PARROT_EXPORT
952 void
953 Parrot_unblock_GC_sweep(PARROT_INTERP)
955 ASSERT_ARGS(Parrot_unblock_GC_sweep)
956 if (interp->gc_sys->unblock_sweep)
957 interp->gc_sys->unblock_sweep(interp);
960 PARROT_EXPORT
961 unsigned int
962 Parrot_is_blocked_GC_mark(PARROT_INTERP)
964 ASSERT_ARGS(Parrot_is_blocked_GC_mark)
965 if (interp->gc_sys->is_blocked_mark)
966 return interp->gc_sys->is_blocked_mark(interp);
967 else
968 return 0;
971 PARROT_EXPORT
972 unsigned int
973 Parrot_is_blocked_GC_sweep(PARROT_INTERP)
975 ASSERT_ARGS(Parrot_is_blocked_GC_sweep)
976 if (interp->gc_sys->is_blocked_sweep)
977 return interp->gc_sys->is_blocked_mark(interp);
978 else
979 return 0;
982 void
983 Parrot_gc_completely_unblock(PARROT_INTERP)
985 ASSERT_ARGS(Parrot_gc_completely_unblock)
986 while (Parrot_is_blocked_GC_mark(interp))
987 Parrot_unblock_GC_mark(interp);
988 while (Parrot_is_blocked_GC_sweep(interp))
989 Parrot_unblock_GC_sweep(interp);
994 =item C<void Parrot_gc_pmc_needs_early_collection(PARROT_INTERP, PMC *pmc)>
996 Mark a PMC as needing timely destruction
998 =cut
1002 void
1003 Parrot_gc_pmc_needs_early_collection(PARROT_INTERP, ARGMOD(PMC *pmc))
1005 ASSERT_ARGS(Parrot_gc_pmc_needs_early_collection)
1006 if (interp->gc_sys->pmc_needs_early_collection)
1007 interp->gc_sys->pmc_needs_early_collection(interp, pmc);
1012 =item C<STRING * Parrot_gc_sys_name(PARROT_INTERP)>
1014 Retrieve the name of the currently active GC system.
1016 =cut
1020 PARROT_CANNOT_RETURN_NULL
1021 STRING *
1022 Parrot_gc_sys_name(PARROT_INTERP)
1024 ASSERT_ARGS(Parrot_gc_sys_name)
1025 STRING *name = NULL;
1026 switch (interp->gc_sys->sys_type) {
1027 case MS:
1028 name = Parrot_str_new(interp, "ms", 2);
1029 break;
1030 case INF:
1031 name = Parrot_str_new(interp, "inf", 3);
1032 break;
1033 default:
1034 name = Parrot_str_new(interp, "unknown", 7);
1035 break;
1037 PARROT_ASSERT(name != NULL);
1038 return name;
1043 =back
1045 =head1 SEE ALSO
1047 F<include/parrot/gc_api.h>, F<src/gc/system.c> and F<docs/pdds/pdd09_gc.pod>.
1049 =head1 HISTORY
1051 Initial version by Mike Lambert on 2002.05.27.
1053 =cut
1058 * Local variables:
1059 * c-file-style: "parrot"
1060 * End:
1061 * vim: expandtab shiftwidth=4: