Merge remote-tracking branch 'joncham/sgen-msvc2'
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 10 Oct 2012 22:01:21 +0000 (18:01 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 10 Oct 2012 22:01:21 +0000 (18:01 -0400)
Conflicts:
mono/metadata/sgen-copy-object.h
mono/metadata/sgen-gc.c

1  2 
mono/metadata/sgen-cardtable.c
mono/metadata/sgen-copy-object.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-marksweep.c
mono/metadata/sgen-os-win32.c

index a8fd7611806325fb912a6e76a07be44c9a2bec59,971058f0cb267ce422fef37d468fdfcc8f5cacfb..4fad8b6678afb2e45404160fd6ecdcfc9b653e7d
@@@ -44,7 -44,9 +44,9 @@@
  
  //#define CARDTABLE_STATS
  
+ #ifdef HAVE_UNISTD_H
  #include <unistd.h>
+ #endif
  #ifdef HAVE_SYS_MMAN_H
  #include <sys/mman.h>
  #endif
@@@ -655,10 -657,10 +657,10 @@@ sgen_card_tables_collect_stats (gboolea
  void
  sgen_card_table_init (SgenRemeberedSet *remset)
  {
 -      sgen_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, TRUE);
 +      sgen_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "card table");
  
  #ifdef SGEN_HAVE_OVERLAPPING_CARDS
 -      sgen_shadow_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, TRUE);
 +      sgen_shadow_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "shadow card table");
  #endif
  
  #ifdef HEAVY_STATISTICS
index a1eccaee0f00418cabacddbcc1b4cc412d16b0ed,767be65fc539ac71218aa53fc724e203e3aa7505..c1404df194360413fae4fdea5a88c38c6ff19cdc
@@@ -37,18 -37,15 +37,21 @@@ extern long long stat_slots_allocated_i
  static inline void
  par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword objsize, SgenGrayQueue *queue)
  {
+ #ifdef __GNUC__
        static const void *copy_labels [] = { &&LAB_0, &&LAB_1, &&LAB_2, &&LAB_3, &&LAB_4, &&LAB_5, &&LAB_6, &&LAB_7, &&LAB_8 };
+ #endif
  
        DEBUG (9, g_assert (vt->klass->inited));
        DEBUG (9, fprintf (gc_debug_file, " (to %p, %s size: %lu)\n", destination, ((MonoObject*)obj)->vtable->klass->name, (unsigned long)objsize));
        binary_protocol_copy (obj, destination, vt, objsize);
 -      
 +
 +      if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
 +              int dest_gen = sgen_ptr_in_nursery (destination) ? GENERATION_NURSERY : GENERATION_OLD;
 +              int src_gen = sgen_ptr_in_nursery (obj) ? GENERATION_NURSERY : GENERATION_OLD;
 +              MONO_GC_OBJ_MOVED ((mword)destination, (mword)obj, dest_gen, src_gen, objsize, vt->klass->name_space, vt->klass->name);
 +      }
 +
+ #ifdef __GNUC__
        if (objsize <= sizeof (gpointer) * 8) {
                mword *dest = (mword*)destination;
                goto *copy_labels [objsize / sizeof (gpointer)];
@@@ -74,6 -71,9 +77,9 @@@
                /*can't trust memcpy doing word copies */
                mono_gc_memmove (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword));
        }
+ #else
+               mono_gc_memmove (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword));
+ #endif
        /* adjust array->bounds */
        DEBUG (9, g_assert (vt->gc_descr));
        if (G_UNLIKELY (vt->rank && ((MonoArray*)obj)->bounds)) {
        }
  }
  
+ #ifdef _MSC_VER
+ static __declspec(noinline) void*
+ #else
  static G_GNUC_UNUSED void* __attribute__((noinline))
