sgen_stop_world (int generation)
{
  unsigned int sgen_global_stop_count.0;
  unsigned int sgen_global_stop_count.1;
  struct FILE * gc_debug_file.2;
  struct SgenThreadInfo * D.17710;
  long unsigned int D.17711;
  void * D.17712;
  long long int stop_world_time.3;
  int count.4;
  int count.5;
  int count.6;
  int D.17721;
  int count;
  int dead;

  try
    {
      sgen_process_togglerefs ();
      mono_profiler_gc_event (6, generation);
      acquire_gc_locks ();
      update_current_thread_stack (&count);
      sgen_global_stop_count.0 = sgen_global_stop_count;
      sgen_global_stop_count.1 = sgen_global_stop_count.0 + 1;
      sgen_global_stop_count = sgen_global_stop_count.1;
      if (0 != 0) goto <D.17707>; else goto <D.17708>;
      <D.17707>:
      gc_debug_file.2 = gc_debug_file;
      sgen_global_stop_count.0 = sgen_global_stop_count;
      D.17710 = mono_thread_info_current ();
      D.17711 = mono_native_thread_id_get ();
      D.17712 = (void *) D.17711;
      fprintf (gc_debug_file.2, "stopping world n %d from %p %p\n", sgen_global_stop_count.0, D.17710, D.17712);
      gc_debug_file.2 = gc_debug_file;
      fflush (gc_debug_file.2);
      <D.17708>:
      stop_world_time.3 = mono_100ns_ticks ();
      stop_world_time = stop_world_time.3;
      count.4 = sgen_thread_handshake (1);
      count = count.4;
      dead = restart_threads_until_none_in_managed_allocator ();
      count.5 = count;
      if (count.5 < dead) goto <D.17716>; else goto <D.17717>;
      <D.17716>:
      count.5 = count;
      monoeg_g_log (0B, 4, "More threads have died (%d) that been initialy suspended %d", dead, count.5);
      <D.17689>:
      goto <D.17689>;
      <D.17717>:
      count.5 = count;
      count.6 = count.5 - dead;
      count = count.6;
      if (0 != 0) goto <D.17719>; else goto <D.17720>;
      <D.17719>:
      gc_debug_file.2 = gc_debug_file;
      count.5 = count;
      fprintf (gc_debug_file.2, "world stopped %d thread(s)\n", count.5);
      gc_debug_file.2 = gc_debug_file;
      fflush (gc_debug_file.2);
      <D.17720>:
      mono_profiler_gc_event (7, generation);
      sgen_memgov_collection_start (generation);
      sgen_bridge_reset_data ();
      D.17721 = count;
      return D.17721;
    }
  finally
    {
      count = {CLOBBER};
    }
}


acquire_gc_locks ()
{
  pthread_mutex_lock (&sgen_interruption_mutex);
  mono_thread_info_suspend_lock ();
}


update_current_thread_stack (void * start)
{
  void * D.17724;
  int iftmp.7;
  void * D.17729;
  void * D.17730;
  void * D.17732;
  _Bool D.17733;
  long int D.17734;
  long int D.17735;
  struct MonoContext * D.17738;
  struct MonoGCCallbacks * D.17739;
  void (*<T29fd>) (void *, void *, struct MonoContext *) D.17740;
  struct MonoGCCallbacks * D.17743;
  void (*<T29fd>) (void *, void *, struct MonoContext *) D.17744;
  void * D.17745;
  int stack_guard;
  struct SgenThreadInfo * info;

  try
    {
      stack_guard = 0;
      info = mono_thread_info_current ();
      D.17724 = align_pointer (&stack_guard);
      info->stack_start = D.17724;
      D.17729 = info->stack_start;
      D.17730 = info->stack_start_limit;
      if (D.17729 < D.17730) goto <D.17726>; else goto <D.17731>;
      <D.17731>:
      D.17729 = info->stack_start;
      D.17732 = info->stack_end;
      if (D.17729 >= D.17732) goto <D.17726>; else goto <D.17727>;
      <D.17726>:
      iftmp.7 = 1;
      goto <D.17728>;
      <D.17727>:
      iftmp.7 = 0;
      <D.17728>:
      D.17733 = iftmp.7 != 0;
      D.17734 = (long int) D.17733;
      D.17735 = __builtin_expect (D.17734, 0);
      if (D.17735 != 0) goto <D.17736>; else goto <D.17737>;
      <D.17736>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 67, "info->stack_start >= info->stack_start_limit && info->stack_start < info->stack_end");
      <D.17737>:
      __asm__ __volatile__("sw $0,0(%0)
	sw $1,4(%0)
	sw $2,8(%0)
	sw $3,12(%0)
	sw $4,16(%0)
	sw $5,20(%0)
	sw $6,24(%0)
	sw $7,28(%0)
	sw $8,32(%0)
	sw $9,36(%0)
	sw $10,40(%0)
	sw $11,44(%0)
	sw $12,48(%0)
	sw $13,52(%0)
	sw $14,56(%0)
	sw $15,60(%0)
	sw $16,64(%0)
	sw $17,68(%0)
	sw $18,72(%0)
	sw $19,76(%0)
	sw $20,80(%0)
	sw $21,84(%0)
	sw $22,88(%0)
	sw $23,92(%0)
	sw $24,96(%0)
	sw $25,100(%0)
	sw $26,104(%0)
	sw $27,108(%0)
	sw $28,112(%0)
	sw $29,116(%0)
	sw $30,120(%0)
	sw $31,124(%0)
	" :  : "r" &cur_thread_ctx.sc_regs[0] : "memory");
      D.17738 = &info->ctx;
      memcpy (D.17738, &cur_thread_ctx, 260);
      D.17739 = mono_gc_get_gc_callbacks ();
      D.17740 = D.17739->thread_suspend_func;
      if (D.17740 != 0B) goto <D.17741>; else goto <D.17742>;
      <D.17741>:
      D.17743 = mono_gc_get_gc_callbacks ();
      D.17744 = D.17743->thread_suspend_func;
      D.17745 = info->runtime_data;
      D.17738 = &info->ctx;
      D.17744 (D.17745, 0B, D.17738);
      <D.17742>:
    }
  finally
    {
      stack_guard = {CLOBBER};
    }
}


align_pointer (void * ptr)
{
  void * D.17746;
  mword p;

  p = (mword) ptr;
  p = p + 3;
  p = p & 4294967292;
  D.17746 = (void *) p;
  return D.17746;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.17748;
  unsigned int D.17749;

  D.17749 = __builtin_object_size (__dest, 0);
  D.17748 = __builtin___memcpy_chk (__dest, __src, __len, D.17749);
  return D.17748;
}


