// SPDX-License-Identifier: GPL-2.0-or-later /** @file * @brief Wrapper for Boehm GC */ /* Authors: * MenTaLguY * * 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 #include # include 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 :