X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-gc.c;h=ae9204f82601f2c041548231acc7fe1c41029b6e;hb=023046395bb3d091f5f1dd60ca4da378356d5964;hp=fddca9c6c346e7be93d95e0a204e6a679a28b2e7;hpb=811674bc6331c98d33134e2a37a7c7dd66402227;p=mono.git diff --git a/mono/mini/mini-gc.c b/mono/mini/mini-gc.c index fddca9c6c34..ae9204f8260 100644 --- a/mono/mini/mini-gc.c +++ b/mono/mini/mini-gc.c @@ -1,23 +1,48 @@ -/* - * mini-gc.c: GC interface for the mono JIT +/** + * \file + * GC interface for the mono JIT * * Author: * Zoltan Varga (vargaz@gmail.com) * * Copyright 2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #include "mini-gc.h" -#include +#include + +static gboolean +get_provenance (StackFrameInfo *frame, MonoContext *ctx, gpointer data) +{ + MonoJitInfo *ji = frame->ji; + MonoMethod *method; + if (!ji) + return FALSE; + method = jinfo_get_method (ji); + if (method->wrapper_type != MONO_WRAPPER_NONE) + return FALSE; + *(gpointer *)data = method; + return TRUE; +} + +static gpointer +get_provenance_func (void) +{ + gpointer provenance = NULL; + mono_walk_stack (get_provenance, MONO_UNWIND_DEFAULT, (gpointer)&provenance); + return provenance; +} #if 0 //#if defined(MONO_ARCH_GC_MAPS_SUPPORTED) #include -#include +#include #include +#include #define SIZEOF_SLOT ((int)sizeof (mgreg_t)) @@ -230,27 +255,27 @@ static gboolean precise_frame_limit_inited; /* Stats */ typedef struct { - int scanned_stacks; - int scanned; - int scanned_precisely; - int scanned_conservatively; - int scanned_registers; - int scanned_native; - int scanned_other; + gint32 scanned_stacks; + gint32 scanned; + gint32 scanned_precisely; + gint32 scanned_conservatively; + gint32 scanned_registers; + gint32 scanned_native; + gint32 scanned_other; - int all_slots; - int noref_slots; - int ref_slots; - int pin_slots; - - int gc_maps_size; - int gc_callsites_size; - int gc_callsites8_size; - int gc_callsites16_size; - int gc_callsites32_size; - int gc_bitmaps_size; - int gc_map_struct_size; - int tlsdata_size; + gint32 all_slots; + gint32 noref_slots; + gint32 ref_slots; + gint32 pin_slots; + + gint32 gc_maps_size; + gint32 gc_callsites_size; + gint32 gc_callsites8_size; + gint32 gc_callsites16_size; + gint32 gc_callsites32_size; + gint32 gc_bitmaps_size; + gint32 gc_map_struct_size; + gint32 tlsdata_size; } JITGCStats; static JITGCStats stats; @@ -575,9 +600,9 @@ thread_attach_func (void) TlsData *tls; tls = g_new0 (TlsData, 1); - tls->tid = GetCurrentThreadId (); + tls->tid = mono_native_thread_id_get (); tls->info = mono_thread_info_current (); - stats.tlsdata_size += sizeof (TlsData); + UnlockedAdd (&stats.tlsdata_size, sizeof (TlsData)); return tls; } @@ -600,7 +625,7 @@ thread_suspend_func (gpointer user_data, void *sigctx, MonoContext *ctx) return; } - if (tls->tid != GetCurrentThreadId ()) { + if (tls->tid != mono_native_thread_id_get ()) { /* Happens on osx because threads are not suspended using signals */ #ifndef TARGET_WIN32 gboolean res; @@ -627,7 +652,7 @@ thread_suspend_func (gpointer user_data, void *sigctx, MonoContext *ctx) } else { tls->unwind_state.valid = FALSE; } - tls->unwind_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = mono_native_tls_get_value (mono_jit_tls_id); + tls->unwind_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = mono_tls_get_jit_tls (); tls->unwind_state.unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get (); } @@ -738,7 +763,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end) /* tls == NULL can happen during startup */ if (mono_thread_internal_current () == NULL || !tls) { mono_gc_conservatively_scan_area (stack_start, stack_end); - stats.scanned_stacks += stack_end - stack_start; + UnlockedAdd (&stats.scanned_stacks, stack_end - stack_start); return; } @@ -799,6 +824,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end) ji = frame.ji; // FIXME: For skipped frames, scan the param area of the parent frame conservatively ? + // FIXME: trampolines if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) { /* @@ -900,8 +926,11 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end) * Debugging aid to control the number of frames scanned precisely */ if (!precise_frame_limit_inited) { - if (g_getenv ("MONO_PRECISE_COUNT")) - precise_frame_limit = atoi (g_getenv ("MONO_PRECISE_COUNT")); + char *mono_precise_count = g_getenv ("MONO_PRECISE_COUNT"); + if (mono_precise_count) { + precise_frame_limit = atoi (mono_precise_count); + g_free (mono_precise_count); + } precise_frame_limit_inited = TRUE; } @@ -965,7 +994,7 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end) /* This scans the previously skipped frames as well */ DEBUG (fprintf (logfile, "\tscan area %p-%p (%d).\n", stack_limit, real_frame_start, (int)(real_frame_start - stack_limit))); mono_gc_conservatively_scan_area (stack_limit, real_frame_start); - stats.scanned_other += real_frame_start - stack_limit; + UnlockedAdd (&stats.scanned_other, real_frame_start - stack_limit); } /* Mark stack slots */ @@ -1091,16 +1120,16 @@ conservative_pass (TlsData *tls, guint8 *stack_start, guint8 *stack_end) if (stack_limit < stack_end) { DEBUG (fprintf (logfile, "\tscan remaining stack %p-%p (%d).\n", stack_limit, stack_end, (int)(stack_end - stack_limit))); mono_gc_conservatively_scan_area (stack_limit, stack_end); - stats.scanned_native += stack_end - stack_limit; + UnlockedAdd (&stats.scanned_native, stack_end - stack_limit); } DEBUG (fprintf (logfile, "Marked %d bytes, p=%d,c=%d out of %d.\n", scanned, scanned_precisely, scanned_conservatively, (int)(stack_end - stack_start))); - stats.scanned_stacks += stack_end - stack_start; - stats.scanned += scanned; - stats.scanned_precisely += scanned_precisely; - stats.scanned_conservatively += scanned_conservatively; - stats.scanned_registers += scanned_registers; + UnlockedAdd (&stats.scanned_stacks, stack_end - stack_start); + UnlockedAdd (&stats.scanned, scanned); + UnlockedAdd (&stats.scanned_precisely, scanned_precisely); + UnlockedAdd (&stats.scanned_conservatively, scanned_conservatively); + UnlockedAdd (&stats.scanned_registers, scanned_registers); //mono_gc_conservatively_scan_area (stack_start, stack_end); } @@ -1256,10 +1285,13 @@ mini_gc_init_gc_map (MonoCompile *cfg) static int precise_count; precise_count ++; - if (g_getenv ("MONO_GCMAP_COUNT")) { - if (precise_count == atoi (g_getenv ("MONO_GCMAP_COUNT"))) + char *mono_gcmap_count = g_getenv ("MONO_GCMAP_COUNT"); + if (mono_gcmap_count) { + int count = atoi (mono_gcmap_count); + g_free (mono_gcmap_count); + if (precise_count == count) printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE)); - if (precise_count > atoi (g_getenv ("MONO_GCMAP_COUNT"))) + if (precise_count > count) return; } } @@ -1656,7 +1688,7 @@ process_variables (MonoCompile *cfg) int hreg; GCSlotType slot_type; - t = mini_type_get_underlying_type (NULL, t); + t = mini_get_underlying_type (t); hreg = ins->dreg; g_assert (hreg < MONO_MAX_IREGS); @@ -1664,7 +1696,7 @@ process_variables (MonoCompile *cfg) if (byref) slot_type = SLOT_PIN; else - slot_type = mini_type_is_reference (cfg, t) ? SLOT_REF : SLOT_NOREF; + slot_type = mini_type_is_reference (t) ? SLOT_REF : SLOT_NOREF; if (slot_type == SLOT_PIN) { /* These have no live interval, be conservative */ @@ -1811,9 +1843,9 @@ process_variables (MonoCompile *cfg) } #endif - t = mini_type_get_underlying_type (NULL, t); + t = mini_get_underlying_type (t); - if (!mini_type_is_reference (cfg, t)) { + if (!mini_type_is_reference (t)) { set_slot_everywhere (gcfg, pos, SLOT_NOREF); if (cfg->verbose_level > 1) printf ("\tnoref%s at %s0x%x(fp) (R%d, slot = %d): %s\n", (is_arg ? " arg" : ""), ins->inst_offset < 0 ? "-" : "", (ins->inst_offset < 0) ? -(int)ins->inst_offset : (int)ins->inst_offset, vmv->vreg, pos, mono_type_full_name (ins->inst_vtype)); @@ -1917,7 +1949,7 @@ process_param_area_slots (MonoCompile *cfg) guint32 size; if (MONO_TYPE_ISSTRUCT (t)) { - size = mini_type_stack_size_full (cfg->generic_sharing_context, t, &align, FALSE); + size = mini_type_stack_size_full (t, &align, FALSE); } else { size = sizeof (mgreg_t); } @@ -2031,7 +2063,7 @@ compute_frame_size (MonoCompile *cfg) if (ins->opcode == OP_REGOFFSET) { int size, size_in_slots; - size = mini_type_stack_size_full (cfg->generic_sharing_context, ins->inst_vtype, NULL, ins->backend.is_pinvoke); + size = mini_type_stack_size_full (ins->inst_vtype, NULL, ins->backend.is_pinvoke); size_in_slots = ALIGN_TO (size, SIZEOF_SLOT) / SIZEOF_SLOT; min_offset = MIN (min_offset, ins->inst_offset); @@ -2392,17 +2424,17 @@ create_map (MonoCompile *cfg) guint8 *offsets = p; for (i = 0; i < ncallsites; ++i) offsets [i] = callsites [i]->pc_offset; - stats.gc_callsites8_size += ncallsites * sizeof (guint8); + UnlockedAdd (&stats.gc_callsites8_size, ncallsites * sizeof (guint8)); } else if (map->callsite_entry_size == 2) { guint16 *offsets = (guint16*)p; for (i = 0; i < ncallsites; ++i) offsets [i] = callsites [i]->pc_offset; - stats.gc_callsites16_size += ncallsites * sizeof (guint16); + UnlockedAdd (&stats.gc_callsites16_size, ncallsites * sizeof (guint16)); } else { guint32 *offsets = (guint32*)p; for (i = 0; i < ncallsites; ++i) offsets [i] = callsites [i]->pc_offset; - stats.gc_callsites32_size += ncallsites * sizeof (guint32); + UnlockedAdd (&stats.gc_callsites32_size, ncallsites * sizeof (guint32)); } p += ncallsites * map->callsite_entry_size; @@ -2412,10 +2444,10 @@ create_map (MonoCompile *cfg) g_assert ((guint8*)p - (guint8*)emap <= alloc_size); - stats.gc_maps_size += alloc_size; - stats.gc_callsites_size += ncallsites * map->callsite_entry_size; - stats.gc_bitmaps_size += bitmaps_size; - stats.gc_map_struct_size += sizeof (GCEncodedMap) + encoded_size; + UnlockedAdd (&stats.gc_maps_size, alloc_size); + UnlockedAdd (&stats.gc_callsites_size, ncallsites * map->callsite_entry_size); + UnlockedAdd (&stats.gc_bitmaps_size, bitmaps_size); + UnlockedAdd (&stats.gc_map_struct_size, sizeof (GCEncodedMap) + encoded_size); cfg->jit_info->gc_info = emap; @@ -2423,10 +2455,10 @@ create_map (MonoCompile *cfg) cfg->gc_map_size = alloc_size; } - stats.all_slots += nslots; - stats.ref_slots += ntypes [SLOT_REF]; - stats.noref_slots += ntypes [SLOT_NOREF]; - stats.pin_slots += ntypes [SLOT_PIN]; + UnlockedAdd (&stats.all_slots, nslots); + UnlockedAdd (&stats.ref_slots, ntypes [SLOT_REF]); + UnlockedAdd (&stats.noref_slots, ntypes [SLOT_NOREF]); + UnlockedAdd (&stats.pin_slots, ntypes [SLOT_PIN]); } void @@ -2479,6 +2511,7 @@ parse_debug_options (void) exit (1); } g_strfreev (opts); + g_free (env); } void @@ -2492,6 +2525,7 @@ mini_gc_init (void) cb.thread_suspend_func = thread_suspend_func; /* Comment this out to disable precise stack marking */ cb.thread_mark_func = thread_mark_func; + cb.get_provenance_func = get_provenance_func; mono_gc_set_gc_callbacks (&cb); logfile = mono_gc_get_logfile (); @@ -2551,6 +2585,10 @@ mini_gc_enable_gc_maps_for_aot (void) void mini_gc_init (void) { + MonoGCCallbacks cb; + memset (&cb, 0, sizeof (cb)); + cb.get_provenance_func = get_provenance_func; + mono_gc_set_gc_callbacks (&cb); } #ifndef DISABLE_JIT