restart_threads_until_none_in_managed_allocator ()
{
  struct MonoLinkedListSet * D.17751;
  struct MonoLinkedListSetNode * * D.17752;
  void * D.17753;
  struct MonoLinkedListSetNode * * D.17754;
  unsigned int D.17755;
  int D.17760;
  int D.17762;
  int D.17766;
  int D.17767;
  void * D.17769;
  int D.17771;
  int D.17773;
  struct MonoDomain * D.17775;
  void * D.17776;
  int D.17777;
  struct FILE * gc_debug_file.8;
  int D.17781;
  void * D.17782;
  long unsigned int sleep_duration.9;
  struct MonoLinkedListSet * D.17795;
  struct MonoLinkedListSetNode * D.17796;
  unsigned int D.17797;
  int D.17806;
  int D.17807;
  struct SgenThreadInfo * info;
  int num_threads_died;
  int sleep_duration;

  num_threads_died = 0;
  sleep_duration = -1;
  <D.17675>:
  {
    int restart_count;
    int restarted_count;

    restart_count = 0;
    restarted_count = 0;
    {
      struct MonoThreadHazardPointers * __hp;
      struct MonoLinkedListSetNode * __cur;
      struct MonoLinkedListSetNode * __next;

      __hp = mono_hazard_pointer_get ();
      D.17751 = mono_thread_info_list_head ();
      D.17752 = &D.17751->head;
      D.17753 = get_hazardous_pointer (D.17752, __hp, 1);
      __cur = mono_lls_pointer_unmask (D.17753);
      goto <D.17666>;
      <D.17665>:
      D.17754 = &__cur->next;
      __next = get_hazardous_pointer_with_mask (D.17754, __hp, 0);
      D.17755 = mono_lls_pointer_get_mark (__next);
      if (D.17755 == 0) goto <D.17756>; else goto <D.17757>;
      <D.17756>:
      info = __cur;
      {
        gboolean result;

        D.17760 = info->skip;
        if (D.17760 != 0) goto <D.17758>; else goto <D.17761>;
        <D.17761>:
        D.17762 = info->gc_disabled;
        if (D.17762 != 0) goto <D.17758>; else goto <D.17759>;
        <D.17758>:
        // predicted unlikely by continue predictor.
        goto <D.17664>;
        <D.17759>:
        D.17766 = MEM[(struct MonoThreadInfo *)info].thread_state;
        D.17767 = D.17766 & 15;
        if (D.17767 == 1) goto <D.17768>; else goto <D.17763>;
        <D.17768>:
        D.17769 = info->stack_start;
        if (D.17769 == 0B) goto <D.17764>; else goto <D.17770>;
        <D.17770>:
        D.17771 = info->in_critical_region;
        if (D.17771 != 0) goto <D.17764>; else goto <D.17772>;
        <D.17772>:
        D.17773 = info->info.inside_critical_region;
        if (D.17773 != 0) goto <D.17764>; else goto <D.17774>;
        <D.17774>:
        D.17775 = info->stopped_domain;
        D.17776 = info->stopped_ip;
        D.17777 = is_ip_in_managed_allocator (D.17775, D.17776);
        if (D.17777 != 0) goto <D.17764>; else goto <D.17763>;
        <D.17764>:
        if (0 != 0) goto <D.17778>; else goto <D.17779>;
        <D.17778>:
        gc_debug_file.8 = gc_debug_file;
        D.17781 = info->info.native_handle;
        D.17782 = (void *) D.17781;
        fprintf (gc_debug_file.8, "thread %p resumed.\n", D.17782);
        gc_debug_file.8 = gc_debug_file;
        fflush (gc_debug_file.8);
        <D.17779>:
        result = sgen_resume_thread (info);
        if (result != 0) goto <D.17783>; else goto <D.17784>;
        <D.17783>:
        restart_count = restart_count + 1;
        goto <D.17785>;
        <D.17784>:
        info->skip = 1;
        <D.17785>:
        goto <D.17765>;
        <D.17763>:
        info->stopped_ip = 0B;
        info->stopped_domain = 0B;
        <D.17765>:
      }
      <D.17757>:
      <D.17664>:
      __cur = mono_lls_info_step (__next, __hp);
      <D.17666>:
      if (__cur != 0B) goto <D.17665>; else goto <D.17667>;
      <D.17667>:
      if (0 != 0) goto <D.17786>; else goto <D.17787>;
      <D.17786>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
      <D.17787>:
      __hp->hazard_pointers[0] = 0B;
      if (0 != 0) goto <D.17788>; else goto <D.17789>;
      <D.17788>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
      <D.17789>:
      __hp->hazard_pointers[1] = 0B;
    }
    if (restart_count == 0) goto <D.17668>; else goto <D.17790>;
    <D.17790>:
    sgen_wait_for_suspend_ack (restart_count);
    if (sleep_duration < 0) goto <D.17791>; else goto <D.17792>;
    <D.17791>:
    sched_yield ();
    sleep_duration = 0;
    goto <D.17793>;
    <D.17792>:
    sleep_duration.9 = (long unsigned int) sleep_duration;
    monoeg_g_usleep (sleep_duration.9);
    sleep_duration = sleep_duration + 10;
    <D.17793>:
    {
      struct MonoLinkedListSetNode * __cur;

      D.17795 = mono_thread_info_list_head ();
      __cur = D.17795->head;
      goto <D.17673>;
      <D.17672>:
      D.17796 = __cur->next;
      D.17797 = mono_lls_pointer_get_mark (D.17796);
      if (D.17797 == 0) goto <D.17798>; else goto <D.17799>;
      <D.17798>:
      info = __cur;
      {
        gboolean result;

        D.17760 = info->skip;
        if (D.17760 != 0) goto <D.17800>; else goto <D.17802>;
        <D.17802>:
        D.17776 = info->stopped_ip;
        if (D.17776 == 0B) goto <D.17800>; else goto <D.17801>;
        <D.17800>:
        // predicted unlikely by continue predictor.
        goto <D.17671>;
        <D.17801>:
        result = sgen_suspend_thread (info);
        if (result != 0) goto <D.17803>; else goto <D.17804>;
        <D.17803>:
        restarted_count = restarted_count + 1;
        goto <D.17805>;
        <D.17804>:
        info->skip = 1;
        <D.17805>:
      }
      <D.17799>:
      <D.17671>:
      D.17796 = __cur->next;
      __cur = mono_lls_pointer_unmask (D.17796);
      <D.17673>:
      if (__cur != 0B) goto <D.17672>; else goto <D.17674>;
      <D.17674>:
    }
    D.17806 = restart_count - restarted_count;
    num_threads_died = D.17806 + num_threads_died;
    sgen_wait_for_suspend_ack (restarted_count);
  }
  goto <D.17675>;
  <D.17668>:
  D.17807 = num_threads_died;
  return D.17807;
}


