2
* @brief Wrapper for Boehm GC
5
* MenTaLguY <mental@rydia.net>
7
* Copyright (C) 2004 MenTaLguY
9
* Released under GNU GPL, read the file 'COPYING' for more information
16
#include <glib/gmessages.h>
17
#include <sigc++/functors/ptr_fun.h>
18
#include <glibmm/main.h>
25
void display_warning(char *msg, GC_word arg) {
31
GC_all_interior_pointers = 1;
32
GC_finalize_on_demand = 0;
36
GC_set_warn_proc(&display_warning);
39
void *debug_malloc(std::size_t size) {
40
return GC_debug_malloc(size, GC_EXTRAS);
43
void *debug_malloc_atomic(std::size_t size) {
44
return GC_debug_malloc_atomic(size, GC_EXTRAS);
47
void *debug_malloc_uncollectable(std::size_t size) {
48
return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
51
void *debug_malloc_atomic_uncollectable(std::size_t size) {
52
return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
55
std::ptrdiff_t compute_debug_base_fixup() {
56
char *base=reinterpret_cast<char *>(GC_debug_malloc(1, GC_EXTRAS));
57
char *real_base=reinterpret_cast<char *>(GC_base(base));
59
return base - real_base;
62
inline std::ptrdiff_t const &debug_base_fixup() {
63
static std::ptrdiff_t fixup=compute_debug_base_fixup();
67
void *debug_base(void *ptr) {
68
char *base=reinterpret_cast<char *>(GC_base(ptr));
69
return base + debug_base_fixup();
72
int debug_general_register_disappearing_link(void **p_ptr, void *base) {
73
char *real_base=reinterpret_cast<char *>(base) - debug_base_fixup();
74
return GC_general_register_disappearing_link(p_ptr, real_base);
77
void dummy_do_init() {}
79
void *dummy_base(void *) { return NULL; }
81
void dummy_register_finalizer(void *, CleanupFunc, void *,
82
CleanupFunc *old_func, void **old_data)
92
int dummy_general_register_disappearing_link(void **, void *) { return false; }
94
int dummy_unregister_disappearing_link(void **/*link*/) { return false; }
96
std::size_t dummy_get_heap_size() { return 0; }
98
std::size_t dummy_get_free_bytes() { return 0; }
100
void dummy_gcollect() {}
102
void dummy_enable() {}
104
void dummy_disable() {}
110
&GC_malloc_uncollectable,
111
&GC_malloc_atomic_uncollectable,
113
&GC_register_finalizer_ignore_self,
114
&GC_general_register_disappearing_link,
115
&GC_unregister_disappearing_link,
127
&debug_malloc_atomic,
128
&debug_malloc_uncollectable,
129
&debug_malloc_atomic_uncollectable,
131
&GC_debug_register_finalizer_ignore_self,
132
&debug_general_register_disappearing_link,
133
&GC_unregister_disappearing_link,
149
&dummy_register_finalizer,
150
&dummy_general_register_disappearing_link,
151
&dummy_unregister_disappearing_link,
152
&dummy_get_heap_size,
153
&dummy_get_free_bytes,
160
class InvalidGCModeError : public std::runtime_error {
162
InvalidGCModeError(const char *mode)
163
: runtime_error(std::string("Unknown GC mode \"") + mode + "\"")
167
Ops const &get_ops() throw (InvalidGCModeError) {
168
char *mode_string=std::getenv("_INKSCAPE_GC");
170
if (!std::strcmp(mode_string, "enable")) {
172
} else if (!std::strcmp(mode_string, "debug")) {
174
} else if (!std::strcmp(mode_string, "disable")) {
177
throw InvalidGCModeError(mode_string);
184
void die_because_not_initialized() {
185
g_error("Attempt to use GC allocator before call to Inkscape::GC::init()");
188
void *stub_malloc(std::size_t) {
189
die_because_not_initialized();
193
void *stub_base(void *) {
194
die_because_not_initialized();
198
void stub_register_finalizer_ignore_self(void *, CleanupFunc, void *,
199
CleanupFunc *, void **)
201
die_because_not_initialized();
204
int stub_general_register_disappearing_link(void **, void *) {
205
die_because_not_initialized();
209
int stub_unregister_disappearing_link(void **) {
210
die_because_not_initialized();
214
std::size_t stub_get_heap_size() {
215
die_because_not_initialized();
219
std::size_t stub_get_free_bytes() {
220
die_because_not_initialized();
224
void stub_gcollect() {
225
die_because_not_initialized();
229
die_because_not_initialized();
232
void stub_disable() {
233
die_because_not_initialized();
236
void stub_free(void *) {
237
die_because_not_initialized();
249
&stub_register_finalizer_ignore_self,
250
&stub_general_register_disappearing_link,
251
&stub_unregister_disappearing_link,
253
&stub_get_free_bytes,
263
} catch (InvalidGCModeError &e) {
264
g_warning("%s; enabling normal collection", e.what());
274
bool collection_requested=false;
275
bool collection_task() {
278
collection_requested=false;
284
void request_early_collection() {
285
if (!collection_requested) {
286
collection_requested=true;
287
Glib::signal_idle().connect(sigc::ptr_fun(&collection_task));
297
c-file-style:"stroustrup"
298
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
303
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :