sgen_stop_world (int generation)
{
  unsigned int sgen_global_stop_count.0;
  unsigned int sgen_global_stop_count.1;
  long unsigned int D.18092;
  void * D.18093;
  struct SgenThreadInfo * D.18094;
  struct FILE * gc_debug_file.2;
  long int stop_world_time.3;
  int count.4;
  int count.5;
  int count.6;
  int D.18104;
  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.18090>; else goto <D.18091>;
      <D.18090>:
      D.18092 = mono_native_thread_id_get ();
      D.18093 = (void *) D.18092;
      D.18094 = 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.18094, D.18093);
      gc_debug_file.2 = gc_debug_file;
      fflush (gc_debug_file.2);
      <D.18091>:
      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.18099>; else goto <D.18100>;
      <D.18099>:
      count.5 = count;
      monoeg_g_log (0B, 4, "More threads have died (%d) that been initialy suspended %d", dead, count.5);
      <D.18072>:
      goto <D.18072>;
      <D.18100>:
      count.5 = count;
      count.6 = count.5 - dead;
      count = count.6;
      if (0 != 0) goto <D.18102>; else goto <D.18103>;
      <D.18102>:
      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.18103>:
      mono_profiler_gc_event (7, generation);
      sgen_memgov_collection_start (generation);
      sgen_bridge_reset_data ();
      D.18104 = count;
      return D.18104;
    }
  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.18107;
  int iftmp.7;
  void * D.18112;
  void * D.18113;
  void * D.18115;
  _Bool D.18116;
  long int D.18117;
  long int D.18118;
  struct MonoContext * D.18121;
  struct MonoGCCallbacks * D.18122;
  void (*<T2aaf>) (void *, void *, struct MonoContext *) D.18123;
  struct MonoGCCallbacks * D.18126;
  void (*<T2aaf>) (void *, void *, struct MonoContext *) D.18127;
  void * D.18128;
  int stack_guard;
  struct SgenThreadInfo * info;

  try
    {
      stack_guard = 0;
      info = mono_thread_info_current ();
      D.18107 = align_pointer (&stack_guard);
      info->stack_start = D.18107;
      D.18112 = info->stack_start;
      D.18113 = info->stack_start_limit;
      if (D.18112 < D.18113) goto <D.18109>; else goto <D.18114>;
      <D.18114>:
      D.18112 = info->stack_start;
      D.18115 = info->stack_end;
      if (D.18112 >= D.18115) goto <D.18109>; else goto <D.18110>;
      <D.18109>:
      iftmp.7 = 1;
      goto <D.18111>;
      <D.18110>:
      iftmp.7 = 0;
      <D.18111>:
      D.18116 = iftmp.7 != 0;
      D.18117 = (long int) D.18116;
      D.18118 = __builtin_expect (D.18117, 0);
      if (D.18118 != 0) goto <D.18119>; else goto <D.18120>;
      <D.18119>:
      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.18120>:
      __asm__ __volatile__("movq $0x0,  0x00(%0)
movq %%rbx, 0x08(%0)
movq %%rcx, 0x10(%0)
movq %%rdx, 0x18(%0)
movq %%rbp, 0x20(%0)
movq %%rsp, 0x28(%0)
movq %%rsi, 0x30(%0)
movq %%rdi, 0x38(%0)
movq %%r8,  0x40(%0)
movq %%r9,  0x48(%0)
movq %%r10, 0x50(%0)
movq %%r11, 0x58(%0)
movq %%r12, 0x60(%0)
movq %%r13, 0x68(%0)
movq %%r14, 0x70(%0)
movq %%r15, 0x78(%0)
leaq (%%rip), %%rdx
movq %%rdx, 0x80(%0)
" :  : "a" &cur_thread_ctx : "memory", "rdx");
      D.18121 = &info->ctx;
      memcpy (D.18121, &cur_thread_ctx, 136);
      D.18122 = mono_gc_get_gc_callbacks ();
      D.18123 = D.18122->thread_suspend_func;
      if (D.18123 != 0B) goto <D.18124>; else goto <D.18125>;
      <D.18124>:
      D.18126 = mono_gc_get_gc_callbacks ();
      D.18127 = D.18126->thread_suspend_func;
      D.18121 = &info->ctx;
      D.18128 = info->runtime_data;
      D.18127 (D.18128, 0B, D.18121);
      <D.18125>:
    }
  finally
    {
      stack_guard = {CLOBBER};
    }
}


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

  p = (mword) ptr;
  p = p + 7;
  p = p & 18446744073709551608;
  D.18129 = (void *) p;
  return D.18129;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.18131;
  long unsigned int D.18132;

  D.18132 = __builtin_object_size (__dest, 0);
  D.18131 = __builtin___memcpy_chk (__dest, __src, __len, D.18132);
  return D.18131;
}