is_ip_in_managed_allocator (struct MonoDomain * domain, void * ip)
{
  struct MonoInternalThread * D.17809;
  gboolean D.17812;
  int D.17816;
  struct MonoMethod * D.17821;
  struct MonoJitInfo * ji;

  D.17809 = mono_thread_internal_current ();
  if (D.17809 == 0B) goto <D.17810>; else goto <D.17811>;
  <D.17810>:
  D.17812 = 0;
  return D.17812;
  <D.17811>:
  if (ip == 0B) goto <D.17813>; else goto <D.17815>;
  <D.17815>:
  if (domain == 0B) goto <D.17813>; else goto <D.17814>;
  <D.17813>:
  D.17812 = 0;
  return D.17812;
  <D.17814>:
  D.17816 = sgen_has_critical_method ();
  if (D.17816 == 0) goto <D.17817>; else goto <D.17818>;
  <D.17817>:
  D.17812 = 0;
  return D.17812;
  <D.17818>:
  ji = mono_jit_info_table_find_internal (domain, ip, 0);
  if (ji == 0B) goto <D.17819>; else goto <D.17820>;
  <D.17819>:
  D.17812 = 0;
  return D.17812;
  <D.17820>:
  D.17821 = mono_jit_info_get_method (ji);
  D.17812 = sgen_is_critical_method (D.17821);
  return D.17812;
}


