__attribute__((visibility ("hidden")))
sgen_stop_world (int generation)
{
  unsigned int sgen_global_stop_count.0;
  unsigned int D.18233;
  struct FILE * gc_debug_file.1;
  struct SgenThreadInfo * D.18237;
  long unsigned int D.18238;
  void * D.18239;
  long int D.18240;
  int count.2;
  int count.3;
  int count.4;
  int D.18248;
  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;
      D.18233 = sgen_global_stop_count.0 + 1;
      sgen_global_stop_count = D.18233;
      if (0 != 0) goto <D.18234>; else goto <D.18235>;
      <D.18234>:
      gc_debug_file.1 = gc_debug_file;
      sgen_global_stop_count.0 = sgen_global_stop_count;
      D.18237 = mono_thread_info_current ();
      D.18238 = mono_native_thread_id_get ();
      D.18239 = (void *) D.18238;
      fprintf (gc_debug_file.1, "stopping world n %d from %p %p\n", sgen_global_stop_count.0, D.18237, D.18239);
      gc_debug_file.1 = gc_debug_file;
      fflush (gc_debug_file.1);
      <D.18235>:
      D.18240 = mono_100ns_ticks ();
      stop_world_time = D.18240;
      count.2 = sgen_thread_handshake (1);
      count = count.2;
      dead = restart_threads_until_none_in_managed_allocator ();
      count.3 = count;
      if (count.3 < dead) goto <D.18243>; else goto <D.18244>;
      <D.18243>:
      count.3 = count;
      monoeg_g_log (0B, 4, "More threads have died (%d) that been initialy suspended %d", dead, count.3);
      <D.18216>:
      goto <D.18216>;
      <D.18244>:
      count.3 = count;
      count.4 = count.3 - dead;
      count = count.4;
      if (0 != 0) goto <D.18246>; else goto <D.18247>;
      <D.18246>:
      gc_debug_file.1 = gc_debug_file;
      count.3 = count;
      fprintf (gc_debug_file.1, "world stopped %d thread(s)\n", count.3);
      gc_debug_file.1 = gc_debug_file;
      fflush (gc_debug_file.1);
      <D.18247>:
      mono_profiler_gc_event (7, generation);
      sgen_memgov_collection_start (generation);
      sgen_bridge_reset_data ();
      D.18248 = count;
      return D.18248;
    }
  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.18251;
  int iftmp.5;
  void * D.18256;
  void * D.18257;
  void * D.18259;
  _Bool D.18260;
  long int D.18261;
  long int D.18262;
  struct MonoContext * D.18265;
  struct MonoGCCallbacks * D.18266;
  void (*<T2bf3>) (void *, void *, struct MonoContext *) D.18267;
  struct MonoGCCallbacks * D.18270;
  void (*<T2bf3>) (void *, void *, struct MonoContext *) D.18271;
  void * D.18272;
  int stack_guard;
  struct SgenThreadInfo * info;

  try
    {
      stack_guard = 0;
      info = mono_thread_info_current ();
      D.18251 = align_pointer (&stack_guard);
      info->stack_start = D.18251;
      D.18256 = info->stack_start;
      D.18257 = info->stack_start_limit;
      if (D.18256 < D.18257) goto <D.18253>; else goto <D.18258>;
      <D.18258>:
      D.18256 = info->stack_start;
      D.18259 = info->stack_end;
      if (D.18256 >= D.18259) goto <D.18253>; else goto <D.18254>;
      <D.18253>:
      iftmp.5 = 1;
      goto <D.18255>;
      <D.18254>:
      iftmp.5 = 0;
      <D.18255>:
      D.18260 = iftmp.5 != 0;
      D.18261 = (long int) D.18260;
      D.18262 = __builtin_expect (D.18261, 0);
      if (D.18262 != 0) goto <D.18263>; else goto <D.18264>;
      <D.18263>:
      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.18264>:
      __asm__ __volatile__("stmg	%%r0,%%r15,0(%0)
" :  : "r" &cur_thread_ctx.uc_mcontext.gregs[0] : "memory");
      D.18265 = &info->ctx;
      memcpy (D.18265, &cur_thread_ctx, 512);
      D.18266 = mono_gc_get_gc_callbacks ();
      D.18267 = D.18266->thread_suspend_func;
      if (D.18267 != 0B) goto <D.18268>; else goto <D.18269>;
      <D.18268>:
      D.18270 = mono_gc_get_gc_callbacks ();
      D.18271 = D.18270->thread_suspend_func;
      D.18272 = info->runtime_data;
      D.18265 = &info->ctx;
      D.18271 (D.18272, 0B, D.18265);
      <D.18269>:
    }
  finally
    {
      stack_guard = {CLOBBER};
    }
}


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

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


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.18275;
  long unsigned int D.18276;

  D.18276 = __builtin_object_size (__dest, 0);
  D.18275 = __builtin___memcpy_chk (__dest, __src, __len, D.18276);
  return D.18275;
}


