mono_gc_run_finalize (void * obj, void * data)
{
  long int data.0;
  unsigned int D.19018;
  sizetype D.19019;
  int suspend_finalizers.1;
  struct MonoVTable * D.19023;
  struct MonoClass * D.19024;
  struct MonoClass * D.19025;
  int D.19028;
  unsigned char D.19031;
  int finalizing_root_domain.2;
  struct MonoImage * D.19037;
  struct MonoImage * D.19038;
  int D.18669;
  int iftmp.3;
  int D.18668;
  const char[14] * D.19044;
  unsigned char D.19045;
  int D.19046;
  unsigned char D.19047;
  int D.19048;
  _Bool D.19049;
  _Bool D.19050;
  _Bool D.19051;
  const unsigned char * D.19054;
  unsigned char D.19055;
  int D.19056;
  const unsigned char * D.19057;
  unsigned char D.19058;
  int D.19059;
  _Bool D.19060;
  _Bool D.19061;
  const unsigned char * D.19064;
  unsigned char D.19065;
  int D.19066;
  const unsigned char * D.19067;
  unsigned char D.19068;
  int D.19069;
  _Bool D.19070;
  _Bool D.19071;
  const unsigned char * D.19074;
  unsigned char D.19075;
  int D.19076;
  const unsigned char * D.19077;
  unsigned char D.19078;
  int D.19079;
  const char * D.19081;
  int D.19086;
  struct MonoDomain * D.19089;
  unsigned char D.19090;
  unsigned char D.19091;
  void * D.19094;
  int D.19097;
  void * D.19102;
  struct MonoClass * D.19105;
  struct MonoMethod * D.19106;
  void * D.19107;
  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 = (long int) data;
      D.19018 = (unsigned int) data.0;
      D.19019 = (sizetype) D.19018;
      o = obj + D.19019;
      suspend_finalizers.1 = suspend_finalizers;
      if (suspend_finalizers.1 != 0) goto <D.19021>; else goto <D.19022>;
      <D.19021>:
      return;
      <D.19022>:
      D.19023 = o->vtable;
      domain = D.19023->domain;
      object_register_finalizer (obj, 0B);
      D.19023 = o->vtable;
      D.19024 = D.19023->klass;
      D.19025 = mono_defaults.internal_thread_class;
      if (D.19024 == D.19025) goto <D.19026>; else goto <D.19027>;
      <D.19026>:
      {
        struct MonoInternalThread * t;

        t = o;
        D.19028 = mono_gc_is_finalizer_internal_thread (t);
        if (D.19028 != 0) goto <D.19029>; else goto <D.19030>;
        <D.19029>:
        return;
        <D.19030>:
        D.19031 = t->threadpool_thread;
        if (D.19031 != 0) goto <D.19032>; else goto <D.19033>;
        <D.19032>:
        finalizing_root_domain.2 = finalizing_root_domain;
        if (finalizing_root_domain.2 != 0) goto <D.19035>; else goto <D.19036>;
        <D.19035>:
        add_thread_to_finalize (t);
        return;
        <D.19036>:
        <D.19033>:
      }
      <D.19027>:
      D.19023 = o->vtable;
      D.19024 = D.19023->klass;
      D.19037 = D.19024->image;
      D.19038 = mono_defaults.corlib;
      if (D.19037 == D.19038) goto <D.19039>; else goto <D.19040>;
      <D.19039>:
      {
        size_t __s1_len;
        size_t __s2_len;

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

          D.19023 = o->vtable;
          D.19024 = D.19023->klass;
          __s2 = D.19024->name;
          D.19044 = "DynamicMethod";
          D.19045 = MEM[(const unsigned char *)D.19044];
          D.19046 = (int) D.19045;
          D.19047 = *__s2;
          D.19048 = (int) D.19047;
          __result = D.19046 - D.19048;
          {
            D.19049 = __s2_len != 0;
            D.19050 = __result == 0;
            D.19051 = D.19049 & D.19050;
            if (D.19051 != 0) goto <D.19052>; else goto <D.19053>;
            <D.19052>:
            D.19054 = &MEM[(void *)"DynamicMethod" + 1B];
            D.19055 = *D.19054;
            D.19056 = (int) D.19055;
            D.19057 = __s2 + 1;
            D.19058 = *D.19057;
            D.19059 = (int) D.19058;
            __result = D.19056 - D.19059;
            D.19060 = __s2_len > 1;
            D.19050 = __result == 0;
            D.19061 = D.19060 & D.19050;
            if (D.19061 != 0) goto <D.19062>; else goto <D.19063>;
            <D.19062>:
            D.19064 = &MEM[(void *)"DynamicMethod" + 2B];
            D.19065 = *D.19064;
            D.19066 = (int) D.19065;
            D.19067 = __s2 + 2;
            D.19068 = *D.19067;
            D.19069 = (int) D.19068;
            __result = D.19066 - D.19069;
            D.19070 = __s2_len > 2;
            D.19050 = __result == 0;
            D.19071 = D.19070 & D.19050;
            if (D.19071 != 0) goto <D.19072>; else goto <D.19073>;
            <D.19072>:
            D.19074 = &MEM[(void *)"DynamicMethod" + 3B];
            D.19075 = *D.19074;
            D.19076 = (int) D.19075;
            D.19077 = __s2 + 3;
            D.19078 = *D.19077;
            D.19079 = (int) D.19078;
            __result = D.19076 - D.19079;
            <D.19073>:
            <D.19063>:
            <D.19053>:
          }
          D.18668 = __result;
        }
        iftmp.3 = -D.18668;
        goto <D.19080>;
        <D.19043>:
        D.19023 = o->vtable;
        D.19024 = D.19023->klass;
        D.19081 = D.19024->name;
        iftmp.3 = __builtin_strcmp (D.19081, "DynamicMethod");
        <D.19080>:
        D.18669 = iftmp.3;
      }
      if (D.18669 == 0) goto <D.19082>; else goto <D.19083>;
      <D.19082>:
      finalizing_root_domain.2 = finalizing_root_domain;
      if (finalizing_root_domain.2 != 0) goto <D.19084>; else goto <D.19085>;
      <D.19084>:
      return;
      <D.19085>:
      <D.19083>:
      <D.19040>:
      D.19086 = mono_runtime_get_no_exec ();
      if (D.19086 != 0) goto <D.19087>; else goto <D.19088>;
      <D.19087>:
      return;
      <D.19088>:
      D.19023 = o->vtable;
      D.19089 = D.19023->domain;
      mono_domain_set_internal (D.19089);
      D.19023 = o->vtable;
      D.19024 = D.19023->klass;
      D.19090 = BIT_FIELD_REF <*D.19024, 8, 280>;
      D.19091 = D.19090 & 1;
      if (D.19091 != 0) goto <D.19092>; else goto <D.19093>;
      <D.19092>:
      {
        struct MonoDelegate * del;

        del = o;
        D.19094 = del->delegate_trampoline;
        if (D.19094 != 0B) goto <D.19095>; else goto <D.19096>;
        <D.19095>:
        mono_delegate_free_ftnptr (o);
        <D.19096>:
        mono_domain_set_internal (caller_domain);
        return;
      }
      <D.19093>:
      D.19023 = o->vtable;
      D.19024 = D.19023->klass;
      finalizer = mono_class_get_finalizer (D.19024);
      D.19097 = mono_marshal_free_ccw (o);
      if (D.19097 != 0) goto <D.19098>; else goto <D.19099>;
      <D.19098>:
      if (finalizer == 0B) goto <D.19100>; else goto <D.19101>;
      <D.19100>:
      mono_domain_set_internal (caller_domain);
      return;
      <D.19101>:
      <D.19099>:
      D.19102 = domain->finalize_runtime_invoke;
      if (D.19102 == 0B) goto <D.19103>; else goto <D.19104>;
      <D.19103>:
      {
        struct MonoMethod * invoke;

        D.19105 = mono_defaults.object_class;
        D.19106 = mono_class_get_method_from_name_flags (D.19105, "Finalize", 0, 0);
        invoke = mono_marshal_get_runtime_invoke (D.19106, 1);
        D.19107 = mono_compile_method (invoke);
        domain->finalize_runtime_invoke = D.19107;
      }
      <D.19104>:
      D.19102 = domain->finalize_runtime_invoke;
      runtime_invoke = (struct MonoObject * (*RuntimeInvokeFunction) (struct MonoObject *, void * *, struct MonoObject * *, void *)) D.19102;
      D.19023 = o->vtable;
      mono_runtime_class_init (D.19023);
      if (0 != 0) goto <D.19108>; else goto <D.19109>;
      <D.19108>:
      <D.19109>:
      runtime_invoke (o, 0B, &exc, 0B);
      exc.4 = exc;
      if (exc.4 != 0B) goto <D.19111>; else goto <D.19112>;
      <D.19111>:
      exc.4 = exc;
      mono_internal_thread_unhandled_exception (exc.4);
      <D.19112>:
      mono_domain_set_internal (caller_domain);
    }
  finally
    {
      exc = {CLOBBER};
    }
}


object_register_finalizer (struct MonoObject * obj, void (*<T100>) (void *, void *) callback)
{
  struct MonoException * D.19118;
  struct MonoVTable * D.19119;
  int D.19120;
  struct MonoDomain * domain;

  if (obj == 0B) goto <D.19116>; else goto <D.19117>;
  <D.19116>:
  D.19118 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19118);
  <D.19117>:
  D.19119 = obj->vtable;
  domain = D.19119->domain;
  D.19120 = mono_domain_is_unloading (domain);
  if (D.19120 == 0) goto <D.19121>; else goto <D.19122>;
  <D.19121>:
  mono_gc_register_for_finalization (obj, callback);
  <D.19122>:
}


add_thread_to_finalize (struct MonoInternalThread * thread)
{
  _Bool D.19125;
  long int D.19126;
  long int D.19127;
  struct MonoMList * threads_to_finalize.5;
  void * D.19135;
  struct MonoMList * threads_to_finalize.6;
  _Bool D.19139;
  long int D.19140;
  long int D.19141;

  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19123>; else goto <D.19124>;
    <D.19123>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19124>:
    D.19125 = ret != 0;
    D.19126 = (long int) D.19125;
    D.19127 = __builtin_expect (D.19126, 0);
    if (D.19127 != 0) goto <D.19128>; else goto <D.19129>;
    <D.19128>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 88, "ret == 0");
    <D.19129>:
  }
  threads_to_finalize.5 = threads_to_finalize;
  if (threads_to_finalize.5 == 0B) goto <D.19131>; else goto <D.19132>;
  <D.19131>:
  if (0 != 0) goto <D.19133>; else goto <D.19134>;
  <D.19133>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 90, "sizeof (threads_to_finalize) == sizeof (MonoObject*)");
  <D.19134>:
  D.19135 = mono_gc_make_root_descr_all_refs (1);
  mono_gc_register_root (&threads_to_finalize, 8, D.19135);
  <D.19132>:
  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.19137>; else goto <D.19138>;
    <D.19137>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19138>:
    D.19139 = ret != 0;
    D.19140 = (long int) D.19139;
    D.19141 = __builtin_expect (D.19140, 0);
    if (D.19141 != 0) goto <D.19142>; else goto <D.19143>;
    <D.19142>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 92, "ret == 0");
    <D.19143>:
  }
}


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

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


