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.18624;
  long unsigned int D.18625;
  void * D.18626;
  long int stop_world_time.3;
  int count.4;
  int count.5;
  int count.6;
  int D.18635;
  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.18621>; else goto <D.18622>;
      <D.18621>:
      gc_debug_file.2 = gc_debug_file;
      sgen_global_stop_count.0 = sgen_global_stop_count;
      D.18624 = mono_thread_info_current ();
      D.18625 = mono_native_thread_id_get ();
      D.18626 = (void *) D.18625;
      fprintf (gc_debug_file.2, "stopping world n %d from %p %p\n", sgen_global_stop_count.0, D.18624, D.18626);
      gc_debug_file.2 = gc_debug_file;
      fflush (gc_debug_file.2);
      <D.18622>:
      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.18630>; else goto <D.18631>;
      <D.18630>:
      count.5 = count;
      monoeg_g_log (0B, 4, "More threads have died (%d) that been initialy suspended %d", dead, count.5);
      <D.18603>:
      goto <D.18603>;
      <D.18631>:
      count.5 = count;
      count.6 = count.5 - dead;
      count = count.6;
      if (0 != 0) goto <D.18633>; else goto <D.18634>;
      <D.18633>:
      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.18634>:
      mono_profiler_gc_event (7, generation);
      sgen_memgov_collection_start (generation);
      sgen_bridge_reset_data ();
      D.18635 = count;
      return D.18635;
    }
  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.18638;
  int iftmp.7;
  void * D.18643;
  void * D.18644;
  void * D.18646;
  _Bool D.18647;
  long int D.18648;
  long int D.18649;
  void *[32] * D.18652;
  struct MonoGCCallbacks * D.18653;
  void (*<T2b37>) (void *, void *, struct MonoContext *) D.18654;
  struct MonoGCCallbacks * D.18657;
  void (*<T2b37>) (void *, void *, struct MonoContext *) D.18658;
  void * D.18659;
  int stack_guard;
  void * reg_ptr;
  struct SgenThreadInfo * info;

  try
    {
      stack_guard = 0;
      reg_ptr = &cur_thread_regs;
      info = mono_thread_info_current ();
      D.18638 = align_pointer (&stack_guard);
      info->stack_start = D.18638;
      D.18643 = info->stack_start;
      D.18644 = info->stack_start_limit;
      if (D.18643 < D.18644) goto <D.18640>; else goto <D.18645>;
      <D.18645>:
      D.18643 = info->stack_start;
      D.18646 = info->stack_end;
      if (D.18643 >= D.18646) goto <D.18640>; else goto <D.18641>;
      <D.18640>:
      iftmp.7 = 1;
      goto <D.18642>;
      <D.18641>:
      iftmp.7 = 0;
      <D.18642>:
      D.18647 = iftmp.7 != 0;
      D.18648 = (long int) D.18647;
      D.18649 = __builtin_expect (D.18648, 0);
      if (D.18649 != 0) goto <D.18650>; else goto <D.18651>;
      <D.18650>:
      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.18651>:
      __asm__ __volatile__("stmw 0, 0(%0)
" :  : "b" reg_ptr);
      D.18652 = &info->regs;
      memcpy (D.18652, reg_ptr, 256);
      D.18653 = mono_gc_get_gc_callbacks ();
      D.18654 = D.18653->thread_suspend_func;
      if (D.18654 != 0B) goto <D.18655>; else goto <D.18656>;
      <D.18655>:
      D.18657 = mono_gc_get_gc_callbacks ();
      D.18658 = D.18657->thread_suspend_func;
      D.18659 = info->runtime_data;
      D.18658 (D.18659, 0B, 0B);
      <D.18656>:
    }
  finally
    {
      stack_guard = {CLOBBER};
    }
}


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

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


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

  D.18663 = __builtin_object_size (__dest, 0);
  D.18662 = __builtin___memcpy_chk (__dest, __src, __len, D.18663);
  return D.18662;
}


