sgen_stop_world (int generation)
{
  unsigned int sgen_global_stop_count.0;
  unsigned int sgen_global_stop_count.1;
  long unsigned int D.17729;
  void * D.17730;
  struct SgenThreadInfo * D.17731;
  struct FILE * gc_debug_file.2;
  long long int stop_world_time.3;
  int count.4;
  int count.5;
  int count.6;
  int D.17741;
  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.17727>; else goto <D.17728>;
      <D.17727>:
      D.17729 = mono_native_thread_id_get ();
      D.17730 = (void *) D.17729;
      D.17731 = mono_thread_info_current ();
      sgen_global_stop_count.0 = sgen_global_stop_count;
      gc_debug_file.2 = gc_debug_file;
      fprintf (gc_debug_file.2, "stopping world n %d from %p %p\n", sgen_global_stop_count.0, D.17731, D.17730);
      gc_debug_file.2 = gc_debug_file;
      fflush (gc_debug_file.2);
      <D.17728>:
      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.17736>; else goto <D.17737>;
      <D.17736>:
      count.5 = count;
      monoeg_g_log (0B, 4, "More threads have died (%d) that been initialy suspended %d", dead, count.5);
      <D.17709>:
      goto <D.17709>;
      <D.17737>:
      count.5 = count;
      count.6 = count.5 - dead;
      count = count.6;
      if (0 != 0) goto <D.17739>; else goto <D.17740>;
      <D.17739>:
      count.5 = count;
      gc_debug_file.2 = gc_debug_file;
      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.17740>:
      mono_profiler_gc_event (7, generation);
      sgen_memgov_collection_start (generation);
      sgen_bridge_reset_data ();
      D.17741 = count;
      return D.17741;
    }
  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.17744;
  int iftmp.7;
  void * D.17749;
  void * D.17750;
  void * D.17752;
  _Bool D.17753;
  long int D.17754;
  long int D.17755;
  struct MonoContext * D.17758;
  struct MonoGCCallbacks * D.17759;
  void (*<T2a03>) (void *, void *, struct MonoContext *) D.17760;
  struct MonoGCCallbacks * D.17763;
  void (*<T2a03>) (void *, void *, struct MonoContext *) D.17764;
  void * D.17765;
  int stack_guard;
  struct SgenThreadInfo * info;

  try
    {
      stack_guard = 0;
      info = mono_thread_info_current ();
      D.17744 = align_pointer (&stack_guard);
      info->stack_start = D.17744;
      D.17749 = info->stack_start;
      D.17750 = info->stack_start_limit;
      if (D.17749 < D.17750) goto <D.17746>; else goto <D.17751>;
      <D.17751>:
      D.17749 = info->stack_start;
      D.17752 = info->stack_end;
      if (D.17749 >= D.17752) goto <D.17746>; else goto <D.17747>;
      <D.17746>:
      iftmp.7 = 1;
      goto <D.17748>;
      <D.17747>:
      iftmp.7 = 0;
      <D.17748>:
      D.17753 = iftmp.7 != 0;
      D.17754 = (long int) D.17753;
      D.17755 = __builtin_expect (D.17754, 0);
      if (D.17755 != 0) goto <D.17756>; else goto <D.17757>;
      <D.17756>:
      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.17757>:
      __asm__ __volatile__("movl $0x0, 0x00(%0)
mov %%ebx, 0x04(%0)
mov %%ecx, 0x08(%0)
mov %%edx, 0x0c(%0)
mov %%ebp, 0x10(%0)
mov %%esp, 0x14(%0)
mov %%esi, 0x18(%0)
mov %%edi, 0x1c(%0)
call 1f
1: pop 0x20(%0)
" :  : "a" &cur_thread_ctx : "memory");
      D.17758 = &info->ctx;
      memcpy (D.17758, &cur_thread_ctx, 36);
      D.17759 = mono_gc_get_gc_callbacks ();
      D.17760 = D.17759->thread_suspend_func;
      if (D.17760 != 0B) goto <D.17761>; else goto <D.17762>;
      <D.17761>:
      D.17763 = mono_gc_get_gc_callbacks ();
      D.17764 = D.17763->thread_suspend_func;
      D.17758 = &info->ctx;
      D.17765 = info->runtime_data;
      D.17764 (D.17765, 0B, D.17758);
      <D.17762>:
    }
  finally
    {
      stack_guard = {CLOBBER};
    }
}


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

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


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

  D.17769 = __builtin_object_size (__dest, 0);
  D.17768 = __builtin___memcpy_chk (__dest, __src, __len, D.17769);
  return D.17768;
}


