mono_gc_run_finalize (void * obj, void * data)
{
  sizetype data.0;
  int suspend_finalizers.1;
  struct MonoVTable * D.18637;
  struct MonoClass * D.18638;
  struct MonoClass * D.18639;
  int D.18642;
  unsigned char D.18645;
  int finalizing_root_domain.2;
  struct MonoImage * D.18651;
  struct MonoImage * D.18652;
  int D.18285;
  int iftmp.3;
  int D.18284;
  const char[14] * D.18658;
  unsigned char D.18659;
  int D.18660;
  unsigned char D.18661;
  int D.18662;
  const unsigned char * D.18667;
  unsigned char D.18668;
  int D.18669;
  const unsigned char * D.18670;
  unsigned char D.18671;
  int D.18672;
  const unsigned char * D.18677;
  unsigned char D.18678;
  int D.18679;
  const unsigned char * D.18680;
  unsigned char D.18681;
  int D.18682;
  const unsigned char * D.18687;
  unsigned char D.18688;
  int D.18689;
  const unsigned char * D.18690;
  unsigned char D.18691;
  int D.18692;
  const char * D.18694;
  int D.18699;
  struct MonoDomain * D.18702;
  unsigned int D.18703;
  unsigned int D.18704;
  void * D.18707;
  int D.18710;
  void * D.18715;
  struct MonoClass * D.18718;
  struct MonoMethod * D.18719;
  void * D.18720;
  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.18635>; else goto <D.18636>;
      <D.18635>:
      return;
      <D.18636>:
      D.18637 = o->vtable;
      domain = D.18637->domain;
      object_register_finalizer (obj, 0B);
      D.18637 = o->vtable;
      D.18638 = D.18637->klass;
      D.18639 = mono_defaults.internal_thread_class;
      if (D.18638 == D.18639) goto <D.18640>; else goto <D.18641>;
      <D.18640>:
      {
        struct MonoInternalThread * t;

        t = o;
        D.18642 = mono_gc_is_finalizer_internal_thread (t);
        if (D.18642 != 0) goto <D.18643>; else goto <D.18644>;
        <D.18643>:
        return;
        <D.18644>:
        D.18645 = t->threadpool_thread;
        if (D.18645 != 0) goto <D.18646>; else goto <D.18647>;
        <D.18646>:
        finalizing_root_domain.2 = finalizing_root_domain;
        if (finalizing_root_domain.2 != 0) goto <D.18649>; else goto <D.18650>;
        <D.18649>:
        add_thread_to_finalize (t);
        return;
        <D.18650>:
        <D.18647>:
      }
      <D.18641>:
      D.18637 = o->vtable;
      D.18638 = D.18637->klass;
      D.18651 = D.18638->image;
      D.18652 = mono_defaults.corlib;
      if (D.18651 == D.18652) goto <D.18653>; else goto <D.18654>;
      <D.18653>:
      {
        size_t __s1_len;
        size_t __s2_len;

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

          D.18637 = o->vtable;
          D.18638 = D.18637->klass;
          __s2 = D.18638->name;
          D.18658 = "DynamicMethod";
          D.18659 = MEM[(const unsigned char *)D.18658];
          D.18660 = (int) D.18659;
          D.18661 = *__s2;
          D.18662 = (int) D.18661;
          __result = D.18660 - D.18662;
          {
            if (__s2_len != 0) goto <D.18663>; else goto <D.18664>;
            <D.18663>:
            if (__result == 0) goto <D.18665>; else goto <D.18666>;
            <D.18665>:
            D.18667 = &MEM[(void *)"DynamicMethod" + 1B];
            D.18668 = *D.18667;
            D.18669 = (int) D.18668;
            D.18670 = __s2 + 1;
            D.18671 = *D.18670;
            D.18672 = (int) D.18671;
            __result = D.18669 - D.18672;
            if (__s2_len > 1) goto <D.18673>; else goto <D.18674>;
            <D.18673>:
            if (__result == 0) goto <D.18675>; else goto <D.18676>;
            <D.18675>:
            D.18677 = &MEM[(void *)"DynamicMethod" + 2B];
            D.18678 = *D.18677;
            D.18679 = (int) D.18678;
            D.18680 = __s2 + 2;
            D.18681 = *D.18680;
            D.18682 = (int) D.18681;
            __result = D.18679 - D.18682;
            if (__s2_len > 2) goto <D.18683>; else goto <D.18684>;
            <D.18683>:
            if (__result == 0) goto <D.18685>; else goto <D.18686>;
            <D.18685>:
            D.18687 = &MEM[(void *)"DynamicMethod" + 3B];
            D.18688 = *D.18687;
            D.18689 = (int) D.18688;
            D.18690 = __s2 + 3;
            D.18691 = *D.18690;
            D.18692 = (int) D.18691;
            __result = D.18689 - D.18692;
            <D.18686>:
            <D.18684>:
            <D.18676>:
            <D.18674>:
            <D.18666>:
            <D.18664>:
          }
          D.18284 = __result;
        }
        iftmp.3 = -D.18284;
        goto <D.18693>;
        <D.18657>:
        D.18637 = o->vtable;
        D.18638 = D.18637->klass;
        D.18694 = D.18638->name;
        iftmp.3 = __builtin_strcmp (D.18694, "DynamicMethod");
        <D.18693>:
        D.18285 = iftmp.3;
      }
      if (D.18285 == 0) goto <D.18695>; else goto <D.18696>;
      <D.18695>:
      finalizing_root_domain.2 = finalizing_root_domain;
      if (finalizing_root_domain.2 != 0) goto <D.18697>; else goto <D.18698>;
      <D.18697>:
      return;
      <D.18698>:
      <D.18696>:
      <D.18654>:
      D.18699 = mono_runtime_get_no_exec ();
      if (D.18699 != 0) goto <D.18700>; else goto <D.18701>;
      <D.18700>:
      return;
      <D.18701>:
      D.18637 = o->vtable;
      D.18702 = D.18637->domain;
      mono_domain_set_internal (D.18702);
      D.18637 = o->vtable;
      D.18638 = D.18637->klass;
      D.18703 = BIT_FIELD_REF <*D.18638, 32, 160>;
      D.18704 = D.18703 & 16777216;
      if (D.18704 != 0) goto <D.18705>; else goto <D.18706>;
      <D.18705>:
      {
        struct MonoDelegate * del;

        del = o;
        D.18707 = del->delegate_trampoline;
        if (D.18707 != 0B) goto <D.18708>; else goto <D.18709>;
        <D.18708>:
        mono_delegate_free_ftnptr (o);
        <D.18709>:
        mono_domain_set_internal (caller_domain);
        return;
      }
      <D.18706>:
      D.18637 = o->vtable;
      D.18638 = D.18637->klass;
      finalizer = mono_class_get_finalizer (D.18638);
      D.18710 = mono_marshal_free_ccw (o);
      if (D.18710 != 0) goto <D.18711>; else goto <D.18712>;
      <D.18711>:
      if (finalizer == 0B) goto <D.18713>; else goto <D.18714>;
      <D.18713>:
      mono_domain_set_internal (caller_domain);
      return;
      <D.18714>:
      <D.18712>:
      D.18715 = domain->finalize_runtime_invoke;
      if (D.18715 == 0B) goto <D.18716>; else goto <D.18717>;
      <D.18716>:
      {
        struct MonoMethod * invoke;

        D.18718 = mono_defaults.object_class;
        D.18719 = mono_class_get_method_from_name_flags (D.18718, "Finalize", 0, 0);
        invoke = mono_marshal_get_runtime_invoke (D.18719, 1);
        D.18720 = mono_compile_method (invoke);
        domain->finalize_runtime_invoke = D.18720;
      }
      <D.18717>:
      D.18715 = domain->finalize_runtime_invoke;
      runtime_invoke = (struct MonoObject * (*RuntimeInvokeFunction) (struct MonoObject *, void * *, struct MonoObject * *, void *)) D.18715;
      D.18637 = o->vtable;
      mono_runtime_class_init (D.18637);
      if (0 != 0) goto <D.18721>; else goto <D.18722>;
      <D.18721>:
      <D.18722>:
      runtime_invoke (o, 0B, &exc, 0B);
      exc.4 = exc;
      if (exc.4 != 0B) goto <D.18724>; else goto <D.18725>;
      <D.18724>:
      exc.4 = exc;
      mono_internal_thread_unhandled_exception (exc.4);
      <D.18725>:
      mono_domain_set_internal (caller_domain);
    }
  finally
    {
      exc = {CLOBBER};
    }
}


object_register_finalizer (struct MonoObject * obj, void (*<T103>) (void *, void *) callback)
{
  struct MonoException * D.18731;
  struct MonoVTable * D.18732;
  int D.18733;
  struct MonoDomain * domain;

  if (obj == 0B) goto <D.18729>; else goto <D.18730>;
  <D.18729>:
  D.18731 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18731);
  <D.18730>:
  D.18732 = obj->vtable;
  domain = D.18732->domain;
  D.18733 = mono_domain_is_unloading (domain);
  if (D.18733 == 0) goto <D.18734>; else goto <D.18735>;
  <D.18734>:
  mono_gc_register_for_finalization (obj, callback);
  <D.18735>:
}


