summaryrefslogtreecommitdiffstats
path: root/src/gc.cpp
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/gc.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/gc.cpp')
-rw-r--r--src/gc.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/src/gc.cpp b/src/gc.cpp
new file mode 100644
index 000000000..7333b4641
--- /dev/null
+++ b/src/gc.cpp
@@ -0,0 +1,279 @@
+/*
+ * Inkscape::GC - Wrapper for Boehm GC
+ *
+ * Authors:
+ * MenTaLguY <mental@rydia.net>
+ *
+ * Copyright (C) 2004 MenTaLguY
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "gc-core.h"
+#include <stdexcept>
+#include <glib/gmessages.h>
+
+namespace Inkscape {
+namespace GC {
+
+namespace {
+
+void display_warning(char *msg, GC_word arg) {
+ g_warning(msg, arg);
+}
+
+void do_init() {
+ GC_no_dls = 1;
+ GC_all_interior_pointers = 1;
+ GC_finalize_on_demand = 0;
+
+ GC_INIT();
+
+ GC_set_warn_proc(&display_warning);
+}
+
+void *debug_malloc(std::size_t size) {
+ return GC_debug_malloc(size, GC_EXTRAS);
+}
+
+void *debug_malloc_atomic(std::size_t size) {
+ return GC_debug_malloc_atomic(size, GC_EXTRAS);
+}
+
+void *debug_malloc_uncollectable(std::size_t size) {
+ return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
+}
+
+void *debug_malloc_atomic_uncollectable(std::size_t size) {
+ return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
+}
+
+std::ptrdiff_t compute_debug_base_fixup() {
+ char *base=reinterpret_cast<char *>(GC_debug_malloc(1, GC_EXTRAS));
+ char *real_base=reinterpret_cast<char *>(GC_base(base));
+ GC_debug_free(base);
+ return base - real_base;
+}
+
+inline std::ptrdiff_t const &debug_base_fixup() {
+ static std::ptrdiff_t fixup=compute_debug_base_fixup();
+ return fixup;
+}
+
+void *debug_base(void *ptr) {
+ char *base=reinterpret_cast<char *>(GC_base(ptr));
+ return base + debug_base_fixup();
+}
+
+int debug_general_register_disappearing_link(void **p_ptr, void *base) {
+ char *real_base=reinterpret_cast<char *>(base) - debug_base_fixup();
+ return GC_general_register_disappearing_link(p_ptr, real_base);
+}
+
+void dummy_do_init() {}
+
+void *dummy_base(void *) { return NULL; }
+
+void dummy_register_finalizer(void *, CleanupFunc, void *,
+ CleanupFunc *old_func, void **old_data)
+{
+ if (old_func) {
+ *old_func = NULL;
+ }
+ if (old_data) {
+ *old_data = NULL;
+ }
+}
+
+int dummy_general_register_disappearing_link(void **, void *) { return false; }
+
+int dummy_unregister_disappearing_link(void **link) { return false; }
+
+std::size_t dummy_get_heap_size() { return 0; }
+
+std::size_t dummy_get_free_bytes() { return 0; }
+
+void dummy_gcollect() {}
+
+void dummy_enable() {}
+
+void dummy_disable() {}
+
+Ops enabled_ops = {
+ &do_init,
+ &GC_malloc,
+ &GC_malloc_atomic,
+ &GC_malloc_uncollectable,
+ &GC_malloc_atomic_uncollectable,
+ &GC_base,
+ &GC_register_finalizer_ignore_self,
+ &GC_general_register_disappearing_link,
+ &GC_unregister_disappearing_link,
+ &GC_get_heap_size,
+ &GC_get_free_bytes,
+ &GC_gcollect,
+ &GC_enable,
+ &GC_disable,
+ &GC_free
+};
+
+Ops debug_ops = {
+ &do_init,
+ &debug_malloc,
+ &debug_malloc_atomic,
+ &debug_malloc_uncollectable,
+ &debug_malloc_atomic_uncollectable,
+ &debug_base,
+ &GC_debug_register_finalizer_ignore_self,
+ &debug_general_register_disappearing_link,
+ &GC_unregister_disappearing_link,
+ &GC_get_heap_size,
+ &GC_get_free_bytes,
+ &GC_gcollect,
+ &GC_enable,
+ &GC_disable,
+ &GC_debug_free
+};
+
+Ops disabled_ops = {
+ &dummy_do_init,
+ &std::malloc,
+ &std::malloc,
+ &std::malloc,
+ &std::malloc,
+ &dummy_base,
+ &dummy_register_finalizer,
+ &dummy_general_register_disappearing_link,
+ &dummy_unregister_disappearing_link,
+ &dummy_get_heap_size,
+ &dummy_get_free_bytes,
+ &dummy_gcollect,
+ &dummy_enable,
+ &dummy_disable,
+ &std::free
+};
+
+class InvalidGCModeError : public std::runtime_error {
+public:
+ InvalidGCModeError(const char *mode)
+ : runtime_error(std::string("Unknown GC mode \"") + mode + "\"")
+ {}
+};
+
+Ops const &get_ops() throw (InvalidGCModeError) {
+ char *mode_string=std::getenv("_INKSCAPE_GC");
+ if (mode_string) {
+ if (!std::strcmp(mode_string, "enable")) {
+ return enabled_ops;
+ } else if (!std::strcmp(mode_string, "debug")) {
+ return debug_ops;
+ } else if (!std::strcmp(mode_string, "disable")) {
+ return disabled_ops;
+ } else {
+ throw InvalidGCModeError(mode_string);
+ }
+ } else {
+ return enabled_ops;
+ }
+}
+
+void die_because_not_initialized() {
+ g_error("Attempt to use GC allocator before call to Inkscape::GC::init()");
+}
+
+void *stub_malloc(std::size_t) {
+ die_because_not_initialized();
+ return NULL;
+}
+
+void *stub_base(void *) {
+ die_because_not_initialized();
+ return NULL;
+}
+
+void stub_register_finalizer_ignore_self(void *, CleanupFunc, void *,
+ CleanupFunc *, void **)
+{
+ die_because_not_initialized();
+}
+
+int stub_general_register_disappearing_link(void **, void *) {
+ die_because_not_initialized();
+ return 0;
+}
+
+int stub_unregister_disappearing_link(void **) {
+ die_because_not_initialized();
+ return 0;
+}
+
+std::size_t stub_get_heap_size() {
+ die_because_not_initialized();
+ return 0;
+}
+
+std::size_t stub_get_free_bytes() {
+ die_because_not_initialized();
+ return 0;
+}
+
+void stub_gcollect() {
+ die_because_not_initialized();
+}
+
+void stub_enable() {
+ die_because_not_initialized();
+}
+
+void stub_disable() {
+ die_because_not_initialized();
+}
+
+void stub_free(void *) {
+ die_because_not_initialized();
+}
+
+}
+
+Ops Core::_ops = {
+ NULL,
+ &stub_malloc,
+ &stub_malloc,
+ &stub_malloc,
+ &stub_malloc,
+ &stub_base,
+ &stub_register_finalizer_ignore_self,
+ &stub_general_register_disappearing_link,
+ &stub_unregister_disappearing_link,
+ &stub_get_heap_size,
+ &stub_get_free_bytes,
+ &stub_gcollect,
+ &stub_enable,
+ &stub_disable,
+ &stub_free
+};
+
+void Core::init() {
+ try {
+ _ops = get_ops();
+ } catch (InvalidGCModeError &e) {
+ g_warning("%s; enabling normal collection", e.what());
+ _ops = enabled_ops;
+ }
+
+ _ops.do_init();
+}
+
+}
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :