X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-tarjan-bridge.c;h=764d9d72626db8df7ac104204980b8e3fb0abd45;hb=ef0ddf45c3081e799edcb4e95770186514b80cf1;hp=59013f70124aa832120f3c0a2216964bea45e1f4;hpb=b9afa882093e6c112faa386ab205f90a056866db;p=mono.git diff --git a/mono/metadata/sgen-tarjan-bridge.c b/mono/metadata/sgen-tarjan-bridge.c index 59013f70124..764d9d72626 100644 --- a/mono/metadata/sgen-tarjan-bridge.c +++ b/mono/metadata/sgen-tarjan-bridge.c @@ -4,37 +4,11 @@ * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2014 Xamarin Inc (http://www.xamarin.com) * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" @@ -43,15 +17,12 @@ #include -#include "sgen-gc.h" -#include "sgen-bridge.h" -#include "sgen-hash-table.h" -#include "sgen-qsort.h" +#include "sgen/sgen-gc.h" +#include "sgen-bridge-internals.h" +#include "sgen/sgen-hash-table.h" +#include "sgen/sgen-qsort.h" #include "tabledefs.h" -#include "utils/mono-logger-internal.h" -#include "utils/mono-time.h" -#include "utils/mono-compiler.h" - +#include "utils/mono-logger-internals.h" typedef struct { int size; @@ -91,7 +62,7 @@ dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size) while (capacity > da->capacity) da->capacity *= 2; - new_data = sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE); + new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE); if (da->data) { memcpy (new_data, da->data, elem_size * da->size); sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA); @@ -140,7 +111,7 @@ dyn_array_ptr_get (DynPtrArray *da, int x) static void dyn_array_ptr_add (DynPtrArray *da, void *ptr) { - void **p = dyn_array_add (&da->array, sizeof (void*)); + void **p = (void **)dyn_array_add (&da->array, sizeof (void*)); *p = ptr; } @@ -182,28 +153,28 @@ enable_accounting (void) } static MonoGCBridgeObjectKind -class_kind (MonoClass *class) +class_kind (MonoClass *klass) { - MonoGCBridgeObjectKind res = bridge_callbacks.bridge_class_kind (class); + MonoGCBridgeObjectKind res = bridge_callbacks.bridge_class_kind (klass); /* If it's a bridge, nothing we can do about it. */ if (res == GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS || res == GC_BRIDGE_OPAQUE_BRIDGE_CLASS) return res; /* Non bridge classes with no pointers will never point to a bridge, so we can savely ignore them. */ - if (!class->has_references) { - SGEN_LOG (6, "class %s is opaque\n", class->name); + if (!klass->has_references) { + SGEN_LOG (6, "class %s is opaque\n", klass->name); return GC_BRIDGE_OPAQUE_CLASS; } /* Some arrays can be ignored */ - if (class->rank == 1) { - MonoClass *elem_class = class->element_class; + if (klass->rank == 1) { + MonoClass *elem_class = klass->element_class; /* FIXME the bridge check can be quite expensive, cache it at the class level. */ /* An array of a sealed type that is not a bridge will never get to a bridge */ if ((elem_class->flags & TYPE_ATTRIBUTE_SEALED) && !elem_class->has_references && !bridge_callbacks.bridge_class_kind (elem_class)) { - SGEN_LOG (6, "class %s is opaque\n", class->name); + SGEN_LOG (6, "class %s is opaque\n", klass->name); return GC_BRIDGE_OPAQUE_CLASS; } } @@ -234,7 +205,7 @@ typedef struct { typedef struct { - MonoObject *obj; //XXX this can be eliminated. + GCObject *obj; //XXX this can be eliminated. mword lock_word; ColorData *color; @@ -279,7 +250,7 @@ static int object_data_count; static ObjectBucket* new_object_bucket (void) { - ObjectBucket *res = sgen_alloc_internal (INTERNAL_MEM_TARJAN_OBJ_BUCKET); + ObjectBucket *res = (ObjectBucket *)sgen_alloc_internal (INTERNAL_MEM_TARJAN_OBJ_BUCKET); res->next_data = &res->data [0]; return res; } @@ -343,7 +314,7 @@ static int color_data_count; static ColorBucket* new_color_bucket (void) { - ColorBucket *res = sgen_alloc_internal (INTERNAL_MEM_TARJAN_OBJ_BUCKET); + ColorBucket *res = (ColorBucket *)sgen_alloc_internal (INTERNAL_MEM_TARJAN_OBJ_BUCKET); res->next_data = &res->data [0]; return res; } @@ -394,7 +365,7 @@ free_color_buckets (void) static ScanData* -create_data (MonoObject *obj) +create_data (GCObject *obj) { mword *o = (mword*)obj; ScanData *res = alloc_object_data (); @@ -410,7 +381,7 @@ create_data (MonoObject *obj) } static ScanData* -find_data (MonoObject *obj) +find_data (GCObject *obj) { ScanData *a = NULL; mword *o = (mword*)obj; @@ -435,10 +406,10 @@ clear_after_processing (void) } } -static MonoObject* -bridge_object_forward (MonoObject *obj) +static GCObject* +bridge_object_forward (GCObject *obj) { - MonoObject *fwd; + GCObject *fwd; mword *o = (mword*)obj; if ((o [0] & SGEN_VTABLE_BITS_MASK) == SGEN_VTABLE_BITS_MASK) return obj; @@ -449,14 +420,14 @@ bridge_object_forward (MonoObject *obj) #ifdef DUMP_GRAPH static const char* -safe_name_bridge (MonoObject *obj) +safe_name_bridge (GCObject *obj) { - MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj); + GCVTable vt = SGEN_LOAD_VTABLE (obj); return vt->klass->name; } static ScanData* -find_or_create_data (MonoObject *obj) +find_or_create_data (GCObject *obj) { ScanData *entry = find_data (obj); if (!entry) @@ -586,15 +557,15 @@ new_color (gboolean force_new) static void -register_bridge_object (MonoObject *obj) +register_bridge_object (GCObject *obj) { create_data (obj)->is_bridge = TRUE; } static gboolean -is_opaque_object (MonoObject *obj) +is_opaque_object (GCObject *obj) { - MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj); + MonoVTable *vt = SGEN_LOAD_VTABLE (obj); if ((vt->gc_bits & SGEN_GC_BIT_BRIDGE_OPAQUE_OBJECT) == SGEN_GC_BIT_BRIDGE_OPAQUE_OBJECT) { SGEN_LOG (6, "ignoring %s\n", vt->klass->name); ++ignored_objects; @@ -604,7 +575,7 @@ is_opaque_object (MonoObject *obj) } static void -push_object (MonoObject *obj) +push_object (GCObject *obj) { ScanData *data; obj = bridge_object_forward (obj); @@ -652,26 +623,27 @@ push_object (MonoObject *obj) #undef HANDLE_PTR #define HANDLE_PTR(ptr,obj) do { \ - MonoObject *dst = (MonoObject*)*(ptr); \ + GCObject *dst = (GCObject*)*(ptr); \ if (dst) push_object (dst); \ } while (0) static void push_all (ScanData *data) { - MonoObject *obj = data->obj; + GCObject *obj = data->obj; char *start = (char*)obj; + mword desc = sgen_obj_get_descriptor_safe (obj); #if DUMP_GRAPH printf ("**scanning %p %s\n", obj, safe_name_bridge (obj)); #endif - #include "sgen-scan-object.h" + #include "sgen/sgen-scan-object.h" } static void -compute_low_index (ScanData *data, MonoObject *obj) +compute_low_index (ScanData *data, GCObject *obj) { ScanData *other; ColorData *cd; @@ -703,17 +675,18 @@ compute_low_index (ScanData *data, MonoObject *obj) #undef HANDLE_PTR #define HANDLE_PTR(ptr,obj) do { \ - MonoObject *dst = (MonoObject*)*(ptr); \ + GCObject *dst = (GCObject*)*(ptr); \ if (dst) compute_low_index (data, dst); \ } while (0) static void compute_low (ScanData *data) { - MonoObject *obj = data->obj; + GCObject *obj = data->obj; char *start = (char*)obj; + mword desc = sgen_obj_get_descriptor_safe (obj); - #include "sgen-scan-object.h" + #include "sgen/sgen-scan-object.h" } static ColorData* @@ -725,7 +698,7 @@ reduce_color (void) if (size == 0) color = NULL; else if (size == 1) { - color = dyn_array_ptr_get (&color_merge_array, 0); + color = (ColorData *)dyn_array_ptr_get (&color_merge_array, 0); } else color = new_color (FALSE); @@ -741,7 +714,7 @@ create_scc (ScanData *data) ColorData *color_data = NULL; for (i = dyn_array_ptr_size (&loop_stack) - 1; i >= 0; --i) { - ScanData *other = dyn_array_ptr_get (&loop_stack, i); + ScanData *other = (ScanData *)dyn_array_ptr_get (&loop_stack, i); found_bridge |= other->is_bridge; if (found_bridge || other == data) break; @@ -770,7 +743,7 @@ create_scc (ScanData *data) } while (dyn_array_ptr_size (&loop_stack) > 0) { - ScanData *other = dyn_array_ptr_pop (&loop_stack); + ScanData *other = (ScanData *)dyn_array_ptr_pop (&loop_stack); #if DUMP_GRAPH printf ("\tmember %s (%p) index %d low-index %d color %p state %d\n", safe_name_bridge (other->obj), other->obj, other->index, other->low_index, other->color, other->state); @@ -798,7 +771,7 @@ create_scc (ScanData *data) g_assert (found); for (i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i) { - ColorData *cd = dyn_array_ptr_get (&color_merge_array, i); + ColorData *cd = (ColorData *)dyn_array_ptr_get (&color_merge_array, i); g_assert (cd->visited); cd->visited = FALSE; } @@ -815,7 +788,7 @@ dfs (void) dyn_array_ptr_set_size (&color_merge_array, 0); while (dyn_array_ptr_size (&scan_stack) > 0) { - ScanData *data = dyn_array_ptr_pop (&scan_stack); + ScanData *data = (ScanData *)dyn_array_ptr_pop (&scan_stack); /** * Ignore finished objects on stack, they happen due to loops. For example: @@ -870,7 +843,7 @@ dfs (void) } static void -register_finalized_object (MonoObject *obj) +register_finalized_object (GCObject *obj) { g_assert (sgen_need_bridge_processing ()); dyn_array_ptr_push (®istered_bridges, obj); @@ -916,7 +889,7 @@ dump_color_table (const char *why, gboolean do_index) if (dyn_array_ptr_size (&cd->bridges)) { printf (" bridges: "); for (j = 0; j < dyn_array_ptr_size (&cd->bridges); ++j) { - MonoObject *obj = dyn_array_ptr_get (&cd->bridges, j); + GCObject *obj = dyn_array_ptr_get (&cd->bridges, j); ScanData *data = find_or_create_data (obj); printf ("%d ", data->index); } @@ -964,12 +937,12 @@ processing_stw_step (void) bridge_count = dyn_array_ptr_size (®istered_bridges); for (i = 0; i < bridge_count ; ++i) - register_bridge_object (dyn_array_ptr_get (®istered_bridges, i)); + register_bridge_object ((GCObject *)dyn_array_ptr_get (®istered_bridges, i)); setup_time = step_timer (&curtime); for (i = 0; i < bridge_count; ++i) { - ScanData *sd = find_data (dyn_array_ptr_get (®istered_bridges, i)); + ScanData *sd = find_data ((GCObject *)dyn_array_ptr_get (®istered_bridges, i)); if (sd->state == INITIAL) { dyn_array_ptr_push (&scan_stack, sd); dfs (); @@ -1000,7 +973,7 @@ gather_xrefs (ColorData *color) { int i; for (i = 0; i < dyn_array_ptr_size (&color->other_colors); ++i) { - ColorData *src = dyn_array_ptr_get (&color->other_colors, i); + ColorData *src = (ColorData *)dyn_array_ptr_get (&color->other_colors, i); if (src->visited) continue; src->visited = TRUE; @@ -1016,7 +989,7 @@ reset_xrefs (ColorData *color) { int i; for (i = 0; i < dyn_array_ptr_size (&color->other_colors); ++i) { - ColorData *src = dyn_array_ptr_get (&color->other_colors, i); + ColorData *src = (ColorData *)dyn_array_ptr_get (&color->other_colors, i); if (!src->visited) continue; src->visited = FALSE; @@ -1050,7 +1023,7 @@ processing_build_callback_data (int generation) #endif /* This is a straightforward translation from colors to the bridge callback format. */ - api_sccs = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_colors_with_bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE); + api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_colors_with_bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE); api_index = xref_count = 0; for (cur = root_color_bucket; cur; cur = cur->next) { @@ -1060,14 +1033,14 @@ processing_build_callback_data (int generation) if (!bridges) continue; - api_sccs [api_index] = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE); + api_sccs [api_index] = (MonoGCBridgeSCC *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE); api_sccs [api_index]->is_alive = FALSE; api_sccs [api_index]->num_objs = bridges; cd->api_index = api_index; for (j = 0; j < bridges; ++j) - api_sccs [api_index]->objs [j] = dyn_array_ptr_get (&cd->bridges, j); + api_sccs [api_index]->objs [j] = (MonoObject *)dyn_array_ptr_get (&cd->bridges, j); api_index++; } } @@ -1096,7 +1069,7 @@ processing_build_callback_data (int generation) dump_color_table (" after xref pass", TRUE); #endif - api_xrefs = sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE); + api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE); api_index = 0; for (cur = root_color_bucket; cur; cur = cur->next) { ColorData *src; @@ -1106,7 +1079,7 @@ processing_build_callback_data (int generation) continue; for (j = 0; j < dyn_array_ptr_size (&src->other_colors); ++j) { - ColorData *dest = dyn_array_ptr_get (&src->other_colors, j); + ColorData *dest = (ColorData *)dyn_array_ptr_get (&src->other_colors, j); g_assert (dyn_array_ptr_size (&dest->bridges)); /* We flattened the color graph, so this must never happen. */ api_xrefs [api_index].src_scc_index = src->api_index; @@ -1165,7 +1138,7 @@ processing_after_callback (int generation) } static void -describe_pointer (MonoObject *obj) +describe_pointer (GCObject *obj) { // HashEntry *entry; int i;