restart_threads_until_none_in_managed_allocator ()
{
  struct MonoLinkedListSet * D.18278;
  struct MonoLinkedListSetNode * * D.18279;
  void * D.18280;
  struct MonoLinkedListSetNode * * D.18281;
  long unsigned int D.18282;
  int D.18287;
  int D.18289;
  int D.18293;
  int D.18294;
  void * D.18296;
  int D.18298;
  int D.18300;
  struct MonoDomain * D.18302;
  void * D.18303;
  int D.18304;
  struct FILE * gc_debug_file.6;
  int D.18308;
  long unsigned int D.18309;
  void * D.18310;
  long unsigned int D.18322;
  struct MonoLinkedListSet * D.18323;
  struct MonoLinkedListSetNode * D.18324;
  long unsigned int D.18325;
  int D.18334;
  int D.18335;
  struct SgenThreadInfo * info;
  int num_threads_died;
  int sleep_duration;

  num_threads_died = 0;
  sleep_duration = -1;
  <D.18202>:
  {
    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.18278 = mono_thread_info_list_head ();
      D.18279 = &D.18278->head;
      D.18280 = get_hazardous_pointer (D.18279, __hp, 1);
      __cur = mono_lls_pointer_unmask (D.18280);
      goto <D.18193>;
      <D.18192>:
      D.18281 = &__cur->next;
      __next = get_hazardous_pointer_with_mask (D.18281, __hp, 0);
      D.18282 = mono_lls_pointer_get_mark (__next);
      if (D.18282 == 0) goto <D.18283>; else goto <D.18284>;
      <D.18283>:
      info = __cur;
      {
        gboolean result;

        D.18287 = info->skip;
        if (D.18287 != 0) goto <D.18285>; else goto <D.18288>;
        <D.18288>:
        D.18289 = info->gc_disabled;
        if (D.18289 != 0) goto <D.18285>; else goto <D.18286>;
        <D.18285>:
        // predicted unlikely by continue predictor.
        goto <D.18191>;
        <D.18286>:
        D.18293 = MEM[(struct MonoThreadInfo *)info].thread_state;
        D.18294 = D.18293 & 15;
        if (D.18294 == 1) goto <D.18295>; else goto <D.18290>;
        <D.18295>:
        D.18296 = info->stack_start;
        if (D.18296 == 0B) goto <D.18291>; else goto <D.18297>;
        <D.18297>:
        D.18298 = info->in_critical_region;
        if (D.18298 != 0) goto <D.18291>; else goto <D.18299>;
        <D.18299>:
        D.18300 = info->info.inside_critical_region;
        if (D.18300 != 0) goto <D.18291>; else goto <D.18301>;
        <D.18301>:
        D.18302 = info->stopped_domain;
        D.18303 = info->stopped_ip;
        D.18304 = is_ip_in_managed_allocator (D.18302, D.18303);
        if (D.18304 != 0) goto <D.18291>; else goto <D.18290>;
        <D.18291>:
        if (0 != 0) goto <D.18305>; else goto <D.18306>;
        <D.18305>:
        gc_debug_file.6 = gc_debug_file;
        D.18308 = info->info.native_handle;
        D.18309 = (long unsigned int) D.18308;
        D.18310 = (void *) D.18309;
        fprintf (gc_debug_file.6, "thread %p resumed.\n", D.18310);
        gc_debug_file.6 = gc_debug_file;
        fflush (gc_debug_file.6);
        <D.18306>:
        result = sgen_resume_thread (info);
        if (result != 0) goto <D.18311>; else goto <D.18312>;
        <D.18311>:
        restart_count = restart_count + 1;
        goto <D.18313>;
        <D.18312>:
        info->skip = 1;
        <D.18313>:
        goto <D.18292>;
        <D.18290>:
        info->stopped_ip = 0B;
        info->stopped_domain = 0B;
        <D.18292>:
      }
      <D.18284>:
      <D.18191>:
      __cur = mono_lls_info_step (__next, __hp);
      <D.18193>:
      if (__cur != 0B) goto <D.18192>; else goto <D.18194>;
      <D.18194>:
      if (0 != 0) goto <D.18314>; else goto <D.18315>;
      <D.18314>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
      <D.18315>:
      __hp->hazard_pointers[0] = 0B;
      if (0 != 0) goto <D.18316>; else goto <D.18317>;
      <D.18316>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-stw.c", 141, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
      <D.18317>:
      __hp->hazard_pointers[1] = 0B;
    }
    if (restart_count == 0) goto <D.18195>; else goto <D.18318>;
    <D.18318>:
    sgen_wait_for_suspend_ack (restart_count);
    if (sleep_duration < 0) goto <D.18319>; else goto <D.18320>;
    <D.18319>:
    sched_yield ();
    sleep_duration = 0;
    goto <D.18321>;
    <D.18320>:
    D.18322 = (long unsigned int) sleep_duration;
    monoeg_g_usleep (D.18322);
    sleep_duration = sleep_duration + 10;
    <D.18321>:
    {
      struct MonoLinkedListSetNode * __cur;

      D.18323 = mono_thread_info_list_head ();
      __cur = D.18323->head;
      goto <D.18200>;
      <D.18199>:
      D.18324 = __cur->next;
      D.18325 = mono_lls_pointer_get_mark (D.18324);
      if (D.18325 == 0) goto <D.18326>; else goto <D.18327>;
      <D.18326>:
      info = __cur;
      {
        gboolean result;

        D.18287 = info->skip;
        if (D.18287 != 0) goto <D.18328>; else goto <D.18330>;
        <D.18330>:
        D.18303 = info->stopped_ip;
        if (D.18303 == 0B) goto <D.18328>; else goto <D.18329>;
        <D.18328>:
        // predicted unlikely by continue predictor.
        goto <D.18198>;
        <D.18329>:
        result = sgen_suspend_thread (info);
        if (result != 0) goto <D.18331>; else goto <D.18332>;
        <D.18331>:
        restarted_count = restarted_count + 1;
        goto <D.18333>;
        <D.18332>:
        info->skip = 1;
        <D.18333>:
      }
      <D.18327>:
      <D.18198>:
      D.18324 = __cur->next;
      __cur = mono_lls_pointer_unmask (D.18324);
      <D.18200>:
      if (__cur != 0B) goto <D.18199>; else goto <D.18201>;
      <D.18201>:
    }
    D.18334 = restart_count - restarted_count;
    num_threads_died = D.18334 + num_threads_died;
    sgen_wait_for_suspend_ack (restarted_count);
  }
  goto <D.18202>;
  <D.18195>:
  D.18335 = num_threads_died;
  return D.18335;
}


is_ip_in_managed_allocator (struct MonoDomain * domain, void * ip)
{
  struct MonoInternalThread * D.18337;
  gboolean D.18340;
  int D.18344;
  struct MonoMethod * D.18349;
  struct MonoJitInfo * ji;

  D.18337 = mono_thread_internal_current ();
  if (D.18337 == 0B) goto <D.18338>; else goto <D.18339>;
  <D.18338>:
  D.18340 = 0;
  return D.18340;
  <D.18339>:
  if (ip == 0B) goto <D.18341>; else goto <D.18343>;
  <D.18343>:
  if (domain == 0B) goto <D.18341>; else goto <D.18342>;
  <D.18341>:
  D.18340 = 0;
  return D.18340;
  <D.18342>:
  D.18344 = sgen_has_critical_method ();
  if (D.18344 == 0) goto <D.18345>; else goto <D.18346>;
  <D.18345>:
  D.18340 = 0;
  return D.18340;
  <D.18346>:
  ji = mono_jit_info_table_find_internal (domain, ip, 0);
  if (ji == 0B) goto <D.18347>; else goto <D.18348>;
  <D.18347>:
  D.18340 = 0;
  return D.18340;
  <D.18348>:
  D.18349 = mono_jit_info_get_method (ji);
  D.18340 = sgen_is_critical_method (D.18349);
  return D.18340;
}


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

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


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_lls_pointer_get_mark (void * n)
{
  uintptr_t D.18355;
  long unsigned int n.7;

  n.7 = (long unsigned int) n;
  D.18355 = n.7 & 1;
  return D.18355;
}


mono_lls_pointer_unmask (void * p)
{
  void * D.18358;
  long unsigned int p.8;
  long unsigned int D.18360;

  p.8 = (long unsigned int) p;
  D.18360 = p.8 & 18446744073709551612;
  D.18358 = (void *) D.18360;
  return D.18358;
}


