2 * sgen-debug.c: Collector debugging
5 * Paolo Molaro (lupus@ximian.com)
6 * Rodrigo Kumpera (kumpera@gmail.com)
8 * Copyright 2005-2011 Novell, Inc (http://www.novell.com)
9 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
10 * Copyright 2011 Xamarin, Inc.
12 * Permission is hereby granted, free of charge, to any person obtaining
13 * a copy of this software and associated documentation files (the
14 * "Software"), to deal in the Software without restriction, including
15 * without limitation the rights to use, copy, modify, merge, publish,
16 * distribute, sublicense, and/or sell copies of the Software, and to
17 * permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #include "metadata/sgen-gc.h"
36 #include "metadata/sgen-cardtable.h"
37 #include "metadata/sgen-ssb.h"
38 #include "metadata/sgen-protocol.h"
40 #define LOAD_VTABLE SGEN_LOAD_VTABLE
42 #define object_is_forwarded SGEN_OBJECT_IS_FORWARDED
43 #define object_is_pinned SGEN_OBJECT_IS_PINNED
44 #define safe_object_get_size sgen_safe_object_get_size
46 void describe_ptr (char *ptr);
47 void check_object (char *start);
50 * ######################################################################
51 * ######## Collector debugging
52 * ######################################################################
55 const char*descriptor_types [] = {
67 describe_ptr (char *ptr)
74 if (sgen_ptr_in_nursery (ptr)) {
75 printf ("Pointer inside nursery.\n");
77 if (sgen_ptr_is_in_los (ptr, &start)) {
79 printf ("Pointer is the start of object %p in LOS space.\n", start);
81 printf ("Pointer is at offset 0x%x of object %p in LOS space.\n", (int)(ptr - start), start);
83 } else if (major_collector.ptr_is_in_non_pinned_space (ptr)) {
84 printf ("Pointer inside oldspace.\n");
85 } else if (major_collector.obj_is_from_pinned_alloc (ptr)) {
86 printf ("Pointer is inside a pinned chunk.\n");
88 printf ("Pointer unknown.\n");
93 if (object_is_pinned (ptr))
94 printf ("Object is pinned.\n");
96 if (object_is_forwarded (ptr))
97 printf ("Object is forwared.\n");
99 // FIXME: Handle pointers to the inside of objects
100 vtable = (MonoVTable*)LOAD_VTABLE (ptr);
102 printf ("VTable: %p\n", vtable);
103 if (vtable == NULL) {
104 printf ("VTable is invalid (empty).\n");
107 if (sgen_ptr_in_nursery (vtable)) {
108 printf ("VTable is invalid (points inside nursery).\n");
111 printf ("Class: %s\n", vtable->klass->name);
113 desc = ((GCVTable*)vtable)->desc;
114 printf ("Descriptor: %lx\n", (long)desc);
117 printf ("Descriptor type: %d (%s)\n", type, descriptor_types [type]);
120 static gboolean missing_remsets;
123 * We let a missing remset slide if the target object is pinned,
124 * because the store might have happened but the remset not yet added,
125 * but in that case the target must be pinned. We might theoretically
126 * miss some missing remsets this way, but it's very unlikely.
129 #define HANDLE_PTR(ptr,obj) do { \
130 if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) { \
131 if (!sgen_get_remset ()->find_address ((char*)(ptr))) { \
132 fprintf (gc_debug_file, "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.\n", *(ptr), (char*)(ptr) - (char*)(obj), (obj), ((MonoObject*)(obj))->vtable->klass->name_space, ((MonoObject*)(obj))->vtable->klass->name); \
133 binary_protocol_missing_remset ((obj), (gpointer)LOAD_VTABLE ((obj)), (char*)(ptr) - (char*)(obj), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \
134 if (!object_is_pinned (*(ptr))) \
135 missing_remsets = TRUE; \
141 * Check that each object reference which points into the nursery can
142 * be found in the remembered sets.
145 check_consistency_callback (char *start, size_t size, void *dummy)
147 GCVTable *vt = (GCVTable*)LOAD_VTABLE (start);
148 DEBUG (8, fprintf (gc_debug_file, "Scanning object %p, vtable: %p (%s)\n", start, vt, vt->klass->name));
150 #define SCAN_OBJECT_ACTION
151 #include "sgen-scan-object.h"
155 * Perform consistency check of the heap.
157 * Assumes the world is stopped.
160 sgen_check_consistency (void)
162 // Need to add more checks
164 missing_remsets = FALSE;
166 DEBUG (1, fprintf (gc_debug_file, "Begin heap consistency check...\n"));
168 // Check that oldspace->newspace pointers are registered with the collector
169 major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)check_consistency_callback, NULL);
171 sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_consistency_callback, NULL);
173 DEBUG (1, fprintf (gc_debug_file, "Heap consistency check done.\n"));
175 if (!binary_protocol_is_enabled ())
176 g_assert (!missing_remsets);
181 #define HANDLE_PTR(ptr,obj) do { \
182 if (*(ptr) && !LOAD_VTABLE (*(ptr))) \
183 g_error ("Could not load vtable for obj %p slot %d (size %d)", obj, (char*)ptr - (char*)obj, safe_object_get_size ((MonoObject*)obj)); \
187 check_major_refs_callback (char *start, size_t size, void *dummy)
189 #define SCAN_OBJECT_ACTION
190 #include "sgen-scan-object.h"
194 sgen_check_major_refs (void)
196 major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)check_major_refs_callback, NULL);
197 sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_major_refs_callback, NULL);
200 /* Check that the reference is valid */
202 #define HANDLE_PTR(ptr,obj) do { \
204 g_assert (sgen_safe_name (*(ptr)) != NULL); \
211 * Perform consistency check on an object. Currently we only check that the
212 * reference fields are valid.
215 check_object (char *start)
220 #include "sgen-scan-object.h"
223 #endif /*HAVE_SGEN_GC*/