-/*
- * sgen-debug.c: Collector debugging
+/**
+ * \file
+ * Collector debugging
*
* Author:
* Paolo Molaro (lupus@ximian.com)
* Copyright 2011 Xamarin, Inc.
* Copyright (C) 2012 Xamarin Inc
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License 2.0 as published by the Free Software Foundation;
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License 2.0 along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
#define safe_object_get_size sgen_safe_object_get_size
void describe_ptr (char *ptr);
-void check_object (char *start);
+void check_object (GCObject *obj);
/*
* ######################################################################
describe_pointer (char *ptr, gboolean need_setup)
{
GCVTable vtable;
- mword desc;
+ SgenDescriptor desc;
int type;
char *start;
char *forwarded;
if (!start)
return;
ptr = start;
- vtable = (GCVTable)LOAD_VTABLE (ptr);
+ vtable = LOAD_VTABLE ((GCObject*)ptr);
} else {
if (sgen_ptr_is_in_los (ptr, &start)) {
if (ptr == start)
printf ("Pointer is at offset 0x%x of object %p in LOS space.\n", (int)(ptr - start), start);
ptr = start;
mono_sgen_los_describe_pointer (ptr);
- vtable = (GCVTable)LOAD_VTABLE (ptr);
+ vtable = LOAD_VTABLE ((GCObject*)ptr);
} else if (major_collector.ptr_is_in_non_pinned_space (ptr, &start)) {
if (ptr == start)
printf ("Pointer is the start of object %p in oldspace.\n", start);
if (start)
ptr = start;
vtable = (GCVTable)major_collector.describe_pointer (ptr);
- } else if (major_collector.obj_is_from_pinned_alloc (ptr)) {
+ } else if (major_collector.ptr_is_from_pinned_alloc (ptr)) {
// FIXME: Handle pointers to the inside of objects
printf ("Pointer is inside a pinned chunk.\n");
- vtable = (GCVTable)LOAD_VTABLE (ptr);
+ vtable = LOAD_VTABLE ((GCObject*)ptr);
} else {
printf ("Pointer unknown.\n");
return;
if (object_is_pinned (ptr))
printf ("Object is pinned.\n");
- if ((forwarded = object_is_forwarded (ptr))) {
+ if ((forwarded = (char *)object_is_forwarded (ptr))) {
printf ("Object is forwarded to %p:\n", forwarded);
ptr = forwarded;
goto restart;
*/
#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
- if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) { \
- if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) { \
- GCVTable __vt = SGEN_LOAD_VTABLE ((obj)); \
- SGEN_LOG (0, "Oldspace->newspace reference %p at offset %zd in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt)); \
- binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \
- if (!object_is_pinned (*(ptr))) \
- missing_remsets = TRUE; \
- } \
- } \
+ if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) { \
+ if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) { \
+ GCVTable __vt = SGEN_LOAD_VTABLE (obj); \
+ gboolean is_pinned = object_is_pinned (*(ptr)); \
+ SGEN_LOG (0, "Oldspace->newspace reference %p at offset %zd in object %p (%s.%s) not found in remsets%s.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt), is_pinned ? ", but object is pinned" : ""); \
+ binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), is_pinned); \
+ if (!is_pinned) \
+ missing_remsets = TRUE; \
+ } \
+ } \
} while (0)
/*
* be found in the remembered sets.
*/
static void
-check_consistency_callback (char *start, size_t size, void *dummy)
+check_consistency_callback (GCObject *obj, size_t size, void *dummy)
{
- GCVTable vt = (GCVTable)LOAD_VTABLE (start);
- mword desc = sgen_vtable_get_descriptor (vt);
+ char *start = (char*)obj;
+ GCVTable vt = LOAD_VTABLE (obj);
+ SgenDescriptor desc = sgen_vtable_get_descriptor (vt);
SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", start, vt, sgen_client_vtable_get_name (vt));
#include "sgen-scan-object.h"
* Assumes the world is stopped.
*/
void
-sgen_check_consistency (void)
+sgen_check_remset_consistency (void)
{
// Need to add more checks
SGEN_LOG (1, "Heap consistency check done.");
+ if (missing_remsets)
+ binary_protocol_flush_buffers (TRUE);
if (!binary_protocol_is_enabled ())
g_assert (!missing_remsets);
}
static gboolean
-is_major_or_los_object_marked (char *obj)
+is_major_or_los_object_marked (GCObject *obj)
{
if (sgen_safe_object_get_size ((GCObject*)obj) > SGEN_MAX_SMALL_OBJ_SIZE) {
return sgen_los_object_is_pinned (obj);
#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
- if (*(ptr) && !sgen_ptr_in_nursery ((char*)*(ptr)) && !is_major_or_los_object_marked ((char*)*(ptr))) { \
- if (!sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \
- GCVTable __vt = SGEN_LOAD_VTABLE ((obj)); \
+ if (*(ptr) && !sgen_ptr_in_nursery ((char*)*(ptr)) && !is_major_or_los_object_marked ((GCObject*)*(ptr))) { \
+ if (!cards || !sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \
+ GCVTable __vt = SGEN_LOAD_VTABLE (obj); \
SGEN_LOG (0, "major->major reference %p at offset %zd in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt)); \
binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \
missing_remsets = TRUE; \
} while (0)
static void
-check_mod_union_callback (char *start, size_t size, void *dummy)
+check_mod_union_callback (GCObject *obj, size_t size, void *dummy)
{
+ char *start = (char*)obj;
gboolean in_los = (gboolean) (size_t) dummy;
- GCVTable vt = (GCVTable)LOAD_VTABLE (start);
- mword desc = sgen_vtable_get_descriptor (vt);
+ GCVTable vt = LOAD_VTABLE (obj);
+ SgenDescriptor desc = sgen_vtable_get_descriptor (vt);
guint8 *cards;
- SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", start, vt, sgen_client_vtable_get_name (vt));
+ SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", obj, vt, sgen_client_vtable_get_name (vt));
- if (!is_major_or_los_object_marked (start))
+ if (!is_major_or_los_object_marked (obj))
return;
if (in_los)
- cards = sgen_los_header_for_object (start)->cardtable_mod_union;
+ cards = sgen_los_header_for_object (obj)->cardtable_mod_union;
else
- cards = sgen_get_major_collector ()->get_cardtable_mod_union_for_object (start);
-
- SGEN_ASSERT (0, cards, "we must have mod union for marked major objects");
+ cards = sgen_get_major_collector ()->get_cardtable_mod_union_for_reference (start);
#include "sgen-scan-object.h"
}
{
missing_remsets = FALSE;
- major_collector.iterate_objects (ITERATE_OBJECTS_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE);
+ major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE);
sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_mod_union_callback, (void*)TRUE);
} while (0)
static void
-check_major_refs_callback (char *start, size_t size, void *dummy)
+check_major_refs_callback (GCObject *obj, size_t size, void *dummy)
{
- mword desc = sgen_obj_get_descriptor (start);
+ char *start = (char*)obj;
+ SgenDescriptor desc = sgen_obj_get_descriptor (obj);
#include "sgen-scan-object.h"
}
* reference fields are valid.
*/
void
-check_object (char *start)
+check_object (GCObject *obj)
{
- mword desc;
+ char *start = (char*)obj;
+ SgenDescriptor desc;
if (!start)
return;
- desc = sgen_obj_get_descriptor (start);
+ desc = sgen_obj_get_descriptor (obj);
#include "sgen-scan-object.h"
}
-static char **valid_nursery_objects;
+static GCObject **valid_nursery_objects;
static int valid_nursery_object_count;
static gboolean broken_heap;
static void
-setup_mono_sgen_scan_area_with_callback (char *object, size_t size, void *data)
+setup_mono_sgen_scan_area_with_callback (GCObject *object, size_t size, void *data)
{
valid_nursery_objects [valid_nursery_object_count++] = object;
}
setup_valid_nursery_objects (void)
{
if (!valid_nursery_objects)
- valid_nursery_objects = sgen_alloc_os_memory (DEFAULT_NURSERY_SIZE, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "debugging data");
+ valid_nursery_objects = (GCObject **)sgen_alloc_os_memory (sgen_nursery_max_size, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), "debugging data", MONO_MEM_ACCOUNT_SGEN_DEBUGGING);
valid_nursery_object_count = 0;
- sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, setup_mono_sgen_scan_area_with_callback, NULL, FALSE);
+ sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, setup_mono_sgen_scan_area_with_callback, NULL, FALSE, FALSE);
}
static gboolean
int first = 0, last = valid_nursery_object_count;
while (first < last) {
int middle = first + ((last - first) >> 1);
- if (object == valid_nursery_objects [middle])
+ if (object == (char*)valid_nursery_objects [middle])
return TRUE;
- if (object < valid_nursery_objects [middle])
+ if (object < (char*)valid_nursery_objects [middle])
last = middle;
else
first = middle + 1;
{
int i;
for (i = 0; i < valid_nursery_object_count; ++i) {
- char *obj = valid_nursery_objects [i];
- callback (obj, safe_object_get_size ((GCObject*)obj), data);
+ GCObject *obj = valid_nursery_objects [i];
+ callback (obj, safe_object_get_size (obj), data);
}
}
setup_valid_nursery_objects ();
for (i = 0; i < valid_nursery_object_count - 1; ++i) {
- if (valid_nursery_objects [i + 1] > ptr)
+ if ((char*)valid_nursery_objects [i + 1] > ptr)
break;
}
- if (i >= valid_nursery_object_count || valid_nursery_objects [i] + safe_object_get_size ((GCObject *)valid_nursery_objects [i]) < ptr) {
+ if (i >= valid_nursery_object_count || (char*)valid_nursery_objects [i] + safe_object_get_size (valid_nursery_objects [i]) < ptr) {
SGEN_LOG (0, "nursery-ptr (unalloc'd-memory)");
return NULL;
} else {
- char *obj = valid_nursery_objects [i];
- if (obj == ptr)
+ GCObject *obj = valid_nursery_objects [i];
+ if ((char*)obj == ptr)
SGEN_LOG (0, "nursery-ptr %p", obj);
else
- SGEN_LOG (0, "nursery-ptr %p (interior-ptr offset %zd)", obj, ptr - obj);
- return obj;
+ SGEN_LOG (0, "nursery-ptr %p (interior-ptr offset %zd)", obj, ptr - (char*)obj);
+ return (char*)obj;
}
}
bad_pointer_spew (char *obj, char **slot)
{
char *ptr = *slot;
- GCVTable vtable = (GCVTable)LOAD_VTABLE (obj);
+ GCVTable vtable = LOAD_VTABLE ((GCObject*)obj);
SGEN_LOG (0, "Invalid object pointer %p at offset %zd in object %p (%s.%s):", ptr,
(char*)slot - obj,
missing_remset_spew (char *obj, char **slot)
{
char *ptr = *slot;
- GCVTable vtable = (GCVTable)LOAD_VTABLE (obj);
+ GCVTable vtable = LOAD_VTABLE ((GCObject*)obj);
SGEN_LOG (0, "Oldspace->newspace reference %p at offset %zd in object %p (%s.%s) not found in remsets.",
ptr, (char*)slot - obj, obj,
FIXME Flag missing remsets due to pinning as non fatal
*/
#undef HANDLE_PTR
-#define HANDLE_PTR(ptr,obj) do { \
- if (*(char**)ptr) { \
+#define HANDLE_PTR(ptr,obj) do { \
+ if (*(char**)ptr) { \
if (!is_valid_object_pointer (*(char**)ptr)) { \
- bad_pointer_spew ((char*)obj, (char**)ptr); \
- } else if (!sgen_ptr_in_nursery (obj) && sgen_ptr_in_nursery ((char*)*ptr)) { \
- if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup ((char*)*(ptr)) && (!allow_missing_pinned || !SGEN_OBJECT_IS_PINNED ((char*)*(ptr)))) \
- missing_remset_spew ((char*)obj, (char**)ptr); \
- } \
- } \
+ bad_pointer_spew ((char*)obj, (char**)ptr); \
+ } else if (!sgen_ptr_in_nursery (obj) && sgen_ptr_in_nursery ((char*)*ptr)) { \
+ if (!allow_missing_pinned && !SGEN_OBJECT_IS_PINNED (*(ptr)) && !sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr))) \
+ missing_remset_spew ((char*)obj, (char**)ptr); \
+ } \
+ } \
} while (0)
static void
-verify_object_pointers_callback (char *start, size_t size, void *data)
+verify_object_pointers_callback (GCObject *obj, size_t size, void *data)
{
+ char *start = (char*)obj;
gboolean allow_missing_pinned = (gboolean) (size_t) data;
- mword desc = sgen_obj_get_descriptor (start);
+ SgenDescriptor desc = sgen_obj_get_descriptor_safe (obj);
#include "sgen-scan-object.h"
}
setup_valid_nursery_objects ();
broken_heap = FALSE;
- sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned, FALSE);
+ sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned, FALSE, TRUE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned);
sgen_los_iterate_objects (verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned);
find_pinning_ref_from_thread (char *obj, size_t size)
{
#ifndef SGEN_WITHOUT_MONO
- int j;
- SgenThreadInfo *info;
char *endobj = obj + size;
FOREACH_THREAD (info) {
+ mword *ctxstart, *ctxcurrent, *ctxend;
char **start = (char**)info->client_info.stack_start;
if (info->client_info.skip || info->client_info.gc_disabled)
continue;
- while (start < (char**)info->client_info.stack_end) {
+ while (start < (char**)info->client_info.info.stack_end) {
if (*start >= obj && *start < endobj)
- SGEN_LOG (0, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->client_info.stack_start, info->client_info.stack_end);
+ SGEN_LOG (0, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->client_info.stack_start, info->client_info.info.stack_end);
start++;
}
- for (j = 0; j < ARCH_NUM_REGS; ++j) {
-#ifdef USE_MONO_CTX
- mword w = ((mword*)&info->client_info.ctx) [j];
-#else
- mword w = (mword)&info->client_info.regs [j];
-#endif
+ for (ctxstart = ctxcurrent = (mword*) &info->client_info.ctx, ctxend = (mword*) (&info->client_info.ctx + 1); ctxcurrent < ctxend; ctxcurrent ++) {
+ mword w = *ctxcurrent;
if (w >= (mword)obj && w < (mword)obj + size)
- SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, j, info, (gpointer)mono_thread_info_get_tid (info));
- } END_FOREACH_THREAD
- }
+ SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, (int) (ctxcurrent - ctxstart), info, (gpointer)mono_thread_info_get_tid (info));
+ }
+ } FOREACH_THREAD_END
#endif
}
RootRecord *root;
char *endobj = obj + size;
- SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_NORMAL], start, root) {
+ SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_NORMAL], char **, start, RootRecord *, root) {
/* if desc is non-null it has precise info */
if (!root->root_desc) {
while (start < (char**)root->end_root) {
} else { \
mword __size = sgen_safe_object_get_size ((GCObject*)__target); \
if (__size <= SGEN_MAX_SMALL_OBJ_SIZE) \
- g_assert (major_collector.is_object_live (__target)); \
+ g_assert (major_collector.is_object_live ((GCObject*)__target)); \
else \
- g_assert (sgen_los_object_is_pinned (__target)); \
+ g_assert (sgen_los_object_is_pinned ((GCObject*)__target)); \
} \
} \
} while (0)
static void
-check_marked_callback (char *start, size_t size, void *dummy)
+check_marked_callback (GCObject *obj, size_t size, void *dummy)
{
+ char *start = (char*)obj;
gboolean flag = (gboolean) (size_t) dummy;
- mword desc;
+ SgenDescriptor desc;
if (sgen_ptr_in_nursery (start)) {
if (flag)
- SGEN_ASSERT (0, SGEN_OBJECT_IS_PINNED (start), "All objects remaining in the nursery must be pinned");
+ SGEN_ASSERT (0, SGEN_OBJECT_IS_PINNED (obj), "All objects remaining in the nursery must be pinned");
} else if (flag) {
- if (!sgen_los_object_is_pinned (start))
+ if (!sgen_los_object_is_pinned (obj))
return;
} else {
- if (!major_collector.is_object_live (start))
+ if (!major_collector.is_object_live (obj))
return;
}
- desc = sgen_obj_get_descriptor_safe (start);
+ desc = sgen_obj_get_descriptor_safe (obj);
#include "sgen-scan-object.h"
}
{
sgen_clear_nursery_fragments ();
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
- (IterateObjectCallbackFunc)check_nursery_objects_pinned_callback, (void*) (size_t) pinned /* (void*)&ctx */, FALSE);
+ (IterateObjectCallbackFunc)check_nursery_objects_pinned_callback, (void*) (size_t) pinned /* (void*)&ctx */, FALSE, TRUE);
}
static void
verify_scan_starts (cur, cur + size);
is_array_fill = sgen_client_object_is_array_fill ((GCObject*)cur);
if (do_dump_nursery_content) {
- GCVTable vtable = SGEN_LOAD_VTABLE (cur);
+ GCVTable vtable = SGEN_LOAD_VTABLE ((GCObject*)cur);
if (cur > hole_start)
SGEN_LOG (0, "HOLE [%p %p %d]", hole_start, cur, (int)(cur - hole_start));
SGEN_LOG (0, "OBJ [%p %p %d %d %s.%s %d]", cur, cur + size, (int)size, (int)ss,
is_array_fill);
}
if (nursery_canaries_enabled () && !is_array_fill) {
- CHECK_CANARY_FOR_OBJECT (cur);
+ CHECK_CANARY_FOR_OBJECT ((GCObject*)cur, TRUE);
CANARIFY_SIZE (size);
}
cur += size;
} while (0)
static void
-scan_object_for_specific_ref (char *start, GCObject *key)
+scan_object_for_specific_ref (GCObject *obj, GCObject *key)
{
- char *forwarded;
+ GCObject *forwarded;
- if ((forwarded = SGEN_OBJECT_IS_FORWARDED (start)))
- start = forwarded;
+ if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj)))
+ obj = forwarded;
if (scan_object_for_specific_ref_precise) {
- mword desc = sgen_obj_get_descriptor_safe (start);
+ char *start = (char*)obj;
+ SgenDescriptor desc = sgen_obj_get_descriptor_safe (obj);
#include "sgen-scan-object.h"
} else {
- mword *words = (mword*)start;
- size_t size = safe_object_get_size ((GCObject*)start);
+ mword *words = (mword*)obj;
+ size_t size = safe_object_get_size (obj);
int i;
for (i = 0; i < size / sizeof (mword); ++i) {
if (words [i] == (mword)key) {
- GCVTable vtable = SGEN_LOAD_VTABLE (start);
+ GCVTable vtable = SGEN_LOAD_VTABLE (obj);
g_print ("found possible ref to %p in object %p (%s.%s) at offset %zd\n",
- key, start, sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), i * sizeof (mword));
+ key, obj, sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), i * sizeof (mword));
}
}
}
}
static void
-scan_object_for_specific_ref_callback (char *obj, size_t size, GCObject *key)
+scan_object_for_specific_ref_callback (GCObject *obj, size_t size, GCObject *key)
{
scan_object_for_specific_ref (obj, key);
}
static RootRecord *check_root = NULL;
static void
-check_root_obj_specific_ref_from_marker (void **obj, void *gc_data)
+check_root_obj_specific_ref_from_marker (GCObject **obj, void *gc_data)
{
check_root_obj_specific_ref (check_root, check_key, *obj);
}
RootRecord *root;
check_key = key;
- SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
- mword desc = root->root_desc;
+ SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], void **, start_root, RootRecord *, root) {
+ SgenDescriptor desc = root->root_desc;
check_root = root;
desc >>= ROOT_DESC_TYPE_SHIFT;
while (desc) {
if (desc & 1)
- check_root_obj_specific_ref (root, key, *start_root);
+ check_root_obj_specific_ref (root, key, (GCObject *)*start_root);
desc >>= 1;
start_root++;
}
return;
case ROOT_DESC_COMPLEX: {
- gsize *bitmap_data = sgen_get_complex_descriptor_bitmap (desc);
+ gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc);
int bwords = (int) ((*bitmap_data) - 1);
void **start_run = start_root;
bitmap_data++;
void **objptr = start_run;
while (bmap) {
if (bmap & 1)
- check_root_obj_specific_ref (root, key, *objptr);
+ check_root_obj_specific_ref (root, key, (GCObject *)*objptr);
bmap >>= 1;
++objptr;
}
}
break;
}
+ case ROOT_DESC_VECTOR: {
+ void **p;
+
+ for (p = start_root; p < (void**)root->end_root; p++) {
+ if (*p)
+ check_root_obj_specific_ref (root, key, (GCObject *)*p);
+ }
+ break;
+ }
case ROOT_DESC_USER: {
SgenUserRootMarkFunc marker = sgen_get_user_descriptor_func (desc);
marker (start_root, check_root_obj_specific_ref_from_marker, NULL);
scan_object_for_specific_ref_precise = precise;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
- (IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key, TRUE);
+ (IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key, TRUE, FALSE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key);
scan_roots_for_specific_ref (key, ROOT_TYPE_NORMAL);
scan_roots_for_specific_ref (key, ROOT_TYPE_WBARRIER);
- SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_PINNED], ptr, root) {
+ SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_PINNED], void **, ptr, RootRecord *, root) {
while (ptr < (void**)root->end_root) {
- check_root_obj_specific_ref (root, *ptr, key);
+ check_root_obj_specific_ref (root, (GCObject *)*ptr, key);
++ptr;
}
} SGEN_HASH_TABLE_FOREACH_END;
static void
-check_obj_not_in_domain_callback (void **o, void *gc_data)
+check_obj_not_in_domain_callback (GCObject **o, void *gc_data)
{
- g_assert (((MonoObject*)(*o))->vtable->domain != check_domain);
+ g_assert ((*o)->vtable->domain != check_domain);
}
void
void **start_root;
RootRecord *root;
check_domain = domain;
- SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
- mword desc = root->root_desc;
+ SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], void **, start_root, RootRecord *, root) {
+ SgenDescriptor desc = root->root_desc;
/* The MonoDomain struct is allowed to hold
references to objects in its own domain. */
desc >>= ROOT_DESC_TYPE_SHIFT;
while (desc) {
if ((desc & 1) && *start_root)
- check_obj_not_in_domain (*start_root);
+ check_obj_not_in_domain ((MonoObject **)*start_root);
desc >>= 1;
start_root++;
}
break;
case ROOT_DESC_COMPLEX: {
- gsize *bitmap_data = sgen_get_complex_descriptor_bitmap (desc);
+ gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc);
int bwords = (int)((*bitmap_data) - 1);
void **start_run = start_root;
bitmap_data++;
void **objptr = start_run;
while (bmap) {
if ((bmap & 1) && *objptr)
- check_obj_not_in_domain (*objptr);
+ check_obj_not_in_domain ((MonoObject **)*objptr);
bmap >>= 1;
++objptr;
}
}
break;
}
+ case ROOT_DESC_VECTOR: {
+ void **p;
+
+ for (p = start_root; p < (void**)root->end_root; p++) {
+ if (*p)
+ check_obj_not_in_domain ((MonoObject **)*p);
+ }
+ break;
+ }
case ROOT_DESC_USER: {
SgenUserRootMarkFunc marker = sgen_get_user_descriptor_func (desc);
marker (start_root, check_obj_not_in_domain_callback, NULL);
}
static gboolean
-is_xdomain_ref_allowed (gpointer *ptr, char *obj, MonoDomain *domain)
+is_xdomain_ref_allowed (GCObject **ptr, GCObject *obj, MonoDomain *domain)
{
MonoObject *o = (MonoObject*)(obj);
- MonoObject *ref = (MonoObject*)*(ptr);
+ MonoObject *ref = *ptr;
size_t offset = (char*)(ptr) - (char*)o;
if (o->vtable->klass == mono_defaults.thread_class && offset == G_STRUCT_OFFSET (MonoThread, internal_thread))
offset == G_STRUCT_OFFSET (MonoRealProxy, unwrapped_server))
return TRUE;
#endif
- /* Thread.cached_culture_info */
- if (!strcmp (ref->vtable->klass->name_space, "System.Globalization") &&
- !strcmp (ref->vtable->klass->name, "CultureInfo") &&
- !strcmp(o->vtable->klass->name_space, "System") &&
- !strcmp(o->vtable->klass->name, "Object[]"))
- return TRUE;
/*
* at System.IO.MemoryStream.InternalConstructor (byte[],int,int,bool,bool) [0x0004d] in /home/schani/Work/novell/trunk/mcs/class/corlib/System.IO/MemoryStream.cs:121
* at System.IO.MemoryStream..ctor (byte[]) [0x00017] in /home/schani/Work/novell/trunk/mcs/class/corlib/System.IO/MemoryStream.cs:81
}
static void
-check_reference_for_xdomain (gpointer *ptr, char *obj, MonoDomain *domain)
+check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain)
{
- MonoObject *o = (MonoObject*)(obj);
- MonoObject *ref = (MonoObject*)*(ptr);
- size_t offset = (char*)(ptr) - (char*)o;
- MonoClass *class;
+ MonoObject *ref = *ptr;
+ size_t offset = (char*)(ptr) - (char*)obj;
+ MonoClass *klass;
MonoClassField *field;
char *str;
return;
field = NULL;
- for (class = o->vtable->klass; class; class = class->parent) {
+ for (klass = obj->vtable->klass; klass; klass = klass->parent) {
int i;
- for (i = 0; i < class->field.count; ++i) {
- if (class->fields[i].offset == offset) {
- field = &class->fields[i];
+ int fcount = mono_class_get_field_count (klass);
+ for (i = 0; i < fcount; ++i) {
+ if (klass->fields[i].offset == offset) {
+ field = &klass->fields[i];
break;
}
}
break;
}
- if (ref->vtable->klass == mono_defaults.string_class)
- str = mono_string_to_utf8 ((MonoString*)ref);
- else
+ if (ref->vtable->klass == mono_defaults.string_class) {
+ MonoError error;
+ str = mono_string_to_utf8_checked ((MonoString*)ref, &error);
+ mono_error_cleanup (&error);
+ } else
str = NULL;
g_print ("xdomain reference in %p (%s.%s) at offset %d (%s) to %p (%s.%s) (%s) - pointed to by:\n",
- o, o->vtable->klass->name_space, o->vtable->klass->name,
+ obj, obj->vtable->klass->name_space, obj->vtable->klass->name,
offset, field ? field->name : "",
ref, ref->vtable->klass->name_space, ref->vtable->klass->name, str ? str : "");
- mono_gc_scan_for_specific_ref (o, TRUE);
+ mono_gc_scan_for_specific_ref (obj, TRUE);
if (str)
g_free (str);
}
#define HANDLE_PTR(ptr,obj) check_reference_for_xdomain ((ptr), (obj), domain)
static void
-scan_object_for_xdomain_refs (char *start, mword size, void *data)
+scan_object_for_xdomain_refs (GCObject *obj, mword size, void *data)
{
- MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (start);
+ char *start = (char*)obj;
+ MonoVTable *vt = SGEN_LOAD_VTABLE (obj);
MonoDomain *domain = vt->domain;
- mword desc = sgen_vtable_get_descriptor (vt);
+ SgenDescriptor desc = sgen_vtable_get_descriptor (vt);
#include "sgen-scan-object.h"
}
LOSObject *bigobj;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
- (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL, FALSE);
+ (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL, FALSE, TRUE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL);
for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
- scan_object_for_xdomain_refs (bigobj->data, sgen_los_object_size (bigobj), NULL);
+ scan_object_for_xdomain_refs ((GCObject*)bigobj->data, sgen_los_object_size (bigobj), NULL);
}
#endif
sgen_dump_section (GCMemSection *section, const char *type)
{
char *start = section->data;
- char *end = section->data + section->size;
+ char *end = section->end_data;
char *occ_start = NULL;
- fprintf (heap_dump_file, "<section type=\"%s\" size=\"%lu\">\n", type, (unsigned long)section->size);
+ fprintf (heap_dump_file, "<section type=\"%s\" size=\"%lu\">\n", type, (unsigned long)(section->end_data - section->data));
while (start < end) {
guint size;
start += sizeof (void*); /* should be ALLOC_ALIGN, really */
continue;
}
- g_assert (start < section->next_data);
if (!occ_start)
occ_start = start;
- //vt = (GCVTable)SGEN_LOAD_VTABLE (start);
+ //vt = SGEN_LOAD_VTABLE (start);
//class = vt->klass;
size = SGEN_ALIGN_UP (safe_object_get_size ((GCObject*) start));
#ifndef SGEN_WITHOUT_MONO
static char class_name [1024];
- MonoClass *class = mono_object_class (obj);
+ MonoClass *klass = mono_object_class (obj);
int i, j;
/*
* in strings, so we just ignore them;
*/
i = j = 0;
- while (class->name [i] && j < sizeof (class_name) - 1) {
- if (!strchr ("<>\"", class->name [i]))
- class_name [j++] = class->name [i];
+ while (klass->name [i] && j < sizeof (class_name) - 1) {
+ if (!strchr ("<>\"", klass->name [i]))
+ class_name [j++] = klass->name [i];
++i;
}
g_assert (j < sizeof (class_name));
class_name [j] = 0;
fprintf (heap_dump_file, "<object class=\"%s.%s\" size=\"%zd\"",
- class->name_space, class_name,
+ klass->name_space, class_name,
safe_object_get_size (obj));
if (dump_location) {
const char *location;
fprintf (heap_dump_file, "<pinned-objects>\n");
pinned_objects = sgen_pin_stats_get_object_list ();
for (i = 0; i < pinned_objects->next_slot; ++i)
- dump_object (pinned_objects->data [i], TRUE);
+ dump_object ((GCObject *)pinned_objects->data [i], TRUE);
fprintf (heap_dump_file, "</pinned-objects>\n");
sgen_dump_section (nursery_section, "nursery");
fprintf (heap_dump_file, "</collection>\n");
}
-static char *found_obj;
+static GCObject *found_obj;
static void
-find_object_for_ptr_callback (char *obj, size_t size, void *user_data)
+find_object_for_ptr_callback (GCObject *obj, size_t size, void *user_data)
{
- char *ptr = user_data;
+ char *ptr = (char *)user_data;
- if (ptr >= obj && ptr < obj + size) {
+ if (ptr >= (char*)obj && ptr < (char*)obj + size) {
g_assert (!found_obj);
found_obj = obj;
}
}
/* for use in the debugger */
-char*
+GCObject*
sgen_find_object_for_ptr (char *ptr)
{
if (ptr >= nursery_section->data && ptr < nursery_section->end_data) {
found_obj = NULL;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
- find_object_for_ptr_callback, ptr, TRUE);
+ find_object_for_ptr_callback, ptr, TRUE, FALSE);
if (found_obj)
return found_obj;
}