mono_gc_out_of_memory (size_t size)
{
  struct MonoDomain * D.19146;
  struct MonoException * D.19147;
  void * D.19148;

  D.19146 = mono_domain_get ();
  D.19147 = D.19146->out_of_memory_ex;
  mono_raise_exception (D.19147);
  D.19148 = 0B;
  return D.19148;
}


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.19150;
  struct MonoInternalThread * gc_thread.9;
  mono_bool D.19154;
  int gc_disabled.10;
  int D.19158;
  struct MonoDomain * D.19161;
  _Bool D.19166;
  long int D.19167;
  long int D.19168;
  struct GSList * domains_to_finalize.11;
  struct GSList * domains_to_finalize.12;
  _Bool D.19175;
  long int D.19176;
  long int D.19177;
  unsigned int D.19184;
  unsigned int D.19185;
  struct MonoDomain * D.19190;
  struct DomainFinalizationReq * req;
  guint32 res;
  void * done_event;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.19150 = mono_thread_internal_current ();
  gc_thread.9 = gc_thread;
  if (D.19150 == gc_thread.9) goto <D.19152>; else goto <D.19153>;
  <D.19152>:
  D.19154 = 0;
  return D.19154;
  <D.19153>:
  gc_disabled.10 = gc_disabled;
  if (gc_disabled.10 != 0) goto <D.19156>; else goto <D.19157>;
  <D.19156>:
  D.19154 = 1;
  return D.19154;
  <D.19157>:
  D.19158 = mono_gc_max_generation ();
  mono_gc_collect (D.19158);
  done_event = CreateEvent (0B, 1, 0, 0B);
  if (done_event == 0B) goto <D.19159>; else goto <D.19160>;
  <D.19159>:
  D.19154 = 0;
  return D.19154;
  <D.19160>:
  req = monoeg_malloc0 (16);
  req->domain = domain;
  req->done_event = done_event;
  D.19161 = mono_get_root_domain ();
  if (D.19161 == domain) goto <D.19162>; else goto <D.19163>;
  <D.19162>:
  finalizing_root_domain = 1;
  <D.19163>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19164>; else goto <D.19165>;
    <D.19164>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19165>:
    D.19166 = ret != 0;
    D.19167 = (long int) D.19166;
    D.19168 = __builtin_expect (D.19167, 0);
    if (D.19168 != 0) goto <D.19169>; else goto <D.19170>;
    <D.19169>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 367, "ret == 0");
    <D.19170>:
  }
  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.19173>; else goto <D.19174>;
    <D.19173>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19174>:
    D.19175 = ret != 0;
    D.19176 = (long int) D.19175;
    D.19177 = __builtin_expect (D.19176, 0);
    if (D.19177 != 0) goto <D.19178>; else goto <D.19179>;
    <D.19178>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 371, "ret == 0");
    <D.19179>:
  }
  mono_gc_finalize_notify ();
  if (timeout == 4294967295) goto <D.19180>; else goto <D.19181>;
  <D.19180>:
  timeout = 4294967295;
  <D.19181>:
  <D.18703>:
  res = WaitForSingleObjectEx (done_event, timeout, 1);
  if (res == 192) goto <D.19182>; else goto <D.19183>;
  <D.19182>:
  D.19184 = thread->state;
  D.19185 = D.19184 & 3;
  if (D.19185 != 0) goto <D.19186>; else goto <D.19187>;
  <D.19186>:
  D.19154 = 0;
  return D.19154;
  <D.19187>:
  goto <D.19188>;
  <D.19183>:
  if (res == 258) goto <D.19189>; else goto <D.18702>;
  <D.19189>:
  D.19154 = 0;
  return D.19154;
  <D.19188>:
  goto <D.18703>;
  <D.18702>:
  CloseHandle (done_event);
  D.19190 = mono_get_root_domain ();
  if (D.19190 == domain) goto <D.19191>; else goto <D.19192>;
  <D.19191>:
  mono_thread_pool_cleanup ();
  mono_gc_finalize_threadpool_threads ();
  <D.19192>:
  D.19154 = 1;
  return D.19154;
}


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


ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
{
  int D.19196;
  gint64 D.19197;

  if (forceCollection != 0) goto <D.19194>; else goto <D.19195>;
  <D.19194>:
  D.19196 = mono_gc_max_generation ();
  mono_gc_collect (D.19196);
  <D.19195>:
  D.19197 = mono_gc_get_used_size ();
  return D.19197;
}


ves_icall_System_GC_KeepAlive (struct MonoObject * obj)
{

}


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

  if (obj == 0B) goto <D.19199>; else goto <D.19200>;
  <D.19199>:
  D.19201 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19201);
  <D.19200>:
  object_register_finalizer (obj, mono_gc_run_finalize);
}


ves_icall_System_GC_SuppressFinalize (struct MonoObject * obj)
{
  struct MonoException * D.19204;
  struct MonoVTable * D.19205;
  struct MonoClass * D.19206;
  unsigned char D.19207;
  unsigned char D.19208;

  if (obj == 0B) goto <D.19202>; else goto <D.19203>;
  <D.19202>:
  D.19204 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19204);
  <D.19203>:
  D.19205 = obj->vtable;
  D.19206 = D.19205->klass;
  D.19207 = BIT_FIELD_REF <*D.19206, 8, 280>;
  D.19208 = D.19207 & 1;
  if (D.19208 != 0) goto <D.19209>; else goto <D.19210>;
  <D.19209>:
  return;
  <D.19210>:
  object_register_finalizer (obj, 0B);
}


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

  D.19212 = mono_gc_pending_finalizers ();
  if (D.19212 == 0) goto <D.19213>; else goto <D.19214>;
  <D.19213>:
  return;
  <D.19214>:
  D.19215 = mono_thread_internal_current ();
  gc_thread.13 = gc_thread;
  if (D.19215 == gc_thread.13) goto <D.19217>; else goto <D.19218>;
  <D.19217>:
  return;
  <D.19218>:
  gc_thread.13 = gc_thread;
  if (gc_thread.13 == 0B) goto <D.19219>; else goto <D.19220>;
  <D.19219>:
  return;
  <D.19220>:
  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.19223;
  struct MonoVTable * D.19226;
  struct MonoDomain * D.19227;
  struct MonoException * D.19228;

  D.19223 = mono_gc_ephemeron_array_add (array);
  if (D.19223 == 0) goto <D.19224>; else goto <D.19225>;
  <D.19224>:
  D.19226 = array->vtable;
  D.19227 = D.19226->domain;
  D.19228 = D.19227->out_of_memory_ex;
  mono_raise_exception (D.19228);
  <D.19225>:
}


ves_icall_System_GC_get_ephemeron_tombstone ()
{
  struct MonoObject * D.19229;
  struct MonoDomain * D.19230;

  D.19230 = mono_domain_get ();
  D.19229 = D.19230->ephemeron_tombstone;
  return D.19229;
}


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

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


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

  if (type == -1) goto <D.19234>; else goto <D.19235>;
  <D.19234>:
  mono_gchandle_set_target (handle, obj);
  D.19236 = handle;
  return D.19236;
  <D.19235>:
  switch (type) <default: <D.18750>, case 0: <D.18746>, case 1: <D.18747>, case 2: <D.18748>, case 3: <D.18749>>
  <D.18746>:
  D.19236 = mono_gchandle_new_weakref (obj, 0);
  return D.19236;
  <D.18747>:
  D.19236 = mono_gchandle_new_weakref (obj, 1);
  return D.19236;
  <D.18748>:
  D.19236 = mono_gchandle_new (obj, 0);
  return D.19236;
  <D.18749>:
  D.19236 = mono_gchandle_new (obj, 1);
  return D.19236;
  <D.18750>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 545);
  D.19236 = 0;
  return D.19236;
}