add_thread_to_finalize (struct MonoInternalThread * thread)
{
  _Bool D.18738;
  long int D.18739;
  long int D.18740;
  struct MonoMList * threads_to_finalize.5;
  void * D.18748;
  struct MonoMList * threads_to_finalize.6;
  _Bool D.18752;
  long int D.18753;
  long int D.18754;

  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18736>; else goto <D.18737>;
    <D.18736>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18737>:
    D.18738 = ret != 0;
    D.18739 = (long int) D.18738;
    D.18740 = __builtin_expect (D.18739, 0);
    if (D.18740 != 0) goto <D.18741>; else goto <D.18742>;
    <D.18741>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 88, "ret == 0");
    <D.18742>:
  }
  threads_to_finalize.5 = threads_to_finalize;
  if (threads_to_finalize.5 == 0B) goto <D.18744>; else goto <D.18745>;
  <D.18744>:
  if (0 != 0) goto <D.18746>; else goto <D.18747>;
  <D.18746>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 90, "sizeof (threads_to_finalize) == sizeof (MonoObject*)");
  <D.18747>:
  D.18748 = mono_gc_make_root_descr_all_refs (1);
  mono_gc_register_root (&threads_to_finalize, 4, D.18748);
  <D.18745>:
  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.18750>; else goto <D.18751>;
    <D.18750>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18751>:
    D.18752 = ret != 0;
    D.18753 = (long int) D.18752;
    D.18754 = __builtin_expect (D.18753, 0);
    if (D.18754 != 0) goto <D.18755>; else goto <D.18756>;
    <D.18755>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 92, "ret == 0");
    <D.18756>:
  }
}


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

  goto <D.18293>;
  <D.18292>:
  {
    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.18293>:
  threads_to_finalize.7 = threads_to_finalize;
  if (threads_to_finalize.7 != 0B) goto <D.18292>; else goto <D.18294>;
  <D.18294>:
}


mono_gc_out_of_memory (size_t size)
{
  struct MonoDomain * D.18759;
  struct MonoException * D.18760;
  void * D.18761;

  D.18759 = mono_domain_get ();
  D.18760 = D.18759->out_of_memory_ex;
  mono_raise_exception (D.18760);
  D.18761 = 0B;
  return D.18761;
}


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.18763;
  struct MonoInternalThread * gc_thread.9;
  mono_bool D.18767;
  int gc_disabled.10;
  int D.18771;
  struct MonoDomain * D.18774;
  _Bool D.18779;
  long int D.18780;
  long int D.18781;
  struct GSList * domains_to_finalize.11;
  struct GSList * domains_to_finalize.12;
  _Bool D.18788;
  long int D.18789;
  long int D.18790;
  unsigned int D.18797;
  unsigned int D.18798;
  struct MonoDomain * D.18803;
  struct DomainFinalizationReq * req;
  guint32 res;
  void * done_event;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.18763 = mono_thread_internal_current ();
  gc_thread.9 = gc_thread;
  if (D.18763 == gc_thread.9) goto <D.18765>; else goto <D.18766>;
  <D.18765>:
  D.18767 = 0;
  return D.18767;
  <D.18766>:
  gc_disabled.10 = gc_disabled;
  if (gc_disabled.10 != 0) goto <D.18769>; else goto <D.18770>;
  <D.18769>:
  D.18767 = 1;
  return D.18767;
  <D.18770>:
  D.18771 = mono_gc_max_generation ();
  mono_gc_collect (D.18771);
  done_event = CreateEvent (0B, 1, 0, 0B);
  if (done_event == 0B) goto <D.18772>; else goto <D.18773>;
  <D.18772>:
  D.18767 = 0;
  return D.18767;
  <D.18773>:
  req = monoeg_malloc0 (8);
  req->domain = domain;
  req->done_event = done_event;
  D.18774 = mono_get_root_domain ();
  if (D.18774 == domain) goto <D.18775>; else goto <D.18776>;
  <D.18775>:
  finalizing_root_domain = 1;
  <D.18776>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.18777>; else goto <D.18778>;
    <D.18777>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18778>:
    D.18779 = ret != 0;
    D.18780 = (long int) D.18779;
    D.18781 = __builtin_expect (D.18780, 0);
    if (D.18781 != 0) goto <D.18782>; else goto <D.18783>;
    <D.18782>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 367, "ret == 0");
    <D.18783>:
  }
  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.18786>; else goto <D.18787>;
    <D.18786>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18787>:
    D.18788 = ret != 0;
    D.18789 = (long int) D.18788;
    D.18790 = __builtin_expect (D.18789, 0);
    if (D.18790 != 0) goto <D.18791>; else goto <D.18792>;
    <D.18791>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 371, "ret == 0");
    <D.18792>:
  }
  mono_gc_finalize_notify ();
  if (timeout == 4294967295) goto <D.18793>; else goto <D.18794>;
  <D.18793>:
  timeout = 4294967295;
  <D.18794>:
  <D.18319>:
  res = WaitForSingleObjectEx (done_event, timeout, 1);
  if (res == 192) goto <D.18795>; else goto <D.18796>;
  <D.18795>:
  D.18797 = thread->state;
  D.18798 = D.18797 & 3;
  if (D.18798 != 0) goto <D.18799>; else goto <D.18800>;
  <D.18799>:
  D.18767 = 0;
  return D.18767;
  <D.18800>:
  goto <D.18801>;
  <D.18796>:
  if (res == 258) goto <D.18802>; else goto <D.18318>;
  <D.18802>:
  D.18767 = 0;
  return D.18767;
  <D.18801>:
  goto <D.18319>;
  <D.18318>:
  CloseHandle (done_event);
  D.18803 = mono_get_root_domain ();
  if (D.18803 == domain) goto <D.18804>; else goto <D.18805>;
  <D.18804>:
  mono_thread_pool_cleanup ();
  mono_gc_finalize_threadpool_threads ();
  <D.18805>:
  D.18767 = 1;
  return D.18767;
}


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


ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
{
  int D.18809;
  gint64 D.18810;

  if (forceCollection != 0) goto <D.18807>; else goto <D.18808>;
  <D.18807>:
  D.18809 = mono_gc_max_generation ();
  mono_gc_collect (D.18809);
  <D.18808>:
  D.18810 = mono_gc_get_used_size ();
  return D.18810;
}


ves_icall_System_GC_KeepAlive (struct MonoObject * obj)
{

}


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

  if (obj == 0B) goto <D.18812>; else goto <D.18813>;
  <D.18812>:
  D.18814 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18814);
  <D.18813>:
  object_register_finalizer (obj, mono_gc_run_finalize);
}


ves_icall_System_GC_SuppressFinalize (struct MonoObject * obj)
{
  struct MonoException * D.18817;
  struct MonoVTable * D.18818;
  struct MonoClass * D.18819;
  unsigned int D.18820;
  unsigned int D.18821;

  if (obj == 0B) goto <D.18815>; else goto <D.18816>;
  <D.18815>:
  D.18817 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18817);
  <D.18816>:
  D.18818 = obj->vtable;
  D.18819 = D.18818->klass;
  D.18820 = BIT_FIELD_REF <*D.18819, 32, 160>;
  D.18821 = D.18820 & 16777216;
  if (D.18821 != 0) goto <D.18822>; else goto <D.18823>;
  <D.18822>:
  return;
  <D.18823>:
  object_register_finalizer (obj, 0B);
}


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

  D.18825 = mono_gc_pending_finalizers ();
  if (D.18825 == 0) goto <D.18826>; else goto <D.18827>;
  <D.18826>:
  return;
  <D.18827>:
  D.18828 = mono_thread_internal_current ();
  gc_thread.13 = gc_thread;
  if (D.18828 == gc_thread.13) goto <D.18830>; else goto <D.18831>;
  <D.18830>:
  return;
  <D.18831>:
  gc_thread.13 = gc_thread;
  if (gc_thread.13 == 0B) goto <D.18832>; else goto <D.18833>;
  <D.18832>:
  return;
  <D.18833>:
  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.18836;
  struct MonoVTable * D.18839;
  struct MonoDomain * D.18840;
  struct MonoException * D.18841;

  D.18836 = mono_gc_ephemeron_array_add (array);
  if (D.18836 == 0) goto <D.18837>; else goto <D.18838>;
  <D.18837>:
  D.18839 = array->vtable;
  D.18840 = D.18839->domain;
  D.18841 = D.18840->out_of_memory_ex;
  mono_raise_exception (D.18841);
  <D.18838>:
}


ves_icall_System_GC_get_ephemeron_tombstone ()
{
  struct MonoObject * D.18842;
  struct MonoDomain * D.18843;

  D.18843 = mono_domain_get ();
  D.18842 = D.18843->ephemeron_tombstone;
  return D.18842;
}


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

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


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

  if (type == -1) goto <D.18847>; else goto <D.18848>;
  <D.18847>:
  mono_gchandle_set_target (handle, obj);
  D.18849 = handle;
  return D.18849;
  <D.18848>:
  switch (type) <default: <D.18366>, case 0: <D.18362>, case 1: <D.18363>, case 2: <D.18364>, case 3: <D.18365>>
  <D.18362>:
  D.18849 = mono_gchandle_new_weakref (obj, 0);
  return D.18849;
  <D.18363>:
  D.18849 = mono_gchandle_new_weakref (obj, 1);
  return D.18849;
  <D.18364>:
  D.18849 = mono_gchandle_new (obj, 0);
  return D.18849;
  <D.18365>:
  D.18849 = mono_gchandle_new (obj, 1);
  return D.18849;
  <D.18366>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 545);
  D.18849 = 0;
  return D.18849;
}