restart_threads_until_none_in_managed_allocator ()
{
  struct MonoLinkedListSet * D.17771;
  struct MonoLinkedListSetNode * * D.17772;
  void * D.17773;
  struct MonoLinkedListSetNode * * D.17774;
  unsigned int D.17775;
  int D.17780;
  int D.17782;
  int D.17786;
  int D.17787;
  void * D.17789;
  int D.17791;
  int D.17793;
  void * D.17795;
  struct MonoDomain * D.17796;
  int D.17797;
  int D.17800;
  void * D.17801;
  struct FILE * gc_debug_file.8;
  long unsigned int sleep_duration.9;
  struct MonoLinkedListSet * D.17815;
  struct MonoLinkedListSetNode * D.17816;
  unsigned int D.17817;
  int D.17826;
  int D.17827;
  struct SgenThreadInfo * info;
  int num_threads_died;
  int sleep_duration;

  num_threads_died = 0;
  sleep_duration = -1;
  <D.17695>:
  {
    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.17771 = mono_thread_info_list_head ();
      D.17772 = &D.17771->head;
      D.17773 = get_hazardous_pointer (D.17772, __hp, 1);
      __cur = mono_lls_pointer_unmask (D.17773);
      goto <D.17686>;
      <D.17685>:
      D.17774 = &__cur->next;
      __next = get_hazardous_pointer_with_mask (D.17774, __hp, 0);
      D.17775 = mono_lls_pointer_get_mark (__next);
      if (D.17775 == 0) goto <D.17776>; else goto <D.17777>;
      <D.17776>:
      info = __cur;
      {
        gboolean result;

        D.17780 = info->skip;
        if (D.17780 != 0) goto <D.17778>; else goto <D.17781>;
        <D.17781>:
        D.17782 = info->gc_disabled;
        if (D.17782 != 0) goto <D.17778>; else goto <D.17779>;
        <D.17778>:
        // predicted unlikely by continue predictor.
        goto <D.17684>;
        <D.17779>:
        D.17786 = MEM[(struct MonoThreadInfo *)info].thread_state;
        D.17787 = D.17786 & 15;
        if (D.17787 == 1) goto <D.17788>; else goto <D.17783>;
        <D.17788>:
        D.17789 = info->stack_start;
        if (D.17789 == 0B) goto <D.17784>; else goto <D.17790>;
        <D.17790>:
        D.17791 = info->in_critical_region;
        if (D.17791 != 0) goto <D.17784>; else goto <D.17792>;
        <D.17792>:
        D.17793 = info->info.inside_critical_region;
        if (D.17793 != 0) goto <D.17784>; else goto <D.17794>;
        <D.17794>:
        D.17795 = info->stopped_ip;
        D.17796 = info->stopped_domain;
        D.17797 = is_ip_in_managed_allocator (D.17796, D.17795);
        if (D.17797 != 0) goto <D.17784>; else goto <D.17783>;
        <D.17784>:
        if (0 != 0) goto <D.17798>; else goto <D.17799>;
        <D.17798>:
        D.17800 = info->info.native_handle;
        D.17801 = (void *) D.17800;
        gc_debug_file.8 = gc_debug_file;
        fprintf (gc_debug_file.8, "thread %p resumed.\n", D.17801);
        gc_debug_file.8 = gc_debug_file;
        fflush (gc_debug_file.8);
        <D.17799>:
        result = sgen_resume_thread (info);
        if (result != 0) goto <D.17803>; else goto <D.17804>;
        <D.17803>:
        restart_count = restart_count + 1;
        goto <D.17805>;
        <D.17804>:
        info->skip = 1;
        <D.17805>:
        goto <D.17785>;
        <D.17783>:
        info->stopped_ip = 0B;
        info->stopped_domain = 0B;
        <D.17785>:
      }
      <D.17777>:
      <D.17684>:
      __cur = mono_lls_info_step (__next, __hp);
      <D.17686>:
      if (__cur != 0B) goto <D.17685>; else goto <D.17687>;
      <D.17687>:
      if (0 != 0) goto <D.17806>; else goto <D.17807>;
      <D.17806>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
      <D.17807>:
      __hp->hazard_pointers[0] = 0B;
      if (0 != 0) goto <D.17808>; else goto <D.17809>;
      <D.17808>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
      <D.17809>:
      __hp->hazard_pointers[1] = 0B;
    }
    if (restart_count == 0) goto <D.17688>; else goto <D.17810>;
    <D.17810>:
    sgen_wait_for_suspend_ack (restart_count);
    if (sleep_duration < 0) goto <D.17811>; else goto <D.17812>;
    <D.17811>:
    sched_yield ();
    sleep_duration = 0;
    goto <D.17813>;
    <D.17812>:
    sleep_duration.9 = (long unsigned int) sleep_duration;
    monoeg_g_usleep (sleep_duration.9);
    sleep_duration = sleep_duration + 10;
    <D.17813>:
    {
      struct MonoLinkedListSetNode * __cur;

      D.17815 = mono_thread_info_list_head ();
      __cur = D.17815->head;
      goto <D.17693>;
      <D.17692>:
      D.17816 = __cur->next;
      D.17817 = mono_lls_pointer_get_mark (D.17816);
      if (D.17817 == 0) goto <D.17818>; else goto <D.17819>;
      <D.17818>:
      info = __cur;
      {
        gboolean result;

        D.17780 = info->skip;
        if (D.17780 != 0) goto <D.17820>; else goto <D.17822>;
        <D.17822>:
        D.17795 = info->stopped_ip;
        if (D.17795 == 0B) goto <D.17820>; else goto <D.17821>;
        <D.17820>:
        // predicted unlikely by continue predictor.
        goto <D.17691>;
        <D.17821>:
        result = sgen_suspend_thread (info);
        if (result != 0) goto <D.17823>; else goto <D.17824>;
        <D.17823>:
        restarted_count = restarted_count + 1;
        goto <D.17825>;
        <D.17824>:
        info->skip = 1;
        <D.17825>:
      }
      <D.17819>:
      <D.17691>:
      D.17816 = __cur->next;
      __cur = mono_lls_pointer_unmask (D.17816);
      <D.17693>:
      if (__cur != 0B) goto <D.17692>; else goto <D.17694>;
      <D.17694>:
    }
    D.17826 = restart_count - restarted_count;
    num_threads_died = D.17826 + num_threads_died;
    sgen_wait_for_suspend_ack (restarted_count);
  }
  goto <D.17695>;
  <D.17688>:
  D.17827 = num_threads_died;
  return D.17827;
}