mono_gchandle_set_target (guint32 gchandle, struct MonoObject * obj)
{
  unsigned int D.19238;
  _Bool D.19243;
  long int D.19244;
  long int D.19245;
  unsigned int D.19248;
  guint32 * D.19251;
  unsigned int D.19252;
  long unsigned int D.19253;
  long unsigned int D.19254;
  guint32 * D.19255;
  unsigned int D.19256;
  int slot.15;
  int D.19258;
  int D.19259;
  unsigned int D.19260;
  unsigned int D.19261;
  unsigned char D.19264;
  void * * D.19267;
  long unsigned int D.19268;
  long unsigned int D.19269;
  void * * D.19270;
  void * D.19271;
  _Bool D.19274;
  int D.19275;
  void * * D.19276;
  guint16 * D.19279;
  long unsigned int D.19280;
  guint16 * D.19281;
  struct MonoDomain * iftmp.16;
  int D.19286;
  short unsigned int D.19287;
  _Bool D.19292;
  long int D.19293;
  long int D.19294;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * old_obj;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19241>; else goto <D.19242>;
    <D.19241>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19242>:
    D.19243 = ret != 0;
    D.19244 = (long int) D.19243;
    D.19245 = __builtin_expect (D.19244, 0);
    if (D.19245 != 0) goto <D.19246>; else goto <D.19247>;
    <D.19246>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 834, "ret == 0");
    <D.19247>:
  }
  D.19248 = handles->size;
  if (D.19248 > slot) goto <D.19249>; else goto <D.19250>;
  <D.19249>:
  D.19251 = handles->bitmap;
  D.19252 = slot / 32;
  D.19253 = (long unsigned int) D.19252;
  D.19254 = D.19253 * 4;
  D.19255 = D.19251 + D.19254;
  D.19256 = *D.19255;
  slot.15 = (int) slot;
  D.19258 = slot.15 & 31;
  D.19259 = 1 << D.19258;
  D.19260 = (unsigned int) D.19259;
  D.19261 = D.19256 & D.19260;
  if (D.19261 != 0) goto <D.19262>; else goto <D.19263>;
  <D.19262>:
  D.19264 = handles->type;
  if (D.19264 <= 1) goto <D.19265>; else goto <D.19266>;
  <D.19265>:
  D.19267 = handles->entries;
  D.19268 = (long unsigned int) slot;
  D.19269 = D.19268 * 8;
  D.19270 = D.19267 + D.19269;
  old_obj = *D.19270;
  D.19267 = handles->entries;
  D.19268 = (long unsigned int) slot;
  D.19269 = D.19268 * 8;
  D.19270 = D.19267 + D.19269;
  D.19271 = *D.19270;
  if (D.19271 != 0B) goto <D.19272>; else goto <D.19273>;
  <D.19272>:
  D.19264 = handles->type;
  D.19274 = D.19264 == 1;
  D.19275 = (int) D.19274;
  D.19267 = handles->entries;
  D.19268 = (long unsigned int) slot;
  D.19269 = D.19268 * 8;
  D.19276 = D.19267 + D.19269;
  mono_gc_weak_link_remove (D.19276, D.19275);
  <D.19273>:
  if (obj != 0B) goto <D.19277>; else goto <D.19278>;
  <D.19277>:
  D.19264 = handles->type;
  D.19274 = D.19264 == 1;
  D.19275 = (int) D.19274;
  D.19267 = handles->entries;
  D.19268 = (long unsigned int) slot;
  D.19269 = D.19268 * 8;
  D.19276 = D.19267 + D.19269;
  mono_gc_weak_link_add (D.19276, obj, D.19275);
  <D.19278>:
  D.19279 = handles->domain_ids;
  D.19268 = (long unsigned int) slot;
  D.19280 = D.19268 * 2;
  D.19281 = D.19279 + D.19280;
  if (obj != 0B) goto <D.19283>; else goto <D.19284>;
  <D.19283>:
  iftmp.16 = mono_object_get_domain (obj);
  goto <D.19285>;
  <D.19284>:
  iftmp.16 = mono_domain_get ();
  <D.19285>:
  D.19286 = iftmp.16->domain_id;
  D.19287 = (short unsigned int) D.19286;
  *D.19281 = D.19287;
  goto <D.19288>;
  <D.19266>:
  D.19267 = handles->entries;
  D.19268 = (long unsigned int) slot;
  D.19269 = D.19268 * 8;
  D.19270 = D.19267 + D.19269;
  *D.19270 = obj;
  <D.19288>:
  goto <D.19289>;
  <D.19263>:
  <D.19289>:
  <D.19250>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19290>; else goto <D.19291>;
    <D.19290>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19291>:
    D.19292 = ret != 0;
    D.19293 = (long int) D.19292;
    D.19294 = __builtin_expect (D.19293, 0);
    if (D.19294 != 0) goto <D.19295>; else goto <D.19296>;
    <D.19295>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 851, "ret == 0");
    <D.19296>:
  }
}


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


ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
{
  <unnamed type> D.19298;
  void * D.19301;
  struct MonoVTable * D.19304;
  struct MonoClass * D.19305;
  unsigned char D.19308;
  unsigned int D.19311;
  unsigned int D.19312;
  struct MonoObject * obj;

  D.19298 = mono_gchandle_get_type (handle);
  if (D.19298 != 3) goto <D.19299>; else goto <D.19300>;
  <D.19299>:
  D.19301 = -2B;
  return D.19301;
  <D.19300>:
  obj = mono_gchandle_get_target (handle);
  if (obj != 0B) goto <D.19302>; else goto <D.19303>;
  <D.19302>:
  {
    struct MonoClass * klass;

    D.19304 = obj->vtable;
    klass = D.19304->klass;
    D.19305 = mono_defaults.string_class;
    if (D.19305 == klass) goto <D.19306>; else goto <D.19307>;
    <D.19306>:
    D.19301 = mono_string_chars (obj);
    return D.19301;
    <D.19307>:
    D.19308 = klass->rank;
    if (D.19308 != 0) goto <D.19309>; else goto <D.19310>;
    <D.19309>:
    D.19301 = mono_array_addr_with_size (obj, 1, 0);
    return D.19301;
    <D.19310>:
    D.19311 = klass->flags;
    D.19312 = D.19311 & 24;
    if (D.19312 == 0) goto <D.19313>; else goto <D.19314>;
    <D.19313>:
    D.19301 = -1B;
    return D.19301;
    <D.19314>:
    D.19301 = obj + 16;
    return D.19301;
  }
  <D.19303>:
  D.19301 = 0B;
  return D.19301;
}


mono_gchandle_get_type (guint32 gchandle)
{
  unsigned int D.19316;
  HandleType D.19317;
  guint type;

  D.19316 = gchandle & 7;
  type = D.19316 + 4294967295;
  D.19317 = type;
  return D.19317;
}


ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
{
  MonoBoolean D.19319;
  int D.19320;
  int D.19321;

  D.19320 = (int) flag;
  D.19321 = mono_gc_set_allow_synchronous_major (D.19320);
  D.19319 = (MonoBoolean) D.19321;
  return D.19319;
}


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

  if (pinned != 0) goto <D.19325>; else goto <D.19326>;
  <D.19325>:
  iftmp.17 = 3;
  goto <D.19327>;
  <D.19326>:
  iftmp.17 = 2;
  <D.19327>:
  D.19328 = &gc_handles[iftmp.17];
  D.19323 = alloc_handle (D.19328, obj, 0);
  return D.19323;
}