mono_gchandle_set_target (guint32 gchandle, struct MonoObject * obj)
{
  unsigned int D.18851;
  _Bool D.18856;
  long int D.18857;
  long int D.18858;
  unsigned int D.18861;
  guint32 * D.18864;
  unsigned int D.18865;
  unsigned int D.18866;
  guint32 * D.18867;
  unsigned int D.18868;
  int slot.15;
  int D.18870;
  int D.18871;
  unsigned int D.18872;
  unsigned int D.18873;
  unsigned char D.18876;
  void * * D.18879;
  unsigned int D.18880;
  void * * D.18881;
  void * D.18882;
  void * * D.18885;
  _Bool D.18886;
  int D.18887;
  guint16 * D.18890;
  unsigned int D.18891;
  guint16 * D.18892;
  struct MonoDomain * iftmp.16;
  int D.18897;
  short unsigned int D.18898;
  _Bool D.18903;
  long int D.18904;
  long int D.18905;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * old_obj;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.18854>; else goto <D.18855>;
    <D.18854>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18855>:
    D.18856 = ret != 0;
    D.18857 = (long int) D.18856;
    D.18858 = __builtin_expect (D.18857, 0);
    if (D.18858 != 0) goto <D.18859>; else goto <D.18860>;
    <D.18859>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 834, "ret == 0");
    <D.18860>:
  }
  D.18861 = handles->size;
  if (D.18861 > slot) goto <D.18862>; else goto <D.18863>;
  <D.18862>:
  D.18864 = handles->bitmap;
  D.18865 = slot / 32;
  D.18866 = D.18865 * 4;
  D.18867 = D.18864 + D.18866;
  D.18868 = *D.18867;
  slot.15 = (int) slot;
  D.18870 = slot.15 & 31;
  D.18871 = 1 << D.18870;
  D.18872 = (unsigned int) D.18871;
  D.18873 = D.18868 & D.18872;
  if (D.18873 != 0) goto <D.18874>; else goto <D.18875>;
  <D.18874>:
  D.18876 = handles->type;
  if (D.18876 <= 1) goto <D.18877>; else goto <D.18878>;
  <D.18877>:
  D.18879 = handles->entries;
  D.18880 = slot * 4;
  D.18881 = D.18879 + D.18880;
  old_obj = *D.18881;
  D.18879 = handles->entries;
  D.18880 = slot * 4;
  D.18881 = D.18879 + D.18880;
  D.18882 = *D.18881;
  if (D.18882 != 0B) goto <D.18883>; else goto <D.18884>;
  <D.18883>:
  D.18879 = handles->entries;
  D.18880 = slot * 4;
  D.18885 = D.18879 + D.18880;
  D.18876 = handles->type;
  D.18886 = D.18876 == 1;
  D.18887 = (int) D.18886;
  mono_gc_weak_link_remove (D.18885, D.18887);
  <D.18884>:
  if (obj != 0B) goto <D.18888>; else goto <D.18889>;
  <D.18888>:
  D.18879 = handles->entries;
  D.18880 = slot * 4;
  D.18885 = D.18879 + D.18880;
  D.18876 = handles->type;
  D.18886 = D.18876 == 1;
  D.18887 = (int) D.18886;
  mono_gc_weak_link_add (D.18885, obj, D.18887);
  <D.18889>:
  D.18890 = handles->domain_ids;
  D.18891 = slot * 2;
  D.18892 = D.18890 + D.18891;
  if (obj != 0B) goto <D.18894>; else goto <D.18895>;
  <D.18894>:
  iftmp.16 = mono_object_get_domain (obj);
  goto <D.18896>;
  <D.18895>:
  iftmp.16 = mono_domain_get ();
  <D.18896>:
  D.18897 = iftmp.16->domain_id;
  D.18898 = (short unsigned int) D.18897;
  *D.18892 = D.18898;
  goto <D.18899>;
  <D.18878>:
  D.18879 = handles->entries;
  D.18880 = slot * 4;
  D.18881 = D.18879 + D.18880;
  *D.18881 = obj;
  <D.18899>:
  goto <D.18900>;
  <D.18875>:
  <D.18900>:
  <D.18863>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.18901>; else goto <D.18902>;
    <D.18901>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18902>:
    D.18903 = ret != 0;
    D.18904 = (long int) D.18903;
    D.18905 = __builtin_expect (D.18904, 0);
    if (D.18905 != 0) goto <D.18906>; else goto <D.18907>;
    <D.18906>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 851, "ret == 0");
    <D.18907>:
  }
}


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


ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
{
  <unnamed type> D.18909;
  void * D.18912;
  struct MonoVTable * D.18915;
  struct MonoClass * D.18916;
  unsigned char D.18919;
  unsigned int D.18922;
  unsigned int D.18923;
  struct MonoObject * obj;

  D.18909 = mono_gchandle_get_type (handle);
  if (D.18909 != 3) goto <D.18910>; else goto <D.18911>;
  <D.18910>:
  D.18912 = 4294967294B;
  return D.18912;
  <D.18911>:
  obj = mono_gchandle_get_target (handle);
  if (obj != 0B) goto <D.18913>; else goto <D.18914>;
  <D.18913>:
  {
    struct MonoClass * klass;

    D.18915 = obj->vtable;
    klass = D.18915->klass;
    D.18916 = mono_defaults.string_class;
    if (D.18916 == klass) goto <D.18917>; else goto <D.18918>;
    <D.18917>:
    D.18912 = mono_string_chars (obj);
    return D.18912;
    <D.18918>:
    D.18919 = klass->rank;
    if (D.18919 != 0) goto <D.18920>; else goto <D.18921>;
    <D.18920>:
    D.18912 = mono_array_addr_with_size (obj, 1, 0);
    return D.18912;
    <D.18921>:
    D.18922 = klass->flags;
    D.18923 = D.18922 & 24;
    if (D.18923 == 0) goto <D.18924>; else goto <D.18925>;
    <D.18924>:
    D.18912 = 4294967295B;
    return D.18912;
    <D.18925>:
    D.18912 = obj + 8;
    return D.18912;
  }
  <D.18914>:
  D.18912 = 0B;
  return D.18912;
}


mono_gchandle_get_type (guint32 gchandle)
{
  unsigned int D.18927;
  HandleType D.18928;
  guint type;

  D.18927 = gchandle & 7;
  type = D.18927 + 4294967295;
  D.18928 = type;
  return D.18928;
}


ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
{
  MonoBoolean D.18930;
  int D.18931;
  int D.18932;

  D.18931 = (int) flag;
  D.18932 = mono_gc_set_allow_synchronous_major (D.18931);
  D.18930 = (MonoBoolean) D.18932;
  return D.18930;
}


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

  if (pinned != 0) goto <D.18936>; else goto <D.18937>;
  <D.18936>:
  iftmp.17 = 3;
  goto <D.18938>;
  <D.18937>:
  iftmp.17 = 2;
  <D.18938>:
  D.18939 = &gc_handles[iftmp.17];
  D.18934 = alloc_handle (D.18939, obj, 0);
  return D.18934;
}