restart_threads_until_none_in_managed_allocator ()
{
  struct MonoLinkedListSet * D.18134;
  struct MonoLinkedListSetNode * * D.18135;
  void * D.18136;
  struct MonoLinkedListSetNode * * D.18137;
  long unsigned int D.18138;
  int D.18143;
  int D.18145;
  int D.18149;
  int D.18150;
  void * D.18152;
  int D.18154;
  int D.18156;
  void * D.18158;
  struct MonoDomain * D.18159;
  int D.18160;
  int D.18163;
  long unsigned int D.18164;
  void * D.18165;
  struct FILE * gc_debug_file.8;
  long unsigned int D.18178;
  struct MonoLinkedListSet * D.18179;
  struct MonoLinkedListSetNode * D.18180;
  long unsigned int D.18181;
  int D.18190;
  int D.18191;
  struct SgenThreadInfo * info;
  int num_threads_died;
  int sleep_duration;

  num_threads_died = 0;
  sleep_duration = -1;
  <D.18058>:
  {
    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.18134 = mono_thread_info_list_head ();
      D.18135 = &D.18134->head;
      D.18136 = get_hazardous_pointer (D.18135, __hp, 1);
      __cur = mono_lls_pointer_unmask (D.18136);
      goto <D.18049>;
      <D.18048>:
      D.18137 = &__cur->next;
      __next = get_hazardous_pointer_with_mask (D.18137, __hp, 0);
      D.18138 = mono_lls_pointer_get_mark (__next);
      if (D.18138 == 0) goto <D.18139>; else goto <D.18140>;
      <D.18139>:
      info = __cur;
      {
        gboolean result;

        D.18143 = info->skip;
        if (D.18143 != 0) goto <D.18141>; else goto <D.18144>;
        <D.18144>:
        D.18145 = info->gc_disabled;
        if (D.18145 != 0) goto <D.18141>; else goto <D.18142>;
        <D.18141>:
        // predicted unlikely by continue predictor.
        goto <D.18047>;
        <D.18142>:
        D.18149 = MEM[(struct MonoThreadInfo *)info].thread_state;
        D.18150 = D.18149 & 15;
        if (D.18150 == 1) goto <D.18151>; else goto <D.18146>;
        <D.18151>:
        D.18152 = info->stack_start;
        if (D.18152 == 0B) goto <D.18147>; else goto <D.18153>;
        <D.18153>:
        D.18154 = info->in_critical_region;
        if (D.18154 != 0) goto <D.18147>; else goto <D.18155>;
        <D.18155>:
        D.18156 = info->info.inside_critical_region;
        if (D.18156 != 0) goto <D.18147>; else goto <D.18157>;
        <D.18157>:
        D.18158 = info->stopped_ip;
        D.18159 = info->stopped_domain;
        D.18160 = is_ip_in_managed_allocator (D.18159, D.18158);
        if (D.18160 != 0) goto <D.18147>; else goto <D.18146>;
        <D.18147>:
        if (0 != 0) goto <D.18161>; else goto <D.18162>;
        <D.18161>:
        D.18163 = info->info.native_handle;
        D.18164 = (long unsigned int) D.18163;
        D.18165 = (void *) D.18164;
        gc_debug_file.8 = gc_debug_file;
        fprintf (gc_debug_file.8, "thread %p resumed.\n", D.18165);
        gc_debug_file.8 = gc_debug_file;
        fflush (gc_debug_file.8);
        <D.18162>:
        result = sgen_resume_thread (info);
        if (result != 0) goto <D.18167>; else goto <D.18168>;
        <D.18167>:
        restart_count = restart_count + 1;
        goto <D.18169>;
        <D.18168>:
        info->skip = 1;
        <D.18169>:
        goto <D.18148>;
        <D.18146>:
        info->stopped_ip = 0B;
        info->stopped_domain = 0B;
        <D.18148>:
      }
      <D.18140>:
      <D.18047>:
      __cur = mono_lls_info_step (__next, __hp);
      <D.18049>:
      if (__cur != 0B) goto <D.18048>; else goto <D.18050>;
      <D.18050>:
      if (0 != 0) goto <D.18170>; else goto <D.18171>;
      <D.18170>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
      <D.18171>:
      __hp->hazard_pointers[0] = 0B;
      if (0 != 0) goto <D.18172>; else goto <D.18173>;
      <D.18172>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
      <D.18173>:
      __hp->hazard_pointers[1] = 0B;
    }
    if (restart_count == 0) goto <D.18051>; else goto <D.18174>;
    <D.18174>:
    sgen_wait_for_suspend_ack (restart_count);
    if (sleep_duration < 0) goto <D.18175>; else goto <D.18176>;
    <D.18175>:
    sched_yield ();
    sleep_duration = 0;
    goto <D.18177>;
    <D.18176>:
    D.18178 = (long unsigned int) sleep_duration;
    monoeg_g_usleep (D.18178);
    sleep_duration = sleep_duration + 10;
    <D.18177>:
    {
      struct MonoLinkedListSetNode * __cur;

      D.18179 = mono_thread_info_list_head ();
      __cur = D.18179->head;
      goto <D.18056>;
      <D.18055>:
      D.18180 = __cur->next;
      D.18181 = mono_lls_pointer_get_mark (D.18180);
      if (D.18181 == 0) goto <D.18182>; else goto <D.18183>;
      <D.18182>:
      info = __cur;
      {
        gboolean result;

        D.18143 = info->skip;
        if (D.18143 != 0) goto <D.18184>; else goto <D.18186>;
        <D.18186>:
        D.18158 = info->stopped_ip;
        if (D.18158 == 0B) goto <D.18184>; else goto <D.18185>;
        <D.18184>:
        // predicted unlikely by continue predictor.
        goto <D.18054>;
        <D.18185>:
        result = sgen_suspend_thread (info);
        if (result != 0) goto <D.18187>; else goto <D.18188>;
        <D.18187>:
        restarted_count = restarted_count + 1;
        goto <D.18189>;
        <D.18188>:
        info->skip = 1;
        <D.18189>:
      }
      <D.18183>:
      <D.18054>:
      D.18180 = __cur->next;
      __cur = mono_lls_pointer_unmask (D.18180);
      <D.18056>:
      if (__cur != 0B) goto <D.18055>; else goto <D.18057>;
      <D.18057>:
    }
    D.18190 = restart_count - restarted_count;
    num_threads_died = D.18190 + num_threads_died;
    sgen_wait_for_suspend_ack (restarted_count);
  }
  goto <D.18058>;
  <D.18051>:
  D.18191 = num_threads_died;
  return D.18191;
}