alloc_handle (struct HandleData * handles, struct MonoObject * obj, gboolean track)
{
  _Bool D.19332;
  long int D.19333;
  long int D.19334;
  unsigned int D.19337;
  unsigned char D.19340;
  _Bool D.19343;
  int D.19344;
  int D.19345;
  void * D.19346;
  long unsigned int D.19347;
  long unsigned int D.19348;
  void * D.19349;
  void * D.19351;
  long unsigned int D.19352;
  void * D.19353;
  unsigned int D.19354;
  long unsigned int D.19355;
  void * D.19356;
  <unnamed-unsigned:24> D.19357;
  guint32 * D.19358;
  long unsigned int D.19359;
  long unsigned int D.19360;
  guint32 * D.19361;
  unsigned int D.19362;
  unsigned int slot.18;
  <unnamed-unsigned:24> D.19366;
  unsigned int slot.19;
  unsigned int D.19368;
  unsigned int D.19371;
  unsigned int D.19372;
  int D.19377;
  unsigned int D.19380;
  long unsigned int D.19381;
  long unsigned int D.19382;
  int new_size.20;
  void * D.19386;
  long unsigned int D.19387;
  long unsigned int D.19388;
  void * * D.19389;
  long unsigned int D.19391;
  guint16 * D.19392;
  long unsigned int D.19393;
  long unsigned int D.19394;
  void * * D.19395;
  void * * D.19398;
  void * * D.19400;
  void * D.19401;
  _Bool D.19402;
  long int D.19403;
  long int D.19404;
  unsigned int i.21;
  unsigned int D.19408;
  unsigned int D.19409;
  <unnamed-unsigned:24> D.19410;
  int D.19411;
  unsigned int D.19412;
  unsigned int D.19413;
  int D.19414;
  long unsigned int D.19415;
  void * * D.19416;
  long unsigned int D.19419;
  guint16 * D.19420;
  struct MonoDomain * iftmp.22;
  int D.19425;
  short unsigned int D.19426;
  void * * D.19429;
  struct MonoPerfCounters * mono_perfcounters.23;
  unsigned int D.19432;
  unsigned int D.19433;
  _Bool D.19436;
  long int D.19437;
  long int D.19438;
  int D.19441;
  int D.19442;
  int D.19443;
  int D.19444;
  long unsigned int D.19445;
  guint32 D.19446;
  gint slot;
  gint i;
  guint32 res;

  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19330>; else goto <D.19331>;
    <D.19330>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19331>:
    D.19332 = ret != 0;
    D.19333 = (long int) D.19332;
    D.19334 = __builtin_expect (D.19333, 0);
    if (D.19334 != 0) goto <D.19335>; else goto <D.19336>;
    <D.19335>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 636, "ret == 0");
    <D.19336>:
  }
  D.19337 = handles->size;
  if (D.19337 == 0) goto <D.19338>; else goto <D.19339>;
  <D.19338>:
  handles->size = 32;
  D.19340 = handles->type;
  if (D.19340 > 1) goto <D.19341>; else goto <D.19342>;
  <D.19341>:
  D.19340 = handles->type;
  D.19343 = D.19340 == 3;
  D.19344 = (int) D.19343;
  D.19337 = handles->size;
  D.19345 = (int) D.19337;
  D.19346 = make_root_descr_all_refs (D.19345, D.19344);
  D.19337 = handles->size;
  D.19347 = (long unsigned int) D.19337;
  D.19348 = D.19347 * 8;
  D.19349 = mono_gc_alloc_fixed (D.19348, D.19346);
  handles->entries = D.19349;
  goto <D.19350>;
  <D.19342>:
  D.19337 = handles->size;
  D.19347 = (long unsigned int) D.19337;
  D.19348 = D.19347 * 8;
  D.19351 = monoeg_malloc0 (D.19348);
  handles->entries = D.19351;
  D.19337 = handles->size;
  D.19347 = (long unsigned int) D.19337;
  D.19352 = D.19347 * 2;
  D.19353 = monoeg_malloc0 (D.19352);
  handles->domain_ids = D.19353;
  <D.19350>:
  D.19337 = handles->size;
  D.19354 = D.19337 / 8;
  D.19355 = (long unsigned int) D.19354;
  D.19356 = monoeg_malloc0 (D.19355);
  handles->bitmap = D.19356;
  <D.19339>:
  i = -1;
  D.19357 = handles->slot_hint;
  slot = (gint) D.19357;
  goto <D.18794>;
  <D.18793>:
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19362 = *D.19361;
  if (D.19362 != 4294967295) goto <D.19363>; else goto <D.19364>;
  <D.19363>:
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19362 = *D.19361;
  i = find_first_unset (D.19362);
  slot.18 = (unsigned int) slot;
  D.19366 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.19366;
  goto <D.18792>;
  <D.19364>:
  slot = slot + 1;
  <D.18794>:
  slot.19 = (unsigned int) slot;
  D.19337 = handles->size;
  D.19368 = D.19337 / 32;
  if (slot.19 < D.19368) goto <D.18793>; else goto <D.18792>;
  <D.18792>:
  if (i == -1) goto <D.19369>; else goto <D.19370>;
  <D.19369>:
  D.19371 = BIT_FIELD_REF <*handles, 32, 160>;
  D.19372 = D.19371 & 4294967040;
  if (D.19372 != 0) goto <D.19373>; else goto <D.19374>;
  <D.19373>:
  slot = 0;
  goto <D.18797>;
  <D.18796>:
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19362 = *D.19361;
  if (D.19362 != 4294967295) goto <D.19375>; else goto <D.19376>;
  <D.19375>:
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19362 = *D.19361;
  i = find_first_unset (D.19362);
  slot.18 = (unsigned int) slot;
  D.19366 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.19366;
  goto <D.18795>;
  <D.19376>:
  slot = slot + 1;
  <D.18797>:
  D.19357 = handles->slot_hint;
  D.19377 = (int) D.19357;
  if (D.19377 > slot) goto <D.18796>; else goto <D.18795>;
  <D.18795>:
  <D.19374>:
  <D.19370>:
  if (i == -1) goto <D.19378>; else goto <D.19379>;
  <D.19378>:
  {
    guint32 * new_bitmap;
    guint32 new_size;

    D.19337 = handles->size;
    new_size = D.19337 * 2;
    D.19380 = new_size / 8;
    D.19381 = (long unsigned int) D.19380;
    new_bitmap = monoeg_malloc0 (D.19381);
    D.19337 = handles->size;
    D.19354 = D.19337 / 8;
    D.19382 = (long unsigned int) D.19354;
    D.19358 = handles->bitmap;
    memcpy (new_bitmap, D.19358, D.19382);
    D.19358 = handles->bitmap;
    monoeg_g_free (D.19358);
    handles->bitmap = new_bitmap;
    D.19340 = handles->type;
    if (D.19340 > 1) goto <D.19383>; else goto <D.19384>;
    <D.19383>:
    {
      void * * entries;

      D.19340 = handles->type;
      D.19343 = D.19340 == 3;
      D.19344 = (int) D.19343;
      new_size.20 = (int) new_size;
      D.19386 = make_root_descr_all_refs (new_size.20, D.19344);
      D.19387 = (long unsigned int) new_size;
      D.19388 = D.19387 * 8;
      entries = mono_gc_alloc_fixed (D.19388, D.19386);
      D.19337 = handles->size;
      D.19347 = (long unsigned int) D.19337;
      D.19348 = D.19347 * 8;
      D.19389 = handles->entries;
      mono_gc_memmove_aligned (entries, D.19389, D.19348);
      D.19389 = handles->entries;
      mono_gc_free_fixed (D.19389);
      handles->entries = entries;
    }
    goto <D.19390>;
    <D.19384>:
    {
      void * * entries;
      guint16 * domain_ids;

      D.19387 = (long unsigned int) new_size;
      D.19391 = D.19387 * 2;
      domain_ids = monoeg_malloc0 (D.19391);
      D.19387 = (long unsigned int) new_size;
      D.19388 = D.19387 * 8;
      entries = monoeg_malloc0 (D.19388);
      D.19337 = handles->size;
      D.19347 = (long unsigned int) D.19337;
      D.19352 = D.19347 * 2;
      D.19392 = handles->domain_ids;
      memcpy (domain_ids, D.19392, D.19352);
      i = 0;
      goto <D.18805>;
      <D.18804>:
      {
        struct MonoObject * obj;

        D.19389 = handles->entries;
        D.19393 = (long unsigned int) i;
        D.19394 = D.19393 * 8;
        D.19395 = D.19389 + D.19394;
        obj = mono_gc_weak_link_get (D.19395);
        if (obj != 0B) goto <D.19396>; else goto <D.19397>;
        <D.19396>:
        D.19393 = (long unsigned int) i;
        D.19394 = D.19393 * 8;
        D.19398 = entries + D.19394;
        mono_gc_weak_link_add (D.19398, obj, track);
        D.19389 = handles->entries;
        D.19393 = (long unsigned int) i;
        D.19394 = D.19393 * 8;
        D.19395 = D.19389 + D.19394;
        mono_gc_weak_link_remove (D.19395, track);
        goto <D.19399>;
        <D.19397>:
        D.19389 = handles->entries;
        D.19393 = (long unsigned int) i;
        D.19394 = D.19393 * 8;
        D.19400 = D.19389 + D.19394;
        D.19401 = *D.19400;
        D.19402 = D.19401 != 0B;
        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", 695, "!handles->entries [i]");
        <D.19406>:
        <D.19399>:
      }
      i = i + 1;
      <D.18805>:
      i.21 = (unsigned int) i;
      D.19337 = handles->size;
      if (i.21 < D.19337) goto <D.18804>; else goto <D.18806>;
      <D.18806>:
      D.19389 = handles->entries;
      monoeg_g_free (D.19389);
      D.19392 = handles->domain_ids;
      monoeg_g_free (D.19392);
      handles->entries = entries;
      handles->domain_ids = domain_ids;
    }
    <D.19390>:
    i = 0;
    D.19337 = handles->size;
    D.19408 = D.19337 + 1;
    D.19409 = D.19408 / 32;
    slot = (gint) D.19409;
    D.19337 = handles->size;
    D.19408 = D.19337 + 1;
    D.19410 = (<unnamed-unsigned:24>) D.19408;
    handles->slot_hint = D.19410;
    handles->size = new_size;
  }
  <D.19379>:
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19358 = handles->bitmap;
  D.19359 = (long unsigned int) slot;
  D.19360 = D.19359 * 4;
  D.19361 = D.19358 + D.19360;
  D.19362 = *D.19361;
  D.19411 = 1 << i;
  D.19412 = (unsigned int) D.19411;
  D.19413 = D.19362 | D.19412;
  *D.19361 = D.19413;
  D.19414 = slot * 32;
  slot = D.19414 + i;
  D.19389 = handles->entries;
  D.19359 = (long unsigned int) slot;
  D.19415 = D.19359 * 8;
  D.19416 = D.19389 + D.19415;
  *D.19416 = 0B;
  D.19340 = handles->type;
  if (D.19340 <= 1) goto <D.19417>; else goto <D.19418>;
  <D.19417>:
  D.19392 = handles->domain_ids;
  D.19359 = (long unsigned int) slot;
  D.19419 = D.19359 * 2;
  D.19420 = D.19392 + D.19419;
  if (obj != 0B) goto <D.19422>; else goto <D.19423>;
  <D.19422>:
  iftmp.22 = mono_object_get_domain (obj);
  goto <D.19424>;
  <D.19423>:
  iftmp.22 = mono_domain_get ();
  <D.19424>:
  D.19425 = iftmp.22->domain_id;
  D.19426 = (short unsigned int) D.19425;
  *D.19420 = D.19426;
  if (obj != 0B) goto <D.19427>; else goto <D.19428>;
  <D.19427>:
  D.19389 = handles->entries;
  D.19359 = (long unsigned int) slot;
  D.19415 = D.19359 * 8;
  D.19429 = D.19389 + D.19415;
  mono_gc_weak_link_add (D.19429, obj, track);
  <D.19428>:
  goto <D.19430>;
  <D.19418>:
  D.19389 = handles->entries;
  D.19359 = (long unsigned int) slot;
  D.19415 = D.19359 * 8;
  D.19416 = D.19389 + D.19415;
  *D.19416 = obj;
  <D.19430>:
  mono_perfcounters.23 = mono_perfcounters;
  D.19432 = mono_perfcounters.23->gc_num_handles;
  D.19433 = D.19432 + 1;
  mono_perfcounters.23->gc_num_handles = D.19433;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19434>; else goto <D.19435>;
    <D.19434>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19435>:
    D.19436 = ret != 0;
    D.19437 = (long int) D.19436;
    D.19438 = __builtin_expect (D.19437, 0);
    if (D.19438 != 0) goto <D.19439>; else goto <D.19440>;
    <D.19439>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 725, "ret == 0");
    <D.19440>:
  }
  D.19441 = slot << 3;
  D.19340 = handles->type;
  D.19442 = (int) D.19340;
  D.19443 = D.19442 + 1;
  D.19444 = D.19441 | D.19443;
  res = (guint32) D.19444;
  D.19445 = (long unsigned int) res;
  D.19340 = handles->type;
  D.19442 = (int) D.19340;
  mono_profiler_gc_handle (0, D.19442, D.19445, obj);
  D.19446 = res;
  return D.19446;
}


find_first_unset (guint32 bitmap)
{
  int D.19448;
  unsigned int D.19449;
  unsigned int D.19450;
  int D.19453;
  int i;

  i = 0;
  goto <D.18777>;
  <D.18776>:
  D.19448 = 1 << i;
  D.19449 = (unsigned int) D.19448;
  D.19450 = D.19449 & bitmap;
  if (D.19450 == 0) goto <D.19451>; else goto <D.19452>;
  <D.19451>:
  D.19453 = i;
  return D.19453;
  <D.19452>:
  i = i + 1;
  <D.18777>:
  if (i <= 31) goto <D.18776>; else goto <D.18778>;
  <D.18778>:
  D.19453 = -1;
  return D.19453;
}


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

  if (pinned != 0) goto <D.19455>; else goto <D.19456>;
  <D.19455>:
  D.19457 = 0B;
  return D.19457;
  <D.19456>:
  D.19457 = mono_gc_make_root_descr_all_refs (numbits);
  return D.19457;
}


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

  D.19460 = __builtin_object_size (__dest, 0);
  D.19459 = __builtin___memcpy_chk (__dest, __src, __len, D.19460);
  return D.19459;
}


mono_gchandle_new_weakref (struct MonoObject * obj, gboolean track_resurrection)
{
  _Bool D.19462;
  int D.19463;
  struct HandleData * D.19464;
  uint32_t D.19465;
  guint32 handle;

  D.19462 = track_resurrection != 0;
  D.19463 = (int) D.19462;
  D.19464 = &gc_handles[D.19463];
  handle = alloc_handle (D.19464, obj, track_resurrection);
  D.19465 = handle;
  return D.19465;
}


mono_gchandle_get_target (guint32 gchandle)
{
  unsigned int D.19467;
  struct MonoObject * D.19470;
  _Bool D.19473;
  long int D.19474;
  long int D.19475;
  unsigned int D.19478;
  guint32 * D.19481;
  unsigned int D.19482;
  long unsigned int D.19483;
  long unsigned int D.19484;
  guint32 * D.19485;
  unsigned int D.19486;
  int slot.24;
  int D.19488;
  int D.19489;
  unsigned int D.19490;
  unsigned int D.19491;
  unsigned char D.19494;
  void * * D.19497;
  long unsigned int D.19498;
  long unsigned int D.19499;
  void * * D.19500;
  void * * D.19502;
  _Bool D.19506;
  long int D.19507;
  long int D.19508;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * obj;

  slot = gchandle >> 3;
  D.19467 = gchandle & 7;
  type = D.19467 + 4294967295;
  handles = &gc_handles[type];
  obj = 0B;
  if (type > 3) goto <D.19468>; else goto <D.19469>;
  <D.19468>:
  D.19470 = 0B;
  return D.19470;
  <D.19469>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19471>; else goto <D.19472>;
    <D.19471>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19472>:
    D.19473 = ret != 0;
    D.19474 = (long int) D.19473;
    D.19475 = __builtin_expect (D.19474, 0);
    if (D.19475 != 0) goto <D.19476>; else goto <D.19477>;
    <D.19476>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 809, "ret == 0");
    <D.19477>:
  }
  D.19478 = handles->size;
  if (D.19478 > slot) goto <D.19479>; else goto <D.19480>;
  <D.19479>:
  D.19481 = handles->bitmap;
  D.19482 = slot / 32;
  D.19483 = (long unsigned int) D.19482;
  D.19484 = D.19483 * 4;
  D.19485 = D.19481 + D.19484;
  D.19486 = *D.19485;
  slot.24 = (int) slot;
  D.19488 = slot.24 & 31;
  D.19489 = 1 << D.19488;
  D.19490 = (unsigned int) D.19489;
  D.19491 = D.19486 & D.19490;
  if (D.19491 != 0) goto <D.19492>; else goto <D.19493>;
  <D.19492>:
  D.19494 = handles->type;
  if (D.19494 <= 1) goto <D.19495>; else goto <D.19496>;
  <D.19495>:
  D.19497 = handles->entries;
  D.19498 = (long unsigned int) slot;
  D.19499 = D.19498 * 8;
  D.19500 = D.19497 + D.19499;
  obj = mono_gc_weak_link_get (D.19500);
  goto <D.19501>;
  <D.19496>:
  D.19497 = handles->entries;
  D.19498 = (long unsigned int) slot;
  D.19499 = D.19498 * 8;
  D.19502 = D.19497 + D.19499;
  obj = *D.19502;
  <D.19501>:
  goto <D.19503>;
  <D.19493>:
  <D.19503>:
  <D.19480>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.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", 819, "ret == 0");
    <D.19510>:
  }
  D.19470 = obj;
  return D.19470;
}


mono_gchandle_is_in_domain (guint32 gchandle, struct MonoDomain * domain)
{
  unsigned int D.19512;
  gboolean D.19515;
  _Bool D.19518;
  long int D.19519;
  long int D.19520;
  unsigned int D.19523;
  guint32 * D.19526;
  unsigned int D.19527;
  long unsigned int D.19528;
  long unsigned int D.19529;
  guint32 * D.19530;
  unsigned int D.19531;
  int slot.25;
  int D.19533;
  int D.19534;
  unsigned int D.19535;
  unsigned int D.19536;
  unsigned char D.19539;
  int D.19542;
  guint16 * D.19543;
  long unsigned int D.19544;
  long unsigned int D.19545;
  guint16 * D.19546;
  short unsigned int D.19547;
  int D.19548;
  _Bool D.19549;
  void * * D.19551;
  long unsigned int D.19552;
  void * * D.19553;
  struct MonoVTable * D.19557;
  struct MonoDomain * D.19558;
  _Bool D.19559;
  _Bool D.19563;
  long int D.19564;
  long int D.19565;
  guint slot;
  guint type;
  struct HandleData * handles;
  gboolean result;

  slot = gchandle >> 3;
  D.19512 = gchandle & 7;
  type = D.19512 + 4294967295;
  handles = &gc_handles[type];
  result = 0;
  if (type > 3) goto <D.19513>; else goto <D.19514>;
  <D.19513>:
  D.19515 = 0;
  return D.19515;
  <D.19514>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19516>; else goto <D.19517>;
    <D.19516>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19517>:
    D.19518 = ret != 0;
    D.19519 = (long int) D.19518;
    D.19520 = __builtin_expect (D.19519, 0);
    if (D.19520 != 0) goto <D.19521>; else goto <D.19522>;
    <D.19521>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 870, "ret == 0");
    <D.19522>:
  }
  D.19523 = handles->size;
  if (D.19523 > slot) goto <D.19524>; else goto <D.19525>;
  <D.19524>:
  D.19526 = handles->bitmap;
  D.19527 = slot / 32;
  D.19528 = (long unsigned int) D.19527;
  D.19529 = D.19528 * 4;
  D.19530 = D.19526 + D.19529;
  D.19531 = *D.19530;
  slot.25 = (int) slot;
  D.19533 = slot.25 & 31;
  D.19534 = 1 << D.19533;
  D.19535 = (unsigned int) D.19534;
  D.19536 = D.19531 & D.19535;
  if (D.19536 != 0) goto <D.19537>; else goto <D.19538>;
  <D.19537>:
  D.19539 = handles->type;
  if (D.19539 <= 1) goto <D.19540>; else goto <D.19541>;
  <D.19540>:
  D.19542 = domain->domain_id;
  D.19543 = handles->domain_ids;
  D.19544 = (long unsigned int) slot;
  D.19545 = D.19544 * 2;
  D.19546 = D.19543 + D.19545;
  D.19547 = *D.19546;
  D.19548 = (int) D.19547;
  D.19549 = D.19542 == D.19548;
  result = (gboolean) D.19549;
  goto <D.19550>;
  <D.19541>:
  {
    struct MonoObject * obj;

    D.19551 = handles->entries;
    D.19544 = (long unsigned int) slot;
    D.19552 = D.19544 * 8;
    D.19553 = D.19551 + D.19552;
    obj = *D.19553;
    if (obj == 0B) goto <D.19554>; else goto <D.19555>;
    <D.19554>:
    result = 1;
    goto <D.19556>;
    <D.19555>:
    D.19557 = obj->vtable;
    D.19558 = D.19557->domain;
    D.19559 = D.19558 == domain;
    result = (gboolean) D.19559;
    <D.19556>:
  }
  <D.19550>:
  goto <D.19560>;
  <D.19538>:
  <D.19560>:
  <D.19525>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19561>; else goto <D.19562>;
    <D.19561>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19562>:
    D.19563 = ret != 0;
    D.19564 = (long int) D.19563;
    D.19565 = __builtin_expect (D.19564, 0);
    if (D.19565 != 0) goto <D.19566>; else goto <D.19567>;
    <D.19566>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 885, "ret == 0");
    <D.19567>:
  }
  D.19515 = result;
  return D.19515;
}


mono_gchandle_free (guint32 gchandle)
{
  unsigned int D.19569;
  _Bool D.19574;
  long int D.19575;
  long int D.19576;
  unsigned int D.19579;
  guint32 * D.19582;
  unsigned int D.19583;
  long unsigned int D.19584;
  long unsigned int D.19585;
  guint32 * D.19586;
  unsigned int D.19587;
  int slot.26;
  int D.19589;
  int D.19590;
  unsigned int D.19591;
  unsigned int D.19592;
  unsigned char D.19595;
  void * * D.19598;
  long unsigned int D.19599;
  long unsigned int D.19600;
  void * * D.19601;
  void * D.19602;
  _Bool D.19605;
  int D.19606;
  void * * D.19607;
  unsigned int D.19609;
  long unsigned int D.19610;
  long unsigned int D.19611;
  guint32 * D.19612;
  unsigned int D.19613;
  int D.19614;
  unsigned int D.19615;
  unsigned int D.19616;
  struct MonoPerfCounters * mono_perfcounters.27;
  unsigned int D.19619;
  unsigned int D.19620;
  _Bool D.19623;
  long int D.19624;
  long int D.19625;
  long unsigned int D.19628;
  int D.19629;
  guint slot;
  guint type;
  struct HandleData * handles;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19572>; else goto <D.19573>;
    <D.19572>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19573>:
    D.19574 = ret != 0;
    D.19575 = (long int) D.19574;
    D.19576 = __builtin_expect (D.19575, 0);
    if (D.19576 != 0) goto <D.19577>; else goto <D.19578>;
    <D.19577>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 906, "ret == 0");
    <D.19578>:
  }
  D.19579 = handles->size;
  if (D.19579 > slot) goto <D.19580>; else goto <D.19581>;
  <D.19580>:
  D.19582 = handles->bitmap;
  D.19583 = slot / 32;
  D.19584 = (long unsigned int) D.19583;
  D.19585 = D.19584 * 4;
  D.19586 = D.19582 + D.19585;
  D.19587 = *D.19586;
  slot.26 = (int) slot;
  D.19589 = slot.26 & 31;
  D.19590 = 1 << D.19589;
  D.19591 = (unsigned int) D.19590;
  D.19592 = D.19587 & D.19591;
  if (D.19592 != 0) goto <D.19593>; else goto <D.19594>;
  <D.19593>:
  D.19595 = handles->type;
  if (D.19595 <= 1) goto <D.19596>; else goto <D.19597>;
  <D.19596>:
  D.19598 = handles->entries;
  D.19599 = (long unsigned int) slot;
  D.19600 = D.19599 * 8;
  D.19601 = D.19598 + D.19600;
  D.19602 = *D.19601;
  if (D.19602 != 0B) goto <D.19603>; else goto <D.19604>;
  <D.19603>:
  D.19595 = handles->type;
  D.19605 = D.19595 == 1;
  D.19606 = (int) D.19605;
  D.19598 = handles->entries;
  D.19599 = (long unsigned int) slot;
  D.19600 = D.19599 * 8;
  D.19607 = D.19598 + D.19600;
  mono_gc_weak_link_remove (D.19607, D.19606);
  <D.19604>:
  goto <D.19608>;
  <D.19597>:
  D.19598 = handles->entries;
  D.19599 = (long unsigned int) slot;
  D.19600 = D.19599 * 8;
  D.19601 = D.19598 + D.19600;
  *D.19601 = 0B;
  <D.19608>:
  D.19582 = handles->bitmap;
  D.19609 = slot / 32;
  D.19610 = (long unsigned int) D.19609;
  D.19611 = D.19610 * 4;
  D.19612 = D.19582 + D.19611;
  D.19582 = handles->bitmap;
  D.19610 = (long unsigned int) D.19609;
  D.19611 = D.19610 * 4;
  D.19612 = D.19582 + D.19611;
  D.19613 = *D.19612;
  slot.26 = (int) slot;
  D.19589 = slot.26 & 31;
  D.19590 = 1 << D.19589;
  D.19614 = ~D.19590;
  D.19615 = (unsigned int) D.19614;
  D.19616 = D.19613 & D.19615;
  *D.19612 = D.19616;
  goto <D.19617>;
  <D.19594>:
  <D.19617>:
  <D.19581>:
  mono_perfcounters.27 = mono_perfcounters;
  D.19619 = mono_perfcounters.27->gc_num_handles;
  D.19620 = D.19619 + 4294967295;
  mono_perfcounters.27->gc_num_handles = D.19620;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19621>; else goto <D.19622>;
    <D.19621>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19622>:
    D.19623 = ret != 0;
    D.19624 = (long int) D.19623;
    D.19625 = __builtin_expect (D.19624, 0);
    if (D.19625 != 0) goto <D.19626>; else goto <D.19627>;
    <D.19626>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 922, "ret == 0");
    <D.19627>:
  }
  D.19628 = (long unsigned int) gchandle;
  D.19595 = handles->type;
  D.19629 = (int) D.19595;
  mono_profiler_gc_handle (1, D.19629, D.19628, 0B);
}