alloc_handle (struct HandleData * handles, struct MonoObject * obj, gboolean track)
{
  _Bool D.18943;
  long int D.18944;
  long int D.18945;
  unsigned int D.18948;
  unsigned char D.18951;
  unsigned int D.18954;
  int D.18955;
  _Bool D.18956;
  int D.18957;
  void * D.18958;
  void * D.18959;
  void * D.18961;
  unsigned int D.18962;
  void * D.18963;
  unsigned int D.18964;
  void * D.18965;
  <unnamed-unsigned:24> D.18966;
  guint32 * D.18967;
  unsigned int slot.18;
  unsigned int D.18969;
  guint32 * D.18970;
  unsigned int D.18971;
  <unnamed-unsigned:24> D.18974;
  unsigned int slot.19;
  unsigned int D.18976;
  unsigned int D.18979;
  unsigned int D.18980;
  int D.18985;
  unsigned int D.18988;
  unsigned int D.18991;
  int new_size.20;
  void * D.18993;
  void * * D.18994;
  unsigned int D.18996;
  guint16 * D.18997;
  unsigned int i.21;
  unsigned int D.18999;
  void * * D.19000;
  void * * D.19003;
  void * * D.19005;
  void * D.19006;
  _Bool D.19007;
  long int D.19008;
  long int D.19009;
  unsigned int i.22;
  unsigned int D.19013;
  unsigned int D.19014;
  <unnamed-unsigned:24> D.19015;
  int D.19016;
  unsigned int D.19017;
  unsigned int D.19018;
  int D.19019;
  void * * D.19020;
  unsigned int D.19023;
  guint16 * D.19024;
  struct MonoDomain * iftmp.23;
  int D.19029;
  short unsigned int D.19030;
  void * * D.19033;
  struct MonoPerfCounters * mono_perfcounters.24;
  unsigned int D.19036;
  unsigned int D.19037;
  _Bool D.19040;
  long int D.19041;
  long int D.19042;
  int D.19045;
  int D.19046;
  int D.19047;
  int D.19048;
  guint32 D.19049;
  gint slot;
  gint i;
  guint32 res;

  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.18941>; else goto <D.18942>;
    <D.18941>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18942>:
    D.18943 = ret != 0;
    D.18944 = (long int) D.18943;
    D.18945 = __builtin_expect (D.18944, 0);
    if (D.18945 != 0) goto <D.18946>; else goto <D.18947>;
    <D.18946>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 636, "ret == 0");
    <D.18947>:
  }
  D.18948 = handles->size;
  if (D.18948 == 0) goto <D.18949>; else goto <D.18950>;
  <D.18949>:
  handles->size = 32;
  D.18951 = handles->type;
  if (D.18951 > 1) goto <D.18952>; else goto <D.18953>;
  <D.18952>:
  D.18948 = handles->size;
  D.18954 = D.18948 * 4;
  D.18948 = handles->size;
  D.18955 = (int) D.18948;
  D.18951 = handles->type;
  D.18956 = D.18951 == 3;
  D.18957 = (int) D.18956;
  D.18958 = make_root_descr_all_refs (D.18955, D.18957);
  D.18959 = mono_gc_alloc_fixed (D.18954, D.18958);
  handles->entries = D.18959;
  goto <D.18960>;
  <D.18953>:
  D.18948 = handles->size;
  D.18954 = D.18948 * 4;
  D.18961 = monoeg_malloc0 (D.18954);
  handles->entries = D.18961;
  D.18948 = handles->size;
  D.18962 = D.18948 * 2;
  D.18963 = monoeg_malloc0 (D.18962);
  handles->domain_ids = D.18963;
  <D.18960>:
  D.18948 = handles->size;
  D.18964 = D.18948 / 8;
  D.18965 = monoeg_malloc0 (D.18964);
  handles->bitmap = D.18965;
  <D.18950>:
  i = -1;
  D.18966 = handles->slot_hint;
  slot = (gint) D.18966;
  goto <D.18410>;
  <D.18409>:
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18971 = *D.18970;
  if (D.18971 != 4294967295) goto <D.18972>; else goto <D.18973>;
  <D.18972>:
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18971 = *D.18970;
  i = find_first_unset (D.18971);
  slot.18 = (unsigned int) slot;
  D.18974 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.18974;
  goto <D.18408>;
  <D.18973>:
  slot = slot + 1;
  <D.18410>:
  slot.19 = (unsigned int) slot;
  D.18948 = handles->size;
  D.18976 = D.18948 / 32;
  if (slot.19 < D.18976) goto <D.18409>; else goto <D.18408>;
  <D.18408>:
  if (i == -1) goto <D.18977>; else goto <D.18978>;
  <D.18977>:
  D.18979 = BIT_FIELD_REF <*handles, 32, 96>;
  D.18980 = D.18979 & 4294967040;
  if (D.18980 != 0) goto <D.18981>; else goto <D.18982>;
  <D.18981>:
  slot = 0;
  goto <D.18413>;
  <D.18412>:
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18971 = *D.18970;
  if (D.18971 != 4294967295) goto <D.18983>; else goto <D.18984>;
  <D.18983>:
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18971 = *D.18970;
  i = find_first_unset (D.18971);
  slot.18 = (unsigned int) slot;
  D.18974 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.18974;
  goto <D.18411>;
  <D.18984>:
  slot = slot + 1;
  <D.18413>:
  D.18966 = handles->slot_hint;
  D.18985 = (int) D.18966;
  if (D.18985 > slot) goto <D.18412>; else goto <D.18411>;
  <D.18411>:
  <D.18982>:
  <D.18978>:
  if (i == -1) goto <D.18986>; else goto <D.18987>;
  <D.18986>:
  {
    guint32 * new_bitmap;
    guint32 new_size;

    D.18948 = handles->size;
    new_size = D.18948 * 2;
    D.18988 = new_size / 8;
    new_bitmap = monoeg_malloc0 (D.18988);
    D.18967 = handles->bitmap;
    D.18948 = handles->size;
    D.18964 = D.18948 / 8;
    memcpy (new_bitmap, D.18967, D.18964);
    D.18967 = handles->bitmap;
    monoeg_g_free (D.18967);
    handles->bitmap = new_bitmap;
    D.18951 = handles->type;
    if (D.18951 > 1) goto <D.18989>; else goto <D.18990>;
    <D.18989>:
    {
      void * * entries;

      D.18991 = new_size * 4;
      new_size.20 = (int) new_size;
      D.18951 = handles->type;
      D.18956 = D.18951 == 3;
      D.18957 = (int) D.18956;
      D.18993 = make_root_descr_all_refs (new_size.20, D.18957);
      entries = mono_gc_alloc_fixed (D.18991, D.18993);
      D.18994 = handles->entries;
      D.18948 = handles->size;
      D.18954 = D.18948 * 4;
      mono_gc_memmove_aligned (entries, D.18994, D.18954);
      D.18994 = handles->entries;
      mono_gc_free_fixed (D.18994);
      handles->entries = entries;
    }
    goto <D.18995>;
    <D.18990>:
    {
      void * * entries;
      guint16 * domain_ids;

      D.18996 = new_size * 2;
      domain_ids = monoeg_malloc0 (D.18996);
      D.18991 = new_size * 4;
      entries = monoeg_malloc0 (D.18991);
      D.18997 = handles->domain_ids;
      D.18948 = handles->size;
      D.18962 = D.18948 * 2;
      memcpy (domain_ids, D.18997, D.18962);
      i = 0;
      goto <D.18421>;
      <D.18420>:
      {
        struct MonoObject * obj;

        D.18994 = handles->entries;
        i.21 = (unsigned int) i;
        D.18999 = i.21 * 4;
        D.19000 = D.18994 + D.18999;
        obj = mono_gc_weak_link_get (D.19000);
        if (obj != 0B) goto <D.19001>; else goto <D.19002>;
        <D.19001>:
        i.21 = (unsigned int) i;
        D.18999 = i.21 * 4;
        D.19003 = entries + D.18999;
        mono_gc_weak_link_add (D.19003, obj, track);
        D.18994 = handles->entries;
        i.21 = (unsigned int) i;
        D.18999 = i.21 * 4;
        D.19000 = D.18994 + D.18999;
        mono_gc_weak_link_remove (D.19000, track);
        goto <D.19004>;
        <D.19002>:
        D.18994 = handles->entries;
        i.21 = (unsigned int) i;
        D.18999 = i.21 * 4;
        D.19005 = D.18994 + D.18999;
        D.19006 = *D.19005;
        D.19007 = D.19006 != 0B;
        D.19008 = (long int) D.19007;
        D.19009 = __builtin_expect (D.19008, 0);
        if (D.19009 != 0) goto <D.19010>; else goto <D.19011>;
        <D.19010>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 695, "!handles->entries [i]");
        <D.19011>:
        <D.19004>:
      }
      i = i + 1;
      <D.18421>:
      i.22 = (unsigned int) i;
      D.18948 = handles->size;
      if (i.22 < D.18948) goto <D.18420>; else goto <D.18422>;
      <D.18422>:
      D.18994 = handles->entries;
      monoeg_g_free (D.18994);
      D.18997 = handles->domain_ids;
      monoeg_g_free (D.18997);
      handles->entries = entries;
      handles->domain_ids = domain_ids;
    }
    <D.18995>:
    i = 0;
    D.18948 = handles->size;
    D.19013 = D.18948 + 1;
    D.19014 = D.19013 / 32;
    slot = (gint) D.19014;
    D.18948 = handles->size;
    D.19013 = D.18948 + 1;
    D.19015 = (<unnamed-unsigned:24>) D.19013;
    handles->slot_hint = D.19015;
    handles->size = new_size;
  }
  <D.18987>:
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18967 = handles->bitmap;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.18970 = D.18967 + D.18969;
  D.18971 = *D.18970;
  D.19016 = 1 << i;
  D.19017 = (unsigned int) D.19016;
  D.19018 = D.18971 | D.19017;
  *D.18970 = D.19018;
  D.19019 = slot * 32;
  slot = D.19019 + i;
  D.18994 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.19020 = D.18994 + D.18969;
  *D.19020 = 0B;
  D.18951 = handles->type;
  if (D.18951 <= 1) goto <D.19021>; else goto <D.19022>;
  <D.19021>:
  D.18997 = handles->domain_ids;
  slot.18 = (unsigned int) slot;
  D.19023 = slot.18 * 2;
  D.19024 = D.18997 + D.19023;
  if (obj != 0B) goto <D.19026>; else goto <D.19027>;
  <D.19026>:
  iftmp.23 = mono_object_get_domain (obj);
  goto <D.19028>;
  <D.19027>:
  iftmp.23 = mono_domain_get ();
  <D.19028>:
  D.19029 = iftmp.23->domain_id;
  D.19030 = (short unsigned int) D.19029;
  *D.19024 = D.19030;
  if (obj != 0B) goto <D.19031>; else goto <D.19032>;
  <D.19031>:
  D.18994 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.19033 = D.18994 + D.18969;
  mono_gc_weak_link_add (D.19033, obj, track);
  <D.19032>:
  goto <D.19034>;
  <D.19022>:
  D.18994 = handles->entries;
  slot.18 = (unsigned int) slot;
  D.18969 = slot.18 * 4;
  D.19020 = D.18994 + D.18969;
  *D.19020 = obj;
  <D.19034>:
  mono_perfcounters.24 = mono_perfcounters;
  D.19036 = mono_perfcounters.24->gc_num_handles;
  D.19037 = D.19036 + 1;
  mono_perfcounters.24->gc_num_handles = D.19037;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19038>; else goto <D.19039>;
    <D.19038>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19039>:
    D.19040 = ret != 0;
    D.19041 = (long int) D.19040;
    D.19042 = __builtin_expect (D.19041, 0);
    if (D.19042 != 0) goto <D.19043>; else goto <D.19044>;
    <D.19043>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 725, "ret == 0");
    <D.19044>:
  }
  D.19045 = slot << 3;
  D.18951 = handles->type;
  D.19046 = (int) D.18951;
  D.19047 = D.19046 + 1;
  D.19048 = D.19045 | D.19047;
  res = (guint32) D.19048;
  D.18951 = handles->type;
  D.19046 = (int) D.18951;
  mono_profiler_gc_handle (0, D.19046, res, obj);
  D.19049 = res;
  return D.19049;
}


find_first_unset (guint32 bitmap)
{
  int D.19051;
  unsigned int D.19052;
  unsigned int D.19053;
  int D.19056;
  int i;

  i = 0;
  goto <D.18393>;
  <D.18392>:
  D.19051 = 1 << i;
  D.19052 = (unsigned int) D.19051;
  D.19053 = D.19052 & bitmap;
  if (D.19053 == 0) goto <D.19054>; else goto <D.19055>;
  <D.19054>:
  D.19056 = i;
  return D.19056;
  <D.19055>:
  i = i + 1;
  <D.18393>:
  if (i <= 31) goto <D.18392>; else goto <D.18394>;
  <D.18394>:
  D.19056 = -1;
  return D.19056;
}


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

  if (pinned != 0) goto <D.19058>; else goto <D.19059>;
  <D.19058>:
  D.19060 = 0B;
  return D.19060;
  <D.19059>:
  D.19060 = mono_gc_make_root_descr_all_refs (numbits);
  return D.19060;
}


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

  D.19063 = __builtin_object_size (__dest, 0);
  D.19062 = __builtin___memcpy_chk (__dest, __src, __len, D.19063);
  return D.19062;
}


mono_gchandle_new_weakref (struct MonoObject * obj, gboolean track_resurrection)
{
  _Bool D.19065;
  int D.19066;
  struct HandleData * D.19067;
  uint32_t D.19068;
  guint32 handle;

  D.19065 = track_resurrection != 0;
  D.19066 = (int) D.19065;
  D.19067 = &gc_handles[D.19066];
  handle = alloc_handle (D.19067, obj, track_resurrection);
  D.19068 = handle;
  return D.19068;
}


mono_gchandle_get_target (guint32 gchandle)
{
  unsigned int D.19070;
  struct MonoObject * D.19073;
  _Bool D.19076;
  long int D.19077;
  long int D.19078;
  unsigned int D.19081;
  guint32 * D.19084;
  unsigned int D.19085;
  unsigned int D.19086;
  guint32 * D.19087;
  unsigned int D.19088;
  int slot.25;
  int D.19090;
  int D.19091;
  unsigned int D.19092;
  unsigned int D.19093;
  unsigned char D.19096;
  void * * D.19099;
  unsigned int D.19100;
  void * * D.19101;
  void * * D.19103;
  _Bool D.19107;
  long int D.19108;
  long int D.19109;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * obj;

  slot = gchandle >> 3;
  D.19070 = gchandle & 7;
  type = D.19070 + 4294967295;
  handles = &gc_handles[type];
  obj = 0B;
  if (type > 3) goto <D.19071>; else goto <D.19072>;
  <D.19071>:
  D.19073 = 0B;
  return D.19073;
  <D.19072>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19074>; else goto <D.19075>;
    <D.19074>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19075>:
    D.19076 = ret != 0;
    D.19077 = (long int) D.19076;
    D.19078 = __builtin_expect (D.19077, 0);
    if (D.19078 != 0) goto <D.19079>; else goto <D.19080>;
    <D.19079>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 809, "ret == 0");
    <D.19080>:
  }
  D.19081 = handles->size;
  if (D.19081 > slot) goto <D.19082>; else goto <D.19083>;
  <D.19082>:
  D.19084 = handles->bitmap;
  D.19085 = slot / 32;
  D.19086 = D.19085 * 4;
  D.19087 = D.19084 + D.19086;
  D.19088 = *D.19087;
  slot.25 = (int) slot;
  D.19090 = slot.25 & 31;
  D.19091 = 1 << D.19090;
  D.19092 = (unsigned int) D.19091;
  D.19093 = D.19088 & D.19092;
  if (D.19093 != 0) goto <D.19094>; else goto <D.19095>;
  <D.19094>:
  D.19096 = handles->type;
  if (D.19096 <= 1) goto <D.19097>; else goto <D.19098>;
  <D.19097>:
  D.19099 = handles->entries;
  D.19100 = slot * 4;
  D.19101 = D.19099 + D.19100;
  obj = mono_gc_weak_link_get (D.19101);
  goto <D.19102>;
  <D.19098>:
  D.19099 = handles->entries;
  D.19100 = slot * 4;
  D.19103 = D.19099 + D.19100;
  obj = *D.19103;
  <D.19102>:
  goto <D.19104>;
  <D.19095>:
  <D.19104>:
  <D.19083>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19105>; else goto <D.19106>;
    <D.19105>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19106>:
    D.19107 = ret != 0;
    D.19108 = (long int) D.19107;
    D.19109 = __builtin_expect (D.19108, 0);
    if (D.19109 != 0) goto <D.19110>; else goto <D.19111>;
    <D.19110>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 819, "ret == 0");
    <D.19111>:
  }
  D.19073 = obj;
  return D.19073;
}


mono_gchandle_is_in_domain (guint32 gchandle, struct MonoDomain * domain)
{
  unsigned int D.19113;
  gboolean D.19116;
  _Bool D.19119;
  long int D.19120;
  long int D.19121;
  unsigned int D.19124;
  guint32 * D.19127;
  unsigned int D.19128;
  unsigned int D.19129;
  guint32 * D.19130;
  unsigned int D.19131;
  int slot.26;
  int D.19133;
  int D.19134;
  unsigned int D.19135;
  unsigned int D.19136;
  unsigned char D.19139;
  int D.19142;
  guint16 * D.19143;
  unsigned int D.19144;
  guint16 * D.19145;
  short unsigned int D.19146;
  int D.19147;
  _Bool D.19148;
  void * * D.19150;
  unsigned int D.19151;
  void * * D.19152;
  struct MonoVTable * D.19156;
  struct MonoDomain * D.19157;
  _Bool D.19158;
  _Bool D.19162;
  long int D.19163;
  long int D.19164;
  guint slot;
  guint type;
  struct HandleData * handles;
  gboolean result;

  slot = gchandle >> 3;
  D.19113 = gchandle & 7;
  type = D.19113 + 4294967295;
  handles = &gc_handles[type];
  result = 0;
  if (type > 3) goto <D.19114>; else goto <D.19115>;
  <D.19114>:
  D.19116 = 0;
  return D.19116;
  <D.19115>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19117>; else goto <D.19118>;
    <D.19117>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19118>:
    D.19119 = ret != 0;
    D.19120 = (long int) D.19119;
    D.19121 = __builtin_expect (D.19120, 0);
    if (D.19121 != 0) goto <D.19122>; else goto <D.19123>;
    <D.19122>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 870, "ret == 0");
    <D.19123>:
  }
  D.19124 = handles->size;
  if (D.19124 > slot) goto <D.19125>; else goto <D.19126>;
  <D.19125>:
  D.19127 = handles->bitmap;
  D.19128 = slot / 32;
  D.19129 = D.19128 * 4;
  D.19130 = D.19127 + D.19129;
  D.19131 = *D.19130;
  slot.26 = (int) slot;
  D.19133 = slot.26 & 31;
  D.19134 = 1 << D.19133;
  D.19135 = (unsigned int) D.19134;
  D.19136 = D.19131 & D.19135;
  if (D.19136 != 0) goto <D.19137>; else goto <D.19138>;
  <D.19137>:
  D.19139 = handles->type;
  if (D.19139 <= 1) goto <D.19140>; else goto <D.19141>;
  <D.19140>:
  D.19142 = domain->domain_id;
  D.19143 = handles->domain_ids;
  D.19144 = slot * 2;
  D.19145 = D.19143 + D.19144;
  D.19146 = *D.19145;
  D.19147 = (int) D.19146;
  D.19148 = D.19142 == D.19147;
  result = (gboolean) D.19148;
  goto <D.19149>;
  <D.19141>:
  {
    struct MonoObject * obj;

    D.19150 = handles->entries;
    D.19151 = slot * 4;
    D.19152 = D.19150 + D.19151;
    obj = *D.19152;
    if (obj == 0B) goto <D.19153>; else goto <D.19154>;
    <D.19153>:
    result = 1;
    goto <D.19155>;
    <D.19154>:
    D.19156 = obj->vtable;
    D.19157 = D.19156->domain;
    D.19158 = D.19157 == domain;
    result = (gboolean) D.19158;
    <D.19155>:
  }
  <D.19149>:
  goto <D.19159>;
  <D.19138>:
  <D.19159>:
  <D.19126>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19160>; else goto <D.19161>;
    <D.19160>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19161>:
    D.19162 = ret != 0;
    D.19163 = (long int) D.19162;
    D.19164 = __builtin_expect (D.19163, 0);
    if (D.19164 != 0) goto <D.19165>; else goto <D.19166>;
    <D.19165>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 885, "ret == 0");
    <D.19166>:
  }
  D.19116 = result;
  return D.19116;
}


mono_gchandle_free (guint32 gchandle)
{
  unsigned int D.19168;
  _Bool D.19173;
  long int D.19174;
  long int D.19175;
  unsigned int D.19178;
  guint32 * D.19181;
  unsigned int D.19182;
  unsigned int D.19183;
  guint32 * D.19184;
  unsigned int D.19185;
  int slot.27;
  int D.19187;
  int D.19188;
  unsigned int D.19189;
  unsigned int D.19190;
  unsigned char D.19193;
  void * * D.19196;
  unsigned int D.19197;
  void * * D.19198;
  void * D.19199;
  void * * D.19202;
  _Bool D.19203;
  int D.19204;
  unsigned int D.19206;
  unsigned int D.19207;
  guint32 * D.19208;
  unsigned int D.19209;
  int D.19210;
  unsigned int D.19211;
  unsigned int D.19212;
  struct MonoPerfCounters * mono_perfcounters.28;
  unsigned int D.19215;
  unsigned int D.19216;
  _Bool D.19219;
  long int D.19220;
  long int D.19221;
  int D.19224;
  guint slot;
  guint type;
  struct HandleData * handles;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19171>; else goto <D.19172>;
    <D.19171>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19172>:
    D.19173 = ret != 0;
    D.19174 = (long int) D.19173;
    D.19175 = __builtin_expect (D.19174, 0);
    if (D.19175 != 0) goto <D.19176>; else goto <D.19177>;
    <D.19176>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 906, "ret == 0");
    <D.19177>:
  }
  D.19178 = handles->size;
  if (D.19178 > slot) goto <D.19179>; else goto <D.19180>;
  <D.19179>:
  D.19181 = handles->bitmap;
  D.19182 = slot / 32;
  D.19183 = D.19182 * 4;
  D.19184 = D.19181 + D.19183;
  D.19185 = *D.19184;
  slot.27 = (int) slot;
  D.19187 = slot.27 & 31;
  D.19188 = 1 << D.19187;
  D.19189 = (unsigned int) D.19188;
  D.19190 = D.19185 & D.19189;
  if (D.19190 != 0) goto <D.19191>; else goto <D.19192>;
  <D.19191>:
  D.19193 = handles->type;
  if (D.19193 <= 1) goto <D.19194>; else goto <D.19195>;
  <D.19194>:
  D.19196 = handles->entries;
  D.19197 = slot * 4;
  D.19198 = D.19196 + D.19197;
  D.19199 = *D.19198;
  if (D.19199 != 0B) goto <D.19200>; else goto <D.19201>;
  <D.19200>:
  D.19196 = handles->entries;
  D.19197 = slot * 4;
  D.19202 = D.19196 + D.19197;
  D.19193 = handles->type;
  D.19203 = D.19193 == 1;
  D.19204 = (int) D.19203;
  mono_gc_weak_link_remove (D.19202, D.19204);
  <D.19201>:
  goto <D.19205>;
  <D.19195>:
  D.19196 = handles->entries;
  D.19197 = slot * 4;
  D.19198 = D.19196 + D.19197;
  *D.19198 = 0B;
  <D.19205>:
  D.19181 = handles->bitmap;
  D.19206 = slot / 32;
  D.19207 = D.19206 * 4;
  D.19208 = D.19181 + D.19207;
  D.19181 = handles->bitmap;
  D.19207 = D.19206 * 4;
  D.19208 = D.19181 + D.19207;
  D.19209 = *D.19208;
  slot.27 = (int) slot;
  D.19187 = slot.27 & 31;
  D.19188 = 1 << D.19187;
  D.19210 = ~D.19188;
  D.19211 = (unsigned int) D.19210;
  D.19212 = D.19209 & D.19211;
  *D.19208 = D.19212;
  goto <D.19213>;
  <D.19192>:
  <D.19213>:
  <D.19180>:
  mono_perfcounters.28 = mono_perfcounters;
  D.19215 = mono_perfcounters.28->gc_num_handles;
  D.19216 = D.19215 + 4294967295;
  mono_perfcounters.28->gc_num_handles = D.19216;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19217>; else goto <D.19218>;
    <D.19217>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19218>:
    D.19219 = ret != 0;
    D.19220 = (long int) D.19219;
    D.19221 = __builtin_expect (D.19220, 0);
    if (D.19221 != 0) goto <D.19222>; else goto <D.19223>;
    <D.19222>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 922, "ret == 0");
    <D.19223>:
  }
  D.19193 = handles->type;
  D.19224 = (int) D.19193;
  mono_profiler_gc_handle (1, D.19224, gchandle, 0B);
}


mono_gchandle_free_domain (struct MonoDomain * domain)
{
  _Bool D.19228;
  long int D.19229;
  long int D.19230;
  guint32 * D.19233;
  unsigned int D.19234;
  unsigned int D.19235;
  guint32 * D.19236;
  unsigned int D.19237;
  int slot.29;
  int D.19239;
  int D.19240;
  unsigned int D.19241;
  unsigned int D.19242;
  int D.19247;
  guint16 * D.19248;
  unsigned int D.19249;
  guint16 * D.19250;
  short unsigned int D.19251;
  int D.19252;
  unsigned int D.19255;
  unsigned int D.19256;
  guint32 * D.19257;
  unsigned int D.19258;
  int D.19259;
  unsigned int D.19260;
  unsigned int D.19261;
  void * * D.19262;
  unsigned int D.19263;
  void * * D.19264;
  void * D.19265;
  void * * D.19268;
  unsigned char D.19269;
  _Bool D.19270;
  int D.19271;
  struct MonoVTable * D.19275;
  struct MonoDomain * D.19276;
  unsigned int D.19279;
  unsigned int D.19280;
  guint32 * D.19281;
  unsigned int D.19282;
  unsigned int D.19283;
  unsigned int D.19284;
  _Bool D.19287;
  long int D.19288;
  long int D.19289;
  guint type;

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

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

      ret = pthread_mutex_lock (&handle_section.mutex);
      if (ret != 0) goto <D.19226>; else goto <D.19227>;
      <D.19226>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.19227>:
      D.19228 = ret != 0;
      D.19229 = (long int) D.19228;
      D.19230 = __builtin_expect (D.19229, 0);
      if (D.19230 != 0) goto <D.19231>; else goto <D.19232>;
      <D.19231>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 941, "ret == 0");
      <D.19232>:
    }
    slot = 0;
    goto <D.18484>;
    <D.18483>:
    D.19233 = handles->bitmap;
    D.19234 = slot / 32;
    D.19235 = D.19234 * 4;
    D.19236 = D.19233 + D.19235;
    D.19237 = *D.19236;
    slot.29 = (int) slot;
    D.19239 = slot.29 & 31;
    D.19240 = 1 << D.19239;
    D.19241 = (unsigned int) D.19240;
    D.19242 = D.19237 & D.19241;
    if (D.19242 == 0) goto <D.19243>; else goto <D.19244>;
    <D.19243>:
    // predicted unlikely by continue predictor.
    goto <D.18482>;
    <D.19244>:
    if (type <= 1) goto <D.19245>; else goto <D.19246>;
    <D.19245>:
    D.19247 = domain->domain_id;
    D.19248 = handles->domain_ids;
    D.19249 = slot * 2;
    D.19250 = D.19248 + D.19249;
    D.19251 = *D.19250;
    D.19252 = (int) D.19251;
    if (D.19247 == D.19252) goto <D.19253>; else goto <D.19254>;
    <D.19253>:
    D.19233 = handles->bitmap;
    D.19255 = slot / 32;
    D.19256 = D.19255 * 4;
    D.19257 = D.19233 + D.19256;
    D.19233 = handles->bitmap;
    D.19256 = D.19255 * 4;
    D.19257 = D.19233 + D.19256;
    D.19258 = *D.19257;
    slot.29 = (int) slot;
    D.19239 = slot.29 & 31;
    D.19240 = 1 << D.19239;
    D.19259 = ~D.19240;
    D.19260 = (unsigned int) D.19259;
    D.19261 = D.19258 & D.19260;
    *D.19257 = D.19261;
    D.19262 = handles->entries;
    D.19263 = slot * 4;
    D.19264 = D.19262 + D.19263;
    D.19265 = *D.19264;
    if (D.19265 != 0B) goto <D.19266>; else goto <D.19267>;
    <D.19266>:
    D.19262 = handles->entries;
    D.19263 = slot * 4;
    D.19268 = D.19262 + D.19263;
    D.19269 = handles->type;
    D.19270 = D.19269 == 1;
    D.19271 = (int) D.19270;
    mono_gc_weak_link_remove (D.19268, D.19271);
    <D.19267>:
    <D.19254>:
    goto <D.19272>;
    <D.19246>:
    D.19262 = handles->entries;
    D.19263 = slot * 4;
    D.19264 = D.19262 + D.19263;
    D.19265 = *D.19264;
    if (D.19265 != 0B) goto <D.19273>; else goto <D.19274>;
    <D.19273>:
    D.19262 = handles->entries;
    D.19263 = slot * 4;
    D.19264 = D.19262 + D.19263;
    D.19265 = *D.19264;
    D.19275 = MEM[(struct MonoObject *)D.19265].vtable;
    D.19276 = D.19275->domain;
    if (D.19276 == domain) goto <D.19277>; else goto <D.19278>;
    <D.19277>:
    D.19233 = handles->bitmap;
    D.19279 = slot / 32;
    D.19280 = D.19279 * 4;
    D.19281 = D.19233 + D.19280;
    D.19233 = handles->bitmap;
    D.19280 = D.19279 * 4;
    D.19281 = D.19233 + D.19280;
    D.19282 = *D.19281;
    slot.29 = (int) slot;
    D.19239 = slot.29 & 31;
    D.19240 = 1 << D.19239;
    D.19259 = ~D.19240;
    D.19260 = (unsigned int) D.19259;
    D.19283 = D.19282 & D.19260;
    *D.19281 = D.19283;
    D.19262 = handles->entries;
    D.19263 = slot * 4;
    D.19264 = D.19262 + D.19263;
    *D.19264 = 0B;
    <D.19278>:
    <D.19274>:
    <D.19272>:
    <D.18482>:
    slot = slot + 1;
    <D.18484>:
    D.19284 = handles->size;
    if (D.19284 > slot) goto <D.18483>; else goto <D.18485>;
    <D.18485>:
    {
      int ret;

      ret = pthread_mutex_unlock (&handle_section.mutex);
      if (ret != 0) goto <D.19285>; else goto <D.19286>;
      <D.19285>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19286>:
      D.19287 = ret != 0;
      D.19288 = (long int) D.19287;
      D.19289 = __builtin_expect (D.19288, 0);
      if (D.19289 != 0) goto <D.19290>; else goto <D.19291>;
      <D.19290>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 958, "ret == 0");
      <D.19291>:
    }
  }
  type = type + 1;
  <D.18488>:
  if (type <= 2) goto <D.18487>; else goto <D.18489>;
  <D.18489>:
}


GCHandle_CheckCurrentDomain (guint32 gchandle)
{
  MonoBoolean D.19292;
  struct MonoDomain * D.19293;
  int D.19294;

  D.19293 = mono_domain_get ();
  D.19294 = mono_gchandle_is_in_domain (gchandle, D.19293);
  D.19292 = (MonoBoolean) D.19294;
  return D.19292;
}


mono_gc_finalize_notify ()
{
  mono_sem_post (&finalizer_sem);
}


mono_gc_init ()
{
  int D.19296;
  int D.19299;
  int D.19302;
  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.19296 = mono_gc_is_moving ();
  if (D.19296 == 0) goto <D.19297>; else goto <D.19298>;
  <D.19297>:
  mono_gc_register_root (&gc_handles[2].entries, 4, 0B);
  <D.19298>:
  D.19299 = mono_gc_is_moving ();
  if (D.19299 == 0) goto <D.19300>; else goto <D.19301>;
  <D.19300>:
  mono_gc_register_root (&gc_handles[3].entries, 4, 0B);
  <D.19301>:
  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.19302 = mono_gc_is_disabled ();
  if (D.19302 != 0) goto <D.19303>; else goto <D.19304>;
  <D.19303>:
  gc_disabled = 1;
  return;
  <D.19304>:
  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.19308>; else goto <D.19311>;
  <D.19311>:
  pending_done_event.34 = pending_done_event;
  if (pending_done_event.34 == 0B) goto <D.19308>; else goto <D.19313>;
  <D.19313>:
  shutdown_event.35 = shutdown_event;
  if (shutdown_event.35 == 0B) goto <D.19308>; else goto <D.19309>;
  <D.19308>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 1152);
  <D.19309>:
  sem_init (&finalizer_sem, 0, 0);
  mono_gc_init_finalizer_thread ();
}


mono_gc_init_finalizer_thread ()
{
  struct MonoDomain * D.19316;
  struct MonoInternalThread * gc_thread.36;
  struct MonoInternalThread * gc_thread.37;
  struct MonoDomain * D.19319;
  struct MonoString * D.19320;

  D.19316 = mono_domain_get ();
  gc_thread.36 = mono_thread_create_internal (D.19316, finalizer_thread, 0B, 0, 1, 0);
  gc_thread = gc_thread.36;
  gc_thread.37 = gc_thread;
  D.19319 = mono_domain_get ();
  D.19320 = mono_string_new (D.19319, "Finalizer");
  ves_icall_System_Threading_Thread_SetName_internal (gc_thread.37, D.19320);
}