is_ip_in_managed_allocator (struct MonoDomain * domain, void * ip)
{
  struct MonoInternalThread * D.17829;
  gboolean D.17832;
  _Bool D.17833;
  _Bool D.17834;
  _Bool D.17835;
  int D.17838;
  struct MonoMethod * D.17843;
  struct MonoJitInfo * ji;

  D.17829 = mono_thread_internal_current ();
  if (D.17829 == 0B) goto <D.17830>; else goto <D.17831>;
  <D.17830>:
  D.17832 = 0;
  return D.17832;
  <D.17831>:
  D.17833 = ip == 0B;
  D.17834 = domain == 0B;
  D.17835 = D.17833 | D.17834;
  if (D.17835 != 0) goto <D.17836>; else goto <D.17837>;
  <D.17836>:
  D.17832 = 0;
  return D.17832;
  <D.17837>:
  D.17838 = sgen_has_critical_method ();
  if (D.17838 == 0) goto <D.17839>; else goto <D.17840>;
  <D.17839>:
  D.17832 = 0;
  return D.17832;
  <D.17840>:
  ji = mono_jit_info_table_find_internal (domain, ip, 0);
  if (ji == 0B) goto <D.17841>; else goto <D.17842>;
  <D.17841>:
  D.17832 = 0;
  return D.17832;
  <D.17842>:
  D.17843 = mono_jit_info_get_method (ji);
  D.17832 = sgen_is_critical_method (D.17843);
  return D.17832;
}


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

  val = mono_lls_pointer_unmask (val);
  if (0 != 0) goto <D.17845>; else goto <D.17846>;
  <D.17845>:
  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.17846>:
  hp->hazard_pointers[1] = val;
  mono_memory_write_barrier ();
  D.17847 = val;
  return D.17847;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


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

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


