[svn:parrot] r43283 - in branches/boehm_gc: config/gen/makefiles src/gc
bacek at svn.parrot.org
bacek at svn.parrot.org
Mon Dec 28 22:12:14 UTC 2009
Author: bacek
Date: Mon Dec 28 22:12:13 2009
New Revision: 43283
URL: https://trac.parrot.org/parrot/changeset/43283
Log:
Almost blindly copy gc_inf into gc_boehm.
Added:
branches/boehm_gc/src/gc/gc_boehm.c
Modified:
branches/boehm_gc/config/gen/makefiles/root.in
branches/boehm_gc/src/gc/gc_private.h
Modified: branches/boehm_gc/config/gen/makefiles/root.in
==============================================================================
--- branches/boehm_gc/config/gen/makefiles/root.in Mon Dec 28 22:11:47 2009 (r43282)
+++ branches/boehm_gc/config/gen/makefiles/root.in Mon Dec 28 22:12:13 2009 (r43283)
@@ -473,6 +473,7 @@
$(SRC_DIR)/gc/api$(O) \
$(SRC_DIR)/gc/gc_ms$(O) \
$(SRC_DIR)/gc/gc_inf$(O) \
+ $(SRC_DIR)/gc/gc_boehm$(O) \
$(SRC_DIR)/gc/mark_sweep$(O) \
$(SRC_DIR)/gc/system$(O) \
$(SRC_DIR)/global$(O) \
@@ -1149,6 +1150,8 @@
$(SRC_DIR)/gc/gc_inf$(O) : $(PARROT_H_HEADERS) $(SRC_DIR)/gc/gc_private.h
+$(SRC_DIR)/gc/gc_boehm$(O) : $(PARROT_H_HEADERS) $(SRC_DIR)/gc/gc_private.h
+
$(SRC_DIR)/gc/api$(O) : $(PARROT_H_HEADERS) $(SRC_DIR)/gc/gc_private.h
$(SRC_DIR)/gc/alloc_resources$(O) : $(PARROT_H_HEADERS) \
Added: branches/boehm_gc/src/gc/gc_boehm.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/boehm_gc/src/gc/gc_boehm.c Mon Dec 28 22:12:13 2009 (r43283)
@@ -0,0 +1,270 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/gc/gc_boehm.c - A Boehm GC in Parrot.
+
+=head1 DESCRIPTION
+
+This code plugs Boehm GC into Parrot.
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "gc_private.h"
+
+#if HAS_BOEHM_GC
+
+#include <gc.h>
+
+/* HEADERIZER HFILE: src/gc/gc_private.h */
+
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+static void gc_boehm_add_free_object(SHIM_INTERP,
+ ARGMOD(Fixed_Size_Pool *pool),
+ ARGIN(void *to_add))
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*pool);
+
+static void gc_boehm_alloc_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
+PARROT_CANNOT_RETURN_NULL
+static void * gc_boehm_get_free_object(SHIM_INTERP,
+ ARGMOD(Fixed_Size_Pool *pool))
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
+static void gc_boehm_mark_and_sweep(SHIM_INTERP, UINTVAL flags);
+static void gc_boehm_more_traceable_objects(SHIM_INTERP,
+ ARGMOD(Fixed_Size_Pool *pool))
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
+static void gc_boehm_pool_init(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*pool);
+
+#define ASSERT_ARGS_gc_boehm_add_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool) \
+ , PARROT_ASSERT_ARG(to_add))
+#define ASSERT_ARGS_gc_boehm_alloc_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_gc_boehm_get_free_object __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_gc_boehm_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_gc_boehm_more_traceable_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_gc_boehm_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(pool))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+/* HEADERIZER END: static */
+
+/*
+
+=head1 Functions
+
+=over 4
+
+=item C<static void gc_boehm_mark_and_sweep(PARROT_INTERP, UINTVAL flags)>
+
+This function would perform a GC run, if we needed to. Luckily we have
+infinite memory!
+
+This function is called from the GC API function C<Parrot_gc_mark_and_sweep>.
+
+Flags can be a combination of these values:
+
+ GC_finish_FLAG
+ GC_lazy_FLAG
+ GC_trace_stack_FLAG
+
+=cut
+
+*/
+
+static void
+gc_boehm_mark_and_sweep(SHIM_INTERP, UINTVAL flags)
+{
+ ASSERT_ARGS(gc_boehm_mark_and_sweep)
+ UNUSED(flags);
+}
+
+/*
+
+=item C<static void gc_boehm_add_free_object(PARROT_INTERP, Fixed_Size_Pool *pool,
+void *to_add)>
+
+Manually frees a chunk of memory. Normally this would return the memory
+to the free list of the pool, but in this case we just return it to the
+OS.
+
+This function is called from places like C<Parrot_gc_free_pmc_header> and
+related manual freeing functions. Some cores will also use it internally to
+add items to the freelist from a freshly allocated arena.
+
+=cut
+
+*/
+
+static void
+gc_boehm_add_free_object(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool),
+ ARGIN(void *to_add))
+{
+ ASSERT_ARGS(gc_boehm_add_free_object)
+ if (to_add)
+ free(to_add);
+}
+
+/*
+
+=item C<static void * gc_boehm_get_free_object(PARROT_INTERP, Fixed_Size_Pool
+*pool)>
+
+Gets a new object from the pool. Each pool specifies an object size in
+C<pool->object_size> so we can use that number to make the allocation. For
+GCs that manage their own memory through the use of arenas or similar
+structures, we can use this basic algorithm here:
+
+ 1) Check if we have any items on the free list and allocate one from there
+ if so.
+ 2) Do a GC run to try and free up new items, and allocate a newly freed
+ item if one becomes available
+ 3) Allocate a new arena from the OS and allocate a new item from there.
+
+This function is called from GC API functions like
+C<Parrot_Gc_get_new_pmc_header>
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+static void *
+gc_boehm_get_free_object(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+{
+ ASSERT_ARGS(gc_boehm_get_free_object)
+ return GC_MALLOC(pool->object_size, 1);
+}
+
+/*
+
+=item C<static void gc_boehm_alloc_objects(PARROT_INTERP, Fixed_Size_Pool *pool)>
+
+Allocates a new arena of objects from the system. This function is only
+really used internally by the core, the API functions don't need to call
+it directly. However, this function is necessary because we may have
+different behaviors for certain pools, so we can't allocate for all of them
+in the same way. We will need to have a new "alloc_objects" function
+for each special case pool.
+
+=cut
+
+*/
+
+static void
+gc_boehm_alloc_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+{
+ ASSERT_ARGS(gc_boehm_alloc_objects)
+ UNUSED(pool);
+}
+
+/*
+
+=item C<static void gc_boehm_more_traceable_objects(PARROT_INTERP, Fixed_Size_Pool
+*pool)>
+
+Would normally try to find new traceable objects by first running a GC sweep
+and then allocating a new arena from the system. Neither of these are
+necessary in the infinite memory collector.
+
+This function is only used internally to the core, and is not called directly
+from the GC API. Different pools may have special requirements so multiple
+"more_traceable_objects" functions may need to be written and used.
+
+=cut
+
+*/
+
+static void
+gc_boehm_more_traceable_objects(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+{
+ ASSERT_ARGS(gc_boehm_more_traceable_objects)
+ UNUSED(pool);
+}
+
+/*
+
+=item C<static void gc_boehm_pool_init(PARROT_INTERP, Fixed_Size_Pool *pool)>
+
+Initializes the function pointers in a new pool. When a new pool is created
+we assign several function pointers to it for managing memory in the pool.
+In this way we can treat different pools differently if they have special
+management needs. In general all PObj-like pools are treated the same.
+
+This function is mostly called from the function C<initialize_fixed_size_pools>
+in F<src/gc/mark_sweep.c> at Parrot startup.
+
+=cut
+
+*/
+
+static void
+gc_boehm_pool_init(SHIM_INTERP, ARGMOD(Fixed_Size_Pool *pool))
+{
+ ASSERT_ARGS(gc_boehm_pool_init)
+ pool->add_free_object = gc_boehm_add_free_object;
+ pool->get_free_object = gc_boehm_get_free_object;
+ pool->alloc_objects = gc_boehm_alloc_objects;
+ pool->more_objects = gc_boehm_more_traceable_objects;
+}
+
+/*
+
+=item C<void Parrot_gc_boehm_init(PARROT_INTERP)>
+
+Initializes the infinite memory collector. Installs the necessary function
+pointers into the Memory_Pools structure. The two most important are the
+C<mark_and_sweep> and C<pool_init> functions. C<finalize_gc_system> function
+will be called at Parrot exit and will shut down the GC system if things
+need to be flushed/closed/deactivated/freed/etc. It can be set to NULL if no
+finalization is necessary.
+
+=cut
+
+*/
+
+void
+Parrot_gc_boehm_init(PARROT_INTERP)
+{
+ ASSERT_ARGS(Parrot_gc_boehm_init)
+
+ interp->gc_sys->do_gc_mark = gc_boehm_mark_and_sweep;
+ interp->gc_sys->finalize_gc_system = NULL;
+ interp->gc_sys->init_pool = gc_boehm_pool_init;
+}
+
+#endif /* HAS_BOEHM_GC */
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Modified: branches/boehm_gc/src/gc/gc_private.h
==============================================================================
--- branches/boehm_gc/src/gc/gc_private.h Mon Dec 28 22:11:47 2009 (r43282)
+++ branches/boehm_gc/src/gc/gc_private.h Mon Dec 28 22:12:13 2009 (r43283)
@@ -517,6 +517,17 @@
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/gc/gc_inf.c */
+/* HEADERIZER BEGIN: src/gc/gc_boehm.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+void Parrot_gc_boehm_init(PARROT_INTERP)
+ __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_Parrot_gc_boehm_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+/* HEADERIZER END: src/gc/gc_boehm.c */
+
#endif /* PARROT_GC_PRIVATE_H_GUARD */
More information about the parrot-commits
mailing list