finalizer_thread (void * unused)
{
  struct MonoDomain * D.19321;
  struct MonoDomain * D.19322;
  _Bool D.19323;
  long int D.19324;
  long int D.19325;
  struct GSList * domains_to_finalize.38;
  _Bool D.19333;
  long int D.19334;
  long int D.19335;
  struct GSList * domains_to_finalize.39;
  _Bool D.19343;
  long int D.19344;
  long int D.19345;
  _Bool D.19351;
  long int D.19352;
  long int D.19353;
  void * pending_done_event.40;
  int finished.41;
  void * shutdown_event.42;
  guint32 D.19359;

  goto <D.18520>;
  <D.18519>:
  D.19321 = mono_domain_get ();
  D.19322 = mono_get_root_domain ();
  D.19323 = D.19321 != D.19322;
  D.19324 = (long int) D.19323;
  D.19325 = __builtin_expect (D.19324, 0);
  if (D.19325 != 0) goto <D.19326>; else goto <D.19327>;
  <D.19326>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1069, "mono_domain_get () == mono_get_root_domain ()");
  <D.19327>:
  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.19329>; else goto <D.19330>;
  <D.19329>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19331>; else goto <D.19332>;
    <D.19331>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19332>:
    D.19333 = ret != 0;
    D.19334 = (long int) D.19333;
    D.19335 = __builtin_expect (D.19334, 0);
    if (D.19335 != 0) goto <D.19336>; else goto <D.19337>;
    <D.19336>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1087, "ret == 0");
    <D.19337>:
  }
  domains_to_finalize.38 = domains_to_finalize;
  if (domains_to_finalize.38 != 0B) goto <D.19338>; else goto <D.19339>;
  <D.19338>:
  {
    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.19341>; else goto <D.19342>;
      <D.19341>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19342>:
      D.19343 = ret != 0;
      D.19344 = (long int) D.19343;
      D.19345 = __builtin_expect (D.19344, 0);
      if (D.19345 != 0) goto <D.19346>; else goto <D.19347>;
      <D.19346>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1091, "ret == 0");
      <D.19347>:
    }
    finalize_domain_objects (req);
  }
  goto <D.19348>;
  <D.19339>:
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19349>; else goto <D.19350>;
    <D.19349>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19350>:
    D.19351 = ret != 0;
    D.19352 = (long int) D.19351;
    D.19353 = __builtin_expect (D.19352, 0);
    if (D.19353 != 0) goto <D.19354>; else goto <D.19355>;
    <D.19354>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1095, "ret == 0");
    <D.19355>:
  }
  <D.19348>:
  <D.19330>:
  mono_gc_invoke_finalizers ();
  reference_queue_proccess_all ();
  pending_done_event.40 = pending_done_event;
  SetEvent (pending_done_event.40);
  <D.18520>:
  finished.41 = finished;
  if (finished.41 == 0) goto <D.18519>; else goto <D.18521>;
  <D.18521>:
  shutdown_event.42 = shutdown_event;
  SetEvent (shutdown_event.42);
  D.19359 = 0;
  return D.19359;
}


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

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

        i = 0;
        goto <D.18507>;
        <D.18506>:
        D.19361 = to_finalize[i];
        mono_gc_run_finalize (D.19361, 0B);
        i = i + 1;
        <D.18507>:
        if (i < count) goto <D.18506>; else goto <D.18508>;
        <D.18508>:
      }
      <D.18510>:
      count = mono_gc_finalizers_for_domain (domain, &to_finalize, 64);
      if (count != 0) goto <D.18509>; else goto <D.18511>;
      <D.18511>:
      reference_queue_clear_for_domain (domain);
      D.19362 = req->done_event;
      SetEvent (D.19362);
      monoeg_g_free (req);
    }
  finally
    {
      to_finalize = {CLOBBER};
    }
}


reference_queue_clear_for_domain (struct MonoDomain * domain)
{
  struct MonoDomain * D.19363;
  void * * D.19366;
  void (*<Tc3>) (void *) D.19367;
  void * D.19368;
  struct MonoReferenceQueue * queue;

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

    iter = &queue->queue;
    goto <D.18612>;
    <D.18611>:
    D.19363 = entry->domain;
    if (D.19363 == domain) goto <D.19364>; else goto <D.19365>;
    <D.19364>:
    D.19366 = &entry->dis_link;
    mono_gc_weak_link_remove (D.19366, 1);
    ref_list_remove_element (iter, entry);
    D.19367 = queue->callback;
    D.19368 = entry->user_data;
    D.19367 (D.19368);
    monoeg_g_free (entry);
    goto <D.19369>;
    <D.19365>:
    iter = &entry->next;
    <D.19369>:
    <D.18612>:
    entry = *iter;
    if (entry != 0B) goto <D.18611>; else goto <D.18613>;
    <D.18613>:
  }
  queue = queue->next;
  <D.18615>:
  if (queue != 0B) goto <D.18614>; else goto <D.18616>;
  <D.18616>:
}


ref_list_remove_element (struct RefQueueEntry * * prev, struct RefQueueEntry * element)
{
  struct RefQueueEntry * D.19370;
  struct RefQueueEntry * D.19372;
  void * D.19373;

  <D.18566>:
  goto <D.18564>;
  <D.18563>:
  D.19370 = *prev;
  prev = &D.19370->next;
  <D.18564>:
  D.19370 = *prev;
  if (D.19370 != element) goto <D.18563>; else goto <D.18565>;
  <D.18565>:
  if (prev != 0B) goto <D.19371>; else goto <D.18567>;
  <D.19371>:
  D.19372 = element->next;
  D.19373 = InterlockedCompareExchangePointer (prev, D.19372, element);
  if (D.19373 != element) goto <D.18566>; else goto <D.18567>;
  <D.18567>:
}


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

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


reference_queue_proccess_all ()
{
  _Bool D.19381;
  long int D.19382;
  long int D.19383;
  int D.19386;
  struct RefQueueEntry * D.19389;
  _Bool D.19394;
  long int D.19395;
  long int D.19396;
  struct MonoReferenceQueue * D.19399;
  struct MonoReferenceQueue * D.19400;
  _Bool D.19403;
  long int D.19404;
  long int D.19405;
  struct MonoReferenceQueue * * iter;
  struct MonoReferenceQueue * queue;
  void restart = <<< error >>>;

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

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19379>; else goto <D.19380>;
    <D.19379>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19380>:
    D.19381 = ret != 0;
    D.19382 = (long int) D.19381;
    D.19383 = __builtin_expect (D.19382, 0);
    if (D.19383 != 0) goto <D.19384>; else goto <D.19385>;
    <D.19384>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1424, "ret == 0");
    <D.19385>:
  }
  iter = &ref_queues;
  goto <D.18593>;
  <D.18595>:
  queue = *iter;
  D.19386 = queue->should_be_deleted;
  if (D.19386 == 0) goto <D.19387>; else goto <D.19388>;
  <D.19387>:
  iter = &queue->next;
  // predicted unlikely by continue predictor.
  goto <D.18593>;
  <D.19388>:
  D.19389 = queue->queue;
  if (D.19389 != 0B) goto <D.19390>; else goto <D.19391>;
  <D.19390>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19392>; else goto <D.19393>;
    <D.19392>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19393>:
    D.19394 = ret != 0;
    D.19395 = (long int) D.19394;
    D.19396 = __builtin_expect (D.19395, 0);
    if (D.19396 != 0) goto <D.19397>; else goto <D.19398>;
    <D.19397>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1432, "ret == 0");
    <D.19398>:
  }
  reference_queue_proccess (queue);
  goto restart;
  <D.19391>:
  D.19399 = queue->next;
  *iter = D.19399;
  monoeg_g_free (queue);
  <D.18593>:
  D.19400 = *iter;
  if (D.19400 != 0B) goto <D.18595>; else goto <D.18596>;
  <D.18596>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19401>; else goto <D.19402>;
    <D.19401>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19402>:
    D.19403 = ret != 0;
    D.19404 = (long int) D.19403;
    D.19405 = __builtin_expect (D.19404, 0);
    if (D.19405 != 0) goto <D.19406>; else goto <D.19407>;
    <D.19406>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1439, "ret == 0");
    <D.19407>:
  }
}


reference_queue_proccess (struct MonoReferenceQueue * queue)
{
  int D.19411;
  void * * D.19413;
  struct MonoObject * D.19414;
  void (*<Tc3>) (void *) D.19415;
  void * D.19416;
  struct RefQueueEntry * * iter;
  struct RefQueueEntry * entry;

  iter = &queue->queue;
  goto <D.18581>;
  <D.18580>:
  D.19411 = queue->should_be_deleted;
  if (D.19411 != 0) goto <D.19408>; else goto <D.19412>;
  <D.19412>:
  D.19413 = &entry->dis_link;
  D.19414 = mono_gc_weak_link_get (D.19413);
  if (D.19414 == 0B) goto <D.19408>; else goto <D.19409>;
  <D.19408>:
  D.19413 = &entry->dis_link;
  mono_gc_weak_link_remove (D.19413, 1);
  ref_list_remove_element (iter, entry);
  D.19415 = queue->callback;
  D.19416 = entry->user_data;
  D.19415 (D.19416);
  monoeg_g_free (entry);
  goto <D.19410>;
  <D.19409>:
  iter = &entry->next;
  <D.19410>:
  <D.18581>:
  entry = *iter;
  if (entry != 0B) goto <D.18580>; else goto <D.18582>;
  <D.18582>:
}