mono_lls_pointer_unmask (void * p)
{
  void * D.17852;
  unsigned int p.11;
  unsigned int D.17854;

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


sgen_restart_world (int generation, struct GGTimingInfo * timing)
{
  <unnamed type> mono_profiler_events.12;
  unsigned int D.17857;
  _Bool D.17858;
  long int D.17859;
  long int D.17860;
  struct MonoLinkedListSet * D.17863;
  struct MonoLinkedListSetNode * D.17864;
  unsigned int D.17865;
  struct MonoContext * D.17868;
  long long int stop_world_time.13;
  long long int D.17870;
  long long int D.17871;
  long unsigned int max_pause_usec.14;
  long unsigned int max_pause_usec.15;
  int gc_debug_level.16;
  _Bool D.17875;
  long int D.17876;
  long int D.17877;
  int max_pause_usec.17;
  int usec.18;
  struct FILE * gc_debug_file.19;
  long long int D.17883;
  long long int D.17884;
  long long int D.17887;
  long long int D.17888;
  int iftmp.20;
  int D.17893;
  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.17857 = mono_profiler_events.12 & 524288;
  D.17858 = D.17857 != 0;
  D.17859 = (long int) D.17858;
  D.17860 = __builtin_expect (D.17859, 0);
  if (D.17860 != 0) goto <D.17861>; else goto <D.17862>;
  <D.17861>:
  sgen_gc_event_moves ();
  <D.17862>:
  mono_profiler_gc_event (8, generation);
  {
    struct MonoLinkedListSetNode * __cur;

    D.17863 = mono_thread_info_list_head ();
    __cur = D.17863->head;
    goto <D.17722>;
    <D.17721>:
    D.17864 = __cur->next;
    D.17865 = mono_lls_pointer_get_mark (D.17864);
    if (D.17865 == 0) goto <D.17866>; else goto <D.17867>;
    <D.17866>:
    info = __cur;
    info->stack_start = 0B;
    D.17868 = &info->ctx;
    memset (D.17868, 0, 36);
    <D.17867>:
    D.17864 = __cur->next;
    __cur = mono_lls_pointer_unmask (D.17864);
    <D.17722>:
    if (__cur != 0B) goto <D.17721>; else goto <D.17723>;
    <D.17723>:
  }
  count = sgen_thread_handshake (0);
  end_sw = mono_100ns_ticks ();
  stop_world_time.13 = stop_world_time;
  D.17870 = end_sw - stop_world_time.13;
  D.17871 = D.17870 / 10;
  usec = (long unsigned int) D.17871;
  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.17875 = gc_debug_level.16 > 1;
  D.17876 = (long int) D.17875;
  D.17877 = __builtin_expect (D.17876, 0);
  if (D.17877 != 0) goto <D.17878>; else goto <D.17879>;
  <D.17878>:
  max_pause_usec.14 = max_pause_usec;
  max_pause_usec.17 = (int) max_pause_usec.14;
  usec.18 = (int) usec;
  gc_debug_file.19 = gc_debug_file;
  fprintf (gc_debug_file.19, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, usec.18, max_pause_usec.17);
  gc_debug_file.19 = gc_debug_file;
  fflush (gc_debug_file.19);
  <D.17879>:
  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.17883 = end_bridge - end_sw;
  D.17884 = D.17883 / 10;
  bridge_usec = (long unsigned int) D.17884;
  if (timing != 0B) goto <D.17885>; else goto <D.17886>;
  <D.17885>:
  D.17887 = (long long int) usec;
  timing->stw_time = D.17887;
  D.17888 = (long long int) bridge_usec;
  timing->bridge_time = D.17888;
  <D.17886>:
  if (timing != 0B) goto <D.17890>; else goto <D.17891>;
  <D.17890>:
  iftmp.20 = 2;
  goto <D.17892>;
  <D.17891>:
  iftmp.20 = 0;
  <D.17892>:
  sgen_memgov_collection_end (generation, timing, iftmp.20);
  D.17893 = count;
  return D.17893;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.17897;
  int D.17902;
  void * D.17904;
  unsigned int D.17905;

  D.17897 = __builtin_constant_p (__len);
  if (D.17897 != 0) goto <D.17898>; else goto <D.17899>;
  <D.17898>:
  if (__len == 0) goto <D.17900>; else goto <D.17901>;
  <D.17900>:
  D.17902 = __builtin_constant_p (__ch);
  if (D.17902 == 0) goto <D.17895>; else goto <D.17903>;
  <D.17903>:
  if (__ch != 0) goto <D.17895>; else goto <D.17896>;
  <D.17895>:
  __warn_memset_zero_len ();
  D.17904 = __dest;
  return D.17904;
  <D.17896>:
  <D.17901>:
  <D.17899>:
  D.17905 = __builtin_object_size (__dest, 0);
  D.17904 = __builtin___memset_chk (__dest, __ch, __len, D.17905);
  return D.17904;
}


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

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


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


