mono_gc_run_finalize (void * obj, void * data)
{
  sizetype data.0;
  int suspend_finalizers.1;
  struct MonoVTable * D.18657;
  struct MonoClass * D.18658;
  struct MonoClass * D.18659;
  int D.18662;
  unsigned char D.18665;
  int finalizing_root_domain.2;
  struct MonoImage * D.18671;
  struct MonoImage * D.18672;
  int D.18305;
  int iftmp.3;
  int D.18304;
  const char[14] * D.18678;
  unsigned char D.18679;
  int D.18680;
  unsigned char D.18681;
  int D.18682;
  _Bool D.18683;
  _Bool D.18684;
  _Bool D.18685;
  const unsigned char * D.18688;
  unsigned char D.18689;
  int D.18690;
  const unsigned char * D.18691;
  unsigned char D.18692;
  int D.18693;
  _Bool D.18694;
  _Bool D.18695;
  const unsigned char * D.18698;
  unsigned char D.18699;
  int D.18700;
  const unsigned char * D.18701;
  unsigned char D.18702;
  int D.18703;
  _Bool D.18704;
  _Bool D.18705;
  const unsigned char * D.18708;
  unsigned char D.18709;
  int D.18710;
  const unsigned char * D.18711;
  unsigned char D.18712;
  int D.18713;
  const char * D.18715;
  int D.18720;
  struct MonoDomain * D.18723;
  unsigned char D.18724;
  unsigned char D.18725;
  void * D.18728;
  int D.18731;
  void * D.18736;
  struct MonoClass * D.18739;
  struct MonoMethod * D.18740;
  void * D.18741;
  struct MonoObject * exc.4;
  struct MonoObject * exc;
  struct MonoObject * o;
  struct MonoMethod * finalizer;
  struct MonoDomain * caller_domain;
  struct MonoDomain * domain;
  struct MonoObject * (*RuntimeInvokeFunction) (struct MonoObject *, void * *, struct MonoObject * *, void *) runtime_invoke;

  try
    {
      exc = 0B;
      finalizer = 0B;
      caller_domain = mono_domain_get ();
      data.0 = (sizetype) data;
      o = obj + data.0;
      suspend_finalizers.1 = suspend_finalizers;
      if (suspend_finalizers.1 != 0) goto <D.18655>; else goto <D.18656>;
      <D.18655>:
      return;
      <D.18656>:
      D.18657 = o->vtable;
      domain = D.18657->domain;
      object_register_finalizer (obj, 0B);
      D.18657 = o->vtable;
      D.18658 = D.18657->klass;
      D.18659 = mono_defaults.internal_thread_class;
      if (D.18658 == D.18659) goto <D.18660>; else goto <D.18661>;
      <D.18660>:
      {
        struct MonoInternalThread * t;

        t = o;
        D.18662 = mono_gc_is_finalizer_internal_thread (t);
        if (D.18662 != 0) goto <D.18663>; else goto <D.18664>;
        <D.18663>:
        return;
        <D.18664>:
        D.18665 = t->threadpool_thread;
        if (D.18665 != 0) goto <D.18666>; else goto <D.18667>;
        <D.18666>:
        finalizing_root_domain.2 = finalizing_root_domain;
        if (finalizing_root_domain.2 != 0) goto <D.18669>; else goto <D.18670>;
        <D.18669>:
        add_thread_to_finalize (t);
        return;
        <D.18670>:
        <D.18667>:
      }
      <D.18661>:
      D.18657 = o->vtable;
      D.18658 = D.18657->klass;
      D.18671 = D.18658->image;
      D.18672 = mono_defaults.corlib;
      if (D.18671 == D.18672) goto <D.18673>; else goto <D.18674>;
      <D.18673>:
      {
        size_t __s1_len;
        size_t __s2_len;

        __s2_len = 13;
        if (__s2_len <= 3) goto <D.18676>; else goto <D.18677>;
        <D.18676>:
        {
          const unsigned char * __s2;
          int __result;

          D.18657 = o->vtable;
          D.18658 = D.18657->klass;
          __s2 = D.18658->name;
          D.18678 = "DynamicMethod";
          D.18679 = MEM[(const unsigned char *)D.18678];
          D.18680 = (int) D.18679;
          D.18681 = *__s2;
          D.18682 = (int) D.18681;
          __result = D.18680 - D.18682;
          {
            D.18683 = __s2_len != 0;
            D.18684 = __result == 0;
            D.18685 = D.18683 & D.18684;
            if (D.18685 != 0) goto <D.18686>; else goto <D.18687>;
            <D.18686>:
            D.18688 = &MEM[(void *)"DynamicMethod" + 1B];
            D.18689 = *D.18688;
            D.18690 = (int) D.18689;
            D.18691 = __s2 + 1;
            D.18692 = *D.18691;
            D.18693 = (int) D.18692;
            __result = D.18690 - D.18693;
            D.18694 = __s2_len > 1;
            D.18684 = __result == 0;
            D.18695 = D.18694 & D.18684;
            if (D.18695 != 0) goto <D.18696>; else goto <D.18697>;
            <D.18696>:
            D.18698 = &MEM[(void *)"DynamicMethod" + 2B];
            D.18699 = *D.18698;
            D.18700 = (int) D.18699;
            D.18701 = __s2 + 2;
            D.18702 = *D.18701;
            D.18703 = (int) D.18702;
            __result = D.18700 - D.18703;
            D.18704 = __s2_len > 2;
            D.18684 = __result == 0;
            D.18705 = D.18704 & D.18684;
            if (D.18705 != 0) goto <D.18706>; else goto <D.18707>;
            <D.18706>:
            D.18708 = &MEM[(void *)"DynamicMethod" + 3B];
            D.18709 = *D.18708;
            D.18710 = (int) D.18709;
            D.18711 = __s2 + 3;
            D.18712 = *D.18711;
            D.18713 = (int) D.18712;
            __result = D.18710 - D.18713;
            <D.18707>:
            <D.18697>:
            <D.18687>:
          }
          D.18304 = __result;
        }
        iftmp.3 = -D.18304;
        goto <D.18714>;
        <D.18677>:
        D.18657 = o->vtable;
        D.18658 = D.18657->klass;
        D.18715 = D.18658->name;
        iftmp.3 = __builtin_strcmp (D.18715, "DynamicMethod");
        <D.18714>:
        D.18305 = iftmp.3;
      }
      if (D.18305 == 0) goto <D.18716>; else goto <D.18717>;
      <D.18716>:
      finalizing_root_domain.2 = finalizing_root_domain;
      if (finalizing_root_domain.2 != 0) goto <D.18718>; else goto <D.18719>;
      <D.18718>:
      return;
      <D.18719>:
      <D.18717>:
      <D.18674>:
      D.18720 = mono_runtime_get_no_exec ();
      if (D.18720 != 0) goto <D.18721>; else goto <D.18722>;
      <D.18721>:
      return;
      <D.18722>:
      D.18657 = o->vtable;
      D.18723 = D.18657->domain;
      mono_domain_set_internal (D.18723);
      D.18657 = o->vtable;
      D.18658 = D.18657->klass;
      D.18724 = BIT_FIELD_REF <*D.18658, 8, 184>;
      D.18725 = D.18724 & 1;
      if (D.18725 != 0) goto <D.18726>; else goto <D.18727>;
      <D.18726>:
      {
        struct MonoDelegate * del;

        del = o;
        D.18728 = del->delegate_trampoline;
        if (D.18728 != 0B) goto <D.18729>; else goto <D.18730>;
        <D.18729>:
        mono_delegate_free_ftnptr (o);
        <D.18730>:
        mono_domain_set_internal (caller_domain);
        return;
      }
      <D.18727>:
      D.18657 = o->vtable;
      D.18658 = D.18657->klass;
      finalizer = mono_class_get_finalizer (D.18658);
      D.18731 = mono_marshal_free_ccw (o);
      if (D.18731 != 0) goto <D.18732>; else goto <D.18733>;
      <D.18732>:
      if (finalizer == 0B) goto <D.18734>; else goto <D.18735>;
      <D.18734>:
      mono_domain_set_internal (caller_domain);
      return;
      <D.18735>:
      <D.18733>:
      D.18736 = domain->finalize_runtime_invoke;
      if (D.18736 == 0B) goto <D.18737>; else goto <D.18738>;
      <D.18737>:
      {
        struct MonoMethod * invoke;

        D.18739 = mono_defaults.object_class;
        D.18740 = mono_class_get_method_from_name_flags (D.18739, "Finalize", 0, 0);
        invoke = mono_marshal_get_runtime_invoke (D.18740, 1);
        D.18741 = mono_compile_method (invoke);
        domain->finalize_runtime_invoke = D.18741;
      }
      <D.18738>:
      D.18736 = domain->finalize_runtime_invoke;
      runtime_invoke = (struct MonoObject * (*RuntimeInvokeFunction) (struct MonoObject *, void * *, struct MonoObject * *, void *)) D.18736;
      D.18657 = o->vtable;
      mono_runtime_class_init (D.18657);
      if (0 != 0) goto <D.18742>; else goto <D.18743>;
      <D.18742>:
      <D.18743>:
      runtime_invoke (o, 0B, &exc, 0B);
      exc.4 = exc;
      if (exc.4 != 0B) goto <D.18745>; else goto <D.18746>;
      <D.18745>:
      exc.4 = exc;
      mono_internal_thread_unhandled_exception (exc.4);
      <D.18746>:
      mono_domain_set_internal (caller_domain);
    }
  finally
    {
      exc = {CLOBBER};
    }
}


object_register_finalizer (struct MonoObject * obj, void (*<Tff>) (void *, void *) callback)
{
  struct MonoException * D.18752;
  struct MonoVTable * D.18753;
  int D.18754;
  struct MonoDomain * domain;

  if (obj == 0B) goto <D.18750>; else goto <D.18751>;
  <D.18750>:
  D.18752 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18752);
  <D.18751>:
  D.18753 = obj->vtable;
  domain = D.18753->domain;
  D.18754 = mono_domain_is_unloading (domain);
  if (D.18754 == 0) goto <D.18755>; else goto <D.18756>;
  <D.18755>:
  mono_gc_register_for_finalization (obj, callback);
  <D.18756>:
}


add_thread_to_finalize (struct MonoInternalThread * thread)
{
  _Bool D.18759;
  long int D.18760;
  long int D.18761;
  struct MonoMList * threads_to_finalize.5;
  void * D.18769;
  struct MonoMList * threads_to_finalize.6;
  _Bool D.18773;
  long int D.18774;
  long int D.18775;

  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18757>; else goto <D.18758>;
    <D.18757>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18758>:
    D.18759 = ret != 0;
    D.18760 = (long int) D.18759;
    D.18761 = __builtin_expect (D.18760, 0);
    if (D.18761 != 0) goto <D.18762>; else goto <D.18763>;
    <D.18762>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 88, "ret == 0");
    <D.18763>:
  }
  threads_to_finalize.5 = threads_to_finalize;
  if (threads_to_finalize.5 == 0B) goto <D.18765>; else goto <D.18766>;
  <D.18765>:
  if (0 != 0) goto <D.18767>; else goto <D.18768>;
  <D.18767>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 90, "sizeof (threads_to_finalize) == sizeof (MonoObject*)");
  <D.18768>:
  D.18769 = mono_gc_make_root_descr_all_refs (1);
  mono_gc_register_root (&threads_to_finalize, 4, D.18769);
  <D.18766>:
  threads_to_finalize.5 = threads_to_finalize;
  threads_to_finalize.6 = mono_mlist_append (threads_to_finalize.5, thread);
  threads_to_finalize = threads_to_finalize.6;
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18771>; else goto <D.18772>;
    <D.18771>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18772>:
    D.18773 = ret != 0;
    D.18774 = (long int) D.18773;
    D.18775 = __builtin_expect (D.18774, 0);
    if (D.18775 != 0) goto <D.18776>; else goto <D.18777>;
    <D.18776>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 92, "ret == 0");
    <D.18777>:
  }
}


mono_gc_finalize_threadpool_threads ()
{
  struct MonoMList * threads_to_finalize.7;
  struct MonoMList * threads_to_finalize.8;

  goto <D.18313>;
  <D.18312>:
  {
    struct MonoInternalThread * thread;

    threads_to_finalize.7 = threads_to_finalize;
    thread = mono_mlist_get_data (threads_to_finalize.7);
    thread->threadpool_thread = 0;
    mono_object_register_finalizer (thread);
    mono_gc_run_finalize (thread, 0B);
    threads_to_finalize.7 = threads_to_finalize;
    threads_to_finalize.8 = mono_mlist_next (threads_to_finalize.7);
    threads_to_finalize = threads_to_finalize.8;
  }
  <D.18313>:
  threads_to_finalize.7 = threads_to_finalize;
  if (threads_to_finalize.7 != 0B) goto <D.18312>; else goto <D.18314>;
  <D.18314>:
}


mono_gc_out_of_memory (size_t size)
{
  struct MonoDomain * D.18780;
  struct MonoException * D.18781;
  void * D.18782;

  D.18780 = mono_domain_get ();
  D.18781 = D.18780->out_of_memory_ex;
  mono_raise_exception (D.18781);
  D.18782 = 0B;
  return D.18782;
}


mono_object_register_finalizer (struct MonoObject * obj)
{
  object_register_finalizer (obj, mono_gc_run_finalize);
}


mono_domain_finalize (struct MonoDomain * domain, guint32 timeout)
{
  struct MonoInternalThread * D.18784;
  struct MonoInternalThread * gc_thread.9;
  mono_bool D.18788;
  int gc_disabled.10;
  int D.18792;
  struct MonoDomain * D.18795;
  _Bool D.18800;
  long int D.18801;
  long int D.18802;
  struct GSList * domains_to_finalize.11;
  struct GSList * domains_to_finalize.12;
  _Bool D.18809;
  long int D.18810;
  long int D.18811;
  unsigned int D.18818;
  unsigned int D.18819;
  struct MonoDomain * D.18824;
  struct DomainFinalizationReq * req;
  guint32 res;
  void * done_event;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.18784 = mono_thread_internal_current ();
  gc_thread.9 = gc_thread;
  if (D.18784 == gc_thread.9) goto <D.18786>; else goto <D.18787>;
  <D.18786>:
  D.18788 = 0;
  return D.18788;
  <D.18787>:
  gc_disabled.10 = gc_disabled;
  if (gc_disabled.10 != 0) goto <D.18790>; else goto <D.18791>;
  <D.18790>:
  D.18788 = 1;
  return D.18788;
  <D.18791>:
  D.18792 = mono_gc_max_generation ();
  mono_gc_collect (D.18792);
  done_event = CreateEvent (0B, 1, 0, 0B);
  if (done_event == 0B) goto <D.18793>; else goto <D.18794>;
  <D.18793>:
  D.18788 = 0;
  return D.18788;
  <D.18794>:
  req = monoeg_malloc0 (8);
  req->domain = domain;
  req->done_event = done_event;
  D.18795 = mono_get_root_domain ();
  if (D.18795 == domain) goto <D.18796>; else goto <D.18797>;
  <D.18796>:
  finalizing_root_domain = 1;
  <D.18797>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18798>; else goto <D.18799>;
    <D.18798>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18799>:
    D.18800 = ret != 0;
    D.18801 = (long int) D.18800;
    D.18802 = __builtin_expect (D.18801, 0);
    if (D.18802 != 0) goto <D.18803>; else goto <D.18804>;
    <D.18803>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 367, "ret == 0");
    <D.18804>:
  }
  domains_to_finalize.11 = domains_to_finalize;
  domains_to_finalize.12 = monoeg_g_slist_append (domains_to_finalize.11, req);
  domains_to_finalize = domains_to_finalize.12;
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18807>; else goto <D.18808>;
    <D.18807>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18808>:
    D.18809 = ret != 0;
    D.18810 = (long int) D.18809;
    D.18811 = __builtin_expect (D.18810, 0);
    if (D.18811 != 0) goto <D.18812>; else goto <D.18813>;
    <D.18812>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 371, "ret == 0");
    <D.18813>:
  }
  mono_gc_finalize_notify ();
  if (timeout == 4294967295) goto <D.18814>; else goto <D.18815>;
  <D.18814>:
  timeout = 4294967295;
  <D.18815>:
  <D.18339>:
  res = WaitForSingleObjectEx (done_event, timeout, 1);
  if (res == 192) goto <D.18816>; else goto <D.18817>;
  <D.18816>:
  D.18818 = thread->state;
  D.18819 = D.18818 & 3;
  if (D.18819 != 0) goto <D.18820>; else goto <D.18821>;
  <D.18820>:
  D.18788 = 0;
  return D.18788;
  <D.18821>:
  goto <D.18822>;
  <D.18817>:
  if (res == 258) goto <D.18823>; else goto <D.18338>;
  <D.18823>:
  D.18788 = 0;
  return D.18788;
  <D.18822>:
  goto <D.18339>;
  <D.18338>:
  CloseHandle (done_event);
  D.18824 = mono_get_root_domain ();
  if (D.18824 == domain) goto <D.18825>; else goto <D.18826>;
  <D.18825>:
  mono_thread_pool_cleanup ();
  mono_gc_finalize_threadpool_threads ();
  <D.18826>:
  D.18788 = 1;
  return D.18788;
}


ves_icall_System_GC_InternalCollect (int generation)
{
  mono_gc_collect (generation);
}


ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
{
  int D.18830;
  gint64 D.18831;

  if (forceCollection != 0) goto <D.18828>; else goto <D.18829>;
  <D.18828>:
  D.18830 = mono_gc_max_generation ();
  mono_gc_collect (D.18830);
  <D.18829>:
  D.18831 = mono_gc_get_used_size ();
  return D.18831;
}


ves_icall_System_GC_KeepAlive (struct MonoObject * obj)
{

}


ves_icall_System_GC_ReRegisterForFinalize (struct MonoObject * obj)
{
  struct MonoException * D.18835;

  if (obj == 0B) goto <D.18833>; else goto <D.18834>;
  <D.18833>:
  D.18835 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18835);
  <D.18834>:
  object_register_finalizer (obj, mono_gc_run_finalize);
}


ves_icall_System_GC_SuppressFinalize (struct MonoObject * obj)
{
  struct MonoException * D.18838;
  struct MonoVTable * D.18839;
  struct MonoClass * D.18840;
  unsigned char D.18841;
  unsigned char D.18842;

  if (obj == 0B) goto <D.18836>; else goto <D.18837>;
  <D.18836>:
  D.18838 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18838);
  <D.18837>:
  D.18839 = obj->vtable;
  D.18840 = D.18839->klass;
  D.18841 = BIT_FIELD_REF <*D.18840, 8, 184>;
  D.18842 = D.18841 & 1;
  if (D.18842 != 0) goto <D.18843>; else goto <D.18844>;
  <D.18843>:
  return;
  <D.18844>:
  object_register_finalizer (obj, 0B);
}


ves_icall_System_GC_WaitForPendingFinalizers ()
{
  int D.18846;
  struct MonoInternalThread * D.18849;
  struct MonoInternalThread * gc_thread.13;
  void * pending_done_event.14;

  D.18846 = mono_gc_pending_finalizers ();
  if (D.18846 == 0) goto <D.18847>; else goto <D.18848>;
  <D.18847>:
  return;
  <D.18848>:
  D.18849 = mono_thread_internal_current ();
  gc_thread.13 = gc_thread;
  if (D.18849 == gc_thread.13) goto <D.18851>; else goto <D.18852>;
  <D.18851>:
  return;
  <D.18852>:
  gc_thread.13 = gc_thread;
  if (gc_thread.13 == 0B) goto <D.18853>; else goto <D.18854>;
  <D.18853>:
  return;
  <D.18854>:
  pending_done_event.14 = pending_done_event;
  ResetEvent (pending_done_event.14);
  mono_gc_finalize_notify ();
  pending_done_event.14 = pending_done_event;
  WaitForSingleObjectEx (pending_done_event.14, 4294967295, 1);
}


ves_icall_System_GC_register_ephemeron_array (struct MonoObject * array)
{
  int D.18857;
  struct MonoVTable * D.18860;
  struct MonoDomain * D.18861;
  struct MonoException * D.18862;

  D.18857 = mono_gc_ephemeron_array_add (array);
  if (D.18857 == 0) goto <D.18858>; else goto <D.18859>;
  <D.18858>:
  D.18860 = array->vtable;
  D.18861 = D.18860->domain;
  D.18862 = D.18861->out_of_memory_ex;
  mono_raise_exception (D.18862);
  <D.18859>:
}


ves_icall_System_GC_get_ephemeron_tombstone ()
{
  struct MonoObject * D.18863;
  struct MonoDomain * D.18864;

  D.18864 = mono_domain_get ();
  D.18863 = D.18864->ephemeron_tombstone;
  return D.18863;
}


ves_icall_System_GCHandle_GetTarget (guint32 handle)
{
  struct MonoObject * D.18866;

  D.18866 = mono_gchandle_get_target (handle);
  return D.18866;
}


ves_icall_System_GCHandle_GetTargetHandle (struct MonoObject * obj, guint32 handle, gint32 type)
{
  guint32 D.18870;

  if (type == -1) goto <D.18868>; else goto <D.18869>;
  <D.18868>:
  mono_gchandle_set_target (handle, obj);
  D.18870 = handle;
  return D.18870;
  <D.18869>:
  switch (type) <default: <D.18386>, case 0: <D.18382>, case 1: <D.18383>, case 2: <D.18384>, case 3: <D.18385>>
  <D.18382>:
  D.18870 = mono_gchandle_new_weakref (obj, 0);
  return D.18870;
  <D.18383>:
  D.18870 = mono_gchandle_new_weakref (obj, 1);
  return D.18870;
  <D.18384>:
  D.18870 = mono_gchandle_new (obj, 0);
  return D.18870;
  <D.18385>:
  D.18870 = mono_gchandle_new (obj, 1);
  return D.18870;
  <D.18386>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 545);
  D.18870 = 0;
  return D.18870;
}


mono_gchandle_set_target (guint32 gchandle, struct MonoObject * obj)
{
  unsigned int D.18872;
  _Bool D.18877;
  long int D.18878;
  long int D.18879;
  unsigned int D.18882;
  guint32 * D.18885;
  unsigned int D.18886;
  unsigned int D.18887;
  guint32 * D.18888;
  unsigned int D.18889;
  int slot.15;
  int D.18891;
  int D.18892;
  unsigned int D.18893;
  unsigned int D.18894;
  unsigned char D.18897;
  void * * D.18900;
  unsigned int D.18901;
  void * * D.18902;
  void * D.18903;
  _Bool D.18906;
  int D.18907;
  void * * D.18908;
  guint16 * D.18911;
  unsigned int D.18912;
  guint16 * D.18913;
  struct MonoDomain * iftmp.16;
  int D.18918;
  short unsigned int D.18919;
  _Bool D.18924;
  long int D.18925;
  long int D.18926;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * old_obj;

  slot = gchandle >> 3;
  D.18872 = gchandle & 7;
  type = D.18872 + 4294967295;
  handles = &gc_handles[type];
  old_obj = 0B;
  if (type > 3) goto <D.18873>; else goto <D.18874>;
  <D.18873>:
  return;
  <D.18874>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.18875>; else goto <D.18876>;
    <D.18875>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18876>:
    D.18877 = ret != 0;
    D.18878 = (long int) D.18877;
    D.18879 = __builtin_expect (D.18878, 0);
    if (D.18879 != 0) goto <D.18880>; else goto <D.18881>;
    <D.18880>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 834, "ret == 0");
    <D.18881>:
  }
  D.18882 = handles->size;
  if (D.18882 > slot) goto <D.18883>; else goto <D.18884>;
  <D.18883>:
  D.18885 = handles->bitmap;
  D.18886 = slot / 32;
  D.18887 = D.18886 * 4;
  D.18888 = D.18885 + D.18887;
  D.18889 = *D.18888;
  slot.15 = (int) slot;
  D.18891 = slot.15 & 31;
  D.18892 = 1 << D.18891;
  D.18893 = (unsigned int) D.18892;
  D.18894 = D.18889 & D.18893;
  if (D.18894 != 0) goto <D.18895>; else goto <D.18896>;
  <D.18895>:
  D.18897 = handles->type;
  if (D.18897 <= 1) goto <D.18898>; else goto <D.18899>;
  <D.18898>:
  D.18900 = handles->entries;
  D.18901 = slot * 4;
  D.18902 = D.18900 + D.18901;
  old_obj = *D.18902;
  D.18900 = handles->entries;
  D.18901 = slot * 4;
  D.18902 = D.18900 + D.18901;
  D.18903 = *D.18902;
  if (D.18903 != 0B) goto <D.18904>; else goto <D.18905>;
  <D.18904>:
  D.18897 = handles->type;
  D.18906 = D.18897 == 1;
  D.18907 = (int) D.18906;
  D.18900 = handles->entries;
  D.18901 = slot * 4;
  D.18908 = D.18900 + D.18901;
  mono_gc_weak_link_remove (D.18908, D.18907);
  <D.18905>:
  if (obj != 0B) goto <D.18909>; else goto <D.18910>;
  <D.18909>:
  D.18897 = handles->type;
  D.18906 = D.18897 == 1;
  D.18907 = (int) D.18906;
  D.18900 = handles->entries;
  D.18901 = slot * 4;
  D.18908 = D.18900 + D.18901;
  mono_gc_weak_link_add (D.18908, obj, D.18907);
  <D.18910>:
  D.18911 = handles->domain_ids;
  D.18912 = slot * 2;
  D.18913 = D.18911 + D.18912;
  if (obj != 0B) goto <D.18915>; else goto <D.18916>;
  <D.18915>:
  iftmp.16 = mono_object_get_domain (obj);
  goto <D.18917>;
  <D.18916>:
  iftmp.16 = mono_domain_get ();
  <D.18917>:
  D.18918 = iftmp.16->domain_id;
  D.18919 = (short unsigned int) D.18918;
  *D.18913 = D.18919;
  goto <D.18920>;
  <D.18899>:
  D.18900 = handles->entries;
  D.18901 = slot * 4;
  D.18902 = D.18900 + D.18901;
  *D.18902 = obj;
  <D.18920>:
  goto <D.18921>;
  <D.18896>:
  <D.18921>:
  <D.18884>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.18922>; else goto <D.18923>;
    <D.18922>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18923>:
    D.18924 = ret != 0;
    D.18925 = (long int) D.18924;
    D.18926 = __builtin_expect (D.18925, 0);
    if (D.18926 != 0) goto <D.18927>; else goto <D.18928>;
    <D.18927>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 851, "ret == 0");
    <D.18928>:
  }
}


ves_icall_System_GCHandle_FreeHandle (guint32 handle)
{
  mono_gchandle_free (handle);
}


ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
{
  <unnamed type> D.18930;
  void * D.18933;
  struct MonoVTable * D.18936;
  struct MonoClass * D.18937;
  unsigned char D.18940;
  unsigned int D.18943;
  unsigned int D.18944;
  struct MonoObject * obj;

  D.18930 = mono_gchandle_get_type (handle);
  if (D.18930 != 3) goto <D.18931>; else goto <D.18932>;
  <D.18931>:
  D.18933 = 4294967294B;
  return D.18933;
  <D.18932>:
  obj = mono_gchandle_get_target (handle);
  if (obj != 0B) goto <D.18934>; else goto <D.18935>;
  <D.18934>:
  {
    struct MonoClass * klass;

    D.18936 = obj->vtable;
    klass = D.18936->klass;
    D.18937 = mono_defaults.string_class;
    if (D.18937 == klass) goto <D.18938>; else goto <D.18939>;
    <D.18938>:
    D.18933 = mono_string_chars (obj);
    return D.18933;
    <D.18939>:
    D.18940 = klass->rank;
    if (D.18940 != 0) goto <D.18941>; else goto <D.18942>;
    <D.18941>:
    D.18933 = mono_array_addr_with_size (obj, 1, 0);
    return D.18933;
    <D.18942>:
    D.18943 = klass->flags;
    D.18944 = D.18943 & 24;
    if (D.18944 == 0) goto <D.18945>; else goto <D.18946>;
    <D.18945>:
    D.18933 = 4294967295B;
    return D.18933;
    <D.18946>:
    D.18933 = obj + 8;
    return D.18933;
  }
  <D.18935>:
  D.18933 = 0B;
  return D.18933;
}


mono_gchandle_get_type (guint32 gchandle)
{
  unsigned int D.18948;
  HandleType D.18949;
  guint type;

  D.18948 = gchandle & 7;
  type = D.18948 + 4294967295;
  D.18949 = type;
  return D.18949;
}


ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
{
  MonoBoolean D.18951;
  int D.18952;
  int D.18953;

  D.18952 = (int) flag;
  D.18953 = mono_gc_set_allow_synchronous_major (D.18952);
  D.18951 = (MonoBoolean) D.18953;
  return D.18951;
}


mono_gchandle_new (struct MonoObject * obj, gboolean pinned)
{
  uint32_t D.18955;
  int iftmp.17;
  struct HandleData * D.18960;

  if (pinned != 0) goto <D.18957>; else goto <D.18958>;
  <D.18957>:
  iftmp.17 = 3;
  goto <D.18959>;
  <D.18958>:
  iftmp.17 = 2;
  <D.18959>:
  D.18960 = &gc_handles[iftmp.17];
  D.18955 = alloc_handle (D.18960, obj, 0);
  return D.18955;
}


alloc_handle (struct HandleData * handles, struct MonoObject * obj, gboolean track)
{
  _Bool D.18964;
  long int D.18965;
  long int D.18966;
  unsigned int D.18969;
  unsigned char D.18972;
  _Bool D.18975;
  int D.18976;
  int D.18977;
  void * D.18978;
  unsigned int D.18979;
  void * D.18980;
  void * D.18982;
  unsigned int D.18983;
  void * D.18984;
  unsigned int D.18985;
  void * D.18986;
  <unnamed-unsigned:24> D.18987;
  guint32 * D.18988;
  unsigned int slot.18;
  unsigned int D.18990;
  guint32 * D.18991;
  unsigned int D.18992;
  <unnamed-unsigned:24> D.18995;
  unsigned int slot.19;
  unsigned int D.18997;
  unsigned int D.19000;
  unsigned int D.19001;
  int D.19006;
  unsigned int D.19009;
  int new_size.20;
  void * D.19013;
  unsigned int D.19014;
  void * * D.19015;
  unsigned int D.19017;
  guint16 * D.19018;
  unsigned int i.21;
  unsigned int D.19020;
  void * * D.19021;
  void * * D.19024;
  void * * D.19026;
  void * D.19027;
  _Bool D.19028;
  long int D.19029;
  long int D.19030;
  unsigned int i.22;
  unsigned int D.19034;
  unsigned int D.19035;
  <unnamed-unsigned:24> D.19036;
  int D.19037;
  unsigned int D.19038;
  unsigned int D.19039;
  int D.19040;
  void * * D.19041;
  unsigned int D.19044;
  guint16 * D.19045;
  struct MonoDomain * iftmp.23;
  int D.19050;
  short unsigned int D.19051;
  void * * D.19054;
  struct MonoPerfCounters * mono_perfcounters.24;
  unsigned int D.19057;
  unsigned int D.19058;
  _Bool D.19061;
  long int D.19062;
  long int D.19063;
  int D.19066;
  int D.19067;
  int D.19068;
  int D.19069;
  guint32 D.19070;
  gint slot;
  gint i;
  guint32 res;

  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.18962>; else goto <D.18963>;
    <D.18962>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18963>:
    D.18964 = ret != 0;
    D.18965 = (long int) D.18964;
    D.18966 = __builtin_expect (D.18965, 0);
    if (D.18966 != 0) goto <D.18967>; else goto <D.18968>;
    <D.18967>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 636, "ret == 0");
    <D.18968>:
  }
  D.18969 = handles->size;
  if (D.18969 == 0) goto <D.18970>; else goto <D.18971>;
  <D.18970>:
  handles->size = 32;
  D.18972 = handles->type;
  if (D.18972 > 1) goto <D.18973>; else goto <D.18974>;
  <D.18973>:
  D.18972 = handles->type;
  D.18975 = D.18972 == 3;
  D.18976 = (int) D.18975;
  D.18969 = handles->size;
  D.18977 = (int) D.18969;
  D.18978 = make_root_descr_all_refs (D.18977, D.18976);
  D.18969 = handles->size;
  D.18979 = D.18969 * 4;
  D.18980 = mono_gc_alloc_fixed (D.18979, D.18978);
  handles->entries = D.18980;
  goto <D.18981>;
  <D.18974>:
  D.18969 = handles->size;
  D.18979 = D.18969 * 4;
  D.18982 = monoeg_malloc0 (D.18979);
  handles->entries = D.18982;
  D.18969 = handles->size;
  D.18983 = D.18969 * 2;
  D.18984 = monoeg_malloc0 (D.18983);
  handles->domain_ids = D.18984;
  <D.18981>:
  D.18969 = handles->size;
  D.18985 = D.18969 / 8;
  D.18986 = monoeg_malloc0 (D.18985);
  handles->bitmap = D.18986;
  <D.18971>:
  i = -1;
  D.18987 = handles->slot_hint;
  slot = (gint) D.18987;
  goto <D.18430>;
  <D.18429>:
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18992 = *D.18991;
  if (D.18992 != 4294967295) goto <D.18993>; else goto <D.18994>;
  <D.18993>:
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18992 = *D.18991;
  i = find_first_unset (D.18992);
  slot.18 = (unsigned int) slot;
  D.18995 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.18995;
  goto <D.18428>;
  <D.18994>:
  slot = slot + 1;
  <D.18430>:
  slot.19 = (unsigned int) slot;
  D.18969 = handles->size;
  D.18997 = D.18969 / 32;
  if (slot.19 < D.18997) goto <D.18429>; else goto <D.18428>;
  <D.18428>:
  if (i == -1) goto <D.18998>; else goto <D.18999>;
  <D.18998>:
  D.19000 = BIT_FIELD_REF <*handles, 32, 96>;
  D.19001 = D.19000 & 4294967040;
  if (D.19001 != 0) goto <D.19002>; else goto <D.19003>;
  <D.19002>:
  slot = 0;
  goto <D.18433>;
  <D.18432>:
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18992 = *D.18991;
  if (D.18992 != 4294967295) goto <D.19004>; else goto <D.19005>;
  <D.19004>:
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18992 = *D.18991;
  i = find_first_unset (D.18992);
  slot.18 = (unsigned int) slot;
  D.18995 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.18995;
  goto <D.18431>;
  <D.19005>:
  slot = slot + 1;
  <D.18433>:
  D.18987 = handles->slot_hint;
  D.19006 = (int) D.18987;
  if (D.19006 > slot) goto <D.18432>; else goto <D.18431>;
  <D.18431>:
  <D.19003>:
  <D.18999>:
  if (i == -1) goto <D.19007>; else goto <D.19008>;
  <D.19007>:
  {
    guint32 * new_bitmap;
    guint32 new_size;

    D.18969 = handles->size;
    new_size = D.18969 * 2;
    D.19009 = new_size / 8;
    new_bitmap = monoeg_malloc0 (D.19009);
    D.18969 = handles->size;
    D.18985 = D.18969 / 8;
    D.18988 = handles->bitmap;
    memcpy (new_bitmap, D.18988, D.18985);
    D.18988 = handles->bitmap;
    monoeg_g_free (D.18988);
    handles->bitmap = new_bitmap;
    D.18972 = handles->type;
    if (D.18972 > 1) goto <D.19010>; else goto <D.19011>;
    <D.19010>:
    {
      void * * entries;

      D.18972 = handles->type;
      D.18975 = D.18972 == 3;
      D.18976 = (int) D.18975;
      new_size.20 = (int) new_size;
      D.19013 = make_root_descr_all_refs (new_size.20, D.18976);
      D.19014 = new_size * 4;
      entries = mono_gc_alloc_fixed (D.19014, D.19013);
      D.18969 = handles->size;
      D.18979 = D.18969 * 4;
      D.19015 = handles->entries;
      mono_gc_memmove_aligned (entries, D.19015, D.18979);
      D.19015 = handles->entries;
      mono_gc_free_fixed (D.19015);
      handles->entries = entries;
    }
    goto <D.19016>;
    <D.19011>:
    {
      void * * entries;
      guint16 * domain_ids;

      D.19017 = new_size * 2;
      domain_ids = monoeg_malloc0 (D.19017);
      D.19014 = new_size * 4;
      entries = monoeg_malloc0 (D.19014);
      D.18969 = handles->size;
      D.18983 = D.18969 * 2;
      D.19018 = handles->domain_ids;
      memcpy (domain_ids, D.19018, D.18983);
      i = 0;
      goto <D.18441>;
      <D.18440>:
      {
        struct MonoObject * obj;

        D.19015 = handles->entries;
        i.21 = (unsigned int) i;
        D.19020 = i.21 * 4;
        D.19021 = D.19015 + D.19020;
        obj = mono_gc_weak_link_get (D.19021);
        if (obj != 0B) goto <D.19022>; else goto <D.19023>;
        <D.19022>:
        i.21 = (unsigned int) i;
        D.19020 = i.21 * 4;
        D.19024 = entries + D.19020;
        mono_gc_weak_link_add (D.19024, obj, track);
        D.19015 = handles->entries;
        i.21 = (unsigned int) i;
        D.19020 = i.21 * 4;
        D.19021 = D.19015 + D.19020;
        mono_gc_weak_link_remove (D.19021, track);
        goto <D.19025>;
        <D.19023>:
        D.19015 = handles->entries;
        i.21 = (unsigned int) i;
        D.19020 = i.21 * 4;
        D.19026 = D.19015 + D.19020;
        D.19027 = *D.19026;
        D.19028 = D.19027 != 0B;
        D.19029 = (long int) D.19028;
        D.19030 = __builtin_expect (D.19029, 0);
        if (D.19030 != 0) goto <D.19031>; else goto <D.19032>;
        <D.19031>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 695, "!handles->entries [i]");
        <D.19032>:
        <D.19025>:
      }
      i = i + 1;
      <D.18441>:
      i.22 = (unsigned int) i;
      D.18969 = handles->size;
      if (i.22 < D.18969) goto <D.18440>; else goto <D.18442>;
      <D.18442>:
      D.19015 = handles->entries;
      monoeg_g_free (D.19015);
      D.19018 = handles->domain_ids;
      monoeg_g_free (D.19018);
      handles->entries = entries;
      handles->domain_ids = domain_ids;
    }
    <D.19016>:
    i = 0;
    D.18969 = handles->size;
    D.19034 = D.18969 + 1;
    D.19035 = D.19034 / 32;
    slot = (gint) D.19035;
    D.18969 = handles->size;
    D.19034 = D.18969 + 1;
    D.19036 = (<unnamed-unsigned:24>) D.19034;
    handles->slot_hint = D.19036;
    handles->size = new_size;
  }
  <D.19008>:
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18988 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.18991 = D.18988 + D.18990;
  D.18992 = *D.18991;
  D.19037 = 1 << i;
  D.19038 = (unsigned int) D.19037;
  D.19039 = D.18992 | D.19038;
  *D.18991 = D.19039;
  D.19040 = slot * 32;
  slot = D.19040 + i;
  D.19015 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.19041 = D.19015 + D.18990;
  *D.19041 = 0B;
  D.18972 = handles->type;
  if (D.18972 <= 1) goto <D.19042>; else goto <D.19043>;
  <D.19042>:
  D.19018 = handles->domain_ids;
  slot.18 = (unsigned int) slot;
  D.19044 = slot.18 * 2;
  D.19045 = D.19018 + D.19044;
  if (obj != 0B) goto <D.19047>; else goto <D.19048>;
  <D.19047>:
  iftmp.23 = mono_object_get_domain (obj);
  goto <D.19049>;
  <D.19048>:
  iftmp.23 = mono_domain_get ();
  <D.19049>:
  D.19050 = iftmp.23->domain_id;
  D.19051 = (short unsigned int) D.19050;
  *D.19045 = D.19051;
  if (obj != 0B) goto <D.19052>; else goto <D.19053>;
  <D.19052>:
  D.19015 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.19054 = D.19015 + D.18990;
  mono_gc_weak_link_add (D.19054, obj, track);
  <D.19053>:
  goto <D.19055>;
  <D.19043>:
  D.19015 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18990 = slot.18 * 4;
  D.19041 = D.19015 + D.18990;
  *D.19041 = obj;
  <D.19055>:
  mono_perfcounters.24 = mono_perfcounters;
  D.19057 = mono_perfcounters.24->gc_num_handles;
  D.19058 = D.19057 + 1;
  mono_perfcounters.24->gc_num_handles = D.19058;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19059>; else goto <D.19060>;
    <D.19059>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19060>:
    D.19061 = ret != 0;
    D.19062 = (long int) D.19061;
    D.19063 = __builtin_expect (D.19062, 0);
    if (D.19063 != 0) goto <D.19064>; else goto <D.19065>;
    <D.19064>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 725, "ret == 0");
    <D.19065>:
  }
  D.19066 = slot << 3;
  D.18972 = handles->type;
  D.19067 = (int) D.18972;
  D.19068 = D.19067 + 1;
  D.19069 = D.19066 | D.19068;
  res = (guint32) D.19069;
  D.18972 = handles->type;
  D.19067 = (int) D.18972;
  mono_profiler_gc_handle (0, D.19067, res, obj);
  D.19070 = res;
  return D.19070;
}


find_first_unset (guint32 bitmap)
{
  int D.19072;
  unsigned int D.19073;
  unsigned int D.19074;
  int D.19077;
  int i;

  i = 0;
  goto <D.18413>;
  <D.18412>:
  D.19072 = 1 << i;
  D.19073 = (unsigned int) D.19072;
  D.19074 = D.19073 & bitmap;
  if (D.19074 == 0) goto <D.19075>; else goto <D.19076>;
  <D.19075>:
  D.19077 = i;
  return D.19077;
  <D.19076>:
  i = i + 1;
  <D.18413>:
  if (i <= 31) goto <D.18412>; else goto <D.18414>;
  <D.18414>:
  D.19077 = -1;
  return D.19077;
}


make_root_descr_all_refs (int numbits, gboolean pinned)
{
  void * D.19081;

  if (pinned != 0) goto <D.19079>; else goto <D.19080>;
  <D.19079>:
  D.19081 = 0B;
  return D.19081;
  <D.19080>:
  D.19081 = mono_gc_make_root_descr_all_refs (numbits);
  return D.19081;
}


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

  D.19084 = __builtin_object_size (__dest, 0);
  D.19083 = __builtin___memcpy_chk (__dest, __src, __len, D.19084);
  return D.19083;
}


mono_gchandle_new_weakref (struct MonoObject * obj, gboolean track_resurrection)
{
  _Bool D.19086;
  int D.19087;
  struct HandleData * D.19088;
  uint32_t D.19089;
  guint32 handle;

  D.19086 = track_resurrection != 0;
  D.19087 = (int) D.19086;
  D.19088 = &gc_handles[D.19087];
  handle = alloc_handle (D.19088, obj, track_resurrection);
  D.19089 = handle;
  return D.19089;
}


mono_gchandle_get_target (guint32 gchandle)
{
  unsigned int D.19091;
  struct MonoObject * D.19094;
  _Bool D.19097;
  long int D.19098;
  long int D.19099;
  unsigned int D.19102;
  guint32 * D.19105;
  unsigned int D.19106;
  unsigned int D.19107;
  guint32 * D.19108;
  unsigned int D.19109;
  int slot.25;
  int D.19111;
  int D.19112;
  unsigned int D.19113;
  unsigned int D.19114;
  unsigned char D.19117;
  void * * D.19120;
  unsigned int D.19121;
  void * * D.19122;
  void * * D.19124;
  _Bool D.19128;
  long int D.19129;
  long int D.19130;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * obj;

  slot = gchandle >> 3;
  D.19091 = gchandle & 7;
  type = D.19091 + 4294967295;
  handles = &gc_handles[type];
  obj = 0B;
  if (type > 3) goto <D.19092>; else goto <D.19093>;
  <D.19092>:
  D.19094 = 0B;
  return D.19094;
  <D.19093>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19095>; else goto <D.19096>;
    <D.19095>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19096>:
    D.19097 = ret != 0;
    D.19098 = (long int) D.19097;
    D.19099 = __builtin_expect (D.19098, 0);
    if (D.19099 != 0) goto <D.19100>; else goto <D.19101>;
    <D.19100>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 809, "ret == 0");
    <D.19101>:
  }
  D.19102 = handles->size;
  if (D.19102 > slot) goto <D.19103>; else goto <D.19104>;
  <D.19103>:
  D.19105 = handles->bitmap;
  D.19106 = slot / 32;
  D.19107 = D.19106 * 4;
  D.19108 = D.19105 + D.19107;
  D.19109 = *D.19108;
  slot.25 = (int) slot;
  D.19111 = slot.25 & 31;
  D.19112 = 1 << D.19111;
  D.19113 = (unsigned int) D.19112;
  D.19114 = D.19109 & D.19113;
  if (D.19114 != 0) goto <D.19115>; else goto <D.19116>;
  <D.19115>:
  D.19117 = handles->type;
  if (D.19117 <= 1) goto <D.19118>; else goto <D.19119>;
  <D.19118>:
  D.19120 = handles->entries;
  D.19121 = slot * 4;
  D.19122 = D.19120 + D.19121;
  obj = mono_gc_weak_link_get (D.19122);
  goto <D.19123>;
  <D.19119>:
  D.19120 = handles->entries;
  D.19121 = slot * 4;
  D.19124 = D.19120 + D.19121;
  obj = *D.19124;
  <D.19123>:
  goto <D.19125>;
  <D.19116>:
  <D.19125>:
  <D.19104>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19126>; else goto <D.19127>;
    <D.19126>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19127>:
    D.19128 = ret != 0;
    D.19129 = (long int) D.19128;
    D.19130 = __builtin_expect (D.19129, 0);
    if (D.19130 != 0) goto <D.19131>; else goto <D.19132>;
    <D.19131>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 819, "ret == 0");
    <D.19132>:
  }
  D.19094 = obj;
  return D.19094;
}


mono_gchandle_is_in_domain (guint32 gchandle, struct MonoDomain * domain)
{
  unsigned int D.19134;
  gboolean D.19137;
  _Bool D.19140;
  long int D.19141;
  long int D.19142;
  unsigned int D.19145;
  guint32 * D.19148;
  unsigned int D.19149;
  unsigned int D.19150;
  guint32 * D.19151;
  unsigned int D.19152;
  int slot.26;
  int D.19154;
  int D.19155;
  unsigned int D.19156;
  unsigned int D.19157;
  unsigned char D.19160;
  int D.19163;
  guint16 * D.19164;
  unsigned int D.19165;
  guint16 * D.19166;
  short unsigned int D.19167;
  int D.19168;
  _Bool D.19169;
  void * * D.19171;
  unsigned int D.19172;
  void * * D.19173;
  struct MonoVTable * D.19177;
  struct MonoDomain * D.19178;
  _Bool D.19179;
  _Bool D.19183;
  long int D.19184;
  long int D.19185;
  guint slot;
  guint type;
  struct HandleData * handles;
  gboolean result;

  slot = gchandle >> 3;
  D.19134 = gchandle & 7;
  type = D.19134 + 4294967295;
  handles = &gc_handles[type];
  result = 0;
  if (type > 3) goto <D.19135>; else goto <D.19136>;
  <D.19135>:
  D.19137 = 0;
  return D.19137;
  <D.19136>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19138>; else goto <D.19139>;
    <D.19138>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19139>:
    D.19140 = ret != 0;
    D.19141 = (long int) D.19140;
    D.19142 = __builtin_expect (D.19141, 0);
    if (D.19142 != 0) goto <D.19143>; else goto <D.19144>;
    <D.19143>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 870, "ret == 0");
    <D.19144>:
  }
  D.19145 = handles->size;
  if (D.19145 > slot) goto <D.19146>; else goto <D.19147>;
  <D.19146>:
  D.19148 = handles->bitmap;
  D.19149 = slot / 32;
  D.19150 = D.19149 * 4;
  D.19151 = D.19148 + D.19150;
  D.19152 = *D.19151;
  slot.26 = (int) slot;
  D.19154 = slot.26 & 31;
  D.19155 = 1 << D.19154;
  D.19156 = (unsigned int) D.19155;
  D.19157 = D.19152 & D.19156;
  if (D.19157 != 0) goto <D.19158>; else goto <D.19159>;
  <D.19158>:
  D.19160 = handles->type;
  if (D.19160 <= 1) goto <D.19161>; else goto <D.19162>;
  <D.19161>:
  D.19163 = domain->domain_id;
  D.19164 = handles->domain_ids;
  D.19165 = slot * 2;
  D.19166 = D.19164 + D.19165;
  D.19167 = *D.19166;
  D.19168 = (int) D.19167;
  D.19169 = D.19163 == D.19168;
  result = (gboolean) D.19169;
  goto <D.19170>;
  <D.19162>:
  {
    struct MonoObject * obj;

    D.19171 = handles->entries;
    D.19172 = slot * 4;
    D.19173 = D.19171 + D.19172;
    obj = *D.19173;
    if (obj == 0B) goto <D.19174>; else goto <D.19175>;
    <D.19174>:
    result = 1;
    goto <D.19176>;
    <D.19175>:
    D.19177 = obj->vtable;
    D.19178 = D.19177->domain;
    D.19179 = D.19178 == domain;
    result = (gboolean) D.19179;
    <D.19176>:
  }
  <D.19170>:
  goto <D.19180>;
  <D.19159>:
  <D.19180>:
  <D.19147>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19181>; else goto <D.19182>;
    <D.19181>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19182>:
    D.19183 = ret != 0;
    D.19184 = (long int) D.19183;
    D.19185 = __builtin_expect (D.19184, 0);
    if (D.19185 != 0) goto <D.19186>; else goto <D.19187>;
    <D.19186>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 885, "ret == 0");
    <D.19187>:
  }
  D.19137 = result;
  return D.19137;
}


mono_gchandle_free (guint32 gchandle)
{
  unsigned int D.19189;
  _Bool D.19194;
  long int D.19195;
  long int D.19196;
  unsigned int D.19199;
  guint32 * D.19202;
  unsigned int D.19203;
  unsigned int D.19204;
  guint32 * D.19205;
  unsigned int D.19206;
  int slot.27;
  int D.19208;
  int D.19209;
  unsigned int D.19210;
  unsigned int D.19211;
  unsigned char D.19214;
  void * * D.19217;
  unsigned int D.19218;
  void * * D.19219;
  void * D.19220;
  _Bool D.19223;
  int D.19224;
  void * * D.19225;
  unsigned int D.19227;
  unsigned int D.19228;
  guint32 * D.19229;
  unsigned int D.19230;
  int D.19231;
  unsigned int D.19232;
  unsigned int D.19233;
  struct MonoPerfCounters * mono_perfcounters.28;
  unsigned int D.19236;
  unsigned int D.19237;
  _Bool D.19240;
  long int D.19241;
  long int D.19242;
  int D.19245;
  guint slot;
  guint type;
  struct HandleData * handles;

  slot = gchandle >> 3;
  D.19189 = gchandle & 7;
  type = D.19189 + 4294967295;
  handles = &gc_handles[type];
  if (type > 3) goto <D.19190>; else goto <D.19191>;
  <D.19190>:
  return;
  <D.19191>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19192>; else goto <D.19193>;
    <D.19192>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19193>:
    D.19194 = ret != 0;
    D.19195 = (long int) D.19194;
    D.19196 = __builtin_expect (D.19195, 0);
    if (D.19196 != 0) goto <D.19197>; else goto <D.19198>;
    <D.19197>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 906, "ret == 0");
    <D.19198>:
  }
  D.19199 = handles->size;
  if (D.19199 > slot) goto <D.19200>; else goto <D.19201>;
  <D.19200>:
  D.19202 = handles->bitmap;
  D.19203 = slot / 32;
  D.19204 = D.19203 * 4;
  D.19205 = D.19202 + D.19204;
  D.19206 = *D.19205;
  slot.27 = (int) slot;
  D.19208 = slot.27 & 31;
  D.19209 = 1 << D.19208;
  D.19210 = (unsigned int) D.19209;
  D.19211 = D.19206 & D.19210;
  if (D.19211 != 0) goto <D.19212>; else goto <D.19213>;
  <D.19212>:
  D.19214 = handles->type;
  if (D.19214 <= 1) goto <D.19215>; else goto <D.19216>;
  <D.19215>:
  D.19217 = handles->entries;
  D.19218 = slot * 4;
  D.19219 = D.19217 + D.19218;
  D.19220 = *D.19219;
  if (D.19220 != 0B) goto <D.19221>; else goto <D.19222>;
  <D.19221>:
  D.19214 = handles->type;
  D.19223 = D.19214 == 1;
  D.19224 = (int) D.19223;
  D.19217 = handles->entries;
  D.19218 = slot * 4;
  D.19225 = D.19217 + D.19218;
  mono_gc_weak_link_remove (D.19225, D.19224);
  <D.19222>:
  goto <D.19226>;
  <D.19216>:
  D.19217 = handles->entries;
  D.19218 = slot * 4;
  D.19219 = D.19217 + D.19218;
  *D.19219 = 0B;
  <D.19226>:
  D.19202 = handles->bitmap;
  D.19227 = slot / 32;
  D.19228 = D.19227 * 4;
  D.19229 = D.19202 + D.19228;
  D.19202 = handles->bitmap;
  D.19228 = D.19227 * 4;
  D.19229 = D.19202 + D.19228;
  D.19230 = *D.19229;
  slot.27 = (int) slot;
  D.19208 = slot.27 & 31;
  D.19209 = 1 << D.19208;
  D.19231 = ~D.19209;
  D.19232 = (unsigned int) D.19231;
  D.19233 = D.19230 & D.19232;
  *D.19229 = D.19233;
  goto <D.19234>;
  <D.19213>:
  <D.19234>:
  <D.19201>:
  mono_perfcounters.28 = mono_perfcounters;
  D.19236 = mono_perfcounters.28->gc_num_handles;
  D.19237 = D.19236 + 4294967295;
  mono_perfcounters.28->gc_num_handles = D.19237;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19238>; else goto <D.19239>;
    <D.19238>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19239>:
    D.19240 = ret != 0;
    D.19241 = (long int) D.19240;
    D.19242 = __builtin_expect (D.19241, 0);
    if (D.19242 != 0) goto <D.19243>; else goto <D.19244>;
    <D.19243>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 922, "ret == 0");
    <D.19244>:
  }
  D.19214 = handles->type;
  D.19245 = (int) D.19214;
  mono_profiler_gc_handle (1, D.19245, gchandle, 0B);
}


mono_gchandle_free_domain (struct MonoDomain * domain)
{
  _Bool D.19249;
  long int D.19250;
  long int D.19251;
  guint32 * D.19254;
  unsigned int D.19255;
  unsigned int D.19256;
  guint32 * D.19257;
  unsigned int D.19258;
  int slot.29;
  int D.19260;
  int D.19261;
  unsigned int D.19262;
  unsigned int D.19263;
  int D.19268;
  guint16 * D.19269;
  unsigned int D.19270;
  guint16 * D.19271;
  short unsigned int D.19272;
  int D.19273;
  unsigned int D.19276;
  unsigned int D.19277;
  guint32 * D.19278;
  unsigned int D.19279;
  int D.19280;
  unsigned int D.19281;
  unsigned int D.19282;
  void * * D.19283;
  unsigned int D.19284;
  void * * D.19285;
  void * D.19286;
  unsigned char D.19289;
  _Bool D.19290;
  int D.19291;
  void * * D.19292;
  struct MonoVTable * D.19296;
  struct MonoDomain * D.19297;
  unsigned int D.19300;
  unsigned int D.19301;
  guint32 * D.19302;
  unsigned int D.19303;
  unsigned int D.19304;
  unsigned int D.19305;
  _Bool D.19308;
  long int D.19309;
  long int D.19310;
  guint type;

  type = 0;
  goto <D.18508>;
  <D.18507>:
  {
    guint slot;
    struct HandleData * handles;

    handles = &gc_handles[type];
    {
      int ret;

      ret = pthread_mutex_lock (&handle_section.mutex);
      if (ret != 0) goto <D.19247>; else goto <D.19248>;
      <D.19247>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.19248>:
      D.19249 = ret != 0;
      D.19250 = (long int) D.19249;
      D.19251 = __builtin_expect (D.19250, 0);
      if (D.19251 != 0) goto <D.19252>; else goto <D.19253>;
      <D.19252>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 941, "ret == 0");
      <D.19253>:
    }
    slot = 0;
    goto <D.18504>;
    <D.18503>:
    D.19254 = handles->bitmap;
    D.19255 = slot / 32;
    D.19256 = D.19255 * 4;
    D.19257 = D.19254 + D.19256;
    D.19258 = *D.19257;
    slot.29 = (int) slot;
    D.19260 = slot.29 & 31;
    D.19261 = 1 << D.19260;
    D.19262 = (unsigned int) D.19261;
    D.19263 = D.19258 & D.19262;
    if (D.19263 == 0) goto <D.19264>; else goto <D.19265>;
    <D.19264>:
    // predicted unlikely by continue predictor.
    goto <D.18502>;
    <D.19265>:
    if (type <= 1) goto <D.19266>; else goto <D.19267>;
    <D.19266>:
    D.19268 = domain->domain_id;
    D.19269 = handles->domain_ids;
    D.19270 = slot * 2;
    D.19271 = D.19269 + D.19270;
    D.19272 = *D.19271;
    D.19273 = (int) D.19272;
    if (D.19268 == D.19273) goto <D.19274>; else goto <D.19275>;
    <D.19274>:
    D.19254 = handles->bitmap;
    D.19276 = slot / 32;
    D.19277 = D.19276 * 4;
    D.19278 = D.19254 + D.19277;
    D.19254 = handles->bitmap;
    D.19277 = D.19276 * 4;
    D.19278 = D.19254 + D.19277;
    D.19279 = *D.19278;
    slot.29 = (int) slot;
    D.19260 = slot.29 & 31;
    D.19261 = 1 << D.19260;
    D.19280 = ~D.19261;
    D.19281 = (unsigned int) D.19280;
    D.19282 = D.19279 & D.19281;
    *D.19278 = D.19282;
    D.19283 = handles->entries;
    D.19284 = slot * 4;
    D.19285 = D.19283 + D.19284;
    D.19286 = *D.19285;
    if (D.19286 != 0B) goto <D.19287>; else goto <D.19288>;
    <D.19287>:
    D.19289 = handles->type;
    D.19290 = D.19289 == 1;
    D.19291 = (int) D.19290;
    D.19283 = handles->entries;
    D.19284 = slot * 4;
    D.19292 = D.19283 + D.19284;
    mono_gc_weak_link_remove (D.19292, D.19291);
    <D.19288>:
    <D.19275>:
    goto <D.19293>;
    <D.19267>:
    D.19283 = handles->entries;
    D.19284 = slot * 4;
    D.19285 = D.19283 + D.19284;
    D.19286 = *D.19285;
    if (D.19286 != 0B) goto <D.19294>; else goto <D.19295>;
    <D.19294>:
    D.19283 = handles->entries;
    D.19284 = slot * 4;
    D.19285 = D.19283 + D.19284;
    D.19286 = *D.19285;
    D.19296 = MEM[(struct MonoObject *)D.19286].vtable;
    D.19297 = D.19296->domain;
    if (D.19297 == domain) goto <D.19298>; else goto <D.19299>;
    <D.19298>:
    D.19254 = handles->bitmap;
    D.19300 = slot / 32;
    D.19301 = D.19300 * 4;
    D.19302 = D.19254 + D.19301;
    D.19254 = handles->bitmap;
    D.19301 = D.19300 * 4;
    D.19302 = D.19254 + D.19301;
    D.19303 = *D.19302;
    slot.29 = (int) slot;
    D.19260 = slot.29 & 31;
    D.19261 = 1 << D.19260;
    D.19280 = ~D.19261;
    D.19281 = (unsigned int) D.19280;
    D.19304 = D.19303 & D.19281;
    *D.19302 = D.19304;
    D.19283 = handles->entries;
    D.19284 = slot * 4;
    D.19285 = D.19283 + D.19284;
    *D.19285 = 0B;
    <D.19299>:
    <D.19295>:
    <D.19293>:
    <D.18502>:
    slot = slot + 1;
    <D.18504>:
    D.19305 = handles->size;
    if (D.19305 > slot) goto <D.18503>; else goto <D.18505>;
    <D.18505>:
    {
      int ret;

      ret = pthread_mutex_unlock (&handle_section.mutex);
      if (ret != 0) goto <D.19306>; else goto <D.19307>;
      <D.19306>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19307>:
      D.19308 = ret != 0;
      D.19309 = (long int) D.19308;
      D.19310 = __builtin_expect (D.19309, 0);
      if (D.19310 != 0) goto <D.19311>; else goto <D.19312>;
      <D.19311>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 958, "ret == 0");
      <D.19312>:
    }
  }
  type = type + 1;
  <D.18508>:
  if (type <= 2) goto <D.18507>; else goto <D.18509>;
  <D.18509>:
}


GCHandle_CheckCurrentDomain (guint32 gchandle)
{
  MonoBoolean D.19313;
  struct MonoDomain * D.19314;
  int D.19315;

  D.19314 = mono_domain_get ();
  D.19315 = mono_gchandle_is_in_domain (gchandle, D.19314);
  D.19313 = (MonoBoolean) D.19315;
  return D.19313;
}


mono_gc_finalize_notify ()
{
  mono_sem_post (&finalizer_sem);
}


mono_gc_init ()
{
  int D.19317;
  int D.19320;
  int D.19323;
  void * finalizer_event.30;
  void * pending_done_event.31;
  void * shutdown_event.32;
  void * finalizer_event.33;
  void * pending_done_event.34;
  void * shutdown_event.35;

  InitializeCriticalSection (&handle_section);
  InitializeCriticalSection (&allocator_section);
  InitializeCriticalSection (&finalizer_mutex);
  InitializeCriticalSection (&reference_queue_mutex);
  D.19317 = mono_gc_is_moving ();
  if (D.19317 == 0) goto <D.19318>; else goto <D.19319>;
  <D.19318>:
  mono_gc_register_root (&gc_handles[2].entries, 4, 0B);
  <D.19319>:
  D.19320 = mono_gc_is_moving ();
  if (D.19320 == 0) goto <D.19321>; else goto <D.19322>;
  <D.19321>:
  mono_gc_register_root (&gc_handles[3].entries, 4, 0B);
  <D.19322>:
  mono_counters_register ("Created object count", 516, &mono_stats.new_object_count);
  mono_counters_register ("Minor GC collections", 512, &gc_stats.minor_gc_count);
  mono_counters_register ("Major GC collections", 512, &gc_stats.major_gc_count);
  mono_counters_register ("Minor GC time", 519, &gc_stats.minor_gc_time_usecs);
  mono_counters_register ("Major GC time", 519, &gc_stats.major_gc_time_usecs);
  mono_gc_base_init ();
  D.19323 = mono_gc_is_disabled ();
  if (D.19323 != 0) goto <D.19324>; else goto <D.19325>;
  <D.19324>:
  gc_disabled = 1;
  return;
  <D.19325>:
  finalizer_event.30 = CreateEvent (0B, 0, 0, 0B);
  finalizer_event = finalizer_event.30;
  pending_done_event.31 = CreateEvent (0B, 1, 0, 0B);
  pending_done_event = pending_done_event.31;
  shutdown_event.32 = CreateEvent (0B, 1, 0, 0B);
  shutdown_event = shutdown_event.32;
  finalizer_event.33 = finalizer_event;
  if (finalizer_event.33 == 0B) goto <D.19329>; else goto <D.19332>;
  <D.19332>:
  pending_done_event.34 = pending_done_event;
  if (pending_done_event.34 == 0B) goto <D.19329>; else goto <D.19334>;
  <D.19334>:
  shutdown_event.35 = shutdown_event;
  if (shutdown_event.35 == 0B) goto <D.19329>; else goto <D.19330>;
  <D.19329>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 1152);
  <D.19330>:
  sem_init (&finalizer_sem, 0, 0);
  mono_gc_init_finalizer_thread ();
}


mono_gc_init_finalizer_thread ()
{
  struct MonoDomain * D.19337;
  struct MonoInternalThread * gc_thread.36;
  struct MonoDomain * D.19339;
  struct MonoString * D.19340;
  struct MonoInternalThread * gc_thread.37;

  D.19337 = mono_domain_get ();
  gc_thread.36 = mono_thread_create_internal (D.19337, finalizer_thread, 0B, 0, 1, 0);
  gc_thread = gc_thread.36;
  D.19339 = mono_domain_get ();
  D.19340 = mono_string_new (D.19339, "Finalizer");
  gc_thread.37 = gc_thread;
  ves_icall_System_Threading_Thread_SetName_internal (gc_thread.37, D.19340);
}


finalizer_thread (void * unused)
{
  struct MonoDomain * D.19342;
  struct MonoDomain * D.19343;
  _Bool D.19344;
  long int D.19345;
  long int D.19346;
  struct GSList * domains_to_finalize.38;
  _Bool D.19354;
  long int D.19355;
  long int D.19356;
  struct GSList * domains_to_finalize.39;
  _Bool D.19364;
  long int D.19365;
  long int D.19366;
  _Bool D.19372;
  long int D.19373;
  long int D.19374;
  void * pending_done_event.40;
  int finished.41;
  void * shutdown_event.42;
  guint32 D.19380;

  goto <D.18540>;
  <D.18539>:
  D.19342 = mono_domain_get ();
  D.19343 = mono_get_root_domain ();
  D.19344 = D.19342 != D.19343;
  D.19345 = (long int) D.19344;
  D.19346 = __builtin_expect (D.19345, 0);
  if (D.19346 != 0) goto <D.19347>; else goto <D.19348>;
  <D.19347>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1069, "mono_domain_get () == mono_get_root_domain ()");
  <D.19348>:
  mono_sem_wait (&finalizer_sem, 1);
  mono_threads_perform_thread_dump ();
  mono_console_handle_async_ops ();
  mono_attach_maybe_start ();
  domains_to_finalize.38 = domains_to_finalize;
  if (domains_to_finalize.38 != 0B) goto <D.19350>; else goto <D.19351>;
  <D.19350>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19352>; else goto <D.19353>;
    <D.19352>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19353>:
    D.19354 = ret != 0;
    D.19355 = (long int) D.19354;
    D.19356 = __builtin_expect (D.19355, 0);
    if (D.19356 != 0) goto <D.19357>; else goto <D.19358>;
    <D.19357>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1087, "ret == 0");
    <D.19358>:
  }
  domains_to_finalize.38 = domains_to_finalize;
  if (domains_to_finalize.38 != 0B) goto <D.19359>; else goto <D.19360>;
  <D.19359>:
  {
    struct DomainFinalizationReq * req;

    domains_to_finalize.38 = domains_to_finalize;
    req = domains_to_finalize.38->data;
    domains_to_finalize.38 = domains_to_finalize;
    domains_to_finalize.39 = monoeg_g_slist_remove (domains_to_finalize.38, req);
    domains_to_finalize = domains_to_finalize.39;
    {
      int ret;

      ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
      if (ret != 0) goto <D.19362>; else goto <D.19363>;
      <D.19362>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19363>:
      D.19364 = ret != 0;
      D.19365 = (long int) D.19364;
      D.19366 = __builtin_expect (D.19365, 0);
      if (D.19366 != 0) goto <D.19367>; else goto <D.19368>;
      <D.19367>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1091, "ret == 0");
      <D.19368>:
    }
    finalize_domain_objects (req);
  }
  goto <D.19369>;
  <D.19360>:
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19370>; else goto <D.19371>;
    <D.19370>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19371>:
    D.19372 = ret != 0;
    D.19373 = (long int) D.19372;
    D.19374 = __builtin_expect (D.19373, 0);
    if (D.19374 != 0) goto <D.19375>; else goto <D.19376>;
    <D.19375>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1095, "ret == 0");
    <D.19376>:
  }
  <D.19369>:
  <D.19351>:
  mono_gc_invoke_finalizers ();
  reference_queue_proccess_all ();
  pending_done_event.40 = pending_done_event;
  SetEvent (pending_done_event.40);
  <D.18540>:
  finished.41 = finished;
  if (finished.41 == 0) goto <D.18539>; else goto <D.18541>;
  <D.18541>:
  shutdown_event.42 = shutdown_event;
  SetEvent (shutdown_event.42);
  D.19380 = 0;
  return D.19380;
}


finalize_domain_objects (struct DomainFinalizationReq * req)
{
  struct MonoObject * D.19382;
  void * D.19383;
  struct MonoDomain * domain;
  struct MonoObject * to_finalize[64];
  int count;

  try
    {
      domain = req->domain;
      mono_gc_invoke_finalizers ();
      goto <D.18530>;
      <D.18529>:
      {
        int i;

        i = 0;
        goto <D.18527>;
        <D.18526>:
        D.19382 = to_finalize[i];
        mono_gc_run_finalize (D.19382, 0B);
        i = i + 1;
        <D.18527>:
        if (i < count) goto <D.18526>; else goto <D.18528>;
        <D.18528>:
      }
      <D.18530>:
      count = mono_gc_finalizers_for_domain (domain, &to_finalize, 64);
      if (count != 0) goto <D.18529>; else goto <D.18531>;
      <D.18531>:
      reference_queue_clear_for_domain (domain);
      D.19383 = req->done_event;
      SetEvent (D.19383);
      monoeg_g_free (req);
    }
  finally
    {
      to_finalize = {CLOBBER};
    }
}


reference_queue_clear_for_domain (struct MonoDomain * domain)
{
  struct MonoDomain * D.19384;
  void * * D.19387;
  void (*<Tbf>) (void *) D.19388;
  void * D.19389;
  struct MonoReferenceQueue * queue;

  queue = ref_queues;
  goto <D.18635>;
  <D.18634>:
  {
    struct RefQueueEntry * * iter;
    struct RefQueueEntry * entry;

    iter = &queue->queue;
    goto <D.18632>;
    <D.18631>:
    D.19384 = entry->domain;
    if (D.19384 == domain) goto <D.19385>; else goto <D.19386>;
    <D.19385>:
    D.19387 = &entry->dis_link;
    mono_gc_weak_link_remove (D.19387, 1);
    ref_list_remove_element (iter, entry);
    D.19388 = queue->callback;
    D.19389 = entry->user_data;
    D.19388 (D.19389);
    monoeg_g_free (entry);
    goto <D.19390>;
    <D.19386>:
    iter = &entry->next;
    <D.19390>:
    <D.18632>:
    entry = *iter;
    if (entry != 0B) goto <D.18631>; else goto <D.18633>;
    <D.18633>:
  }
  queue = queue->next;
  <D.18635>:
  if (queue != 0B) goto <D.18634>; else goto <D.18636>;
  <D.18636>:
}


ref_list_remove_element (struct RefQueueEntry * * prev, struct RefQueueEntry * element)
{
  struct RefQueueEntry * D.19391;
  struct RefQueueEntry * D.19393;
  void * D.19394;

  <D.18586>:
  goto <D.18584>;
  <D.18583>:
  D.19391 = *prev;
  prev = &D.19391->next;
  <D.18584>:
  D.19391 = *prev;
  if (D.19391 != element) goto <D.18583>; else goto <D.18585>;
  <D.18585>:
  if (prev != 0B) goto <D.19392>; else goto <D.18587>;
  <D.19392>:
  D.19393 = element->next;
  D.19394 = InterlockedCompareExchangePointer (prev, D.19393, element);
  if (D.19394 != element) goto <D.18586>; else goto <D.18587>;
  <D.18587>:
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.19395;
  unsigned int exch.43;
  unsigned int comp.44;
  unsigned int D.19398;

  exch.43 = (unsigned int) exch;
  comp.44 = (unsigned int) comp;
  D.19398 = __sync_val_compare_and_swap_4 (dest, comp.44, exch.43);
  D.19395 = (void *) D.19398;
  return D.19395;
}


reference_queue_proccess_all ()
{
  _Bool D.19402;
  long int D.19403;
  long int D.19404;
  int D.19407;
  struct RefQueueEntry * D.19410;
  _Bool D.19415;
  long int D.19416;
  long int D.19417;
  struct MonoReferenceQueue * D.19420;
  struct MonoReferenceQueue * D.19421;
  _Bool D.19424;
  long int D.19425;
  long int D.19426;
  struct MonoReferenceQueue * * iter;
  struct MonoReferenceQueue * queue;
  void restart = <<< error >>>;

  queue = ref_queues;
  goto <D.18609>;
  <D.18608>:
  reference_queue_proccess (queue);
  queue = queue->next;
  <D.18609>:
  if (queue != 0B) goto <D.18608>; else goto <D.18610>;
  <D.18610>:
  restart:
  {
    int ret;

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19400>; else goto <D.19401>;
    <D.19400>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19401>:
    D.19402 = ret != 0;
    D.19403 = (long int) D.19402;
    D.19404 = __builtin_expect (D.19403, 0);
    if (D.19404 != 0) goto <D.19405>; else goto <D.19406>;
    <D.19405>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1424, "ret == 0");
    <D.19406>:
  }
  iter = &ref_queues;
  goto <D.18613>;
  <D.18615>:
  queue = *iter;
  D.19407 = queue->should_be_deleted;
  if (D.19407 == 0) goto <D.19408>; else goto <D.19409>;
  <D.19408>:
  iter = &queue->next;
  // predicted unlikely by continue predictor.
  goto <D.18613>;
  <D.19409>:
  D.19410 = queue->queue;
  if (D.19410 != 0B) goto <D.19411>; else goto <D.19412>;
  <D.19411>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19413>; else goto <D.19414>;
    <D.19413>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19414>:
    D.19415 = ret != 0;
    D.19416 = (long int) D.19415;
    D.19417 = __builtin_expect (D.19416, 0);
    if (D.19417 != 0) goto <D.19418>; else goto <D.19419>;
    <D.19418>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1432, "ret == 0");
    <D.19419>:
  }
  reference_queue_proccess (queue);
  goto restart;
  <D.19412>:
  D.19420 = queue->next;
  *iter = D.19420;
  monoeg_g_free (queue);
  <D.18613>:
  D.19421 = *iter;
  if (D.19421 != 0B) goto <D.18615>; else goto <D.18616>;
  <D.18616>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19422>; else goto <D.19423>;
    <D.19422>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19423>:
    D.19424 = ret != 0;
    D.19425 = (long int) D.19424;
    D.19426 = __builtin_expect (D.19425, 0);
    if (D.19426 != 0) goto <D.19427>; else goto <D.19428>;
    <D.19427>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1439, "ret == 0");
    <D.19428>:
  }
}


reference_queue_proccess (struct MonoReferenceQueue * queue)
{
  int D.19432;
  void * * D.19434;
  struct MonoObject * D.19435;
  void (*<Tbf>) (void *) D.19436;
  void * D.19437;
  struct RefQueueEntry * * iter;
  struct RefQueueEntry * entry;

  iter = &queue->queue;
  goto <D.18601>;
  <D.18600>:
  D.19432 = queue->should_be_deleted;
  if (D.19432 != 0) goto <D.19429>; else goto <D.19433>;
  <D.19433>:
  D.19434 = &entry->dis_link;
  D.19435 = mono_gc_weak_link_get (D.19434);
  if (D.19435 == 0B) goto <D.19429>; else goto <D.19430>;
  <D.19429>:
  D.19434 = &entry->dis_link;
  mono_gc_weak_link_remove (D.19434, 1);
  ref_list_remove_element (iter, entry);
  D.19436 = queue->callback;
  D.19437 = entry->user_data;
  D.19436 (D.19437);
  monoeg_g_free (entry);
  goto <D.19431>;
  <D.19430>:
  iter = &entry->next;
  <D.19431>:
  <D.18601>:
  entry = *iter;
  if (entry != 0B) goto <D.18600>; else goto <D.18602>;
  <D.18602>:
}


mono_gc_cleanup ()
{
  int gc_disabled.45;
  void * shutdown_event.46;
  struct MonoInternalThread * D.19442;
  struct MonoInternalThread * gc_thread.47;
  unsigned int D.19446;
  void * D.19449;
  unsigned int D.19450;
  unsigned int D.19455;
  _Bool D.19456;
  long int D.19457;
  long int D.19458;
  long long unsigned int D.19461;
  long unsigned int D.19462;

  gc_disabled.45 = gc_disabled;
  if (gc_disabled.45 == 0) goto <D.19439>; else goto <D.19440>;
  <D.19439>:
  shutdown_event.46 = shutdown_event;
  ResetEvent (shutdown_event.46);
  finished = 1;
  D.19442 = mono_thread_internal_current ();
  gc_thread.47 = gc_thread;
  if (D.19442 != gc_thread.47) goto <D.19444>; else goto <D.19445>;
  <D.19444>:
  mono_gc_finalize_notify ();
  shutdown_event.46 = shutdown_event;
  D.19446 = WaitForSingleObjectEx (shutdown_event.46, 2000, 0);
  if (D.19446 == 258) goto <D.19447>; else goto <D.19448>;
  <D.19447>:
  {
    int ret;

    suspend_finalizers = 1;
    gc_thread.47 = gc_thread;
    mono_thread_internal_stop (gc_thread.47);
    gc_thread.47 = gc_thread;
    D.19449 = gc_thread.47->handle;
    D.19450 = WaitForSingleObjectEx (D.19449, 100, 1);
    ret = (int) D.19450;
    if (ret == 258) goto <D.19451>; else goto <D.19452>;
    <D.19451>:
    monoeg_g_log (0B, 16, "Shutting down finalizer thread timed out.");
    goto <D.19453>;
    <D.19452>:
    Sleep (100);
    <D.19453>:
  }
  goto <D.19454>;
  <D.19448>:
  {
    int ret;

    gc_thread.47 = gc_thread;
    D.19449 = gc_thread.47->handle;
    D.19455 = WaitForSingleObjectEx (D.19449, 4294967295, 1);
    ret = (int) D.19455;
    D.19456 = ret != 0;
    D.19457 = (long int) D.19456;
    D.19458 = __builtin_expect (D.19457, 0);
    if (D.19458 != 0) goto <D.19459>; else goto <D.19460>;
    <D.19459>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1208, "ret == WAIT_OBJECT_0");
    <D.19460>:
    gc_thread.47 = gc_thread;
    D.19461 = gc_thread.47->tid;
    D.19462 = (long unsigned int) D.19461;
    ret = pthread_join (D.19462, 0B);
    D.19456 = ret != 0;
    D.19457 = (long int) D.19456;
    D.19458 = __builtin_expect (D.19457, 0);
    if (D.19458 != 0) goto <D.19463>; else goto <D.19464>;
    <D.19463>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1216, "ret == 0");
    <D.19464>:
  }
  <D.19454>:
  <D.19445>:
  gc_thread = 0B;
  <D.19440>:
  mono_reference_queue_cleanup ();
  DeleteCriticalSection (&handle_section);
  DeleteCriticalSection (&allocator_section);
  DeleteCriticalSection (&finalizer_mutex);
  DeleteCriticalSection (&reference_queue_mutex);
}


mono_reference_queue_cleanup ()
{
  struct MonoReferenceQueue * queue;

  queue = ref_queues;
  goto <D.18623>;
  <D.18622>:
  queue->should_be_deleted = 1;
  queue = queue->next;
  <D.18623>:
  if (queue != 0B) goto <D.18622>; else goto <D.18624>;
  <D.18624>:
  reference_queue_proccess_all ();
}


mono_gc_is_finalizer_internal_thread (struct MonoInternalThread * thread)
{
  gboolean D.19465;
  struct MonoInternalThread * gc_thread.48;
  _Bool D.19467;

  gc_thread.48 = gc_thread;
  D.19467 = thread == gc_thread.48;
  D.19465 = (gboolean) D.19467;
  return D.19465;
}


mono_gc_is_finalizer_thread (struct MonoThread * thread)
{
  gboolean D.19469;
  struct _MonoInternalThread * D.19470;

  D.19470 = thread->internal_thread;
  D.19469 = mono_gc_is_finalizer_internal_thread (D.19470);
  return D.19469;
}


mono_gc_parse_environment_string_extract_number (const char * str, glong * out)
{
  unsigned int D.19472;
  gboolean D.19475;
  sizetype len.49;
  sizetype D.19477;
  const char * D.19478;
  int D.19479;
  const short unsigned int * * D.19480;
  const short unsigned int * D.19481;
  unsigned int D.19482;
  unsigned int D.19483;
  const short unsigned int * D.19484;
  short unsigned int D.19485;
  int D.19486;
  int D.19487;
  int * D.19490;
  int D.19495;
  unsigned int val.50;
  unsigned int D.19498;
  char * endptr.51;
  char * D.19505;
  char D.19506;
  long unsigned int val.52;
  long unsigned int D.19512;
  char * endptr;
  int len;
  int shift;
  glong val;
  gboolean is_suffix;
  char suffix;

  try
    {
      D.19472 = strlen (str);
      len = (int) D.19472;
      shift = 0;
      is_suffix = 0;
      if (len == 0) goto <D.19473>; else goto <D.19474>;
      <D.19473>:
      D.19475 = 0;
      return D.19475;
      <D.19474>:
      len.49 = (sizetype) len;
      D.19477 = len.49 + 4294967295;
      D.19478 = str + D.19477;
      suffix = *D.19478;
      D.19479 = (int) suffix;
      switch (D.19479) <default: <D.18576>, case 71: <D.18570>, case 75: <D.18574>, case 77: <D.18572>, case 103: <D.18569>, case 107: <D.18573>, case 109: <D.18571>>
      <D.18569>:
      <D.18570>:
      shift = shift + 10;
      <D.18571>:
      <D.18572>:
      shift = shift + 10;
      <D.18573>:
      <D.18574>:
      shift = shift + 10;
      is_suffix = 1;
      goto <D.18575>;
      <D.18576>:
      D.19480 = __ctype_b_loc ();
      D.19481 = *D.19480;
      D.19482 = (unsigned int) suffix;
      D.19483 = D.19482 * 2;
      D.19484 = D.19481 + D.19483;
      D.19485 = *D.19484;
      D.19486 = (int) D.19485;
      D.19487 = D.19486 & 2048;
      if (D.19487 == 0) goto <D.19488>; else goto <D.19489>;
      <D.19488>:
      D.19475 = 0;
      return D.19475;
      <D.19489>:
      goto <D.18575>;
      <D.18575>:
      D.19490 = __errno_location ();
      *D.19490 = 0;
      val = strtol (str, &endptr, 10);
      D.19490 = __errno_location ();
      D.19495 = *D.19490;
      if (D.19495 == 34) goto <D.19496>; else goto <D.19491>;
      <D.19496>:
      val.50 = (unsigned int) val;
      D.19498 = val.50 + 2147483647;
      if (D.19498 > 4294967293) goto <D.19492>; else goto <D.19491>;
      <D.19491>:
      D.19490 = __errno_location ();
      D.19495 = *D.19490;
      if (D.19495 != 0) goto <D.19499>; else goto <D.19493>;
      <D.19499>:
      if (val == 0) goto <D.19492>; else goto <D.19493>;
      <D.19493>:
      endptr.51 = endptr;
      if (endptr.51 == str) goto <D.19492>; else goto <D.19494>;
      <D.19492>:
      D.19475 = 0;
      return D.19475;
      <D.19494>:
      if (is_suffix != 0) goto <D.19501>; else goto <D.19502>;
      <D.19501>:
      {
        gulong unshifted;

        if (val < 0) goto <D.19503>; else goto <D.19504>;
        <D.19503>:
        D.19475 = 0;
        return D.19475;
        <D.19504>:
        endptr.51 = endptr;
        D.19505 = endptr.51 + 1;
        D.19506 = *D.19505;
        if (D.19506 != 0) goto <D.19507>; else goto <D.19508>;
        <D.19507>:
        D.19475 = 0;
        return D.19475;
        <D.19508>:
        unshifted = (gulong) val;
        val = val << shift;
        if (val < 0) goto <D.19509>; else goto <D.19510>;
        <D.19509>:
        D.19475 = 0;
        return D.19475;
        <D.19510>:
        val.52 = (long unsigned int) val;
        D.19512 = val.52 >> shift;
        if (D.19512 != unshifted) goto <D.19513>; else goto <D.19514>;
        <D.19513>:
        D.19475 = 0;
        return D.19475;
        <D.19514>:
      }
      <D.19502>:
      *out = val;
      D.19475 = 1;
      return D.19475;
    }
  finally
    {
      endptr = {CLOBBER};
    }
}


mono_gc_reference_queue_new (void (*mono_reference_queue_callback) (void *) callback)
{
  _Bool D.19519;
  long int D.19520;
  long int D.19521;
  struct MonoReferenceQueue * ref_queues.53;
  _Bool D.19527;
  long int D.19528;
  long int D.19529;
  struct MonoReferenceQueue * D.19532;
  struct MonoReferenceQueue * res;

  res = monoeg_malloc0 (16);
  res->callback = callback;
  {
    int ret;

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19517>; else goto <D.19518>;
    <D.19517>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19518>:
    D.19519 = ret != 0;
    D.19520 = (long int) D.19519;
    D.19521 = __builtin_expect (D.19520, 0);
    if (D.19521 != 0) goto <D.19522>; else goto <D.19523>;
    <D.19522>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1497, "ret == 0");
    <D.19523>:
  }
  ref_queues.53 = ref_queues;
  res->next = ref_queues.53;
  ref_queues = res;
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19525>; else goto <D.19526>;
    <D.19525>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19526>:
    D.19527 = ret != 0;
    D.19528 = (long int) D.19527;
    D.19529 = __builtin_expect (D.19528, 0);
    if (D.19529 != 0) goto <D.19530>; else goto <D.19531>;
    <D.19530>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1500, "ret == 0");
    <D.19531>:
  }
  D.19532 = res;
  return D.19532;
}


mono_gc_reference_queue_add (struct MonoReferenceQueue * queue, struct MonoObject * obj, void * user_data)
{
  int D.19534;
  mono_bool D.19537;
  struct MonoVTable * D.19538;
  struct MonoDomain * D.19539;
  void * * D.19540;
  struct RefQueueEntry * * D.19541;
  struct RefQueueEntry * entry;

  D.19534 = queue->should_be_deleted;
  if (D.19534 != 0) goto <D.19535>; else goto <D.19536>;
  <D.19535>:
  D.19537 = 0;
  return D.19537;
  <D.19536>:
  entry = monoeg_malloc0 (20);
  entry->user_data = user_data;
  D.19538 = obj->vtable;
  D.19539 = D.19538->domain;
  entry->domain = D.19539;
  D.19540 = &entry->dis_link;
  mono_gc_weak_link_add (D.19540, obj, 1);
  D.19541 = &queue->queue;
  ref_list_push (D.19541, entry);
  D.19537 = 1;
  return D.19537;
}


ref_list_push (struct RefQueueEntry * * head, struct RefQueueEntry * value)
{
  void * D.19543;
  struct RefQueueEntry * current;

  <D.18593>:
  current = *head;
  value->next = current;
  D.19543 = InterlockedCompareExchangePointer (head, value, current);
  if (D.19543 != current) goto <D.18593>; else goto <D.18594>;
  <D.18594>:
}


mono_gc_reference_queue_free (struct MonoReferenceQueue * queue)
{
  queue->should_be_deleted = 1;
}