mono_gc_cleanup ()
{
  int gc_disabled.45;
  void * shutdown_event.46;
  struct MonoInternalThread * D.19421;
  struct MonoInternalThread * gc_thread.47;
  unsigned int D.19425;
  void * D.19428;
  unsigned int D.19429;
  unsigned int D.19434;
  _Bool D.19435;
  long int D.19436;
  long int D.19437;
  long long unsigned int D.19440;
  long unsigned int D.19441;

  gc_disabled.45 = gc_disabled;
  if (gc_disabled.45 == 0) goto <D.19418>; else goto <D.19419>;
  <D.19418>:
  shutdown_event.46 = shutdown_event;
  ResetEvent (shutdown_event.46);
  finished = 1;
  D.19421 = mono_thread_internal_current ();
  gc_thread.47 = gc_thread;
  if (D.19421 != gc_thread.47) goto <D.19423>; else goto <D.19424>;
  <D.19423>:
  mono_gc_finalize_notify ();
  shutdown_event.46 = shutdown_event;
  D.19425 = WaitForSingleObjectEx (shutdown_event.46, 2000, 0);
  if (D.19425 == 258) goto <D.19426>; else goto <D.19427>;
  <D.19426>:
  {
    int ret;

    suspend_finalizers = 1;
    gc_thread.47 = gc_thread;
    mono_thread_internal_stop (gc_thread.47);
    gc_thread.47 = gc_thread;
    D.19428 = gc_thread.47->handle;
    D.19429 = WaitForSingleObjectEx (D.19428, 100, 1);
    ret = (int) D.19429;
    if (ret == 258) goto <D.19430>; else goto <D.19431>;
    <D.19430>:
    monoeg_g_log (0B, 16, "Shutting down finalizer thread timed out.");
    goto <D.19432>;
    <D.19431>:
    Sleep (100);
    <D.19432>:
  }
  goto <D.19433>;
  <D.19427>:
  {
    int ret;

    gc_thread.47 = gc_thread;
    D.19428 = gc_thread.47->handle;
    D.19434 = WaitForSingleObjectEx (D.19428, 4294967295, 1);
    ret = (int) D.19434;
    D.19435 = ret != 0;
    D.19436 = (long int) D.19435;
    D.19437 = __builtin_expect (D.19436, 0);
    if (D.19437 != 0) goto <D.19438>; else goto <D.19439>;
    <D.19438>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1208, "ret == WAIT_OBJECT_0");
    <D.19439>:
    gc_thread.47 = gc_thread;
    D.19440 = gc_thread.47->tid;
    D.19441 = (long unsigned int) D.19440;
    ret = pthread_join (D.19441, 0B);
    D.19435 = ret != 0;
    D.19436 = (long int) D.19435;
    D.19437 = __builtin_expect (D.19436, 0);
    if (D.19437 != 0) goto <D.19442>; else goto <D.19443>;
    <D.19442>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1216, "ret == 0");
    <D.19443>:
  }
  <D.19433>:
  <D.19424>:
  gc_thread = 0B;
  <D.19419>:
  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.18603>;
  <D.18602>:
  queue->should_be_deleted = 1;
  queue = queue->next;
  <D.18603>:
  if (queue != 0B) goto <D.18602>; else goto <D.18604>;
  <D.18604>:
  reference_queue_proccess_all ();
}


mono_gc_is_finalizer_internal_thread (struct MonoInternalThread * thread)
{
  gboolean D.19444;
  struct MonoInternalThread * gc_thread.48;
  _Bool D.19446;

  gc_thread.48 = gc_thread;
  D.19446 = thread == gc_thread.48;
  D.19444 = (gboolean) D.19446;
  return D.19444;
}


mono_gc_is_finalizer_thread (struct MonoThread * thread)
{
  gboolean D.19448;
  struct _MonoInternalThread * D.19449;

  D.19449 = thread->internal_thread;
  D.19448 = mono_gc_is_finalizer_internal_thread (D.19449);
  return D.19448;
}


mono_gc_parse_environment_string_extract_number (const char * str, glong * out)
{
  unsigned int D.19451;
  gboolean D.19454;
  sizetype len.49;
  sizetype D.19456;
  const char * D.19457;
  int D.19458;
  const short unsigned int * * D.19459;
  const short unsigned int * D.19460;
  unsigned int D.19461;
  unsigned int D.19462;
  const short unsigned int * D.19463;
  short unsigned int D.19464;
  int D.19465;
  int D.19466;
  int * D.19469;
  int D.19474;
  unsigned int val.50;
  unsigned int D.19477;
  char * endptr.51;
  char * D.19484;
  char D.19485;
  long unsigned int val.52;
  long unsigned int D.19491;
  char * endptr;
  int len;
  int shift;
  glong val;
  gboolean is_suffix;
  char suffix;

  try
    {
      D.19451 = strlen (str);
      len = (int) D.19451;
      shift = 0;
      is_suffix = 0;
      if (len == 0) goto <D.19452>; else goto <D.19453>;
      <D.19452>:
      D.19454 = 0;
      return D.19454;
      <D.19453>:
      len.49 = (sizetype) len;
      D.19456 = len.49 + 4294967295;
      D.19457 = str + D.19456;
      suffix = *D.19457;
      D.19458 = (int) suffix;
      switch (D.19458) <default: <D.18556>, case 71: <D.18550>, case 75: <D.18554>, case 77: <D.18552>, case 103: <D.18549>, case 107: <D.18553>, case 109: <D.18551>>
      <D.18549>:
      <D.18550>:
      shift = shift + 10;
      <D.18551>:
      <D.18552>:
      shift = shift + 10;
      <D.18553>:
      <D.18554>:
      shift = shift + 10;
      is_suffix = 1;
      goto <D.18555>;
      <D.18556>:
      D.19459 = __ctype_b_loc ();
      D.19460 = *D.19459;
      D.19461 = (unsigned int) suffix;
      D.19462 = D.19461 * 2;
      D.19463 = D.19460 + D.19462;
      D.19464 = *D.19463;
      D.19465 = (int) D.19464;
      D.19466 = D.19465 & 2048;
      if (D.19466 == 0) goto <D.19467>; else goto <D.19468>;
      <D.19467>:
      D.19454 = 0;
      return D.19454;
      <D.19468>:
      goto <D.18555>;
      <D.18555>:
      D.19469 = __errno_location ();
      *D.19469 = 0;
      val = strtol (str, &endptr, 10);
      D.19469 = __errno_location ();
      D.19474 = *D.19469;
      if (D.19474 == 34) goto <D.19475>; else goto <D.19470>;
      <D.19475>:
      val.50 = (unsigned int) val;
      D.19477 = val.50 + 2147483647;
      if (D.19477 > 4294967293) goto <D.19471>; else goto <D.19470>;
      <D.19470>:
      D.19469 = __errno_location ();
      D.19474 = *D.19469;
      if (D.19474 != 0) goto <D.19478>; else goto <D.19472>;
      <D.19478>:
      if (val == 0) goto <D.19471>; else goto <D.19472>;
      <D.19472>:
      endptr.51 = endptr;
      if (endptr.51 == str) goto <D.19471>; else goto <D.19473>;
      <D.19471>:
      D.19454 = 0;
      return D.19454;
      <D.19473>:
      if (is_suffix != 0) goto <D.19480>; else goto <D.19481>;
      <D.19480>:
      {
        gulong unshifted;

        if (val < 0) goto <D.19482>; else goto <D.19483>;
        <D.19482>:
        D.19454 = 0;
        return D.19454;
        <D.19483>:
        endptr.51 = endptr;
        D.19484 = endptr.51 + 1;
        D.19485 = *D.19484;
        if (D.19485 != 0) goto <D.19486>; else goto <D.19487>;
        <D.19486>:
        D.19454 = 0;
        return D.19454;
        <D.19487>:
        unshifted = (gulong) val;
        val = val << shift;
        if (val < 0) goto <D.19488>; else goto <D.19489>;
        <D.19488>:
        D.19454 = 0;
        return D.19454;
        <D.19489>:
        val.52 = (long unsigned int) val;
        D.19491 = val.52 >> shift;
        if (D.19491 != unshifted) goto <D.19492>; else goto <D.19493>;
        <D.19492>:
        D.19454 = 0;
        return D.19454;
        <D.19493>:
      }
      <D.19481>:
      *out = val;
      D.19454 = 1;
      return D.19454;
    }
  finally
    {
      endptr = {CLOBBER};
    }
}


mono_gc_reference_queue_new (void (*mono_reference_queue_callback) (void *) callback)
{
  _Bool D.19498;
  long int D.19499;
  long int D.19500;
  struct MonoReferenceQueue * ref_queues.53;
  _Bool D.19506;
  long int D.19507;
  long int D.19508;
  struct MonoReferenceQueue * D.19511;
  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.19496>; else goto <D.19497>;
    <D.19496>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19497>:
    D.19498 = ret != 0;
    D.19499 = (long int) D.19498;
    D.19500 = __builtin_expect (D.19499, 0);
    if (D.19500 != 0) goto <D.19501>; else goto <D.19502>;
    <D.19501>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1497, "ret == 0");
    <D.19502>:
  }
  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.19504>; else goto <D.19505>;
    <D.19504>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19505>:
    D.19506 = ret != 0;
    D.19507 = (long int) D.19506;
    D.19508 = __builtin_expect (D.19507, 0);
    if (D.19508 != 0) goto <D.19509>; else goto <D.19510>;
    <D.19509>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1500, "ret == 0");
    <D.19510>:
  }
  D.19511 = res;
  return D.19511;
}


mono_gc_reference_queue_add (struct MonoReferenceQueue * queue, struct MonoObject * obj, void * user_data)
{
  int D.19513;
  mono_bool D.19516;
  struct MonoVTable * D.19517;
  struct MonoDomain * D.19518;
  void * * D.19519;
  struct RefQueueEntry * * D.19520;
  struct RefQueueEntry * entry;

  D.19513 = queue->should_be_deleted;
  if (D.19513 != 0) goto <D.19514>; else goto <D.19515>;
  <D.19514>:
  D.19516 = 0;
  return D.19516;
  <D.19515>:
  entry = monoeg_malloc0 (20);
  entry->user_data = user_data;
  D.19517 = obj->vtable;
  D.19518 = D.19517->domain;
  entry->domain = D.19518;
  D.19519 = &entry->dis_link;
  mono_gc_weak_link_add (D.19519, obj, 1);
  D.19520 = &queue->queue;
  ref_list_push (D.19520, entry);
  D.19516 = 1;
  return D.19516;
}


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

  <D.18573>:
  current = *head;
  value->next = current;
  mono_memory_write_barrier ();
  D.19522 = InterlockedCompareExchangePointer (head, value, current);
  if (D.19522 != current) goto <D.18573>; else goto <D.18574>;
  <D.18574>:
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


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


