probe gc__end (int generation);
probe gc__concurrent__start__begin (int generation);
- probe gc__concurrent__start__end (int generation);
- probe gc__concurrent__update__finish__begin (int generation);
- probe gc__concurrent__update__end (int generation);
- probe gc__concurrent__finish__end (int generation);
+ probe gc__concurrent__start__end (int generation, long long num_major_objects_marked);
+ probe gc__concurrent__update__finish__begin (int generation, long long num_major_objects_marked);
+ probe gc__concurrent__update__end (int generation, long long num_major_objects_marked);
+ probe gc__concurrent__finish__end (int generation, long long num_major_objects_marked);
probe gc__sweep__begin (int generation, int full_sweep);
probe gc__sweep__end (int generation, int full_sweep);
*/
//#define XDOMAIN_CHECKS_IN_WBARRIER
+/*
+ * Define this to get number of objects marked information in the
+ * concurrent GC DTrace probes. Has a small performance impact, so
+ * it's disabled by default.
+ */
+//#define SGEN_COUNT_NUMBER_OF_MAJOR_OBJECTS_MARKED
+
#ifndef SGEN_BINARY_PROTOCOL
#ifndef HEAVY_STATISTICS
#define MANAGED_ALLOCATION
TV_DECLARE (all_btv);
int old_next_pin_slot;
+ if (major_collector.get_and_reset_num_major_objects_marked) {
+ long long num_marked = major_collector.get_and_reset_num_major_objects_marked ();
+ g_assert (!num_marked);
+ }
+
/* world must be stopped already */
TV_GETTIME (all_atv);
TV_GETTIME (all_btv);
gc_stats.major_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
+ /* FIXME: also report this to the user, preferably in gc-end. */
+ if (major_collector.get_and_reset_num_major_objects_marked)
+ major_collector.get_and_reset_num_major_objects_marked ();
+
return bytes_pinned_from_failed_allocation > 0;
}
static void
major_start_concurrent_collection (const char *reason)
{
+ long long num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
+
+ g_assert (num_objects_marked == 0);
+
MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD);
// FIXME: store reason and pass it when finishing
gray_queue_redirect (&gray_queue);
sgen_workers_wait_for_jobs ();
- MONO_GC_CONCURRENT_START_END (GENERATION_OLD);
+ num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
+ MONO_GC_CONCURRENT_START_END (GENERATION_OLD, num_objects_marked);
current_collection_generation = -1;
}
static gboolean
major_update_or_finish_concurrent_collection (gboolean force_finish)
{
- MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD);
+ MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
if (!have_non_collection_major_object_remembers)
sgen_los_update_cardtable_mod_union ();
if (!force_finish && !sgen_workers_all_done ()) {
- MONO_GC_CONCURRENT_UPDATE_END (GENERATION_OLD);
+ MONO_GC_CONCURRENT_UPDATE_END (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
return FALSE;
}
current_collection_generation = GENERATION_OLD;
major_finish_collection ("finishing", -1, TRUE);
- MONO_GC_CONCURRENT_FINISH_END (GENERATION_OLD);
+ MONO_GC_CONCURRENT_FINISH_END (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
current_collection_generation = -1;
void (*reset_worker_data) (void *data);
gboolean (*is_valid_object) (char *object);
gboolean (*describe_pointer) (char *pointer);
+ long long (*get_and_reset_num_major_objects_marked) (void);
};
extern SgenMajorCollector major_collector;
static long long stat_major_blocks_lazy_swept = 0;
static long long stat_major_objects_evacuated = 0;
+static long long num_major_objects_marked = 0;
+
+#ifdef SGEN_COUNT_NUMBER_OF_MAJOR_OBJECTS_MARKED
+#define INC_NUM_MAJOR_OBJECTS_MARKED() (++num_major_objects_marked)
+#else
+#define INC_NUM_MAJOR_OBJECTS_MARKED()
+#endif
+
static void
sweep_block (MSBlockInfo *block);
MS_CALC_MARK_BIT (word, bit, obj);
MS_SET_MARK_BIT (block, word, bit);
binary_protocol_mark (obj, NULL, size);
+ INC_NUM_MAJOR_OBJECTS_MARKED ();
}
#endif
if ((block)->has_references) \
GRAY_OBJECT_ENQUEUE ((queue), (obj)); \
binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+ INC_NUM_MAJOR_OBJECTS_MARKED (); \
} \
} while (0)
#define MS_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \
if ((block)->has_references) \
GRAY_OBJECT_ENQUEUE ((queue), (obj)); \
binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+ INC_NUM_MAJOR_OBJECTS_MARKED (); \
} \
} while (0)
#define MS_PAR_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \
if ((block)->has_references) \
GRAY_OBJECT_ENQUEUE ((queue), (obj)); \
binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+ INC_NUM_MAJOR_OBJECTS_MARKED (); \
} \
} while (0)
sgen_los_pin_object (obj);
/* FIXME: only enqueue if object has references */
GRAY_OBJECT_ENQUEUE (queue, obj);
+ INC_NUM_MAJOR_OBJECTS_MARKED ();
}
}
}
#endif
#endif
+#ifdef SGEN_CONCURRENT_MARK
+static long long
+major_get_and_reset_num_major_objects_marked (void)
+{
+ long long num = num_major_objects_marked;
+ num_major_objects_marked = 0;
+ return num;
+}
+#endif
+
#include "sgen-major-scan-object.h"
static void
#endif
#ifdef SGEN_CONCURRENT_MARK
collector->is_concurrent = TRUE;
+ collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked;
#else
collector->is_concurrent = FALSE;
#endif