is_ip_in_managed_allocator (struct MonoDomain * domain, void * ip)
{
  struct MonoInternalThread * D.18193;
  gboolean D.18196;
  _Bool D.18197;
  _Bool D.18198;
  _Bool D.18199;
  int D.18202;
  struct MonoMethod * D.18207;
  struct MonoJitInfo * ji;

  D.18193 = mono_thread_internal_current ();
  if (D.18193 == 0B) goto <D.18194>; else goto <D.18195>;
  <D.18194>:
  D.18196 = 0;
  return D.18196;
  <D.18195>:
  D.18197 = ip == 0B;
  D.18198 = domain == 0B;
  D.18199 = D.18197 | D.18198;
  if (D.18199 != 0) goto <D.18200>; else goto <D.18201>;
  <D.18200>:
  D.18196 = 0;
  return D.18196;
  <D.18201>:
  D.18202 = sgen_has_critical_method ();
  if (D.18202 == 0) goto <D.18203>; else goto <D.18204>;
  <D.18203>:
  D.18196 = 0;
  return D.18196;
  <D.18204>:
  ji = mono_jit_info_table_find_internal (domain, ip, 0);
  if (ji == 0B) goto <D.18205>; else goto <D.18206>;
  <D.18205>:
  D.18196 = 0;
  return D.18196;
  <D.18206>:
  D.18207 = mono_jit_info_get_method (ji);
  D.18196 = sgen_is_critical_method (D.18207);
  return D.18196;
}


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

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


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_lls_pointer_get_mark (void * n)
{
  uintptr_t D.18213;
  long unsigned int n.9;

  n.9 = (long unsigned int) n;
  D.18213 = n.9 & 1;
  return D.18213;
}


mono_lls_pointer_unmask (void * p)
{
  void * D.18216;
  long unsigned int p.10;
  long unsigned int D.18218;

  p.10 = (long unsigned int) p;
  D.18218 = p.10 & 18446744073709551612;
  D.18216 = (void *) D.18218;
  return D.18216;
}