restart_threads_until_none_in_managed_allocator ()
{
  struct MonoLinkedListSet * D.18665;
  struct MonoLinkedListSetNode * * D.18666;
  void * D.18667;
  struct MonoLinkedListSetNode * * D.18668;
  long unsigned int D.18669;
  int D.18674;
  int D.18676;
  int D.18680;
  int D.18681;
  void * D.18683;
  int D.18685;
  int D.18687;
  struct MonoDomain * D.18689;
  void * D.18690;
  int D.18691;
  struct FILE * gc_debug_file.8;
  int D.18695;
  long unsigned int D.18696;
  void * D.18697;
  long unsigned int D.18709;
  struct MonoLinkedListSet * D.18710;
  struct MonoLinkedListSetNode * D.18711;
  long unsigned int D.18712;
  int D.18721;
  int D.18722;
  struct SgenThreadInfo * info;
  int num_threads_died;
  int sleep_duration;

  num_threads_died = 0;
  sleep_duration = -1;
  <D.18589>:
  {
    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.18665 = mono_thread_info_list_head ();
      D.18666 = &D.18665->head;
      D.18667 = get_hazardous_pointer (D.18666, __hp, 1);
      __cur = mono_lls_pointer_unmask (D.18667);
      goto <D.18580>;
      <D.18579>:
      D.18668 = &__cur->next;
      __next = get_hazardous_pointer_with_mask (D.18668, __hp, 0);
      D.18669 = mono_lls_pointer_get_mark (__next);
      if (D.18669 == 0) goto <D.18670>; else goto <D.18671>;
      <D.18670>:
      info = __cur;
      {
        gboolean result;

        D.18674 = info->skip;
        if (D.18674 != 0) goto <D.18672>; else goto <D.18675>;
        <D.18675>:
        D.18676 = info->gc_disabled;
        if (D.18676 != 0) goto <D.18672>; else goto <D.18673>;
        <D.18672>:
        // predicted unlikely by continue predictor.
        goto <D.18578>;
        <D.18673>:
        D.18680 = MEM[(struct MonoThreadInfo *)info].thread_state;
        D.18681 = D.18680 & 15;
        if (D.18681 == 1) goto <D.18682>; else goto <D.18677>;
        <D.18682>:
        D.18683 = info->stack_start;
        if (D.18683 == 0B) goto <D.18678>; else goto <D.18684>;
        <D.18684>:
        D.18685 = info->in_critical_region;
        if (D.18685 != 0) goto <D.18678>; else goto <D.18686>;
        <D.18686>:
        D.18687 = info->info.inside_critical_region;
        if (D.18687 != 0) goto <D.18678>; else goto <D.18688>;
        <D.18688>:
        D.18689 = info->stopped_domain;
        D.18690 = info->stopped_ip;
        D.18691 = is_ip_in_managed_allocator (D.18689, D.18690);
        if (D.18691 != 0) goto <D.18678>; else goto <D.18677>;
        <D.18678>:
        if (0 != 0) goto <D.18692>; else goto <D.18693>;
        <D.18692>:
        gc_debug_file.8 = gc_debug_file;
        D.18695 = info->info.native_handle;
        D.18696 = (long unsigned int) D.18695;
        D.18697 = (void *) D.18696;
        fprintf (gc_debug_file.8, "thread %p resumed.\n", D.18697);
        gc_debug_file.8 = gc_debug_file;
        fflush (gc_debug_file.8);
        <D.18693>:
        result = sgen_resume_thread (info);
        if (result != 0) goto <D.18698>; else goto <D.18699>;
        <D.18698>:
        restart_count = restart_count + 1;
        goto <D.18700>;
        <D.18699>:
        info->skip = 1;
        <D.18700>:
        goto <D.18679>;
        <D.18677>:
        info->stopped_ip = 0B;
        info->stopped_domain = 0B;
        <D.18679>:
      }
      <D.18671>:
      <D.18578>:
      __cur = mono_lls_info_step (__next, __hp);
      <D.18580>:
      if (__cur != 0B) goto <D.18579>; else goto <D.18581>;
      <D.18581>:
      if (0 != 0) goto <D.18701>; else goto <D.18702>;
      <D.18701>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
      <D.18702>:
      __hp->hazard_pointers[0] = 0B;
      if (0 != 0) goto <D.18703>; else goto <D.18704>;
      <D.18703>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
      <D.18704>:
      __hp->hazard_pointers[1] = 0B;
    }
    if (restart_count == 0) goto <D.18582>; else goto <D.18705>;
    <D.18705>:
    sgen_wait_for_suspend_ack (restart_count);
    if (sleep_duration < 0) goto <D.18706>; else goto <D.18707>;
    <D.18706>:
    sched_yield ();
    sleep_duration = 0;
    goto <D.18708>;
    <D.18707>:
    D.18709 = (long unsigned int) sleep_duration;
    monoeg_g_usleep (D.18709);
    sleep_duration = sleep_duration + 10;
    <D.18708>:
    {
      struct MonoLinkedListSetNode * __cur;

      D.18710 = mono_thread_info_list_head ();
      __cur = D.18710->head;
      goto <D.18587>;
      <D.18586>:
      D.18711 = __cur->next;
      D.18712 = mono_lls_pointer_get_mark (D.18711);
      if (D.18712 == 0) goto <D.18713>; else goto <D.18714>;
      <D.18713>:
      info = __cur;
      {
        gboolean result;

        D.18674 = info->skip;
        if (D.18674 != 0) goto <D.18715>; else goto <D.18717>;
        <D.18717>:
        D.18690 = info->stopped_ip;
        if (D.18690 == 0B) goto <D.18715>; else goto <D.18716>;
        <D.18715>:
        // predicted unlikely by continue predictor.
        goto <D.18585>;
        <D.18716>:
        result = sgen_suspend_thread (info);
        if (result != 0) goto <D.18718>; else goto <D.18719>;
        <D.18718>:
        restarted_count = restarted_count + 1;
        goto <D.18720>;
        <D.18719>:
        info->skip = 1;
        <D.18720>:
      }
      <D.18714>:
      <D.18585>:
      D.18711 = __cur->next;
      __cur = mono_lls_pointer_unmask (D.18711);
      <D.18587>:
      if (__cur != 0B) goto <D.18586>; else goto <D.18588>;
      <D.18588>:
    }
    D.18721 = restart_count - restarted_count;
    num_threads_died = D.18721 + num_threads_died;
    sgen_wait_for_suspend_ack (restarted_count);
  }
  goto <D.18589>;
  <D.18582>:
  D.18722 = num_threads_died;
  return D.18722;
}