mono_lls_info_step (struct MonoLinkedListSetNode * val, struct MonoThreadHazardPointers * hp)
{
  struct MonoLinkedListSetNode * D.17825;

  val = mono_lls_pointer_unmask (val);
  if (0 != 0) goto <D.17823>; else goto <D.17824>;
  <D.17823>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "../../mono/utils/mono-linked-list-set.h", 77, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
  <D.17824>:
  hp->hazard_pointers[1] = val;
  mono_memory_write_barrier ();
  D.17825 = val;
  return D.17825;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_lls_pointer_get_mark (void * n)
{
  uintptr_t D.17827;
  unsigned int n.10;

  n.10 = (unsigned int) n;
  D.17827 = n.10 & 1;
  return D.17827;
}


mono_lls_pointer_unmask (void * p)
{
  void * D.17830;
  unsigned int p.11;
  unsigned int D.17832;

  p.11 = (unsigned int) p;
  D.17832 = p.11 & 4294967292;
  D.17830 = (void *) D.17832;
  return D.17830;
}


sgen_restart_world (int generation, struct GGTimingInfo * timing)
{
  <unnamed type> mono_profiler_events.12;
  unsigned int D.17835;
  _Bool D.17836;
  long int D.17837;
  long int D.17838;
  struct MonoLinkedListSet * D.17841;
  struct MonoLinkedListSetNode * D.17842;
  unsigned int D.17843;
  struct MonoContext * D.17846;
  long long int stop_world_time.13;
  long long int D.17848;
  long long int D.17849;
  long unsigned int max_pause_usec.14;
  long unsigned int max_pause_usec.15;
  int gc_debug_level.16;
  _Bool D.17853;
  long int D.17854;
  long int D.17855;
  struct FILE * gc_debug_file.17;
  int usec.18;
  int max_pause_usec.19;
  long long int D.17861;
  long long int D.17862;
  long long int D.17865;
  long long int D.17866;
  int iftmp.20;
  int D.17871;
  int count;
  struct SgenThreadInfo * info;
  gint64 end_sw;
  gint64 end_bridge;
  long unsigned int usec;
  long unsigned int bridge_usec;

  mono_profiler_events.12 = mono_profiler_events;
  D.17835 = mono_profiler_events.12 & 524288;
  D.17836 = D.17835 != 0;
  D.17837 = (long int) D.17836;
  D.17838 = __builtin_expect (D.17837, 0);
  if (D.17838 != 0) goto <D.17839>; else goto <D.17840>;
  <D.17839>:
  sgen_gc_event_moves ();
  <D.17840>:
  mono_profiler_gc_event (8, generation);
  {
    struct MonoLinkedListSetNode * __cur;

    D.17841 = mono_thread_info_list_head ();
    __cur = D.17841->head;
    goto <D.17702>;
    <D.17701>:
    D.17842 = __cur->next;
    D.17843 = mono_lls_pointer_get_mark (D.17842);
    if (D.17843 == 0) goto <D.17844>; else goto <D.17845>;
    <D.17844>:
    info = __cur;
    info->stack_start = 0B;
    D.17846 = &info->ctx;
    memset (D.17846, 0, 260);
    <D.17845>:
    D.17842 = __cur->next;
    __cur = mono_lls_pointer_unmask (D.17842);
    <D.17702>:
    if (__cur != 0B) goto <D.17701>; else goto <D.17703>;
    <D.17703>:
  }
  count = sgen_thread_handshake (0);
  end_sw = mono_100ns_ticks ();
  stop_world_time.13 = stop_world_time;
  D.17848 = end_sw - stop_world_time.13;
  D.17849 = D.17848 / 10;
  usec = (long unsigned int) D.17849;
  max_pause_usec.14 = max_pause_usec;
  max_pause_usec.15 = MAX_EXPR <max_pause_usec.14, usec>;
  max_pause_usec = max_pause_usec.15;
  gc_debug_level.16 = gc_debug_level;
  D.17853 = gc_debug_level.16 > 1;
  D.17854 = (long int) D.17853;
  D.17855 = __builtin_expect (D.17854, 0);
  if (D.17855 != 0) goto <D.17856>; else goto <D.17857>;
  <D.17856>:
  gc_debug_file.17 = gc_debug_file;
  usec.18 = (int) usec;
  max_pause_usec.14 = max_pause_usec;
  max_pause_usec.19 = (int) max_pause_usec.14;
  fprintf (gc_debug_file.17, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, usec.18, max_pause_usec.19);
  gc_debug_file.17 = gc_debug_file;
  fflush (gc_debug_file.17);
  <D.17857>:
  mono_profiler_gc_event (9, generation);
  release_gc_locks ();
  sgen_try_free_some_memory = 1;
  sgen_bridge_processing_finish (generation);
  end_bridge = mono_100ns_ticks ();
  D.17861 = end_bridge - end_sw;
  D.17862 = D.17861 / 10;
  bridge_usec = (long unsigned int) D.17862;
  if (timing != 0B) goto <D.17863>; else goto <D.17864>;
  <D.17863>:
  D.17865 = (long long int) usec;
  timing->stw_time = D.17865;
  D.17866 = (long long int) bridge_usec;
  timing->bridge_time = D.17866;
  <D.17864>:
  if (timing != 0B) goto <D.17868>; else goto <D.17869>;
  <D.17868>:
  iftmp.20 = 2;
  goto <D.17870>;
  <D.17869>:
  iftmp.20 = 0;
  <D.17870>:
  sgen_memgov_collection_end (generation, timing, iftmp.20);
  D.17871 = count;
  return D.17871;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.17875;
  int D.17880;
  void * D.17882;
  unsigned int D.17883;

  D.17875 = __builtin_constant_p (__len);
  if (D.17875 != 0) goto <D.17876>; else goto <D.17877>;
  <D.17876>:
  if (__len == 0) goto <D.17878>; else goto <D.17879>;
  <D.17878>:
  D.17880 = __builtin_constant_p (__ch);
  if (D.17880 == 0) goto <D.17873>; else goto <D.17881>;
  <D.17881>:
  if (__ch != 0) goto <D.17873>; else goto <D.17874>;
  <D.17873>:
  __warn_memset_zero_len ();
  D.17882 = __dest;
  return D.17882;
  <D.17874>:
  <D.17879>:
  <D.17877>:
  D.17883 = __builtin_object_size (__dest, 0);
  D.17882 = __builtin___memset_chk (__dest, __ch, __len, D.17883);
  return D.17882;
}


fprintf (struct FILE * restrict __stream, const char * restrict __fmt)
{
  int D.17885;

  D.17885 = __fprintf_chk (__stream, 1, __fmt, __builtin_va_arg_pack ());
  return D.17885;
}


release_gc_locks ()
{
  mono_thread_info_suspend_unlock ();
  pthread_mutex_unlock (&sgen_interruption_mutex);
}


