summaryrefslogtreecommitdiffstats
path: root/src/inkgc/gc-core.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inkgc/gc-core.h')
-rw-r--r--src/inkgc/gc-core.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/inkgc/gc-core.h b/src/inkgc/gc-core.h
new file mode 100644
index 0000000..cbd4b7e
--- /dev/null
+++ b/src/inkgc/gc-core.h
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * @brief Wrapper for Boehm GC
+ */
+/* Authors:
+ * MenTaLguY <mental@rydia.net>
+ *
+ * Copyright (C) 2004 MenTaLguY
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifndef SEEN_INKSCAPE_GC_CORE_H
+#define SEEN_INKSCAPE_GC_CORE_H
+
+#include <new>
+#include <cstdlib>
+
+# include <gc.h>
+
+namespace Inkscape {
+namespace GC {
+
+enum ScanPolicy {
+ SCANNED,
+ ATOMIC
+};
+
+enum CollectionPolicy {
+ AUTO,
+ MANUAL
+};
+
+enum Delete {
+ GC
+};
+
+typedef void (*CleanupFunc)(void *mem, void *data);
+
+struct Ops {
+ void (*do_init)();
+ void *(*malloc)(std::size_t size);
+ void *(*malloc_atomic)(std::size_t size);
+ void *(*malloc_uncollectable)(std::size_t size);
+ void *(*malloc_atomic_uncollectable)(std::size_t size);
+ void *(*base)(void *ptr);
+ void (*register_finalizer_ignore_self)(void *base,
+ CleanupFunc func, void *data,
+ CleanupFunc *old_func,
+ void **old_data);
+ int (*general_register_disappearing_link)(void **p_ptr,
+ void const *base);
+ int (*unregister_disappearing_link)(void **p_ptr);
+ std::size_t (*get_heap_size)();
+ std::size_t (*get_free_bytes)();
+ void (*gcollect)();
+ void (*enable)();
+ void (*disable)();
+ void (*free)(void *ptr);
+};
+
+struct Core {
+public:
+ static void init();
+ static inline void *malloc(std::size_t size) {
+ return _ops.malloc(size);
+ }
+ static inline void *malloc_atomic(std::size_t size) {
+ return _ops.malloc_atomic(size);
+ }
+ static inline void *malloc_uncollectable(std::size_t size) {
+ return _ops.malloc_uncollectable(size);
+ }
+ static inline void *malloc_atomic_uncollectable(std::size_t size) {
+ return _ops.malloc_atomic_uncollectable(size);
+ }
+ static inline void *base(void *ptr) {
+ return _ops.base(ptr);
+ }
+ static inline void register_finalizer_ignore_self(void *base,
+ CleanupFunc func,
+ void *data,
+ CleanupFunc *old_func,
+ void **old_data)
+ {
+ return _ops.register_finalizer_ignore_self(base, func, data,
+ old_func, old_data);
+ }
+ static inline int general_register_disappearing_link(void **p_ptr,
+ void *base)
+ {
+ return _ops.general_register_disappearing_link(p_ptr, base);
+ }
+ static inline int unregister_disappearing_link(void **p_ptr) {
+ return _ops.unregister_disappearing_link(p_ptr);
+ }
+ static inline std::size_t get_heap_size() {
+ return _ops.get_heap_size();
+ }
+ static inline std::size_t get_free_bytes() {
+ return _ops.get_free_bytes();
+ }
+ static inline void gcollect() {
+ _ops.gcollect();
+ }
+ static inline void enable() {
+ _ops.enable();
+ }
+ static inline void disable() {
+ _ops.disable();
+ }
+ static inline void free(void *ptr) {
+ return _ops.free(ptr);
+ }
+private:
+ static Ops _ops;
+};
+
+inline void init() {
+ Core::init();
+}
+
+void request_early_collection();
+
+}
+}
+
+inline void *operator new(std::size_t size,
+ Inkscape::GC::ScanPolicy scan,
+ Inkscape::GC::CollectionPolicy collect,
+ Inkscape::GC::CleanupFunc cleanup=nullptr,
+ void *data=nullptr)
+{
+ using namespace Inkscape::GC;
+
+ void *mem;
+ if ( collect == AUTO ) {
+ if ( scan == SCANNED ) {
+ mem = Core::malloc(size);
+ } else {
+ mem = Core::malloc_atomic(size);
+ }
+ } else {
+ if ( scan == SCANNED ) {
+ mem = Core::malloc_uncollectable(size);
+ } else {
+ mem = Core::malloc_atomic_uncollectable(size);
+ }
+ }
+ if (!mem) {
+ throw std::bad_alloc();
+ }
+ if (cleanup) {
+ Core::register_finalizer_ignore_self(mem, cleanup, data, nullptr, nullptr);
+ }
+ return mem;
+}
+
+inline void *operator new(std::size_t size,
+ Inkscape::GC::ScanPolicy scan,
+ Inkscape::GC::CleanupFunc cleanup=nullptr,
+ void *data=nullptr)
+{
+ return operator new(size, scan, Inkscape::GC::AUTO, cleanup, data);
+}
+
+inline void *operator new[](std::size_t size,
+ Inkscape::GC::ScanPolicy scan,
+ Inkscape::GC::CollectionPolicy collect,
+ Inkscape::GC::CleanupFunc cleanup=nullptr,
+ void *data=nullptr)
+{
+ return operator new(size, scan, collect, cleanup, data);
+}
+
+inline void *operator new[](std::size_t size,
+ Inkscape::GC::ScanPolicy scan,
+ Inkscape::GC::CleanupFunc cleanup=nullptr,
+ void *data=nullptr)
+{
+ return operator new[](size, scan, Inkscape::GC::AUTO, cleanup, data);
+}
+
+inline void operator delete(void *mem, Inkscape::GC::Delete) {
+ Inkscape::GC::Core::free(mem);
+}
+
+inline void operator delete[](void *mem, Inkscape::GC::Delete) {
+ operator delete(mem, Inkscape::GC::GC);
+}
+
+#endif
+/*
+ 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:fileencoding=utf-8:textwidth=99 :