INTERNAL_MEM_MAX
};
+static inline mword
+sgen_mono_array_size (GCVTable vtable, MonoArray *array, mword *bounds_size, mword descr)
+{
+ mword size, size_without_bounds;
+ int element_size;
+
+ if ((descr & DESC_TYPE_MASK) == DESC_TYPE_VECTOR)
+ element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
+ else
+ element_size = vtable->klass->sizes.element_size;
+
+ size_without_bounds = size = sizeof (MonoArray) + element_size * mono_array_length_fast (array);
+
+ if (G_UNLIKELY (array->bounds)) {
+ size += sizeof (mono_array_size_t) - 1;
+ size &= ~(sizeof (mono_array_size_t) - 1);
+ size += sizeof (MonoArrayBounds) * vtable->klass->rank;
+ }
+
+ if (bounds_size)
+ *bounds_size = size - size_without_bounds;
+ return size;
+}
+
#define SGEN_CLIENT_OBJECT_HEADER_SIZE (sizeof (GCObject))
#define SGEN_CLIENT_MINIMUM_OBJECT_SIZE SGEN_CLIENT_OBJECT_HEADER_SIZE
if (klass == mono_defaults.string_class) {
return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
} else if (klass->rank) {
- MonoArray *array = (MonoArray*)o;
- size_t size = sizeof (MonoArray) + klass->sizes.element_size * mono_array_length_fast (array);
- if (G_UNLIKELY (array->bounds)) {
- size += sizeof (mono_array_size_t) - 1;
- size &= ~(sizeof (mono_array_size_t) - 1);
- size += sizeof (MonoArrayBounds) * klass->rank;
- }
- return size;
+ return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, 0);
} else {
/* from a created object: the class must be inited already */
return klass->instance_size;
} else if (descr == SGEN_DESC_STRING) {
return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
} else if (type == DESC_TYPE_VECTOR) {
- int element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
- MonoArray *array = (MonoArray*)o;
- size_t size = sizeof (MonoArray) + element_size * mono_array_length_fast (array);
-
- /*
- * Non-vector arrays with a single dimension whose lower bound is zero are
- * allocated without bounds.
- */
- if ((descr & VECTOR_KIND_ARRAY) && array->bounds) {
- size += sizeof (mono_array_size_t) - 1;
- size &= ~(sizeof (mono_array_size_t) - 1);
- size += sizeof (MonoArrayBounds) * ((MonoVTable*)vtable)->klass->rank;
- }
- return size;
+ return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, descr);
}
return sgen_client_slow_object_get_size (vtable, o);
SGEN_ASSERT (0, SGEN_VTABLE_HAS_REFERENCES (vt), "Why would we ever call this on reference-free objects?");
if (vt->rank) {
+ MonoArray *arr = (MonoArray*)obj;
guint8 *card_data, *card_base;
guint8 *card_data_end;
char *obj_start = sgen_card_table_align_pointer (obj);
- mword obj_size = sgen_client_par_object_get_size (vt, obj);
- char *obj_end = (char*)obj + obj_size;
+ mword bounds_size;
+ mword obj_size = sgen_mono_array_size (vt, arr, &bounds_size, sgen_vtable_get_descriptor (vt));
+ /* We don't want to scan the bounds entries at the end of multidimensional arrays */
+ char *obj_end = (char*)obj + obj_size - bounds_size;
size_t card_count;
size_t extra_idx = 0;
- MonoArray *arr = (MonoArray*)obj;
mword desc = (mword)klass->element_class->gc_descr;
int elem_size = mono_array_element_size (klass);
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include "sgen-protocol-def.h"
sgen_client_scan_thread_data (start_nursery, end_nursery, FALSE, ctx);
}
-static void
-unpin_objects_from_queue (SgenGrayQueue *queue)
-{
- for (;;) {
- GCObject *addr;
- SgenDescriptor desc;
- GRAY_OBJECT_DEQUEUE (queue, &addr, &desc);
- if (!addr)
- break;
- g_assert (SGEN_OBJECT_IS_PINNED (addr));
- SGEN_UNPIN_OBJECT (addr);
- }
-}
-
static void
single_arg_user_copy_or_mark (GCObject **obj, void *gc_data)
{
return needs_major;
}
-static void
-scan_nursery_objects_callback (GCObject *obj, size_t size, ScanCopyContext *ctx)
-{
- /*
- * This is called on all objects in the nursery, including pinned ones, so we need
- * to use sgen_obj_get_descriptor_safe(), which masks out the vtable tag bits.
- */
- ctx->ops->scan_object (obj, sgen_obj_get_descriptor_safe (obj), ctx->queue);
-}
-
-static void
-scan_nursery_objects (ScanCopyContext ctx)
-{
- sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
- (IterateObjectCallbackFunc)scan_nursery_objects_callback, (void*)&ctx, FALSE, TRUE);
-}
-
typedef enum {
COPY_OR_MARK_FROM_ROOTS_SERIAL,
COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT,
} CopyOrMarkFromRootsMode;
static void
-major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMode mode, gboolean scan_whole_nursery, SgenObjectOperations *object_ops)
+major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMode mode, SgenObjectOperations *object_ops)
{
LOSObject *bigobj;
TV_DECLARE (atv);
SGEN_ASSERT (0, !!concurrent == !!concurrent_collection_in_progress, "We've been called with the wrong mode.");
- if (scan_whole_nursery)
- SGEN_ASSERT (0, mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT, "Scanning whole nursery only makes sense when we're finishing a concurrent collection.");
-
- if (concurrent) {
+ if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
/*This cleans up unused fragments */
sgen_nursery_allocator_prepare_for_pinning ();
SGEN_LOG (6, "Collecting pinned addresses");
pin_from_roots ((void*)lowest_heap_address, (void*)highest_heap_address, ctx);
- if (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
- if (major_collector.is_concurrent) {
- /*
- * The concurrent major collector cannot evict
- * yet, so we need to pin cemented objects to
- * not break some asserts.
- *
- * FIXME: We could evict now!
- */
- sgen_pin_cemented_objects ();
- }
- }
-
sgen_optimize_pin_queue ();
sgen_client_collecting_major_1 ();
sgen_client_pinned_los_object (bigobj->data);
}
}
- /* second pass for the sections */
- /*
- * Concurrent mark never follows references into the nursery. In the start and
- * finish pauses we must scan live nursery objects, though.
- *
- * In the finish pause we do this conservatively by scanning all nursery objects.
- * Previously we would only scan pinned objects here. We assumed that all objects
- * that were pinned during the nursery collection immediately preceding this finish
- * mark would be pinned again here. Due to the way we get the stack end for the GC
- * thread, however, that's not necessarily the case: we scan part of the stack used
- * by the GC itself, which changes constantly, so pinning isn't entirely
- * deterministic.
- *
- * The split nursery also complicates things because non-pinned objects can survive
- * in the nursery. That's why we need to do a full scan of the nursery for it, too.
- *
- * In the future we shouldn't do a preceding nursery collection at all and instead
- * do the finish pause with promotion from the nursery.
- *
- * A further complication arises when we have late-pinned objects from the preceding
- * nursery collection. Those are the result of being out of memory when trying to
- * evacuate objects. They won't be found from the roots, so we just scan the whole
- * nursery.
- *
- * Non-concurrent mark evacuates from the nursery, so it's
- * sufficient to just scan pinned nursery objects.
- */
- if (scan_whole_nursery || mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT || (concurrent && sgen_minor_collector.is_split)) {
- scan_nursery_objects (ctx);
- } else {
- pin_objects_in_nursery (concurrent, ctx);
- if (check_nursery_objects_pinned && !sgen_minor_collector.is_split)
- sgen_check_nursery_objects_pinned (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
- }
+ pin_objects_in_nursery (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT, ctx);
+ if (check_nursery_objects_pinned && !sgen_minor_collector.is_split)
+ sgen_check_nursery_objects_pinned (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
major_collector.pin_objects (WORKERS_DISTRIBUTE_GRAY_QUEUE);
if (old_next_pin_slot)
}
static void
-major_finish_copy_or_mark (void)
+major_finish_copy_or_mark (CopyOrMarkFromRootsMode mode)
{
- if (!concurrent_collection_in_progress)
- return;
-
- /*
- * Prepare the pin queue for the next collection. Since pinning runs on the worker
- * threads we must wait for the jobs to finish before we can reset it.
- */
- sgen_workers_wait_for_jobs_finished ();
- sgen_finish_pinning ();
+ switch (mode) {
+ case COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT:
+ /*
+ * Prepare the pin queue for the next collection. Since pinning runs on the worker
+ * threads we must wait for the jobs to finish before we can reset it.
+ */
+ sgen_workers_wait_for_jobs_finished ();
+ sgen_finish_pinning ();
- sgen_pin_stats_reset ();
+ sgen_pin_stats_reset ();
- if (do_concurrent_checks)
- sgen_debug_check_nursery_is_clean ();
+ if (do_concurrent_checks)
+ sgen_debug_check_nursery_is_clean ();
+ break;
+ case COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT:
+ sgen_workers_wait_for_jobs_finished ();
+ break;
+ case COPY_OR_MARK_FROM_ROOTS_SERIAL:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
static void
g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
- sgen_cement_reset ();
+ if (!concurrent)
+ sgen_cement_reset ();
if (concurrent) {
g_assert (major_collector.is_concurrent);
if (major_collector.start_major_collection)
major_collector.start_major_collection ();
- major_copy_or_mark_from_roots (old_next_pin_slot, concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL, FALSE, object_ops);
- major_finish_copy_or_mark ();
+ major_copy_or_mark_from_roots (old_next_pin_slot, concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL, object_ops);
+ major_finish_copy_or_mark (concurrent ? COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT : COPY_OR_MARK_FROM_ROOTS_SERIAL);
}
static void
-major_finish_collection (const char *reason, size_t old_next_pin_slot, gboolean forced, gboolean scan_whole_nursery)
+major_finish_collection (const char *reason, size_t old_next_pin_slot, gboolean forced)
{
ScannedObjectCounts counts;
SgenObjectOperations *object_ops;
+ mword fragment_total;
TV_DECLARE (atv);
TV_DECLARE (btv);
if (concurrent_collection_in_progress) {
object_ops = &major_collector.major_ops_concurrent_finish;
- major_copy_or_mark_from_roots (NULL, COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT, scan_whole_nursery, object_ops);
+ major_copy_or_mark_from_roots (NULL, COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT, object_ops);
- major_finish_copy_or_mark ();
+ major_finish_copy_or_mark (COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT);
sgen_workers_join ();
#ifdef SGEN_DEBUG_INTERNAL_ALLOC
main_gc_thread = NULL;
#endif
-
- if (do_concurrent_checks)
- sgen_debug_check_nursery_is_clean ();
} else {
- SGEN_ASSERT (0, !scan_whole_nursery, "scan_whole_nursery only applies to concurrent collections");
object_ops = &major_collector.major_ops_serial;
}
reset_heap_boundaries ();
sgen_update_heap_boundaries ((mword)sgen_get_nursery_start (), (mword)sgen_get_nursery_end ());
- if (!concurrent_collection_in_progress) {
- /* walk the pin_queue, build up the fragment list of free memory, unmark
- * pinned objects as we go, memzero() the empty fragments so they are ready for the
- * next allocations.
- */
- if (!sgen_build_nursery_fragments (nursery_section, NULL))
- degraded_mode = 1;
+ /* walk the pin_queue, build up the fragment list of free memory, unmark
+ * pinned objects as we go, memzero() the empty fragments so they are ready for the
+ * next allocations.
+ */
+ fragment_total = sgen_build_nursery_fragments (nursery_section, NULL);
+ if (!fragment_total)
+ degraded_mode = 1;
+ SGEN_LOG (4, "Free space in nursery after major %ld", fragment_total);
- /* prepare the pin queue for the next collection */
- sgen_finish_pinning ();
+ if (do_concurrent_checks && concurrent_collection_in_progress)
+ sgen_debug_check_nursery_is_clean ();
- /* Clear TLABs for all threads */
- sgen_clear_tlabs ();
+ /* prepare the pin queue for the next collection */
+ sgen_finish_pinning ();
- sgen_pin_stats_reset ();
- }
+ /* Clear TLABs for all threads */
+ sgen_clear_tlabs ();
+
+ sgen_pin_stats_reset ();
sgen_cement_clear_below_threshold ();
TV_GETTIME (time_start);
major_start_collection (FALSE, &old_next_pin_slot);
- major_finish_collection (reason, old_next_pin_slot, forced, FALSE);
+ major_finish_collection (reason, old_next_pin_slot, forced);
TV_GETTIME (time_end);
gc_stats.major_gc_time += TV_ELAPSED (time_start, time_end);
{
TV_DECLARE (total_start);
TV_DECLARE (total_end);
- gboolean late_pinned;
- SgenGrayQueue unpin_queue;
- memset (&unpin_queue, 0, sizeof (unpin_queue));
TV_GETTIME (total_start);
major_collector.update_cardtable_mod_union ();
sgen_los_update_cardtable_mod_union ();
- late_pinned = collect_nursery (&unpin_queue, TRUE);
-
if (mod_union_consistency_check)
sgen_check_mod_union_consistency ();
current_collection_generation = GENERATION_OLD;
- major_finish_collection ("finishing", -1, forced, late_pinned);
+ sgen_cement_reset ();
+ major_finish_collection ("finishing", -1, forced);
if (whole_heap_check_before_collection)
sgen_check_whole_heap (FALSE);
- unpin_objects_from_queue (&unpin_queue);
- sgen_gray_object_queue_deinit (&unpin_queue);
-
TV_GETTIME (total_end);
gc_stats.major_gc_time += TV_ELAPSED (total_start, total_end) - TV_ELAPSED (last_minor_collection_start_tv, last_minor_collection_end_tv);
{
SGEN_LOG (8, "Wbarrier store at %p to %p (%s)", ptr, value, value ? sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (value)) : "null");
SGEN_UPDATE_REFERENCE_ALLOW_NULL (ptr, value);
- if (ptr_in_nursery (value))
+ if (ptr_in_nursery (value) || concurrent_collection_in_progress)
mono_gc_wbarrier_generic_nostore (ptr);
sgen_dummy_use (value);
}
InterlockedWritePointer (ptr, value);
- if (ptr_in_nursery (value))
+ if (ptr_in_nursery (value) || concurrent_collection_in_progress)
mono_gc_wbarrier_generic_nostore (ptr);
sgen_dummy_use (value);
sgen_nursery_size = DEFAULT_NURSERY_SIZE;
- if (major_collector.is_concurrent)
- cement_enabled = FALSE;
-
if (opts) {
gboolean usage_printed = FALSE;
alloc_nursery ();
- if (major_collector.is_concurrent && cement_enabled) {
- sgen_env_var_error (MONO_GC_PARAMS_NAME, "Ignoring.", "`cementing` is not supported on concurrent major collectors.");
- cement_enabled = FALSE;
- }
-
sgen_cement_init (cement_enabled);
if ((env = g_getenv (MONO_GC_DEBUG_NAME))) {
sgen_env_var_error (MONO_GC_DEBUG_NAME, "Ignoring.", "`check-concurrent` only works with concurrent major collectors.");
continue;
}
+ nursery_clear_policy = CLEAR_AT_GC;
do_concurrent_checks = TRUE;
} else if (!strcmp (opt, "dump-nursery-at-minor-gc")) {
do_dump_nursery_content = TRUE;
major_scan_object_no_mark_concurrent_anywhere (start, desc, queue);
}
-#undef ADD_TO_GLOBAL_REMSET
-#define ADD_TO_GLOBAL_REMSET(object,ptr,target) sgen_add_to_global_remset ((ptr), (target))
+#undef HANDLE_PTR
+#define HANDLE_PTR(ptr,obj) do { \
+ void *__old = *(ptr); \
+ binary_protocol_scan_process_reference ((obj), (ptr), __old); \
+ if (__old) { \
+ gboolean __still_in_nursery = major_copy_or_mark_object_no_evacuation ((ptr), __old, queue); \
+ if (G_UNLIKELY (__still_in_nursery && !sgen_ptr_in_nursery ((ptr)) && !SGEN_OBJECT_IS_CEMENTED (*(ptr)))) { \
+ void *__copy = *(ptr); \
+ sgen_add_to_global_remset ((ptr), __copy); \
+ } \
+ } \
+ } while (0)
+
static void
major_scan_vtype_concurrent_finish (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue *queue BINARY_PROTOCOL_ARG (size_t size))
static GCObject*
major_alloc_degraded (GCVTable vtable, size_t size)
{
- GCObject *obj = alloc_obj (vtable, size, FALSE, SGEN_VTABLE_HAS_REFERENCES (vtable));
+ GCObject *obj;
+
+ major_finish_sweep_checking ();
+
+ obj = alloc_obj (vtable, size, FALSE, SGEN_VTABLE_HAS_REFERENCES (vtable));
if (G_LIKELY (obj)) {
HEAVY_STAT (++stat_objects_alloced_degraded);
HEAVY_STAT (stat_bytes_alloced_degraded += size);
END_PROTOCOL_ENTRY
BEGIN_PROTOCOL_ENTRY2 (binary_protocol_collection_begin, TYPE_INT, index, TYPE_INT, generation)
-FLUSH ()
DEFAULT_PRINT ()
IS_ALWAYS_MATCH (TRUE)
MATCH_INDEX (BINARY_PROTOCOL_MATCH)
IS_VTABLE_MATCH (FALSE)
-END_PROTOCOL_ENTRY
+END_PROTOCOL_ENTRY_FLUSH
BEGIN_PROTOCOL_ENTRY4 (binary_protocol_collection_end, TYPE_INT, index, TYPE_INT, generation, TYPE_LONGLONG, num_scanned_objects, TYPE_LONGLONG, num_unique_scanned_objects)
-FLUSH()
CUSTOM_PRINT (printf ("%d generation %d scanned %lld unique %lld %0.2f%%", entry->index, entry->generation, entry->num_scanned_objects, entry->num_unique_scanned_objects, entry->num_unique_scanned_objects ? (100.0 * (double) entry->num_scanned_objects / (double) entry->num_unique_scanned_objects) : 0.0))
IS_ALWAYS_MATCH (TRUE)
MATCH_INDEX (BINARY_PROTOCOL_MATCH)
IS_VTABLE_MATCH (FALSE)
-END_PROTOCOL_ENTRY
+END_PROTOCOL_ENTRY_FLUSH
BEGIN_PROTOCOL_ENTRY0 (binary_protocol_concurrent_start)
DEFAULT_PRINT ()
#undef BEGIN_PROTOCOL_ENTRY_HEAVY5
#undef BEGIN_PROTOCOL_ENTRY_HEAVY6
-#undef FLUSH
-
#undef DEFAULT_PRINT
#undef CUSTOM_PRINT
#undef IS_VTABLE_MATCH
#undef END_PROTOCOL_ENTRY
+#undef END_PROTOCOL_ENTRY_FLUSH
#undef END_PROTOCOL_ENTRY_HEAVY
int __size = sizeof (PROTOCOL_STRUCT(method)); \
CLIENT_PROTOCOL_NAME (method) (f1, f2, f3, f4, f5, f6);
-#define FLUSH() \
- binary_protocol_flush_buffers (FALSE);
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
protocol_entry (__type, __data, __size); \
}
+#define END_PROTOCOL_ENTRY_FLUSH \
+ protocol_entry (__type, __data, __size); \
+ binary_protocol_flush_buffers (FALSE); \
+ }
+
#ifdef SGEN_HEAVY_BINARY_PROTOCOL
#define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
BEGIN_PROTOCOL_ENTRY0 (method)
#define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) PROTOCOL_ID(method),
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) PROTOCOL_ID(method),
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include "sgen-protocol-def.h"
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include "sgen-protocol-def.h"
static inline void method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6) {}
#endif
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include "sgen-protocol-def.h"
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include <mono/sgen/sgen-protocol-def.h>
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
+#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include <mono/sgen/sgen-protocol-def.h>
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT() \
print_entry_content (pes_size, pes, color_output);
#define CUSTOM_PRINT(print) \
printf ("\n"); \
break; \
}
+#define END_PROTOCOL_ENTRY_FLUSH \
+ END_PROTOCOL_ENTRY
#define END_PROTOCOL_ENTRY_HEAVY \
END_PROTOCOL_ENTRY
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define END_PROTOCOL_ENTRY \
break; \
}
+#define END_PROTOCOL_ENTRY_FLUSH \
+ END_PROTOCOL_ENTRY
#define END_PROTOCOL_ENTRY_HEAVY \
END_PROTOCOL_ENTRY
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
BEGIN_PROTOCOL_ENTRY6 (method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6)
-#define FLUSH()
-
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
#define END_PROTOCOL_ENTRY \
break; \
}
+#define END_PROTOCOL_ENTRY_FLUSH \
+ END_PROTOCOL_ENTRY
#define END_PROTOCOL_ENTRY_HEAVY \
END_PROTOCOL_ENTRY