is_ip_in_managed_allocator (struct MonoDomain * domain, void * ip)
{
  struct MonoInternalThread * D.18724;
  gboolean D.18727;
  int D.18731;
  struct MonoMethod * D.18736;
  struct MonoJitInfo * ji;

  D.18724 = mono_thread_internal_current ();
  if (D.18724 == 0B) goto <D.18725>; else goto <D.18726>;
  <D.18725>:
  D.18727 = 0;
  return D.18727;
  <D.18726>:
  if (ip == 0B) goto <D.18728>; else goto <D.18730>;
  <D.18730>:
  if (domain == 0B) goto <D.18728>; else goto <D.18729>;
  <D.18728>:
  D.18727 = 0;
  return D.18727;
  <D.18729>:
  D.18731 = sgen_has_critical_method ();
  if (D.18731 == 0) goto <D.18732>; else goto <D.18733>;
  <D.18732>:
  D.18727 = 0;
  return D.18727;
  <D.18733>:
  ji = mono_jit_info_table_find_internal (domain, ip, 0);
  if (ji == 0B) goto <D.18734>; else goto <D.18735>;
  <D.18734>:
  D.18727 = 0;
  return D.18727;
  <D.18735>:
  D.18736 = mono_jit_info_get_method (ji);
  D.18727 = sgen_is_critical_method (D.18736);
  return D.18727;
}


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

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


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


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

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


