dc76e9913c0023ba1534f1608bd6edcb263d39e4
[mono.git] / mono / metadata / gc.c
1 /*
2  * metadata/gc.c: GC icalls.
3  *
4  * Author: Paolo Molaro <lupus@ximian.com>
5  *
6  * (C) 2002 Ximian, Inc.
7  */
8
9 #include <config.h>
10 #include <glib.h>
11 #include <string.h>
12
13 #include <mono/metadata/gc.h>
14 #include <mono/metadata/threads.h>
15 #if HAVE_BOEHM_GC
16 #include <gc/gc.h>
17 #endif
18
19 static int finalize_slot = -1;
20
21 /* 
22  * actually, we might want to queue the finalize requests in a separate thread,
23  * but we need to be careful about the execution domain of the thread...
24  */
25 static void
26 run_finalize (void *obj, void *data)
27 {
28         MonoObject *exc = NULL;
29         MonoObject *o;
30         o = (MonoObject*)((char*)obj + GPOINTER_TO_UINT (data));
31
32         if (finalize_slot < 0) {
33                 int i;
34                 for (i = 0; i < mono_defaults.object_class->vtable_size; ++i) {
35                         MonoMethod *cm = mono_defaults.object_class->vtable [i];
36                
37                         if (!strcmp (cm->name, "Finalize")) {
38                                 finalize_slot = i;
39                                 break;
40                         }
41                 }
42         }
43         /* speedup later... */
44         /* g_print ("Finalize run on %s\n", mono_object_class (o)->name); */
45         mono_runtime_invoke (o->vtable->klass->vtable [finalize_slot], o, NULL, &exc);
46
47         if (exc) {
48                 /* fixme: do something useful */
49         }
50 }
51
52 /*
53  * Some of our objects may point to a different address than the address returned by GC_malloc()
54  * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer.
55  * This also means that in the callback we need to adjust the pointer to get back the real
56  * MonoObject*.
57  * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, 
58  * since that, too, can cause the underlying pointer to be offset.
59  */
60 static void
61 object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
62 {
63 #if HAVE_BOEHM_GC
64         guint offset = 0;
65
66         g_assert (GC_base (obj) == (char*)obj - offset);
67         GC_register_finalizer ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL);
68 #endif
69 }
70
71 void
72 mono_object_register_finalizer (MonoObject *obj)
73 {
74         object_register_finalizer (obj, run_finalize);
75 }
76
77 void
78 ves_icall_System_GC_InternalCollect (int generation)
79 {
80 #if HAVE_BOEHM_GC
81         GC_gcollect ();
82 #endif
83 }
84
85 gint64
86 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
87 {
88 #if HAVE_BOEHM_GC
89         if (forceCollection)
90                 GC_gcollect ();
91         return GC_get_heap_size ();
92 #else
93         return 0;
94 #endif
95 }
96
97 void
98 ves_icall_System_GC_KeepAlive (MonoObject *obj)
99 {
100         /*
101          * Does nothing.
102          */
103 }
104
105 void
106 ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj)
107 {
108         object_register_finalizer (obj, run_finalize);
109 }
110
111 void
112 ves_icall_System_GC_SuppressFinalize (MonoObject *obj)
113 {
114         object_register_finalizer (obj, NULL);
115 }
116
117 void
118 ves_icall_System_GC_WaitForPendingFinalizers (void)
119 {
120 }
121