+ #endif
  copy_object_no_checks (void *obj, SgenGrayQueue *queue)
  {
        MonoVTable *vt = ((MonoObject*)obj)->vtable;
@@@ -150,7 -154,11 +160,11 @@@ extern long long stat_nursery_copy_obje
   * copy_object could be made into a macro once debugged (use inline for now).
   */
  
+ #ifdef _MSC_VER
+ static __forceinline void
+ #else
  static inline void __attribute__((always_inline))
+ #endif
  serial_copy_object (void **obj_slot, SgenGrayQueue *queue) 
  {
        char *forwarded;
diff --combined mono/metadata/sgen-gc.c
index a79b307328c8d795955d1426a2712f37e4b7b5bf,e6a0bec947927159f12f0ddcb07e9750a6299b2a..3431875933b56b7d6cdfccc95ded9beb1c5262c4
  #include "metadata/sgen-archdep.h"
  #include "metadata/sgen-bridge.h"
  #include "metadata/sgen-memory-governor.h"
 +#include "metadata/sgen-hash-table.h"
  #include "metadata/mono-gc.h"
  #include "metadata/method-builder.h"
  #include "metadata/profiler-private.h"
  #include "utils/mono-proclib.h"
  #include "utils/mono-memory-model.h"
  #include "utils/mono-logger-internal.h"
 +#include "utils/dtrace.h"
  
  #include <mono/utils/mono-logger-internal.h>
  #include <mono/utils/memcheck.h>
@@@ -1246,11 -1244,6 +1246,11 @@@ pin_objects_from_addresses (GCMemSectio
                                        if (addr >= search_start && (char*)addr < (char*)last_obj + last_obj_size) {
                                                DEBUG (4, fprintf (gc_debug_file, "Pinned object %p, vtable %p (%s), count %d\n", search_start, *(void**)search_start, safe_name (search_start), count));
                                                binary_protocol_pin (search_start, (gpointer)LOAD_VTABLE (search_start), safe_object_get_size (search_start));
 +                                              if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
 +                                                      int gen = sgen_ptr_in_nursery (search_start) ? GENERATION_NURSERY : GENERATION_OLD;
 +                                                      MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (search_start);
 +                                                      MONO_GC_OBJ_PINNED ((mword)search_start, sgen_safe_object_get_size (search_start), vt->klass->name_space, vt->klass->name, gen);
 +                                              }
                                                pin_object (search_start);
                                                GRAY_OBJECT_ENQUEUE (queue, search_start);
                                                if (G_UNLIKELY (do_pin_stats))
@@@ -1316,11 -1309,6 +1316,11 @@@ sgen_pin_object (void *object, GrayQueu
        }
        GRAY_OBJECT_ENQUEUE (queue, object);
        binary_protocol_pin (object, (gpointer)LOAD_VTABLE (object), safe_object_get_size (object));
 +      if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
 +              int gen = sgen_ptr_in_nursery (object) ? GENERATION_NURSERY : GENERATION_OLD;
 +              MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (object);
 +              MONO_GC_OBJ_PINNED ((mword)object, sgen_safe_object_get_size (object), vt->klass->name_space, vt->klass->name, gen);
 +      }
  }
  
  void
@@@ -1649,7 -1637,7 +1649,7 @@@ alloc_nursery (void
        section->size = alloc_size;
        section->end_data = data + sgen_nursery_size;
        scan_starts = (alloc_size + SCAN_START_SIZE - 1) / SCAN_START_SIZE;
 -      section->scan_starts = sgen_alloc_internal_dynamic (sizeof (char*) * scan_starts, INTERNAL_MEM_SCAN_STARTS);
 +      section->scan_starts = sgen_alloc_internal_dynamic (sizeof (char*) * scan_starts, INTERNAL_MEM_SCAN_STARTS, TRUE);
        section->num_scan_start = scan_starts;
        section->block.role = MEMORY_ROLE_GEN0;
        section->block.next = NULL;
@@@ -1824,9 -1812,9 +1824,9 @@@ stw_bridge_process (void
  }
  
  static void
 -bridge_process (void)
 +bridge_process (int generation)
  {
 -      sgen_bridge_processing_finish ();
 +      sgen_bridge_processing_finish (generation);
  }
  
  SgenObjectOperations *
@@@ -2363,8 -2351,6 +2363,8 @@@ collect_nursery (void
        if (disable_minor_collections)
                return TRUE;
  
 +      MONO_GC_BEGIN (GENERATION_NURSERY);
 +
        verify_nursery ();
  
        mono_perfcounters->gc_collections0++;
        sgen_workers_init_distribute_gray_queue ();
  
        stat_minor_gcs++;
 -      mono_stats.minor_gc_count ++;
 +      gc_stats.minor_gc_count ++;
  
        if (remset.prepare_for_minor_collection)
                remset.prepare_for_minor_collection ();
        major_collector.finish_nursery_collection ();
  
        TV_GETTIME (all_btv);
 -      mono_stats.minor_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
 +      gc_stats.minor_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
  
        if (heap_dump_file)
                dump_heap ("minor", stat_minor_gcs - 1, NULL);
        current_collection_generation = -1;
        objects_pinned = 0;
  
 +      MONO_GC_END (GENERATION_NURSERY);
 +
        return needs_major;
  }
  
@@@ -2608,8 -2592,6 +2608,8 @@@ major_do_collection (const char *reason
        ScanThreadDataJobData stdjd;
        ScanFinalizerEntriesJobData sfejd_fin_ready, sfejd_critical_fin;
  
 +      MONO_GC_BEGIN (GENERATION_OLD);
 +
        current_collection_generation = GENERATION_OLD;
        mono_perfcounters->gc_collections1++;
  
        degraded_mode = 0;
        DEBUG (1, fprintf (gc_debug_file, "Start major collection %d\n", stat_major_gcs));
        stat_major_gcs++;
 -      mono_stats.major_gc_count ++;
 +      gc_stats.major_gc_count ++;
  
        /* world must be stopped already */
        TV_GETTIME (all_atv);
                report.count = 0;
                if (sgen_find_optimized_pin_queue_area (bigobj->data, (char*)bigobj->data + bigobj->size, &dummy)) {
                        binary_protocol_pin (bigobj->data, (gpointer)LOAD_VTABLE (bigobj->data), safe_object_get_size (bigobj->data));
 +                      if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
 +                              MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (bigobj->data);
 +                              MONO_GC_OBJ_PINNED ((mword)bigobj->data, sgen_safe_object_get_size ((MonoObject*)bigobj->data), vt->klass->name_space, vt->klass->name, GENERATION_OLD);
 +                      }
                        pin_object (bigobj->data);
                        /* FIXME: only enqueue if object has references */
                        GRAY_OBJECT_ENQUEUE (WORKERS_DISTRIBUTE_GRAY_QUEUE, bigobj->data);
        time_major_fragment_creation += TV_ELAPSED (btv, atv);
  
        TV_GETTIME (all_btv);
 -      mono_stats.major_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
 +      gc_stats.major_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
  
        if (heap_dump_file)
                dump_heap ("major", stat_major_gcs - 1, reason);
  
        //consistency_check ();
  
 +      MONO_GC_END (GENERATION_OLD);
 +
        return bytes_pinned_from_failed_allocation > 0;
  }
  
@@@ -3434,7 -3410,7 +3434,7 @@@ update_current_thread_stack (void *star
  {
        int stack_guard = 0;
  #ifndef USE_MONO_CTX
-       void *ptr = cur_thread_regs;
+       void *reg_ptr = cur_thread_regs;
  #endif
        SgenThreadInfo *info = mono_thread_info_current ();
        
  #ifdef USE_MONO_CTX
        MONO_CONTEXT_GET_CURRENT (cur_thread_ctx);
        info->monoctx = &cur_thread_ctx;
 +      if (gc_callbacks.thread_suspend_func)
 +              gc_callbacks.thread_suspend_func (info->runtime_data, NULL, info->monoctx);
  #else
-       ARCH_STORE_REGS (ptr);
-       info->stopped_regs = ptr;
+       ARCH_STORE_REGS (reg_ptr);
+       info->stopped_regs = reg_ptr;
 -#endif
        if (gc_callbacks.thread_suspend_func)
 -              gc_callbacks.thread_suspend_func (info->runtime_data, NULL);
 +              gc_callbacks.thread_suspend_func (info->runtime_data, NULL, NULL);
 +#endif
  }
  
  void
@@@ -3624,7 -3598,7 +3624,7 @@@ restart_world (int generation, GGTiming
        DEBUG (2, fprintf (gc_debug_file, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, (int)usec, (int)max_pause_usec));
        mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD, generation);
  
 -      bridge_process ();
 +      bridge_process (generation);
  
        TV_GETTIME (end_bridge);
        bridge_usec = TV_ELAPSED (end_sw, end_bridge);
@@@ -3903,7 -3877,6 +3903,7 @@@ sgen_thread_unregister (SgenThreadInfo 
                if (!sgen_park_current_thread_if_doing_handshake (p))
                        g_usleep (50);
        }
 +      MONO_GC_LOCKED ();
  #endif
  
        binary_protocol_thread_unregister ((gpointer)mono_thread_info_get_tid (p));
@@@ -4415,27 -4388,9 +4415,27 @@@ mono_gc_weak_link_remove (void **link_a
  MonoObject*
  mono_gc_weak_link_get (void **link_addr)
  {
 -      if (!*link_addr)
 +      /*
 +       * We must only load *link_addr once because it might change
 +       * under our feet, and REVEAL_POINTER (NULL) results in an
 +       * invalid reference.
 +       */
 +      void *ptr = *link_addr;
 +      if (!ptr)
                return NULL;
 -      return (MonoObject*) REVEAL_POINTER (*link_addr);
 +
 +      /*
 +       * During the second bridge processing step the world is
 +       * running again.  That step processes all weak links once
 +       * more to null those that refer to dead objects.  Before that
 +       * is completed, those links must not be followed, so we
 +       * conservatively wait for bridge processing when any weak
 +       * link is dereferenced.
 +       */
 +      if (G_UNLIKELY (bridge_processing_in_progress))
 +              mono_gc_wait_for_bridge_processing ();
 +
 +      return (MonoObject*) REVEAL_POINTER (ptr);
  }
  
  gboolean
@@@ -4644,9 -4599,6 +4644,9 @@@ mono_gc_base_init (void
                                                        fprintf (stderr, "The major collector does not support the cardtable write barrier.\n");
                                                exit (1);
                                        }
 +                              } else {
 +                                      fprintf (stderr, "wbarrier must either be `remset' or `cardtable'.");
 +                                      exit (1);
                                }
                                continue;
                        }
@@@ -4947,12 -4899,6 +4947,12 @@@ mono_gc_is_critical_method (MonoMethod 
        return (method == write_barrier_method || sgen_is_managed_allocator (method));
  }
  
 +static gboolean
 +sgen_has_critical_method (void)
 +{
 +      return write_barrier_method || sgen_has_managed_allocator ();
 +}
 +
  static gboolean
  is_ip_in_managed_allocator (MonoDomain *domain, gpointer ip)
  {
  
        if (!ip || !domain)
                return FALSE;
 +      if (!sgen_has_critical_method ())
 +              return FALSE;
        ji = mono_jit_info_table_find (domain, ip);
        if (!ji)
                return FALSE;
index 5546a929d381a322eb70be2fa6a8370df8fcbab7,bc0c19bf2a751dafa88b345afc744d0b01500726..d861f22f2528d2856afed04dbf608787f66d5059
@@@ -101,7 -101,7 +101,7 @@@ struct _MSBlockInfo 
  };
  
  #ifdef FIXED_HEAP
 -static int ms_heap_num_blocks = MS_DEFAULT_HEAP_NUM_BLOCKS;
 +static mword ms_heap_num_blocks = MS_DEFAULT_HEAP_NUM_BLOCKS;
  
  static char *ms_heap_start;
  static char *ms_heap_end;
@@@ -304,18 -304,18 +304,18 @@@ major_alloc_heap (mword nursery_size, m
        char *nursery_start;
        mword major_heap_size = ms_heap_num_blocks * MS_BLOCK_SIZE;
        mword alloc_size = nursery_size + major_heap_size;
 -      int i;
 +      mword i;
  
        g_assert (ms_heap_num_blocks > 0);
        g_assert (nursery_size % MS_BLOCK_SIZE == 0);
        if (nursery_align)
                g_assert (nursery_align % MS_BLOCK_SIZE == 0);
  
 -      nursery_start = sgen_alloc_os_memory_aligned (alloc_size, nursery_align ? nursery_align : MS_BLOCK_SIZE, TRUE);
 +      nursery_start = sgen_alloc_os_memory_aligned (alloc_size, nursery_align ? nursery_align : MS_BLOCK_SIZE, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "heap");
        ms_heap_start = nursery_start + nursery_size;
        ms_heap_end = ms_heap_start + major_heap_size;
  
 -      block_infos = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo) * ms_heap_num_blocks, INTERNAL_MEM_MS_BLOCK_INFO);
 +      block_infos = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo) * ms_heap_num_blocks, INTERNAL_MEM_MS_BLOCK_INFO, TRUE);
  
        for (i = 0; i < ms_heap_num_blocks; ++i) {
                block_infos [i].block = ms_heap_start + i * MS_BLOCK_SIZE;
@@@ -336,9 -336,9 +336,9 @@@ major_alloc_heap (mword nursery_size, m
  {
        char *start;
        if (nursery_align)
 -              start = sgen_alloc_os_memory_aligned (nursery_size, nursery_align, TRUE);
 +              start = sgen_alloc_os_memory_aligned (nursery_size, nursery_align, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "nursery");
        else
 -              start = sgen_alloc_os_memory (nursery_size, TRUE);
 +              start = sgen_alloc_os_memory (nursery_size, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "nursery");
  
        return start;
  }
@@@ -389,7 -389,7 +389,7 @@@ ms_get_empty_block (void
  
   retry:
        if (!empty_blocks) {
 -              p = sgen_alloc_os_memory_aligned (MS_BLOCK_SIZE * MS_BLOCK_ALLOC_NUM, MS_BLOCK_SIZE, TRUE);
 +              p = sgen_alloc_os_memory_aligned (MS_BLOCK_SIZE * MS_BLOCK_ALLOC_NUM, MS_BLOCK_SIZE, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "major heap section");
  
                for (i = 0; i < MS_BLOCK_ALLOC_NUM; ++i) {
                        block = p;
@@@ -1370,10 -1370,6 +1370,10 @@@ major_copy_or_mark_object (void **ptr, 
                        if (SGEN_OBJECT_IS_PINNED (obj))
                                return;
                        binary_protocol_pin (obj, (gpointer)SGEN_LOAD_VTABLE (obj), sgen_safe_object_get_size ((MonoObject*)obj));
 +                      if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
 +                              MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj);
 +                              MONO_GC_OBJ_PINNED ((mword)obj, sgen_safe_object_get_size (obj), vt->klass->name_space, vt->klass->name, GENERATION_OLD);
 +                      }
                        SGEN_PIN_OBJECT (obj);
                        /* FIXME: only enqueue if object has references */
                        GRAY_OBJECT_ENQUEUE (queue, obj);
@@@ -1460,14 -1456,7 +1460,14 @@@ ms_sweep (void
                        } else {
                                /* an unmarked object */
                                if (MS_OBJ_ALLOCED (obj, block)) {
 +                                      /*
 +                                       * FIXME: Merge consecutive
 +                                       * slots for lower reporting
 +                                       * overhead.  Maybe memset
 +                                       * will also benefit?
 +                                       */
                                        binary_protocol_empty (obj, block->obj_size);
 +                                      MONO_GC_MAJOR_SWEPT ((mword)obj, block->obj_size);
                                        memset (obj, 0, block->obj_size);
                                }
                                *(void**)obj = block->free_list;
@@@ -1597,7 -1586,7 +1597,7 @@@ count_pinned_callback (char *obj, size_
                ++count_pinned_nonref;
  }
  
- static void __attribute__ ((unused))
+ static G_GNUC_UNUSED void
  count_ref_nonref_objs (void)
  {
        int total;
@@@ -1708,7 -1697,7 +1708,7 @@@ major_have_computer_minor_collection_al
  
        while (num_empty_blocks > section_reserve) {
                void *next = *(void**)empty_blocks;
 -              sgen_free_os_memory (empty_blocks, MS_BLOCK_SIZE);
 +              sgen_free_os_memory (empty_blocks, MS_BLOCK_SIZE, SGEN_ALLOC_HEAP);
                empty_blocks = next;
                /*
                 * Needs not be atomic because this is running
@@@ -1998,7 -1987,7 +1998,7 @@@ alloc_free_block_lists (MSBlockInfo ***
  {
        int i;
        for (i = 0; i < MS_BLOCK_TYPE_MAX; ++i)
 -              lists [i] = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo*) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES);
 +              lists [i] = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo*) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES, TRUE);
  }
  
  #ifdef SGEN_PARALLEL_MARK
@@@ -2080,10 -2069,10 +2080,10 @@@ sgen_marksweep_ini
  #endif
  
        num_block_obj_sizes = ms_calculate_block_obj_sizes (MS_BLOCK_OBJ_SIZE_FACTOR, NULL);
 -      block_obj_sizes = sgen_alloc_internal_dynamic (sizeof (int) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES);
 +      block_obj_sizes = sgen_alloc_internal_dynamic (sizeof (int) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES, TRUE);
        ms_calculate_block_obj_sizes (MS_BLOCK_OBJ_SIZE_FACTOR, block_obj_sizes);
  
 -      evacuate_block_obj_sizes = sgen_alloc_internal_dynamic (sizeof (gboolean) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES);
 +      evacuate_block_obj_sizes = sgen_alloc_internal_dynamic (sizeof (gboolean) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES, TRUE);
        for (i = 0; i < num_block_obj_sizes; ++i)
                evacuate_block_obj_sizes [i] = FALSE;
  
index 79e907c91af87219754162d130a818afbaf0c421,f2d7803f04c174c253f4365e8b9cd63388735dc4..7a8b8b63887222e907fcb81349187ec9bdf671b1
@@@ -2,7 -2,7 +2,7 @@@
  
  #if defined(HAVE_SGEN_GC) && defined(HOST_WIN32)
  
- #include <windows.h>
+ #include "io-layer/io-layer.h"
  
  #include "metadata/sgen-gc.h"
  #include "metadata/gc-internal.h"
@@@ -72,7 -72,7 +72,7 @@@ sgen_suspend_thread (SgenThreadInfo *in
  
        /* Notify the JIT */
        if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
 -              mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, NULL);
 +              mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, NULL, NULL);
  
        return TRUE;
  }