#include "mono/sgen/sgen-memory-governor.h"
#include "mono/sgen/sgen-pinning.h"
#include "mono/sgen/sgen-client.h"
-#ifndef SGEN_WITHOUT_MONO
-#include "mono/metadata/sgen-bridge-internal.h"
-#endif
#define LOAD_VTABLE SGEN_LOAD_VTABLE
#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);
/*
* ######################################################################
static void
describe_pointer (char *ptr, gboolean need_setup)
{
- GCVTable *vtable;
- mword desc;
+ GCVTable vtable;
+ 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);
printf ("Pointer inside oldspace.\n");
if (start)
ptr = start;
- vtable = (GCVTable*)major_collector.describe_pointer (ptr);
- } else if (major_collector.obj_is_from_pinned_alloc (ptr)) {
+ vtable = (GCVTable)major_collector.describe_pointer (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;
printf ("VTable: %p\n", vtable);
if (vtable == NULL) {
printf ("VTable is invalid (empty).\n");
- goto bridge;
+ goto invalid_vtable;
}
if (sgen_ptr_in_nursery (vtable)) {
printf ("VTable is invalid (points inside nursery).\n");
- goto bridge;
+ goto invalid_vtable;
}
printf ("Class: %s.%s\n", sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
- desc = sgen_vtable_get_descriptor ((GCVTable*)vtable);
+ desc = sgen_vtable_get_descriptor (vtable);
printf ("Descriptor: %lx\n", (long)desc);
type = desc & DESC_TYPE_MASK;
size = sgen_safe_object_get_size ((GCObject*)ptr);
printf ("Size: %d\n", (int)size);
- bridge:
+ invalid_vtable:
;
-#ifndef SGEN_WITHOUT_MONO
- sgen_bridge_describe_pointer ((GCObject*)ptr);
-#endif
+ sgen_client_describe_invalid_pointer ((GCObject *) ptr);
}
void
#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)); \
+ 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))) \
* 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 ((GCVTable*)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"
}
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 (*(ptr) && !sgen_ptr_in_nursery ((char*)*(ptr)) && !is_major_or_los_object_marked ((GCObject*)*(ptr))) { \
if (!sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \
- GCVTable *__vt = SGEN_LOAD_VTABLE ((obj)); \
+ 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 ((GCVTable*)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);
+ cards = sgen_get_major_collector ()->get_cardtable_mod_union_for_reference (start);
SGEN_ASSERT (0, cards, "we must have mod union for marked major objects");
} 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;
}
if (!valid_nursery_objects)
valid_nursery_objects = sgen_alloc_os_memory (DEFAULT_NURSERY_SIZE, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "debugging data");
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,
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)))) \
+ if (!sgen_get_remset ()->find_address ((char*)(ptr)) && !sgen_cement_lookup (*(ptr)) && (!allow_missing_pinned || !SGEN_OBJECT_IS_PINNED (*(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 (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);
} 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;
#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
if ((GCObject*)*(ptr) == key) { \
- GCVTable *vtable = SGEN_LOAD_VTABLE (*(ptr)); \
+ GCVTable vtable = SGEN_LOAD_VTABLE (*(ptr)); \
g_print ("found ref to %p in object %p (%s.%s) at offset %zd\n", \
key, (obj), sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), ((char*)(ptr) - (char*)(obj))); \
} \
} 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);
}
check_key = key;
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
- mword desc = root->root_desc;
+ SgenDescriptor desc = root->root_desc;
check_root = root;
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);
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
RootRecord *root;
check_domain = domain;
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
- mword desc = root->root_desc;
+ SgenDescriptor desc = root->root_desc;
/* The MonoDomain struct is allowed to hold
references to objects in its own domain. */
}
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))
}
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;
+ MonoObject *ref = *ptr;
+ size_t offset = (char*)(ptr) - (char*)obj;
MonoClass *class;
MonoClassField *field;
char *str;
return;
field = NULL;
- for (class = o->vtable->klass; class; class = class->parent) {
+ for (class = obj->vtable->klass; class; class = class->parent) {
int i;
for (i = 0; i < class->field.count; ++i) {
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 ((GCVTable*)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
while (start < end) {
guint size;
- //GCVTable *vt;
+ //GCVTable vt;
//MonoClass *class;
if (!*(void**)start) {
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));
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;
- 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;
}
return found_obj;
}
-#ifndef SGEN_WITHOUT_MONO
-
-static int
-compare_xrefs (const void *a_ptr, const void *b_ptr)
-{
- const MonoGCBridgeXRef *a = a_ptr;
- const MonoGCBridgeXRef *b = b_ptr;
-
- if (a->src_scc_index < b->src_scc_index)
- return -1;
- if (a->src_scc_index > b->src_scc_index)
- return 1;
-
- if (a->dst_scc_index < b->dst_scc_index)
- return -1;
- if (a->dst_scc_index > b->dst_scc_index)
- return 1;
-
- return 0;
-}
-
-/*
-static void
-dump_processor_state (SgenBridgeProcessor *p)
-{
- int i;
-
- printf ("------\n");
- printf ("SCCS %d\n", p->num_sccs);
- for (i = 0; i < p->num_sccs; ++i) {
- int j;
- MonoGCBridgeSCC *scc = p->api_sccs [i];
- printf ("\tSCC %d:", i);
- for (j = 0; j < scc->num_objs; ++j) {
- MonoObject *obj = scc->objs [j];
- printf (" %p", obj);
- }
- printf ("\n");
- }
-
- printf ("XREFS %d\n", p->num_xrefs);
- for (i = 0; i < p->num_xrefs; ++i)
- printf ("\t%d -> %d\n", p->api_xrefs [i].src_scc_index, p->api_xrefs [i].dst_scc_index);
-
- printf ("-------\n");
-}
-*/
-
-gboolean
-sgen_compare_bridge_processor_results (SgenBridgeProcessor *a, SgenBridgeProcessor *b)
-{
- int i;
- SgenHashTable obj_to_a_scc = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_DEBUG, INTERNAL_MEM_BRIDGE_DEBUG, sizeof (int), mono_aligned_addr_hash, NULL);
- SgenHashTable b_scc_to_a_scc = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_DEBUG, INTERNAL_MEM_BRIDGE_DEBUG, sizeof (int), g_direct_hash, NULL);
- MonoGCBridgeXRef *a_xrefs, *b_xrefs;
- size_t xrefs_alloc_size;
-
- // dump_processor_state (a);
- // dump_processor_state (b);
-
- if (a->num_sccs != b->num_sccs)
- g_error ("SCCS count expected %d but got %d", a->num_sccs, b->num_sccs);
- if (a->num_xrefs != b->num_xrefs)
- g_error ("SCCS count expected %d but got %d", a->num_xrefs, b->num_xrefs);
-
- /*
- * First we build a hash of each object in `a` to its respective SCC index within
- * `a`. Along the way we also assert that no object is more than one SCC.
- */
- for (i = 0; i < a->num_sccs; ++i) {
- int j;
- MonoGCBridgeSCC *scc = a->api_sccs [i];
-
- g_assert (scc->num_objs > 0);
-
- for (j = 0; j < scc->num_objs; ++j) {
- GCObject *obj = scc->objs [j];
- gboolean new_entry = sgen_hash_table_replace (&obj_to_a_scc, obj, &i, NULL);
- g_assert (new_entry);
- }
- }
-
- /*
- * Now we check whether each of the objects in `b` are in `a`, and whether the SCCs
- * of `b` contain the same sets of objects as those of `a`.
- *
- * While we're doing this, build a hash table to map from `b` SCC indexes to `a` SCC
- * indexes.
- */
- for (i = 0; i < b->num_sccs; ++i) {
- MonoGCBridgeSCC *scc = b->api_sccs [i];
- MonoGCBridgeSCC *a_scc;
- int *a_scc_index_ptr;
- int a_scc_index;
- int j;
- gboolean new_entry;
-
- g_assert (scc->num_objs > 0);
- a_scc_index_ptr = sgen_hash_table_lookup (&obj_to_a_scc, scc->objs [0]);
- g_assert (a_scc_index_ptr);
- a_scc_index = *a_scc_index_ptr;
-
- //g_print ("A SCC %d -> B SCC %d\n", a_scc_index, i);
-
- a_scc = a->api_sccs [a_scc_index];
- g_assert (a_scc->num_objs == scc->num_objs);
-
- for (j = 1; j < scc->num_objs; ++j) {
- a_scc_index_ptr = sgen_hash_table_lookup (&obj_to_a_scc, scc->objs [j]);
- g_assert (a_scc_index_ptr);
- g_assert (*a_scc_index_ptr == a_scc_index);
- }
-
- new_entry = sgen_hash_table_replace (&b_scc_to_a_scc, GINT_TO_POINTER (i), &a_scc_index, NULL);
- g_assert (new_entry);
- }
-
- /*
- * Finally, check that we have the same xrefs. We do this by making copies of both
- * xref arrays, and replacing the SCC indexes in the copy for `b` with the
- * corresponding indexes in `a`. Then we sort both arrays and assert that they're
- * the same.
- *
- * At the same time, check that no xref is self-referential and that there are no
- * duplicate ones.
- */
-
- xrefs_alloc_size = a->num_xrefs * sizeof (MonoGCBridgeXRef);
- a_xrefs = sgen_alloc_internal_dynamic (xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG, TRUE);
- b_xrefs = sgen_alloc_internal_dynamic (xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG, TRUE);
-
- memcpy (a_xrefs, a->api_xrefs, xrefs_alloc_size);
- for (i = 0; i < b->num_xrefs; ++i) {
- MonoGCBridgeXRef *xref = &b->api_xrefs [i];
- int *scc_index_ptr;
-
- g_assert (xref->src_scc_index != xref->dst_scc_index);
-
- scc_index_ptr = sgen_hash_table_lookup (&b_scc_to_a_scc, GINT_TO_POINTER (xref->src_scc_index));
- g_assert (scc_index_ptr);
- b_xrefs [i].src_scc_index = *scc_index_ptr;
-
- scc_index_ptr = sgen_hash_table_lookup (&b_scc_to_a_scc, GINT_TO_POINTER (xref->dst_scc_index));
- g_assert (scc_index_ptr);
- b_xrefs [i].dst_scc_index = *scc_index_ptr;
- }
-
- qsort (a_xrefs, a->num_xrefs, sizeof (MonoGCBridgeXRef), compare_xrefs);
- qsort (b_xrefs, a->num_xrefs, sizeof (MonoGCBridgeXRef), compare_xrefs);
-
- for (i = 0; i < a->num_xrefs; ++i) {
- g_assert (a_xrefs [i].src_scc_index == b_xrefs [i].src_scc_index);
- g_assert (a_xrefs [i].dst_scc_index == b_xrefs [i].dst_scc_index);
- }
-
- sgen_hash_table_clean (&obj_to_a_scc);
- sgen_hash_table_clean (&b_scc_to_a_scc);
- sgen_free_internal_dynamic (a_xrefs, xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG);
- sgen_free_internal_dynamic (b_xrefs, xrefs_alloc_size, INTERNAL_MEM_BRIDGE_DEBUG);
-
- return TRUE;
-}
-
-#endif
-
#endif /*HAVE_SGEN_GC*/