diff options
Diffstat (limited to 'src/inkgc/gc-core.h')
-rw-r--r-- | src/inkgc/gc-core.h | 202 |
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 : |