mono_gchandle_free_domain (struct MonoDomain * domain)
{
  _Bool D.19633;
  long int D.19634;
  long int D.19635;
  guint32 * D.19638;
  unsigned int D.19639;
  long unsigned int D.19640;
  long unsigned int D.19641;
  guint32 * D.19642;
  unsigned int D.19643;
  int slot.28;
  int D.19645;
  int D.19646;
  unsigned int D.19647;
  unsigned int D.19648;
  int D.19653;
  guint16 * D.19654;
  long unsigned int D.19655;
  long unsigned int D.19656;
  guint16 * D.19657;
  short unsigned int D.19658;
  int D.19659;
  unsigned int D.19662;
  long unsigned int D.19663;
  long unsigned int D.19664;
  guint32 * D.19665;
  unsigned int D.19666;
  int D.19667;
  unsigned int D.19668;
  unsigned int D.19669;
  void * * D.19670;
  long unsigned int D.19671;
  void * * D.19672;
  void * D.19673;
  unsigned char D.19676;
  _Bool D.19677;
  int D.19678;
  void * * D.19679;
  struct MonoVTable * D.19683;
  struct MonoDomain * D.19684;
  unsigned int D.19687;
  long unsigned int D.19688;
  long unsigned int D.19689;
  guint32 * D.19690;
  unsigned int D.19691;
  unsigned int D.19692;
  unsigned int D.19693;
  _Bool D.19696;
  long int D.19697;
  long int D.19698;
  guint type;

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

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

      ret = pthread_mutex_lock (&handle_section.mutex);
      if (ret != 0) goto <D.19631>; else goto <D.19632>;
      <D.19631>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.19632>:
      D.19633 = ret != 0;
      D.19634 = (long int) D.19633;
      D.19635 = __builtin_expect (D.19634, 0);
      if (D.19635 != 0) goto <D.19636>; else goto <D.19637>;
      <D.19636>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 941, "ret == 0");
      <D.19637>:
    }
    slot = 0;
    goto <D.18868>;
    <D.18867>:
    D.19638 = handles->bitmap;
    D.19639 = slot / 32;
    D.19640 = (long unsigned int) D.19639;
    D.19641 = D.19640 * 4;
    D.19642 = D.19638 + D.19641;
    D.19643 = *D.19642;
    slot.28 = (int) slot;
    D.19645 = slot.28 & 31;
    D.19646 = 1 << D.19645;
    D.19647 = (unsigned int) D.19646;
    D.19648 = D.19643 & D.19647;
    if (D.19648 == 0) goto <D.19649>; else goto <D.19650>;
    <D.19649>:
    // predicted unlikely by continue predictor.
    goto <D.18866>;
    <D.19650>:
    if (type <= 1) goto <D.19651>; else goto <D.19652>;
    <D.19651>:
    D.19653 = domain->domain_id;
    D.19654 = handles->domain_ids;
    D.19655 = (long unsigned int) slot;
    D.19656 = D.19655 * 2;
    D.19657 = D.19654 + D.19656;
    D.19658 = *D.19657;
    D.19659 = (int) D.19658;
    if (D.19653 == D.19659) goto <D.19660>; else goto <D.19661>;
    <D.19660>:
    D.19638 = handles->bitmap;
    D.19662 = slot / 32;
    D.19663 = (long unsigned int) D.19662;
    D.19664 = D.19663 * 4;
    D.19665 = D.19638 + D.19664;
    D.19638 = handles->bitmap;
    D.19663 = (long unsigned int) D.19662;
    D.19664 = D.19663 * 4;
    D.19665 = D.19638 + D.19664;
    D.19666 = *D.19665;
    slot.28 = (int) slot;
    D.19645 = slot.28 & 31;
    D.19646 = 1 << D.19645;
    D.19667 = ~D.19646;
    D.19668 = (unsigned int) D.19667;
    D.19669 = D.19666 & D.19668;
    *D.19665 = D.19669;
    D.19670 = handles->entries;
    D.19655 = (long unsigned int) slot;
    D.19671 = D.19655 * 8;
    D.19672 = D.19670 + D.19671;
    D.19673 = *D.19672;
    if (D.19673 != 0B) goto <D.19674>; else goto <D.19675>;
    <D.19674>:
    D.19676 = handles->type;
    D.19677 = D.19676 == 1;
    D.19678 = (int) D.19677;
    D.19670 = handles->entries;
    D.19655 = (long unsigned int) slot;
    D.19671 = D.19655 * 8;
    D.19679 = D.19670 + D.19671;
    mono_gc_weak_link_remove (D.19679, D.19678);
    <D.19675>:
    <D.19661>:
    goto <D.19680>;
    <D.19652>:
    D.19670 = handles->entries;
    D.19655 = (long unsigned int) slot;
    D.19671 = D.19655 * 8;
    D.19672 = D.19670 + D.19671;
    D.19673 = *D.19672;
    if (D.19673 != 0B) goto <D.19681>; else goto <D.19682>;
    <D.19681>:
    D.19670 = handles->entries;
    D.19655 = (long unsigned int) slot;
    D.19671 = D.19655 * 8;
    D.19672 = D.19670 + D.19671;
    D.19673 = *D.19672;
    D.19683 = MEM[(struct MonoObject *)D.19673].vtable;
    D.19684 = D.19683->domain;
    if (D.19684 == domain) goto <D.19685>; else goto <D.19686>;
    <D.19685>:
    D.19638 = handles->bitmap;
    D.19687 = slot / 32;
    D.19688 = (long unsigned int) D.19687;
    D.19689 = D.19688 * 4;
    D.19690 = D.19638 + D.19689;
    D.19638 = handles->bitmap;
    D.19688 = (long unsigned int) D.19687;
    D.19689 = D.19688 * 4;
    D.19690 = D.19638 + D.19689;
    D.19691 = *D.19690;
    slot.28 = (int) slot;
    D.19645 = slot.28 & 31;
    D.19646 = 1 << D.19645;
    D.19667 = ~D.19646;
    D.19668 = (unsigned int) D.19667;
    D.19692 = D.19691 & D.19668;
    *D.19690 = D.19692;
    D.19670 = handles->entries;
    D.19655 = (long unsigned int) slot;
    D.19671 = D.19655 * 8;
    D.19672 = D.19670 + D.19671;
    *D.19672 = 0B;
    <D.19686>:
    <D.19682>:
    <D.19680>:
    <D.18866>:
    slot = slot + 1;
    <D.18868>:
    D.19693 = handles->size;
    if (D.19693 > slot) goto <D.18867>; else goto <D.18869>;
    <D.18869>:
    {
      int ret;

      ret = pthread_mutex_unlock (&handle_section.mutex);
      if (ret != 0) goto <D.19694>; else goto <D.19695>;
      <D.19694>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19695>:
      D.19696 = ret != 0;
      D.19697 = (long int) D.19696;
      D.19698 = __builtin_expect (D.19697, 0);
      if (D.19698 != 0) goto <D.19699>; else goto <D.19700>;
      <D.19699>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 958, "ret == 0");
      <D.19700>:
    }
  }
  type = type + 1;
  <D.18872>:
  if (type <= 2) goto <D.18871>; else goto <D.18873>;
  <D.18873>:
}


GCHandle_CheckCurrentDomain (guint32 gchandle)
{
  MonoBoolean D.19701;
  struct MonoDomain * D.19702;
  int D.19703;

  D.19702 = mono_domain_get ();
  D.19703 = mono_gchandle_is_in_domain (gchandle, D.19702);
  D.19701 = (MonoBoolean) D.19703;
  return D.19701;
}


mono_gc_finalize_notify ()
{
  mono_sem_post (&finalizer_sem);
}


mono_gc_init ()
{
  int D.19705;
  int D.19708;
  int D.19711;
  void * finalizer_event.29;
  void * pending_done_event.30;
  void * shutdown_event.31;
  void * finalizer_event.32;
  void * pending_done_event.33;
  void * shutdown_event.34;

  InitializeCriticalSection (&handle_section);
  InitializeCriticalSection (&allocator_section);
  InitializeCriticalSection (&finalizer_mutex);
  InitializeCriticalSection (&reference_queue_mutex);
  D.19705 = mono_gc_is_moving ();
  if (D.19705 == 0) goto <D.19706>; else goto <D.19707>;
  <D.19706>:
  mono_gc_register_root (&gc_handles[2].entries, 8, 0B);
  <D.19707>:
  D.19708 = mono_gc_is_moving ();
  if (D.19708 == 0) goto <D.19709>; else goto <D.19710>;
  <D.19709>:
  mono_gc_register_root (&gc_handles[3].entries, 8, 0B);
  <D.19710>:
  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.19711 = mono_gc_is_disabled ();
  if (D.19711 != 0) goto <D.19712>; else goto <D.19713>;
  <D.19712>:
  gc_disabled = 1;
  return;
  <D.19713>:
  finalizer_event.29 = CreateEvent (0B, 0, 0, 0B);
  finalizer_event = finalizer_event.29;
  pending_done_event.30 = CreateEvent (0B, 1, 0, 0B);
  pending_done_event = pending_done_event.30;
  shutdown_event.31 = CreateEvent (0B, 1, 0, 0B);
  shutdown_event = shutdown_event.31;
  finalizer_event.32 = finalizer_event;
  if (finalizer_event.32 == 0B) goto <D.19717>; else goto <D.19720>;
  <D.19720>:
  pending_done_event.33 = pending_done_event;
  if (pending_done_event.33 == 0B) goto <D.19717>; else goto <D.19722>;
  <D.19722>:
  shutdown_event.34 = shutdown_event;
  if (shutdown_event.34 == 0B) goto <D.19717>; else goto <D.19718>;
  <D.19717>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 1152);
  <D.19718>:
  sem_init (&finalizer_sem, 0, 0);
  mono_gc_init_finalizer_thread ();
}


mono_gc_init_finalizer_thread ()
{
  struct MonoDomain * D.19725;
  struct MonoInternalThread * gc_thread.35;
  struct MonoDomain * D.19727;
  struct MonoString * D.19728;
  struct MonoInternalThread * gc_thread.36;

  D.19725 = mono_domain_get ();
  gc_thread.35 = mono_thread_create_internal (D.19725, finalizer_thread, 0B, 0, 1, 0);
  gc_thread = gc_thread.35;
  D.19727 = mono_domain_get ();
  D.19728 = mono_string_new (D.19727, "Finalizer");
  gc_thread.36 = gc_thread;
  ves_icall_System_Threading_Thread_SetName_internal (gc_thread.36, D.19728);
}