__attribute__((visibility ("hidden")))
sgen_restart_world (int generation, struct GGTimingInfo * timing)
{
  <unnamed type> mono_profiler_events.9;
  unsigned int D.18363;
  _Bool D.18364;
  long int D.18365;
  long int D.18366;
  struct MonoLinkedListSet * D.18369;
  struct MonoLinkedListSetNode * D.18370;
  long unsigned int D.18371;
  struct MonoContext * D.18374;
  long int stop_world_time.10;
  long int D.18376;
  long int D.18377;
  int D.18378;
  long unsigned int max_pause_usec.11;
  long unsigned int D.18380;
  int gc_debug_level.12;
  _Bool D.18382;
  long int D.18383;
  long int D.18384;
  struct FILE * gc_debug_file.13;
  int D.18388;
  int D.18389;
  long int D.18390;
  long int D.18391;
  int D.18392;
  long int usec.14;
  long int bridge_usec.15;
  int iftmp.16;
  int D.18401;
  int count;
  struct SgenThreadInfo * info;
  gint64 end_sw;
  gint64 end_bridge;
  long unsigned int usec;
  long unsigned int bridge_usec;

  mono_profiler_events.9 = mono_profiler_events;
  D.18363 = mono_profiler_events.9 & 524288;
  D.18364 = D.18363 != 0;
  D.18365 = (long int) D.18364;
  D.18366 = __builtin_expect (D.18365, 0);
  if (D.18366 != 0) goto <D.18367>; else goto <D.18368>;
  <D.18367>:
  sgen_gc_event_moves ();
  <D.18368>:
  mono_profiler_gc_event (8, generation);
  {
    struct MonoLinkedListSetNode * __cur;

    D.18369 = mono_thread_info_list_head ();
    __cur = D.18369->head;
    goto <D.18229>;
    <D.18228>:
    D.18370 = __cur->next;
    D.18371 = mono_lls_pointer_get_mark (D.18370);
    if (D.18371 == 0) goto <D.18372>; else goto <D.18373>;
    <D.18372>:
    info = __cur;
    info->stack_start = 0B;
    D.18374 = &info->ctx;
    memset (D.18374, 0, 512);
    <D.18373>:
    D.18370 = __cur->next;
    __cur = mono_lls_pointer_unmask (D.18370);
    <D.18229>:
    if (__cur != 0B) goto <D.18228>; else goto <D.18230>;
    <D.18230>:
  }
  count = sgen_thread_handshake (0);
  end_sw = mono_100ns_ticks ();
  stop_world_time.10 = stop_world_time;
  D.18376 = end_sw - stop_world_time.10;
  D.18377 = D.18376 / 10;
  D.18378 = (int) D.18377;
  usec = (long unsigned int) D.18378;
  max_pause_usec.11 = max_pause_usec;
  D.18380 = MAX_EXPR <max_pause_usec.11, usec>;
  max_pause_usec = D.18380;
  gc_debug_level.12 = gc_debug_level;
  D.18382 = gc_debug_level.12 > 1;
  D.18383 = (long int) D.18382;
  D.18384 = __builtin_expect (D.18383, 0);
  if (D.18384 != 0) goto <D.18385>; else goto <D.18386>;
  <D.18385>:
  gc_debug_file.13 = gc_debug_file;
  D.18388 = (int) usec;
  max_pause_usec.11 = max_pause_usec;
  D.18389 = (int) max_pause_usec.11;
  fprintf (gc_debug_file.13, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, D.18388, D.18389);
  gc_debug_file.13 = gc_debug_file;
  fflush (gc_debug_file.13);
  <D.18386>:
  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.18390 = end_bridge - end_sw;
  D.18391 = D.18390 / 10;
  D.18392 = (int) D.18391;
  bridge_usec = (long unsigned int) D.18392;
  if (timing != 0B) goto <D.18393>; else goto <D.18394>;
  <D.18393>:
  usec.14 = (long int) usec;
  timing->stw_time = usec.14;
  bridge_usec.15 = (long int) bridge_usec;
  timing->bridge_time = bridge_usec.15;
  <D.18394>:
  if (timing != 0B) goto <D.18398>; else goto <D.18399>;
  <D.18398>:
  iftmp.16 = 2;
  goto <D.18400>;
  <D.18399>:
  iftmp.16 = 0;
  <D.18400>:
  sgen_memgov_collection_end (generation, timing, iftmp.16);
  D.18401 = count;
  return D.18401;
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memset (void * __dest, int __ch, size_t __len)
{
  void * D.18403;
  long unsigned int D.18404;

  D.18404 = __builtin_object_size (__dest, 0);
  D.18403 = __builtin___memset_chk (__dest, __ch, __len, D.18404);
  return D.18403;
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__))
fprintf (struct FILE * restrict __stream, const char * restrict __fmt)
{
  int D.18406;

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


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