sgen_restart_world (int generation, struct GGTimingInfo * timing)
{
  <unnamed type> mono_profiler_events.11;
  unsigned int D.18221;
  _Bool D.18222;
  long int D.18223;
  long int D.18224;
  struct MonoLinkedListSet * D.18227;
  struct MonoLinkedListSetNode * D.18228;
  long unsigned int D.18229;
  struct MonoContext * D.18232;
  long int stop_world_time.12;
  long int D.18234;
  long int D.18235;
  int D.18236;
  long unsigned int max_pause_usec.13;
  long unsigned int max_pause_usec.14;
  int gc_debug_level.15;
  _Bool D.18240;
  long int D.18241;
  long int D.18242;
  int D.18245;
  int D.18246;
  struct FILE * gc_debug_file.16;
  long int D.18248;
  long int D.18249;
  int D.18250;
  long int usec.17;
  long int bridge_usec.18;
  int iftmp.19;
  int D.18259;
  int count;
  struct SgenThreadInfo * info;
  gint64 end_sw;
  gint64 end_bridge;
  long unsigned int usec;
  long unsigned int bridge_usec;

  mono_profiler_events.11 = mono_profiler_events;
  D.18221 = mono_profiler_events.11 & 524288;
  D.18222 = D.18221 != 0;
  D.18223 = (long int) D.18222;
  D.18224 = __builtin_expect (D.18223, 0);
  if (D.18224 != 0) goto <D.18225>; else goto <D.18226>;
  <D.18225>:
  sgen_gc_event_moves ();
  <D.18226>:
  mono_profiler_gc_event (8, generation);
  {
    struct MonoLinkedListSetNode * __cur;

    D.18227 = mono_thread_info_list_head ();
    __cur = D.18227->head;
    goto <D.18085>;
    <D.18084>:
    D.18228 = __cur->next;
    D.18229 = mono_lls_pointer_get_mark (D.18228);
    if (D.18229 == 0) goto <D.18230>; else goto <D.18231>;
    <D.18230>:
    info = __cur;
    info->stack_start = 0B;
    D.18232 = &info->ctx;
    memset (D.18232, 0, 136);
    <D.18231>:
    D.18228 = __cur->next;
    __cur = mono_lls_pointer_unmask (D.18228);
    <D.18085>:
    if (__cur != 0B) goto <D.18084>; else goto <D.18086>;
    <D.18086>:
  }
  count = sgen_thread_handshake (0);
  end_sw = mono_100ns_ticks ();
  stop_world_time.12 = stop_world_time;
  D.18234 = end_sw - stop_world_time.12;
  D.18235 = D.18234 / 10;
  D.18236 = (int) D.18235;
  usec = (long unsigned int) D.18236;
  max_pause_usec.13 = max_pause_usec;
  max_pause_usec.14 = MAX_EXPR <max_pause_usec.13, usec>;
  max_pause_usec = max_pause_usec.14;
  gc_debug_level.15 = gc_debug_level;
  D.18240 = gc_debug_level.15 > 1;
  D.18241 = (long int) D.18240;
  D.18242 = __builtin_expect (D.18241, 0);
  if (D.18242 != 0) goto <D.18243>; else goto <D.18244>;
  <D.18243>:
  max_pause_usec.13 = max_pause_usec;
  D.18245 = (int) max_pause_usec.13;
  D.18246 = (int) usec;
  gc_debug_file.16 = gc_debug_file;
  fprintf (gc_debug_file.16, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, D.18246, D.18245);
  gc_debug_file.16 = gc_debug_file;
  fflush (gc_debug_file.16);
  <D.18244>:
  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.18248 = end_bridge - end_sw;
  D.18249 = D.18248 / 10;
  D.18250 = (int) D.18249;
  bridge_usec = (long unsigned int) D.18250;
  if (timing != 0B) goto <D.18251>; else goto <D.18252>;
  <D.18251>:
  usec.17 = (long int) usec;
  timing->stw_time = usec.17;
  bridge_usec.18 = (long int) bridge_usec;
  timing->bridge_time = bridge_usec.18;
  <D.18252>:
  if (timing != 0B) goto <D.18256>; else goto <D.18257>;
  <D.18256>:
  iftmp.19 = 2;
  goto <D.18258>;
  <D.18257>:
  iftmp.19 = 0;
  <D.18258>:
  sgen_memgov_collection_end (generation, timing, iftmp.19);
  D.18259 = count;
  return D.18259;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.18263;
  int D.18268;
  void * D.18270;
  long unsigned int D.18271;

  D.18263 = __builtin_constant_p (__len);
  if (D.18263 != 0) goto <D.18264>; else goto <D.18265>;
  <D.18264>:
  if (__len == 0) goto <D.18266>; else goto <D.18267>;
  <D.18266>:
  D.18268 = __builtin_constant_p (__ch);
  if (D.18268 == 0) goto <D.18261>; else goto <D.18269>;
  <D.18269>:
  if (__ch != 0) goto <D.18261>; else goto <D.18262>;
  <D.18261>:
  __warn_memset_zero_len ();
  D.18270 = __dest;
  return D.18270;
  <D.18262>:
  <D.18267>:
  <D.18265>:
  D.18271 = __builtin_object_size (__dest, 0);
  D.18270 = __builtin___memset_chk (__dest, __ch, __len, D.18271);
  return D.18270;
}


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

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


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