finalizer_thread (void * unused)
{
  struct MonoDomain * D.19730;
  struct MonoDomain * D.19731;
  _Bool D.19732;
  long int D.19733;
  long int D.19734;
  struct GSList * domains_to_finalize.37;
  _Bool D.19742;
  long int D.19743;
  long int D.19744;
  struct GSList * domains_to_finalize.38;
  _Bool D.19752;
  long int D.19753;
  long int D.19754;
  _Bool D.19760;
  long int D.19761;
  long int D.19762;
  void * pending_done_event.39;
  int finished.40;
  void * shutdown_event.41;
  guint32 D.19768;

  goto <D.18904>;
  <D.18903>:
  D.19730 = mono_domain_get ();
  D.19731 = mono_get_root_domain ();
  D.19732 = D.19730 != D.19731;
  D.19733 = (long int) D.19732;
  D.19734 = __builtin_expect (D.19733, 0);
  if (D.19734 != 0) goto <D.19735>; else goto <D.19736>;
  <D.19735>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1069, "mono_domain_get () == mono_get_root_domain ()");
  <D.19736>:
  mono_sem_wait (&finalizer_sem, 1);
  mono_threads_perform_thread_dump ();
  mono_console_handle_async_ops ();
  mono_attach_maybe_start ();
  domains_to_finalize.37 = domains_to_finalize;
  if (domains_to_finalize.37 != 0B) goto <D.19738>; else goto <D.19739>;
  <D.19738>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19740>; else goto <D.19741>;
    <D.19740>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19741>:
    D.19742 = ret != 0;
    D.19743 = (long int) D.19742;
    D.19744 = __builtin_expect (D.19743, 0);
    if (D.19744 != 0) goto <D.19745>; else goto <D.19746>;
    <D.19745>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1087, "ret == 0");
    <D.19746>:
  }
  domains_to_finalize.37 = domains_to_finalize;
  if (domains_to_finalize.37 != 0B) goto <D.19747>; else goto <D.19748>;
  <D.19747>:
  {
    struct DomainFinalizationReq * req;

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

      ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
      if (ret != 0) goto <D.19750>; else goto <D.19751>;
      <D.19750>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.19751>:
      D.19752 = ret != 0;
      D.19753 = (long int) D.19752;
      D.19754 = __builtin_expect (D.19753, 0);
      if (D.19754 != 0) goto <D.19755>; else goto <D.19756>;
      <D.19755>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1091, "ret == 0");
      <D.19756>:
    }
    finalize_domain_objects (req);
  }
  goto <D.19757>;
  <D.19748>:
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19758>; else goto <D.19759>;
    <D.19758>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19759>:
    D.19760 = ret != 0;
    D.19761 = (long int) D.19760;
    D.19762 = __builtin_expect (D.19761, 0);
    if (D.19762 != 0) goto <D.19763>; else goto <D.19764>;
    <D.19763>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1095, "ret == 0");
    <D.19764>:
  }
  <D.19757>:
  <D.19739>:
  mono_gc_invoke_finalizers ();
  reference_queue_proccess_all ();
  pending_done_event.39 = pending_done_event;
  SetEvent (pending_done_event.39);
  <D.18904>:
  finished.40 = finished;
  if (finished.40 == 0) goto <D.18903>; else goto <D.18905>;
  <D.18905>:
  shutdown_event.41 = shutdown_event;
  SetEvent (shutdown_event.41);
  D.19768 = 0;
  return D.19768;
}


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

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

        i = 0;
        goto <D.18891>;
        <D.18890>:
        D.19770 = to_finalize[i];
        mono_gc_run_finalize (D.19770, 0B);
        i = i + 1;
        <D.18891>:
        if (i < count) goto <D.18890>; else goto <D.18892>;
        <D.18892>:
      }
      <D.18894>:
      count = mono_gc_finalizers_for_domain (domain, &to_finalize, 64);
      if (count != 0) goto <D.18893>; else goto <D.18895>;
      <D.18895>:
      reference_queue_clear_for_domain (domain);
      D.19771 = req->done_event;
      SetEvent (D.19771);
      monoeg_g_free (req);
    }
  finally
    {
      to_finalize = {CLOBBER};
    }
}


reference_queue_clear_for_domain (struct MonoDomain * domain)
{
  struct MonoDomain * D.19772;
  void * * D.19775;
  void (*<Tc2>) (void *) D.19776;
  void * D.19777;
  struct MonoReferenceQueue * queue;

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

    iter = &queue->queue;
    goto <D.18996>;
    <D.18995>:
    D.19772 = entry->domain;
    if (D.19772 == domain) goto <D.19773>; else goto <D.19774>;
    <D.19773>:
    D.19775 = &entry->dis_link;
    mono_gc_weak_link_remove (D.19775, 1);
    ref_list_remove_element (iter, entry);
    D.19776 = queue->callback;
    D.19777 = entry->user_data;
    D.19776 (D.19777);
    monoeg_g_free (entry);
    goto <D.19778>;
    <D.19774>:
    iter = &entry->next;
    <D.19778>:
    <D.18996>:
    entry = *iter;
    if (entry != 0B) goto <D.18995>; else goto <D.18997>;
    <D.18997>:
  }
  queue = queue->next;
  <D.18999>:
  if (queue != 0B) goto <D.18998>; else goto <D.19000>;
  <D.19000>:
}


ref_list_remove_element (struct RefQueueEntry * * prev, struct RefQueueEntry * element)
{
  struct RefQueueEntry * D.19779;
  struct RefQueueEntry * D.19781;
  void * D.19782;

  <D.18950>:
  goto <D.18948>;
  <D.18947>:
  D.19779 = *prev;
  prev = &D.19779->next;
  <D.18948>:
  D.19779 = *prev;
  if (D.19779 != element) goto <D.18947>; else goto <D.18949>;
  <D.18949>:
  if (prev != 0B) goto <D.19780>; else goto <D.18951>;
  <D.19780>:
  D.19781 = element->next;
  D.19782 = InterlockedCompareExchangePointer (prev, D.19781, element);
  if (D.19782 != element) goto <D.18950>; else goto <D.18951>;
  <D.18951>:
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.19783;
  long unsigned int exch.42;
  long unsigned int comp.43;
  long unsigned int D.19786;

  exch.42 = (long unsigned int) exch;
  comp.43 = (long unsigned int) comp;
  D.19786 = __sync_val_compare_and_swap_8 (dest, comp.43, exch.42);
  D.19783 = (void *) D.19786;
  return D.19783;
}


reference_queue_proccess_all ()
{
  _Bool D.19790;
  long int D.19791;
  long int D.19792;
  int D.19795;
  struct RefQueueEntry * D.19798;
  _Bool D.19803;
  long int D.19804;
  long int D.19805;
  struct MonoReferenceQueue * D.19808;
  struct MonoReferenceQueue * D.19809;
  _Bool D.19812;
  long int D.19813;
  long int D.19814;
  struct MonoReferenceQueue * * iter;
  struct MonoReferenceQueue * queue;
  void restart = <<< error >>>;

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

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19788>; else goto <D.19789>;
    <D.19788>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19789>:
    D.19790 = ret != 0;
    D.19791 = (long int) D.19790;
    D.19792 = __builtin_expect (D.19791, 0);
    if (D.19792 != 0) goto <D.19793>; else goto <D.19794>;
    <D.19793>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1424, "ret == 0");
    <D.19794>:
  }
  iter = &ref_queues;
  goto <D.18977>;
  <D.18979>:
  queue = *iter;
  D.19795 = queue->should_be_deleted;
  if (D.19795 == 0) goto <D.19796>; else goto <D.19797>;
  <D.19796>:
  iter = &queue->next;
  // predicted unlikely by continue predictor.
  goto <D.18977>;
  <D.19797>:
  D.19798 = queue->queue;
  if (D.19798 != 0B) goto <D.19799>; else goto <D.19800>;
  <D.19799>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19801>; else goto <D.19802>;
    <D.19801>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19802>:
    D.19803 = ret != 0;
    D.19804 = (long int) D.19803;
    D.19805 = __builtin_expect (D.19804, 0);
    if (D.19805 != 0) goto <D.19806>; else goto <D.19807>;
    <D.19806>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1432, "ret == 0");
    <D.19807>:
  }
  reference_queue_proccess (queue);
  goto restart;
  <D.19800>:
  D.19808 = queue->next;
  *iter = D.19808;
  monoeg_g_free (queue);
  <D.18977>:
  D.19809 = *iter;
  if (D.19809 != 0B) goto <D.18979>; else goto <D.18980>;
  <D.18980>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19810>; else goto <D.19811>;
    <D.19810>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19811>:
    D.19812 = ret != 0;
    D.19813 = (long int) D.19812;
    D.19814 = __builtin_expect (D.19813, 0);
    if (D.19814 != 0) goto <D.19815>; else goto <D.19816>;
    <D.19815>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1439, "ret == 0");
    <D.19816>:
  }
}


reference_queue_proccess (struct MonoReferenceQueue * queue)
{
  int D.19820;
  void * * D.19822;
  struct MonoObject * D.19823;
  void (*<Tc2>) (void *) D.19824;
  void * D.19825;
  struct RefQueueEntry * * iter;
  struct RefQueueEntry * entry;

  iter = &queue->queue;
  goto <D.18965>;
  <D.18964>:
  D.19820 = queue->should_be_deleted;
  if (D.19820 != 0) goto <D.19817>; else goto <D.19821>;
  <D.19821>:
  D.19822 = &entry->dis_link;
  D.19823 = mono_gc_weak_link_get (D.19822);
  if (D.19823 == 0B) goto <D.19817>; else goto <D.19818>;
  <D.19817>:
  D.19822 = &entry->dis_link;
  mono_gc_weak_link_remove (D.19822, 1);
  ref_list_remove_element (iter, entry);
  D.19824 = queue->callback;
  D.19825 = entry->user_data;
  D.19824 (D.19825);
  monoeg_g_free (entry);
  goto <D.19819>;
  <D.19818>:
  iter = &entry->next;
  <D.19819>:
  <D.18965>:
  entry = *iter;
  if (entry != 0B) goto <D.18964>; else goto <D.18966>;
  <D.18966>:
}