mono_lls_pointer_unmask (void * p)
{
  void * D.18745;
  long unsigned int p.10;
  long unsigned int D.18747;

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


sgen_restart_world (int generation, struct GGTimingInfo * timing)
{
  <unnamed type> mono_profiler_events.11;
  unsigned int D.18750;
  _Bool D.18751;
  long int D.18752;
  long int D.18753;
  struct MonoLinkedListSet * D.18756;
  struct MonoLinkedListSetNode * D.18757;
  long unsigned int D.18758;
  void *[32] * D.18761;
  long int stop_world_time.12;
  long int D.18763;
  long int D.18764;
  int D.18765;
  long unsigned int max_pause_usec.13;
  long unsigned int max_pause_usec.14;
  int gc_debug_level.15;
  _Bool D.18769;
  long int D.18770;
  long int D.18771;
  struct FILE * gc_debug_file.16;
  int D.18775;
  int D.18776;
  long int D.18777;
  long int D.18778;
  int D.18779;
  long int usec.17;
  long int bridge_usec.18;
  int iftmp.19;
  int D.18788;
  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.18750 = mono_profiler_events.11 & 524288;
  D.18751 = D.18750 != 0;
  D.18752 = (long int) D.18751;
  D.18753 = __builtin_expect (D.18752, 0);
  if (D.18753 != 0) goto <D.18754>; else goto <D.18755>;
  <D.18754>:
  sgen_gc_event_moves ();
  <D.18755>:
  mono_profiler_gc_event (8, generation);
  {
    struct MonoLinkedListSetNode * __cur;

    D.18756 = mono_thread_info_list_head ();
    __cur = D.18756->head;
    goto <D.18616>;
    <D.18615>:
    D.18757 = __cur->next;
    D.18758 = mono_lls_pointer_get_mark (D.18757);
    if (D.18758 == 0) goto <D.18759>; else goto <D.18760>;
    <D.18759>:
    info = __cur;
    info->stack_start = 0B;
    D.18761 = &info->regs;
    memset (D.18761, 0, 256);
    <D.18760>:
    D.18757 = __cur->next;
    __cur = mono_lls_pointer_unmask (D.18757);
    <D.18616>:
    if (__cur != 0B) goto <D.18615>; else goto <D.18617>;
    <D.18617>:
  }
  count = sgen_thread_handshake (0);
  end_sw = mono_100ns_ticks ();
  stop_world_time.12 = stop_world_time;
  D.18763 = end_sw - stop_world_time.12;
  D.18764 = D.18763 / 10;
  D.18765 = (int) D.18764;
  usec = (long unsigned int) D.18765;
  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.18769 = gc_debug_level.15 > 1;
  D.18770 = (long int) D.18769;
  D.18771 = __builtin_expect (D.18770, 0);
  if (D.18771 != 0) goto <D.18772>; else goto <D.18773>;
  <D.18772>:
  gc_debug_file.16 = gc_debug_file;
  D.18775 = (int) usec;
  max_pause_usec.13 = max_pause_usec;
  D.18776 = (int) max_pause_usec.13;
  fprintf (gc_debug_file.16, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, D.18775, D.18776);
  gc_debug_file.16 = gc_debug_file;
  fflush (gc_debug_file.16);
  <D.18773>:
  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.18777 = end_bridge - end_sw;
  D.18778 = D.18777 / 10;
  D.18779 = (int) D.18778;
  bridge_usec = (long unsigned int) D.18779;
  if (timing != 0B) goto <D.18780>; else goto <D.18781>;
  <D.18780>:
  usec.17 = (long int) usec;
  timing->stw_time = usec.17;
  bridge_usec.18 = (long int) bridge_usec;
  timing->bridge_time = bridge_usec.18;
  <D.18781>:
  if (timing != 0B) goto <D.18785>; else goto <D.18786>;
  <D.18785>:
  iftmp.19 = 2;
  goto <D.18787>;
  <D.18786>:
  iftmp.19 = 0;
  <D.18787>:
  sgen_memgov_collection_end (generation, timing, iftmp.19);
  D.18788 = count;
  return D.18788;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.18792;
  int D.18797;
  void * D.18799;
  long unsigned int D.18800;

  D.18792 = __builtin_constant_p (__len);
  if (D.18792 != 0) goto <D.18793>; else goto <D.18794>;
  <D.18793>:
  if (__len == 0) goto <D.18795>; else goto <D.18796>;
  <D.18795>:
  D.18797 = __builtin_constant_p (__ch);
  if (D.18797 == 0) goto <D.18790>; else goto <D.18798>;
  <D.18798>:
  if (__ch != 0) goto <D.18790>; else goto <D.18791>;
  <D.18790>:
  __warn_memset_zero_len ();
  D.18799 = __dest;
  return D.18799;
  <D.18791>:
  <D.18796>:
  <D.18794>:
  D.18800 = __builtin_object_size (__dest, 0);
  D.18799 = __builtin___memset_chk (__dest, __ch, __len, D.18800);
  return D.18799;
}


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

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


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