mono_gc_cleanup ()
{
  int gc_disabled.44;
  void * shutdown_event.45;
  struct MonoInternalThread * D.19830;
  struct MonoInternalThread * gc_thread.46;
  unsigned int D.19834;
  void * D.19837;
  unsigned int D.19838;
  unsigned int D.19843;
  _Bool D.19844;
  long int D.19845;
  long int D.19846;
  long unsigned int D.19849;

  gc_disabled.44 = gc_disabled;
  if (gc_disabled.44 == 0) goto <D.19827>; else goto <D.19828>;
  <D.19827>:
  shutdown_event.45 = shutdown_event;
  ResetEvent (shutdown_event.45);
  finished = 1;
  D.19830 = mono_thread_internal_current ();
  gc_thread.46 = gc_thread;
  if (D.19830 != gc_thread.46) goto <D.19832>; else goto <D.19833>;
  <D.19832>:
  mono_gc_finalize_notify ();
  shutdown_event.45 = shutdown_event;
  D.19834 = WaitForSingleObjectEx (shutdown_event.45, 2000, 0);
  if (D.19834 == 258) goto <D.19835>; else goto <D.19836>;
  <D.19835>:
  {
    int ret;

    suspend_finalizers = 1;
    gc_thread.46 = gc_thread;
    mono_thread_internal_stop (gc_thread.46);
    gc_thread.46 = gc_thread;
    D.19837 = gc_thread.46->handle;
    D.19838 = WaitForSingleObjectEx (D.19837, 100, 1);
    ret = (int) D.19838;
    if (ret == 258) goto <D.19839>; else goto <D.19840>;
    <D.19839>:
    monoeg_g_log (0B, 16, "Shutting down finalizer thread timed out.");
    goto <D.19841>;
    <D.19840>:
    Sleep (100);
    <D.19841>:
  }
  goto <D.19842>;
  <D.19836>:
  {
    int ret;

    gc_thread.46 = gc_thread;
    D.19837 = gc_thread.46->handle;
    D.19843 = WaitForSingleObjectEx (D.19837, 4294967295, 1);
    ret = (int) D.19843;
    D.19844 = ret != 0;
    D.19845 = (long int) D.19844;
    D.19846 = __builtin_expect (D.19845, 0);
    if (D.19846 != 0) goto <D.19847>; else goto <D.19848>;
    <D.19847>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1208, "ret == WAIT_OBJECT_0");
    <D.19848>:
    gc_thread.46 = gc_thread;
    D.19849 = gc_thread.46->tid;
    ret = pthread_join (D.19849, 0B);
    D.19844 = ret != 0;
    D.19845 = (long int) D.19844;
    D.19846 = __builtin_expect (D.19845, 0);
    if (D.19846 != 0) goto <D.19850>; else goto <D.19851>;
    <D.19850>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1216, "ret == 0");
    <D.19851>:
  }
  <D.19842>:
  <D.19833>:
  gc_thread = 0B;
  <D.19828>:
  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.18987>;
  <D.18986>:
  queue->should_be_deleted = 1;
  queue = queue->next;
  <D.18987>:
  if (queue != 0B) goto <D.18986>; else goto <D.18988>;
  <D.18988>:
  reference_queue_proccess_all ();
}


mono_gc_is_finalizer_internal_thread (struct MonoInternalThread * thread)
{
  gboolean D.19852;
  struct MonoInternalThread * gc_thread.47;
  _Bool D.19854;

  gc_thread.47 = gc_thread;
  D.19854 = thread == gc_thread.47;
  D.19852 = (gboolean) D.19854;
  return D.19852;
}


mono_gc_is_finalizer_thread (struct MonoThread * thread)
{
  gboolean D.19856;
  struct _MonoInternalThread * D.19857;

  D.19857 = thread->internal_thread;
  D.19856 = mono_gc_is_finalizer_internal_thread (D.19857);
  return D.19856;
}


mono_gc_parse_environment_string_extract_number (const char * str, glong * out)
{
  long unsigned int D.19859;
  gboolean D.19862;
  sizetype D.19863;
  sizetype D.19864;
  const char * D.19865;
  int D.19866;
  const short unsigned int * * D.19867;
  const short unsigned int * D.19868;
  long unsigned int D.19869;
  long unsigned int D.19870;
  const short unsigned int * D.19871;
  short unsigned int D.19872;
  int D.19873;
  int D.19874;
  int * D.19877;
  int D.19882;
  unsigned long val.48;
  unsigned long D.19885;
  char * endptr.49;
  char * D.19892;
  char D.19893;
  long unsigned int val.50;
  long unsigned int D.19899;
  char * endptr;
  int len;
  int shift;
  glong val;
  gboolean is_suffix;
  char suffix;

  try
    {
      D.19859 = strlen (str);
      len = (int) D.19859;
      shift = 0;
      is_suffix = 0;
      if (len == 0) goto <D.19860>; else goto <D.19861>;
      <D.19860>:
      D.19862 = 0;
      return D.19862;
      <D.19861>:
      D.19863 = (sizetype) len;
      D.19864 = D.19863 + 18446744073709551615;
      D.19865 = str + D.19864;
      suffix = *D.19865;
      D.19866 = (int) suffix;
      switch (D.19866) <default: <D.18940>, case 71: <D.18934>, case 75: <D.18938>, case 77: <D.18936>, case 103: <D.18933>, case 107: <D.18937>, case 109: <D.18935>>
      <D.18933>:
      <D.18934>:
      shift = shift + 10;
      <D.18935>:
      <D.18936>:
      shift = shift + 10;
      <D.18937>:
      <D.18938>:
      shift = shift + 10;
      is_suffix = 1;
      goto <D.18939>;
      <D.18940>:
      D.19867 = __ctype_b_loc ();
      D.19868 = *D.19867;
      D.19869 = (long unsigned int) suffix;
      D.19870 = D.19869 * 2;
      D.19871 = D.19868 + D.19870;
      D.19872 = *D.19871;
      D.19873 = (int) D.19872;
      D.19874 = D.19873 & 2048;
      if (D.19874 == 0) goto <D.19875>; else goto <D.19876>;
      <D.19875>:
      D.19862 = 0;
      return D.19862;
      <D.19876>:
      goto <D.18939>;
      <D.18939>:
      D.19877 = __errno_location ();
      *D.19877 = 0;
      val = strtol (str, &endptr, 10);
      D.19877 = __errno_location ();
      D.19882 = *D.19877;
      if (D.19882 == 34) goto <D.19883>; else goto <D.19878>;
      <D.19883>:
      val.48 = (unsigned long) val;
      D.19885 = val.48 + 9223372036854775807;
      if (D.19885 > 18446744073709551613) goto <D.19879>; else goto <D.19878>;
      <D.19878>:
      D.19877 = __errno_location ();
      D.19882 = *D.19877;
      if (D.19882 != 0) goto <D.19886>; else goto <D.19880>;
      <D.19886>:
      if (val == 0) goto <D.19879>; else goto <D.19880>;
      <D.19880>:
      endptr.49 = endptr;
      if (endptr.49 == str) goto <D.19879>; else goto <D.19881>;
      <D.19879>:
      D.19862 = 0;
      return D.19862;
      <D.19881>:
      if (is_suffix != 0) goto <D.19888>; else goto <D.19889>;
      <D.19888>:
      {
        gulong unshifted;

        if (val < 0) goto <D.19890>; else goto <D.19891>;
        <D.19890>:
        D.19862 = 0;
        return D.19862;
        <D.19891>:
        endptr.49 = endptr;
        D.19892 = endptr.49 + 1;
        D.19893 = *D.19892;
        if (D.19893 != 0) goto <D.19894>; else goto <D.19895>;
        <D.19894>:
        D.19862 = 0;
        return D.19862;
        <D.19895>:
        unshifted = (gulong) val;
        val = val << shift;
        if (val < 0) goto <D.19896>; else goto <D.19897>;
        <D.19896>:
        D.19862 = 0;
        return D.19862;
        <D.19897>:
        val.50 = (long unsigned int) val;
        D.19899 = val.50 >> shift;
        if (D.19899 != unshifted) goto <D.19900>; else goto <D.19901>;
        <D.19900>:
        D.19862 = 0;
        return D.19862;
        <D.19901>:
      }
      <D.19889>:
      *out = val;
      D.19862 = 1;
      return D.19862;
    }
  finally
    {
      endptr = {CLOBBER};
    }
}


mono_gc_reference_queue_new (void (*mono_reference_queue_callback) (void *) callback)
{
  _Bool D.19906;
  long int D.19907;
  long int D.19908;
  struct MonoReferenceQueue * ref_queues.51;
  _Bool D.19914;
  long int D.19915;
  long int D.19916;
  struct MonoReferenceQueue * D.19919;
  struct MonoReferenceQueue * res;

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

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19904>; else goto <D.19905>;
    <D.19904>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19905>:
    D.19906 = ret != 0;
    D.19907 = (long int) D.19906;
    D.19908 = __builtin_expect (D.19907, 0);
    if (D.19908 != 0) goto <D.19909>; else goto <D.19910>;
    <D.19909>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1497, "ret == 0");
    <D.19910>:
  }
  ref_queues.51 = ref_queues;
  res->next = ref_queues.51;
  ref_queues = res;
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.19912>; else goto <D.19913>;
    <D.19912>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19913>:
    D.19914 = ret != 0;
    D.19915 = (long int) D.19914;
    D.19916 = __builtin_expect (D.19915, 0);
    if (D.19916 != 0) goto <D.19917>; else goto <D.19918>;
    <D.19917>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1500, "ret == 0");
    <D.19918>:
  }
  D.19919 = res;
  return D.19919;
}


mono_gc_reference_queue_add (struct MonoReferenceQueue * queue, struct MonoObject * obj, void * user_data)
{
  int D.19921;
  mono_bool D.19924;
  struct MonoVTable * D.19925;
  struct MonoDomain * D.19926;
  void * * D.19927;
  struct RefQueueEntry * * D.19928;
  struct RefQueueEntry * entry;

  D.19921 = queue->should_be_deleted;
  if (D.19921 != 0) goto <D.19922>; else goto <D.19923>;
  <D.19922>:
  D.19924 = 0;
  return D.19924;
  <D.19923>:
  entry = monoeg_malloc0 (40);
  entry->user_data = user_data;
  D.19925 = obj->vtable;
  D.19926 = D.19925->domain;
  entry->domain = D.19926;
  D.19927 = &entry->dis_link;
  mono_gc_weak_link_add (D.19927, obj, 1);
  D.19928 = &queue->queue;
  ref_list_push (D.19928, entry);
  D.19924 = 1;
  return D.19924;
}


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

  <D.18957>:
  current = *head;
  value->next = current;
  D.19930 = InterlockedCompareExchangePointer (head, value, current);
  if (D.19930 != current) goto <D.18957>; else goto <D.18958>;
  <D.18958>:
}


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


