mono_gc_run_finalize (void * obj, void * data)
{
  long int data.0;
  unsigned int D.19548;
  sizetype D.19549;
  int suspend_finalizers.1;
  struct MonoVTable * D.19553;
  struct MonoClass * D.19554;
  struct MonoClass * D.19555;
  int D.19558;
  unsigned char D.19561;
  int finalizing_root_domain.2;
  struct MonoImage * D.19567;
  struct MonoImage * D.19568;
  int D.19199;
  int iftmp.3;
  int D.19198;
  const char[14] * D.19574;
  unsigned char D.19575;
  int D.19576;
  unsigned char D.19577;
  int D.19578;
  const unsigned char * D.19583;
  unsigned char D.19584;
  int D.19585;
  const unsigned char * D.19586;
  unsigned char D.19587;
  int D.19588;
  const unsigned char * D.19593;
  unsigned char D.19594;
  int D.19595;
  const unsigned char * D.19596;
  unsigned char D.19597;
  int D.19598;
  const unsigned char * D.19603;
  unsigned char D.19604;
  int D.19605;
  const unsigned char * D.19606;
  unsigned char D.19607;
  int D.19608;
  const char * D.19610;
  int D.19615;
  struct MonoDomain * D.19618;
  long unsigned int D.19619;
  long unsigned int D.19620;
  void * D.19623;
  int D.19626;
  void * D.19631;
  struct MonoClass * D.19634;
  struct MonoMethod * D.19635;
  void * D.19636;
  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.19548 = (unsigned int) data.0;
      D.19549 = (sizetype) D.19548;
      o = obj + D.19549;
      suspend_finalizers.1 = suspend_finalizers;
      if (suspend_finalizers.1 != 0) goto <D.19551>; else goto <D.19552>;
      <D.19551>:
      return;
      <D.19552>:
      D.19553 = o->vtable;
      domain = D.19553->domain;
      object_register_finalizer (obj, 0B);
      D.19553 = o->vtable;
      D.19554 = D.19553->klass;
      D.19555 = mono_defaults.internal_thread_class;
      if (D.19554 == D.19555) goto <D.19556>; else goto <D.19557>;
      <D.19556>:
      {
        struct MonoInternalThread * t;

        t = o;
        D.19558 = mono_gc_is_finalizer_internal_thread (t);
        if (D.19558 != 0) goto <D.19559>; else goto <D.19560>;
        <D.19559>:
        return;
        <D.19560>:
        D.19561 = t->threadpool_thread;
        if (D.19561 != 0) goto <D.19562>; else goto <D.19563>;
        <D.19562>:
        finalizing_root_domain.2 = finalizing_root_domain;
        if (finalizing_root_domain.2 != 0) goto <D.19565>; else goto <D.19566>;
        <D.19565>:
        add_thread_to_finalize (t);
        return;
        <D.19566>:
        <D.19563>:
      }
      <D.19557>:
      D.19553 = o->vtable;
      D.19554 = D.19553->klass;
      D.19567 = D.19554->image;
      D.19568 = mono_defaults.corlib;
      if (D.19567 == D.19568) goto <D.19569>; else goto <D.19570>;
      <D.19569>:
      {
        size_t __s1_len;
        size_t __s2_len;

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

          D.19553 = o->vtable;
          D.19554 = D.19553->klass;
          __s2 = D.19554->name;
          D.19574 = "DynamicMethod";
          D.19575 = MEM[(const unsigned char *)D.19574];
          D.19576 = (int) D.19575;
          D.19577 = *__s2;
          D.19578 = (int) D.19577;
          __result = D.19576 - D.19578;
          {
            if (__s2_len != 0) goto <D.19579>; else goto <D.19580>;
            <D.19579>:
            if (__result == 0) goto <D.19581>; else goto <D.19582>;
            <D.19581>:
            D.19583 = &MEM[(void *)"DynamicMethod" + 1B];
            D.19584 = *D.19583;
            D.19585 = (int) D.19584;
            D.19586 = __s2 + 1;
            D.19587 = *D.19586;
            D.19588 = (int) D.19587;
            __result = D.19585 - D.19588;
            if (__s2_len > 1) goto <D.19589>; else goto <D.19590>;
            <D.19589>:
            if (__result == 0) goto <D.19591>; else goto <D.19592>;
            <D.19591>:
            D.19593 = &MEM[(void *)"DynamicMethod" + 2B];
            D.19594 = *D.19593;
            D.19595 = (int) D.19594;
            D.19596 = __s2 + 2;
            D.19597 = *D.19596;
            D.19598 = (int) D.19597;
            __result = D.19595 - D.19598;
            if (__s2_len > 2) goto <D.19599>; else goto <D.19600>;
            <D.19599>:
            if (__result == 0) goto <D.19601>; else goto <D.19602>;
            <D.19601>:
            D.19603 = &MEM[(void *)"DynamicMethod" + 3B];
            D.19604 = *D.19603;
            D.19605 = (int) D.19604;
            D.19606 = __s2 + 3;
            D.19607 = *D.19606;
            D.19608 = (int) D.19607;
            __result = D.19605 - D.19608;
            <D.19602>:
            <D.19600>:
            <D.19592>:
            <D.19590>:
            <D.19582>:
            <D.19580>:
          }
          D.19198 = __result;
        }
        iftmp.3 = -D.19198;
        goto <D.19609>;
        <D.19573>:
        D.19553 = o->vtable;
        D.19554 = D.19553->klass;
        D.19610 = D.19554->name;
        iftmp.3 = __builtin_strcmp (D.19610, "DynamicMethod");
        <D.19609>:
        D.19199 = iftmp.3;
      }
      if (D.19199 == 0) goto <D.19611>; else goto <D.19612>;
      <D.19611>:
      finalizing_root_domain.2 = finalizing_root_domain;
      if (finalizing_root_domain.2 != 0) goto <D.19613>; else goto <D.19614>;
      <D.19613>:
      return;
      <D.19614>:
      <D.19612>:
      <D.19570>:
      D.19615 = mono_runtime_get_no_exec ();
      if (D.19615 != 0) goto <D.19616>; else goto <D.19617>;
      <D.19616>:
      return;
      <D.19617>:
      D.19553 = o->vtable;
      D.19618 = D.19553->domain;
      mono_domain_set_internal (D.19618);
      D.19553 = o->vtable;
      D.19554 = D.19553->klass;
      D.19619 = BIT_FIELD_REF <*D.19554, 64, 256>;
      D.19620 = D.19619 & 16777216;
      if (D.19620 != 0) goto <D.19621>; else goto <D.19622>;
      <D.19621>:
      {
        struct MonoDelegate * del;

        del = o;
        D.19623 = del->delegate_trampoline;
        if (D.19623 != 0B) goto <D.19624>; else goto <D.19625>;
        <D.19624>:
        mono_delegate_free_ftnptr (o);
        <D.19625>:
        mono_domain_set_internal (caller_domain);
        return;
      }
      <D.19622>:
      D.19553 = o->vtable;
      D.19554 = D.19553->klass;
      finalizer = mono_class_get_finalizer (D.19554);
      D.19626 = mono_marshal_free_ccw (o);
      if (D.19626 != 0) goto <D.19627>; else goto <D.19628>;
      <D.19627>:
      if (finalizer == 0B) goto <D.19629>; else goto <D.19630>;
      <D.19629>:
      mono_domain_set_internal (caller_domain);
      return;
      <D.19630>:
      <D.19628>:
      D.19631 = domain->finalize_runtime_invoke;
      if (D.19631 == 0B) goto <D.19632>; else goto <D.19633>;
      <D.19632>:
      {
        struct MonoMethod * invoke;

        D.19634 = mono_defaults.object_class;
        D.19635 = mono_class_get_method_from_name_flags (D.19634, "Finalize", 0, 0);
        invoke = mono_marshal_get_runtime_invoke (D.19635, 1);
        D.19636 = mono_compile_method (invoke);
        domain->finalize_runtime_invoke = D.19636;
      }
      <D.19633>:
      D.19631 = domain->finalize_runtime_invoke;
      runtime_invoke = (struct MonoObject * (*RuntimeInvokeFunction) (struct MonoObject *, void * *, struct MonoObject * *, void *)) D.19631;
      D.19553 = o->vtable;
      mono_runtime_class_init (D.19553);
      if (0 != 0) goto <D.19637>; else goto <D.19638>;
      <D.19637>:
      <D.19638>:
      runtime_invoke (o, 0B, &exc, 0B);
      exc.4 = exc;
      if (exc.4 != 0B) goto <D.19640>; else goto <D.19641>;
      <D.19640>:
      exc.4 = exc;
      mono_internal_thread_unhandled_exception (exc.4);
      <D.19641>:
      mono_domain_set_internal (caller_domain);
    }
  finally
    {
      exc = {CLOBBER};
    }
}


object_register_finalizer (struct MonoObject * obj, void (*<Tff>) (void *, void *) callback)
{
  struct MonoException * D.19647;
  struct MonoVTable * D.19648;
  int D.19649;
  struct MonoDomain * domain;

  if (obj == 0B) goto <D.19645>; else goto <D.19646>;
  <D.19645>:
  D.19647 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19647);
  <D.19646>:
  D.19648 = obj->vtable;
  domain = D.19648->domain;
  D.19649 = mono_domain_is_unloading (domain);
  if (D.19649 == 0) goto <D.19650>; else goto <D.19651>;
  <D.19650>:
  mono_gc_register_for_finalization (obj, callback);
  <D.19651>:
}


add_thread_to_finalize (struct MonoInternalThread * thread)
{
  _Bool D.19654;
  long int D.19655;
  long int D.19656;
  struct MonoMList * threads_to_finalize.5;
  void * D.19664;
  struct MonoMList * threads_to_finalize.6;
  _Bool D.19668;
  long int D.19669;
  long int D.19670;

  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19652>; else goto <D.19653>;
    <D.19652>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19653>:
    D.19654 = ret != 0;
    D.19655 = (long int) D.19654;
    D.19656 = __builtin_expect (D.19655, 0);
    if (D.19656 != 0) goto <D.19657>; else goto <D.19658>;
    <D.19657>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 88, "ret == 0");
    <D.19658>:
  }
  threads_to_finalize.5 = threads_to_finalize;
  if (threads_to_finalize.5 == 0B) goto <D.19660>; else goto <D.19661>;
  <D.19660>:
  if (0 != 0) goto <D.19662>; else goto <D.19663>;
  <D.19662>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 90, "sizeof (threads_to_finalize) == sizeof (MonoObject*)");
  <D.19663>:
  D.19664 = mono_gc_make_root_descr_all_refs (1);
  mono_gc_register_root (&threads_to_finalize, 8, D.19664);
  <D.19661>:
  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.19666>; else goto <D.19667>;
    <D.19666>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19667>:
    D.19668 = ret != 0;
    D.19669 = (long int) D.19668;
    D.19670 = __builtin_expect (D.19669, 0);
    if (D.19670 != 0) goto <D.19671>; else goto <D.19672>;
    <D.19671>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 92, "ret == 0");
    <D.19672>:
  }
}


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

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


mono_gc_out_of_memory (size_t size)
{
  struct MonoDomain * D.19675;
  struct MonoException * D.19676;
  void * D.19677;

  D.19675 = mono_domain_get ();
  D.19676 = D.19675->out_of_memory_ex;
  mono_raise_exception (D.19676);
  D.19677 = 0B;
  return D.19677;
}


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.19679;
  struct MonoInternalThread * gc_thread.9;
  mono_bool D.19683;
  int gc_disabled.10;
  int D.19687;
  struct MonoDomain * D.19690;
  _Bool D.19695;
  long int D.19696;
  long int D.19697;
  struct GSList * domains_to_finalize.11;
  struct GSList * domains_to_finalize.12;
  _Bool D.19704;
  long int D.19705;
  long int D.19706;
  unsigned int D.19713;
  unsigned int D.19714;
  struct MonoDomain * D.19719;
  struct DomainFinalizationReq * req;
  guint32 res;
  void * done_event;
  struct MonoInternalThread * thread;

  thread = mono_thread_internal_current ();
  D.19679 = mono_thread_internal_current ();
  gc_thread.9 = gc_thread;
  if (D.19679 == gc_thread.9) goto <D.19681>; else goto <D.19682>;
  <D.19681>:
  D.19683 = 0;
  return D.19683;
  <D.19682>:
  gc_disabled.10 = gc_disabled;
  if (gc_disabled.10 != 0) goto <D.19685>; else goto <D.19686>;
  <D.19685>:
  D.19683 = 1;
  return D.19683;
  <D.19686>:
  D.19687 = mono_gc_max_generation ();
  mono_gc_collect (D.19687);
  done_event = CreateEvent (0B, 1, 0, 0B);
  if (done_event == 0B) goto <D.19688>; else goto <D.19689>;
  <D.19688>:
  D.19683 = 0;
  return D.19683;
  <D.19689>:
  req = monoeg_malloc0 (16);
  req->domain = domain;
  req->done_event = done_event;
  D.19690 = mono_get_root_domain ();
  if (D.19690 == domain) goto <D.19691>; else goto <D.19692>;
  <D.19691>:
  finalizing_root_domain = 1;
  <D.19692>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.19693>; else goto <D.19694>;
    <D.19693>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19694>:
    D.19695 = ret != 0;
    D.19696 = (long int) D.19695;
    D.19697 = __builtin_expect (D.19696, 0);
    if (D.19697 != 0) goto <D.19698>; else goto <D.19699>;
    <D.19698>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 367, "ret == 0");
    <D.19699>:
  }
  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.19702>; else goto <D.19703>;
    <D.19702>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19703>:
    D.19704 = ret != 0;
    D.19705 = (long int) D.19704;
    D.19706 = __builtin_expect (D.19705, 0);
    if (D.19706 != 0) goto <D.19707>; else goto <D.19708>;
    <D.19707>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 371, "ret == 0");
    <D.19708>:
  }
  mono_gc_finalize_notify ();
  if (timeout == 4294967295) goto <D.19709>; else goto <D.19710>;
  <D.19709>:
  timeout = 4294967295;
  <D.19710>:
  <D.19233>:
  res = WaitForSingleObjectEx (done_event, timeout, 1);
  if (res == 192) goto <D.19711>; else goto <D.19712>;
  <D.19711>:
  D.19713 = thread->state;
  D.19714 = D.19713 & 3;
  if (D.19714 != 0) goto <D.19715>; else goto <D.19716>;
  <D.19715>:
  D.19683 = 0;
  return D.19683;
  <D.19716>:
  goto <D.19717>;
  <D.19712>:
  if (res == 258) goto <D.19718>; else goto <D.19232>;
  <D.19718>:
  D.19683 = 0;
  return D.19683;
  <D.19717>:
  goto <D.19233>;
  <D.19232>:
  CloseHandle (done_event);
  D.19719 = mono_get_root_domain ();
  if (D.19719 == domain) goto <D.19720>; else goto <D.19721>;
  <D.19720>:
  mono_thread_pool_cleanup ();
  mono_gc_finalize_threadpool_threads ();
  <D.19721>:
  D.19683 = 1;
  return D.19683;
}


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


ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection)
{
  int D.19725;
  gint64 D.19726;

  if (forceCollection != 0) goto <D.19723>; else goto <D.19724>;
  <D.19723>:
  D.19725 = mono_gc_max_generation ();
  mono_gc_collect (D.19725);
  <D.19724>:
  D.19726 = mono_gc_get_used_size ();
  return D.19726;
}


ves_icall_System_GC_KeepAlive (struct MonoObject * obj)
{

}


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

  if (obj == 0B) goto <D.19728>; else goto <D.19729>;
  <D.19728>:
  D.19730 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19730);
  <D.19729>:
  object_register_finalizer (obj, mono_gc_run_finalize);
}


ves_icall_System_GC_SuppressFinalize (struct MonoObject * obj)
{
  struct MonoException * D.19733;
  struct MonoVTable * D.19734;
  struct MonoClass * D.19735;
  long unsigned int D.19736;
  long unsigned int D.19737;

  if (obj == 0B) goto <D.19731>; else goto <D.19732>;
  <D.19731>:
  D.19733 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19733);
  <D.19732>:
  D.19734 = obj->vtable;
  D.19735 = D.19734->klass;
  D.19736 = BIT_FIELD_REF <*D.19735, 64, 256>;
  D.19737 = D.19736 & 16777216;
  if (D.19737 != 0) goto <D.19738>; else goto <D.19739>;
  <D.19738>:
  return;
  <D.19739>:
  object_register_finalizer (obj, 0B);
}


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

  D.19741 = mono_gc_pending_finalizers ();
  if (D.19741 == 0) goto <D.19742>; else goto <D.19743>;
  <D.19742>:
  return;
  <D.19743>:
  D.19744 = mono_thread_internal_current ();
  gc_thread.13 = gc_thread;
  if (D.19744 == gc_thread.13) goto <D.19746>; else goto <D.19747>;
  <D.19746>:
  return;
  <D.19747>:
  gc_thread.13 = gc_thread;
  if (gc_thread.13 == 0B) goto <D.19748>; else goto <D.19749>;
  <D.19748>:
  return;
  <D.19749>:
  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.19752;
  struct MonoVTable * D.19755;
  struct MonoDomain * D.19756;
  struct MonoException * D.19757;

  D.19752 = mono_gc_ephemeron_array_add (array);
  if (D.19752 == 0) goto <D.19753>; else goto <D.19754>;
  <D.19753>:
  D.19755 = array->vtable;
  D.19756 = D.19755->domain;
  D.19757 = D.19756->out_of_memory_ex;
  mono_raise_exception (D.19757);
  <D.19754>:
}


ves_icall_System_GC_get_ephemeron_tombstone ()
{
  struct MonoObject * D.19758;
  struct MonoDomain * D.19759;

  D.19759 = mono_domain_get ();
  D.19758 = D.19759->ephemeron_tombstone;
  return D.19758;
}


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

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


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

  if (type == -1) goto <D.19763>; else goto <D.19764>;
  <D.19763>:
  mono_gchandle_set_target (handle, obj);
  D.19765 = handle;
  return D.19765;
  <D.19764>:
  switch (type) <default: <D.19280>, case 0: <D.19276>, case 1: <D.19277>, case 2: <D.19278>, case 3: <D.19279>>
  <D.19276>:
  D.19765 = mono_gchandle_new_weakref (obj, 0);
  return D.19765;
  <D.19277>:
  D.19765 = mono_gchandle_new_weakref (obj, 1);
  return D.19765;
  <D.19278>:
  D.19765 = mono_gchandle_new (obj, 0);
  return D.19765;
  <D.19279>:
  D.19765 = mono_gchandle_new (obj, 1);
  return D.19765;
  <D.19280>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 545);
  D.19765 = 0;
  return D.19765;
}


mono_gchandle_set_target (guint32 gchandle, struct MonoObject * obj)
{
  unsigned int D.19767;
  _Bool D.19772;
  long int D.19773;
  long int D.19774;
  unsigned int D.19777;
  guint32 * D.19780;
  unsigned int D.19781;
  long unsigned int D.19782;
  long unsigned int D.19783;
  guint32 * D.19784;
  unsigned int D.19785;
  int slot.15;
  int D.19787;
  int D.19788;
  unsigned int D.19789;
  unsigned int D.19790;
  unsigned char D.19793;
  void * * D.19796;
  long unsigned int D.19797;
  long unsigned int D.19798;
  void * * D.19799;
  void * D.19800;
  void * * D.19803;
  _Bool D.19804;
  int D.19805;
  guint16 * D.19808;
  long unsigned int D.19809;
  guint16 * D.19810;
  struct MonoDomain * iftmp.16;
  int D.19815;
  short unsigned int D.19816;
  _Bool D.19821;
  long int D.19822;
  long int D.19823;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * old_obj;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19770>; else goto <D.19771>;
    <D.19770>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19771>:
    D.19772 = ret != 0;
    D.19773 = (long int) D.19772;
    D.19774 = __builtin_expect (D.19773, 0);
    if (D.19774 != 0) goto <D.19775>; else goto <D.19776>;
    <D.19775>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 834, "ret == 0");
    <D.19776>:
  }
  D.19777 = handles->size;
  if (D.19777 > slot) goto <D.19778>; else goto <D.19779>;
  <D.19778>:
  D.19780 = handles->bitmap;
  D.19781 = slot / 32;
  D.19782 = (long unsigned int) D.19781;
  D.19783 = D.19782 * 4;
  D.19784 = D.19780 + D.19783;
  D.19785 = *D.19784;
  slot.15 = (int) slot;
  D.19787 = slot.15 & 31;
  D.19788 = 1 << D.19787;
  D.19789 = (unsigned int) D.19788;
  D.19790 = D.19785 & D.19789;
  if (D.19790 != 0) goto <D.19791>; else goto <D.19792>;
  <D.19791>:
  D.19793 = handles->type;
  if (D.19793 <= 1) goto <D.19794>; else goto <D.19795>;
  <D.19794>:
  D.19796 = handles->entries;
  D.19797 = (long unsigned int) slot;
  D.19798 = D.19797 * 8;
  D.19799 = D.19796 + D.19798;
  old_obj = *D.19799;
  D.19796 = handles->entries;
  D.19797 = (long unsigned int) slot;
  D.19798 = D.19797 * 8;
  D.19799 = D.19796 + D.19798;
  D.19800 = *D.19799;
  if (D.19800 != 0B) goto <D.19801>; else goto <D.19802>;
  <D.19801>:
  D.19796 = handles->entries;
  D.19797 = (long unsigned int) slot;
  D.19798 = D.19797 * 8;
  D.19803 = D.19796 + D.19798;
  D.19793 = handles->type;
  D.19804 = D.19793 == 1;
  D.19805 = (int) D.19804;
  mono_gc_weak_link_remove (D.19803, D.19805);
  <D.19802>:
  if (obj != 0B) goto <D.19806>; else goto <D.19807>;
  <D.19806>:
  D.19796 = handles->entries;
  D.19797 = (long unsigned int) slot;
  D.19798 = D.19797 * 8;
  D.19803 = D.19796 + D.19798;
  D.19793 = handles->type;
  D.19804 = D.19793 == 1;
  D.19805 = (int) D.19804;
  mono_gc_weak_link_add (D.19803, obj, D.19805);
  <D.19807>:
  D.19808 = handles->domain_ids;
  D.19797 = (long unsigned int) slot;
  D.19809 = D.19797 * 2;
  D.19810 = D.19808 + D.19809;
  if (obj != 0B) goto <D.19812>; else goto <D.19813>;
  <D.19812>:
  iftmp.16 = mono_object_get_domain (obj);
  goto <D.19814>;
  <D.19813>:
  iftmp.16 = mono_domain_get ();
  <D.19814>:
  D.19815 = iftmp.16->domain_id;
  D.19816 = (short unsigned int) D.19815;
  *D.19810 = D.19816;
  goto <D.19817>;
  <D.19795>:
  D.19796 = handles->entries;
  D.19797 = (long unsigned int) slot;
  D.19798 = D.19797 * 8;
  D.19799 = D.19796 + D.19798;
  *D.19799 = obj;
  <D.19817>:
  goto <D.19818>;
  <D.19792>:
  <D.19818>:
  <D.19779>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19819>; else goto <D.19820>;
    <D.19819>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19820>:
    D.19821 = ret != 0;
    D.19822 = (long int) D.19821;
    D.19823 = __builtin_expect (D.19822, 0);
    if (D.19823 != 0) goto <D.19824>; else goto <D.19825>;
    <D.19824>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 851, "ret == 0");
    <D.19825>:
  }
}


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


ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
{
  <unnamed type> D.19827;
  void * D.19830;
  struct MonoVTable * D.19833;
  struct MonoClass * D.19834;
  unsigned char D.19837;
  unsigned int D.19840;
  unsigned int D.19841;
  struct MonoObject * obj;

  D.19827 = mono_gchandle_get_type (handle);
  if (D.19827 != 3) goto <D.19828>; else goto <D.19829>;
  <D.19828>:
  D.19830 = -2B;
  return D.19830;
  <D.19829>:
  obj = mono_gchandle_get_target (handle);
  if (obj != 0B) goto <D.19831>; else goto <D.19832>;
  <D.19831>:
  {
    struct MonoClass * klass;

    D.19833 = obj->vtable;
    klass = D.19833->klass;
    D.19834 = mono_defaults.string_class;
    if (D.19834 == klass) goto <D.19835>; else goto <D.19836>;
    <D.19835>:
    D.19830 = mono_string_chars (obj);
    return D.19830;
    <D.19836>:
    D.19837 = klass->rank;
    if (D.19837 != 0) goto <D.19838>; else goto <D.19839>;
    <D.19838>:
    D.19830 = mono_array_addr_with_size (obj, 1, 0);
    return D.19830;
    <D.19839>:
    D.19840 = klass->flags;
    D.19841 = D.19840 & 24;
    if (D.19841 == 0) goto <D.19842>; else goto <D.19843>;
    <D.19842>:
    D.19830 = -1B;
    return D.19830;
    <D.19843>:
    D.19830 = obj + 16;
    return D.19830;
  }
  <D.19832>:
  D.19830 = 0B;
  return D.19830;
}


mono_gchandle_get_type (guint32 gchandle)
{
  unsigned int D.19845;
  HandleType D.19846;
  guint type;

  D.19845 = gchandle & 7;
  type = D.19845 + 4294967295;
  D.19846 = type;
  return D.19846;
}


ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
{
  MonoBoolean D.19848;
  int D.19849;
  int D.19850;

  D.19849 = (int) flag;
  D.19850 = mono_gc_set_allow_synchronous_major (D.19849);
  D.19848 = (MonoBoolean) D.19850;
  return D.19848;
}


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

  if (pinned != 0) goto <D.19854>; else goto <D.19855>;
  <D.19854>:
  iftmp.17 = 3;
  goto <D.19856>;
  <D.19855>:
  iftmp.17 = 2;
  <D.19856>:
  D.19857 = &gc_handles[iftmp.17];
  D.19852 = alloc_handle (D.19857, obj, 0);
  return D.19852;
}


alloc_handle (struct HandleData * handles, struct MonoObject * obj, gboolean track)
{
  _Bool D.19861;
  long int D.19862;
  long int D.19863;
  unsigned int D.19866;
  unsigned char D.19869;
  long unsigned int D.19872;
  long unsigned int D.19873;
  int D.19874;
  _Bool D.19875;
  int D.19876;
  void * D.19877;
  void * D.19878;
  void * D.19880;
  long unsigned int D.19881;
  void * D.19882;
  unsigned int D.19883;
  long unsigned int D.19884;
  void * D.19885;
  <unnamed-unsigned:24> D.19886;
  guint32 * D.19887;
  long unsigned int D.19888;
  long unsigned int D.19889;
  guint32 * D.19890;
  unsigned int D.19891;
  unsigned int slot.18;
  <unnamed-unsigned:24> D.19895;
  unsigned int slot.19;
  unsigned int D.19897;
  long unsigned int D.19900;
  long unsigned int D.19901;
  int D.19906;
  unsigned int D.19909;
  long unsigned int D.19910;
  long unsigned int D.19911;
  long unsigned int D.19914;
  long unsigned int D.19915;
  int new_size.20;
  void * D.19917;
  void * * D.19918;
  long unsigned int D.19920;
  guint16 * D.19921;
  long unsigned int D.19922;
  long unsigned int D.19923;
  void * * D.19924;
  void * * D.19927;
  void * * D.19929;
  void * D.19930;
  _Bool D.19931;
  long int D.19932;
  long int D.19933;
  unsigned int i.21;
  unsigned int D.19937;
  unsigned int D.19938;
  <unnamed-unsigned:24> D.19939;
  int D.19940;
  unsigned int D.19941;
  unsigned int D.19942;
  int D.19943;
  long unsigned int D.19944;
  void * * D.19945;
  long unsigned int D.19948;
  guint16 * D.19949;
  struct MonoDomain * iftmp.22;
  int D.19954;
  short unsigned int D.19955;
  void * * D.19958;
  struct MonoPerfCounters * mono_perfcounters.23;
  unsigned int D.19961;
  unsigned int D.19962;
  _Bool D.19965;
  long int D.19966;
  long int D.19967;
  int D.19970;
  int D.19971;
  int D.19972;
  int D.19973;
  long unsigned int D.19974;
  guint32 D.19975;
  gint slot;
  gint i;
  guint32 res;

  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.19859>; else goto <D.19860>;
    <D.19859>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19860>:
    D.19861 = ret != 0;
    D.19862 = (long int) D.19861;
    D.19863 = __builtin_expect (D.19862, 0);
    if (D.19863 != 0) goto <D.19864>; else goto <D.19865>;
    <D.19864>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 636, "ret == 0");
    <D.19865>:
  }
  D.19866 = handles->size;
  if (D.19866 == 0) goto <D.19867>; else goto <D.19868>;
  <D.19867>:
  handles->size = 32;
  D.19869 = handles->type;
  if (D.19869 > 1) goto <D.19870>; else goto <D.19871>;
  <D.19870>:
  D.19866 = handles->size;
  D.19872 = (long unsigned int) D.19866;
  D.19873 = D.19872 * 8;
  D.19866 = handles->size;
  D.19874 = (int) D.19866;
  D.19869 = handles->type;
  D.19875 = D.19869 == 3;
  D.19876 = (int) D.19875;
  D.19877 = make_root_descr_all_refs (D.19874, D.19876);
  D.19878 = mono_gc_alloc_fixed (D.19873, D.19877);
  handles->entries = D.19878;
  goto <D.19879>;
  <D.19871>:
  D.19866 = handles->size;
  D.19872 = (long unsigned int) D.19866;
  D.19873 = D.19872 * 8;
  D.19880 = monoeg_malloc0 (D.19873);
  handles->entries = D.19880;
  D.19866 = handles->size;
  D.19872 = (long unsigned int) D.19866;
  D.19881 = D.19872 * 2;
  D.19882 = monoeg_malloc0 (D.19881);
  handles->domain_ids = D.19882;
  <D.19879>:
  D.19866 = handles->size;
  D.19883 = D.19866 / 8;
  D.19884 = (long unsigned int) D.19883;
  D.19885 = monoeg_malloc0 (D.19884);
  handles->bitmap = D.19885;
  <D.19868>:
  i = -1;
  D.19886 = handles->slot_hint;
  slot = (gint) D.19886;
  goto <D.19324>;
  <D.19323>:
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19891 = *D.19890;
  if (D.19891 != 4294967295) goto <D.19892>; else goto <D.19893>;
  <D.19892>:
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19891 = *D.19890;
  i = find_first_unset (D.19891);
  slot.18 = (unsigned int) slot;
  D.19895 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.19895;
  goto <D.19322>;
  <D.19893>:
  slot = slot + 1;
  <D.19324>:
  slot.19 = (unsigned int) slot;
  D.19866 = handles->size;
  D.19897 = D.19866 / 32;
  if (slot.19 < D.19897) goto <D.19323>; else goto <D.19322>;
  <D.19322>:
  if (i == -1) goto <D.19898>; else goto <D.19899>;
  <D.19898>:
  D.19900 = BIT_FIELD_REF <*handles, 64, 128>;
  D.19901 = D.19900 & 18446742974197923840;
  if (D.19901 != 0) goto <D.19902>; else goto <D.19903>;
  <D.19902>:
  slot = 0;
  goto <D.19327>;
  <D.19326>:
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19891 = *D.19890;
  if (D.19891 != 4294967295) goto <D.19904>; else goto <D.19905>;
  <D.19904>:
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19891 = *D.19890;
  i = find_first_unset (D.19891);
  slot.18 = (unsigned int) slot;
  D.19895 = (<unnamed-unsigned:24>) slot.18;
  handles->slot_hint = D.19895;
  goto <D.19325>;
  <D.19905>:
  slot = slot + 1;
  <D.19327>:
  D.19886 = handles->slot_hint;
  D.19906 = (int) D.19886;
  if (D.19906 > slot) goto <D.19326>; else goto <D.19325>;
  <D.19325>:
  <D.19903>:
  <D.19899>:
  if (i == -1) goto <D.19907>; else goto <D.19908>;
  <D.19907>:
  {
    guint32 * new_bitmap;
    guint32 new_size;

    D.19866 = handles->size;
    new_size = D.19866 * 2;
    D.19909 = new_size / 8;
    D.19910 = (long unsigned int) D.19909;
    new_bitmap = monoeg_malloc0 (D.19910);
    D.19887 = handles->bitmap;
    D.19866 = handles->size;
    D.19883 = D.19866 / 8;
    D.19911 = (long unsigned int) D.19883;
    memcpy (new_bitmap, D.19887, D.19911);
    D.19887 = handles->bitmap;
    monoeg_g_free (D.19887);
    handles->bitmap = new_bitmap;
    D.19869 = handles->type;
    if (D.19869 > 1) goto <D.19912>; else goto <D.19913>;
    <D.19912>:
    {
      void * * entries;

      D.19914 = (long unsigned int) new_size;
      D.19915 = D.19914 * 8;
      new_size.20 = (int) new_size;
      D.19869 = handles->type;
      D.19875 = D.19869 == 3;
      D.19876 = (int) D.19875;
      D.19917 = make_root_descr_all_refs (new_size.20, D.19876);
      entries = mono_gc_alloc_fixed (D.19915, D.19917);
      D.19918 = handles->entries;
      D.19866 = handles->size;
      D.19872 = (long unsigned int) D.19866;
      D.19873 = D.19872 * 8;
      mono_gc_memmove_aligned (entries, D.19918, D.19873);
      D.19918 = handles->entries;
      mono_gc_free_fixed (D.19918);
      handles->entries = entries;
    }
    goto <D.19919>;
    <D.19913>:
    {
      void * * entries;
      guint16 * domain_ids;

      D.19914 = (long unsigned int) new_size;
      D.19920 = D.19914 * 2;
      domain_ids = monoeg_malloc0 (D.19920);
      D.19914 = (long unsigned int) new_size;
      D.19915 = D.19914 * 8;
      entries = monoeg_malloc0 (D.19915);
      D.19921 = handles->domain_ids;
      D.19866 = handles->size;
      D.19872 = (long unsigned int) D.19866;
      D.19881 = D.19872 * 2;
      memcpy (domain_ids, D.19921, D.19881);
      i = 0;
      goto <D.19335>;
      <D.19334>:
      {
        struct MonoObject * obj;

        D.19918 = handles->entries;
        D.19922 = (long unsigned int) i;
        D.19923 = D.19922 * 8;
        D.19924 = D.19918 + D.19923;
        obj = mono_gc_weak_link_get (D.19924);
        if (obj != 0B) goto <D.19925>; else goto <D.19926>;
        <D.19925>:
        D.19922 = (long unsigned int) i;
        D.19923 = D.19922 * 8;
        D.19927 = entries + D.19923;
        mono_gc_weak_link_add (D.19927, obj, track);
        D.19918 = handles->entries;
        D.19922 = (long unsigned int) i;
        D.19923 = D.19922 * 8;
        D.19924 = D.19918 + D.19923;
        mono_gc_weak_link_remove (D.19924, track);
        goto <D.19928>;
        <D.19926>:
        D.19918 = handles->entries;
        D.19922 = (long unsigned int) i;
        D.19923 = D.19922 * 8;
        D.19929 = D.19918 + D.19923;
        D.19930 = *D.19929;
        D.19931 = D.19930 != 0B;
        D.19932 = (long int) D.19931;
        D.19933 = __builtin_expect (D.19932, 0);
        if (D.19933 != 0) goto <D.19934>; else goto <D.19935>;
        <D.19934>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 695, "!handles->entries [i]");
        <D.19935>:
        <D.19928>:
      }
      i = i + 1;
      <D.19335>:
      i.21 = (unsigned int) i;
      D.19866 = handles->size;
      if (i.21 < D.19866) goto <D.19334>; else goto <D.19336>;
      <D.19336>:
      D.19918 = handles->entries;
      monoeg_g_free (D.19918);
      D.19921 = handles->domain_ids;
      monoeg_g_free (D.19921);
      handles->entries = entries;
      handles->domain_ids = domain_ids;
    }
    <D.19919>:
    i = 0;
    D.19866 = handles->size;
    D.19937 = D.19866 + 1;
    D.19938 = D.19937 / 32;
    slot = (gint) D.19938;
    D.19866 = handles->size;
    D.19937 = D.19866 + 1;
    D.19939 = (<unnamed-unsigned:24>) D.19937;
    handles->slot_hint = D.19939;
    handles->size = new_size;
  }
  <D.19908>:
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19887 = handles->bitmap;
  D.19888 = (long unsigned int) slot;
  D.19889 = D.19888 * 4;
  D.19890 = D.19887 + D.19889;
  D.19891 = *D.19890;
  D.19940 = 1 << i;
  D.19941 = (unsigned int) D.19940;
  D.19942 = D.19891 | D.19941;
  *D.19890 = D.19942;
  D.19943 = slot * 32;
  slot = D.19943 + i;
  D.19918 = handles->entries;
  D.19888 = (long unsigned int) slot;
  D.19944 = D.19888 * 8;
  D.19945 = D.19918 + D.19944;
  *D.19945 = 0B;
  D.19869 = handles->type;
  if (D.19869 <= 1) goto <D.19946>; else goto <D.19947>;
  <D.19946>:
  D.19921 = handles->domain_ids;
  D.19888 = (long unsigned int) slot;
  D.19948 = D.19888 * 2;
  D.19949 = D.19921 + D.19948;
  if (obj != 0B) goto <D.19951>; else goto <D.19952>;
  <D.19951>:
  iftmp.22 = mono_object_get_domain (obj);
  goto <D.19953>;
  <D.19952>:
  iftmp.22 = mono_domain_get ();
  <D.19953>:
  D.19954 = iftmp.22->domain_id;
  D.19955 = (short unsigned int) D.19954;
  *D.19949 = D.19955;
  if (obj != 0B) goto <D.19956>; else goto <D.19957>;
  <D.19956>:
  D.19918 = handles->entries;
  D.19888 = (long unsigned int) slot;
  D.19944 = D.19888 * 8;
  D.19958 = D.19918 + D.19944;
  mono_gc_weak_link_add (D.19958, obj, track);
  <D.19957>:
  goto <D.19959>;
  <D.19947>:
  D.19918 = handles->entries;
  D.19888 = (long unsigned int) slot;
  D.19944 = D.19888 * 8;
  D.19945 = D.19918 + D.19944;
  *D.19945 = obj;
  <D.19959>:
  mono_perfcounters.23 = mono_perfcounters;
  D.19961 = mono_perfcounters.23->gc_num_handles;
  D.19962 = D.19961 + 1;
  mono_perfcounters.23->gc_num_handles = D.19962;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.19963>; else goto <D.19964>;
    <D.19963>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19964>:
    D.19965 = ret != 0;
    D.19966 = (long int) D.19965;
    D.19967 = __builtin_expect (D.19966, 0);
    if (D.19967 != 0) goto <D.19968>; else goto <D.19969>;
    <D.19968>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 725, "ret == 0");
    <D.19969>:
  }
  D.19970 = slot << 3;
  D.19869 = handles->type;
  D.19971 = (int) D.19869;
  D.19972 = D.19971 + 1;
  D.19973 = D.19970 | D.19972;
  res = (guint32) D.19973;
  D.19869 = handles->type;
  D.19971 = (int) D.19869;
  D.19974 = (long unsigned int) res;
  mono_profiler_gc_handle (0, D.19971, D.19974, obj);
  D.19975 = res;
  return D.19975;
}


find_first_unset (guint32 bitmap)
{
  int D.19977;
  unsigned int D.19978;
  unsigned int D.19979;
  int D.19982;
  int i;

  i = 0;
  goto <D.19307>;
  <D.19306>:
  D.19977 = 1 << i;
  D.19978 = (unsigned int) D.19977;
  D.19979 = D.19978 & bitmap;
  if (D.19979 == 0) goto <D.19980>; else goto <D.19981>;
  <D.19980>:
  D.19982 = i;
  return D.19982;
  <D.19981>:
  i = i + 1;
  <D.19307>:
  if (i <= 31) goto <D.19306>; else goto <D.19308>;
  <D.19308>:
  D.19982 = -1;
  return D.19982;
}


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

  if (pinned != 0) goto <D.19984>; else goto <D.19985>;
  <D.19984>:
  D.19986 = 0B;
  return D.19986;
  <D.19985>:
  D.19986 = mono_gc_make_root_descr_all_refs (numbits);
  return D.19986;
}


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

  D.19989 = __builtin_object_size (__dest, 0);
  D.19988 = __builtin___memcpy_chk (__dest, __src, __len, D.19989);
  return D.19988;
}


mono_gchandle_new_weakref (struct MonoObject * obj, gboolean track_resurrection)
{
  _Bool D.19991;
  int D.19992;
  struct HandleData * D.19993;
  uint32_t D.19994;
  guint32 handle;

  D.19991 = track_resurrection != 0;
  D.19992 = (int) D.19991;
  D.19993 = &gc_handles[D.19992];
  handle = alloc_handle (D.19993, obj, track_resurrection);
  D.19994 = handle;
  return D.19994;
}


mono_gchandle_get_target (guint32 gchandle)
{
  unsigned int D.19996;
  struct MonoObject * D.19999;
  _Bool D.20002;
  long int D.20003;
  long int D.20004;
  unsigned int D.20007;
  guint32 * D.20010;
  unsigned int D.20011;
  long unsigned int D.20012;
  long unsigned int D.20013;
  guint32 * D.20014;
  unsigned int D.20015;
  int slot.24;
  int D.20017;
  int D.20018;
  unsigned int D.20019;
  unsigned int D.20020;
  unsigned char D.20023;
  void * * D.20026;
  long unsigned int D.20027;
  long unsigned int D.20028;
  void * * D.20029;
  void * * D.20031;
  _Bool D.20035;
  long int D.20036;
  long int D.20037;
  guint slot;
  guint type;
  struct HandleData * handles;
  struct MonoObject * obj;

  slot = gchandle >> 3;
  D.19996 = gchandle & 7;
  type = D.19996 + 4294967295;
  handles = &gc_handles[type];
  obj = 0B;
  if (type > 3) goto <D.19997>; else goto <D.19998>;
  <D.19997>:
  D.19999 = 0B;
  return D.19999;
  <D.19998>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.20000>; else goto <D.20001>;
    <D.20000>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20001>:
    D.20002 = ret != 0;
    D.20003 = (long int) D.20002;
    D.20004 = __builtin_expect (D.20003, 0);
    if (D.20004 != 0) goto <D.20005>; else goto <D.20006>;
    <D.20005>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 809, "ret == 0");
    <D.20006>:
  }
  D.20007 = handles->size;
  if (D.20007 > slot) goto <D.20008>; else goto <D.20009>;
  <D.20008>:
  D.20010 = handles->bitmap;
  D.20011 = slot / 32;
  D.20012 = (long unsigned int) D.20011;
  D.20013 = D.20012 * 4;
  D.20014 = D.20010 + D.20013;
  D.20015 = *D.20014;
  slot.24 = (int) slot;
  D.20017 = slot.24 & 31;
  D.20018 = 1 << D.20017;
  D.20019 = (unsigned int) D.20018;
  D.20020 = D.20015 & D.20019;
  if (D.20020 != 0) goto <D.20021>; else goto <D.20022>;
  <D.20021>:
  D.20023 = handles->type;
  if (D.20023 <= 1) goto <D.20024>; else goto <D.20025>;
  <D.20024>:
  D.20026 = handles->entries;
  D.20027 = (long unsigned int) slot;
  D.20028 = D.20027 * 8;
  D.20029 = D.20026 + D.20028;
  obj = mono_gc_weak_link_get (D.20029);
  goto <D.20030>;
  <D.20025>:
  D.20026 = handles->entries;
  D.20027 = (long unsigned int) slot;
  D.20028 = D.20027 * 8;
  D.20031 = D.20026 + D.20028;
  obj = *D.20031;
  <D.20030>:
  goto <D.20032>;
  <D.20022>:
  <D.20032>:
  <D.20009>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.20033>; else goto <D.20034>;
    <D.20033>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20034>:
    D.20035 = ret != 0;
    D.20036 = (long int) D.20035;
    D.20037 = __builtin_expect (D.20036, 0);
    if (D.20037 != 0) goto <D.20038>; else goto <D.20039>;
    <D.20038>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 819, "ret == 0");
    <D.20039>:
  }
  D.19999 = obj;
  return D.19999;
}


mono_gchandle_is_in_domain (guint32 gchandle, struct MonoDomain * domain)
{
  unsigned int D.20041;
  gboolean D.20044;
  _Bool D.20047;
  long int D.20048;
  long int D.20049;
  unsigned int D.20052;
  guint32 * D.20055;
  unsigned int D.20056;
  long unsigned int D.20057;
  long unsigned int D.20058;
  guint32 * D.20059;
  unsigned int D.20060;
  int slot.25;
  int D.20062;
  int D.20063;
  unsigned int D.20064;
  unsigned int D.20065;
  unsigned char D.20068;
  int D.20071;
  guint16 * D.20072;
  long unsigned int D.20073;
  long unsigned int D.20074;
  guint16 * D.20075;
  short unsigned int D.20076;
  int D.20077;
  _Bool D.20078;
  void * * D.20080;
  long unsigned int D.20081;
  void * * D.20082;
  struct MonoVTable * D.20086;
  struct MonoDomain * D.20087;
  _Bool D.20088;
  _Bool D.20092;
  long int D.20093;
  long int D.20094;
  guint slot;
  guint type;
  struct HandleData * handles;
  gboolean result;

  slot = gchandle >> 3;
  D.20041 = gchandle & 7;
  type = D.20041 + 4294967295;
  handles = &gc_handles[type];
  result = 0;
  if (type > 3) goto <D.20042>; else goto <D.20043>;
  <D.20042>:
  D.20044 = 0;
  return D.20044;
  <D.20043>:
  {
    int ret;

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.20045>; else goto <D.20046>;
    <D.20045>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20046>:
    D.20047 = ret != 0;
    D.20048 = (long int) D.20047;
    D.20049 = __builtin_expect (D.20048, 0);
    if (D.20049 != 0) goto <D.20050>; else goto <D.20051>;
    <D.20050>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 870, "ret == 0");
    <D.20051>:
  }
  D.20052 = handles->size;
  if (D.20052 > slot) goto <D.20053>; else goto <D.20054>;
  <D.20053>:
  D.20055 = handles->bitmap;
  D.20056 = slot / 32;
  D.20057 = (long unsigned int) D.20056;
  D.20058 = D.20057 * 4;
  D.20059 = D.20055 + D.20058;
  D.20060 = *D.20059;
  slot.25 = (int) slot;
  D.20062 = slot.25 & 31;
  D.20063 = 1 << D.20062;
  D.20064 = (unsigned int) D.20063;
  D.20065 = D.20060 & D.20064;
  if (D.20065 != 0) goto <D.20066>; else goto <D.20067>;
  <D.20066>:
  D.20068 = handles->type;
  if (D.20068 <= 1) goto <D.20069>; else goto <D.20070>;
  <D.20069>:
  D.20071 = domain->domain_id;
  D.20072 = handles->domain_ids;
  D.20073 = (long unsigned int) slot;
  D.20074 = D.20073 * 2;
  D.20075 = D.20072 + D.20074;
  D.20076 = *D.20075;
  D.20077 = (int) D.20076;
  D.20078 = D.20071 == D.20077;
  result = (gboolean) D.20078;
  goto <D.20079>;
  <D.20070>:
  {
    struct MonoObject * obj;

    D.20080 = handles->entries;
    D.20073 = (long unsigned int) slot;
    D.20081 = D.20073 * 8;
    D.20082 = D.20080 + D.20081;
    obj = *D.20082;
    if (obj == 0B) goto <D.20083>; else goto <D.20084>;
    <D.20083>:
    result = 1;
    goto <D.20085>;
    <D.20084>:
    D.20086 = obj->vtable;
    D.20087 = D.20086->domain;
    D.20088 = D.20087 == domain;
    result = (gboolean) D.20088;
    <D.20085>:
  }
  <D.20079>:
  goto <D.20089>;
  <D.20067>:
  <D.20089>:
  <D.20054>:
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.20090>; else goto <D.20091>;
    <D.20090>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20091>:
    D.20092 = ret != 0;
    D.20093 = (long int) D.20092;
    D.20094 = __builtin_expect (D.20093, 0);
    if (D.20094 != 0) goto <D.20095>; else goto <D.20096>;
    <D.20095>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 885, "ret == 0");
    <D.20096>:
  }
  D.20044 = result;
  return D.20044;
}


mono_gchandle_free (guint32 gchandle)
{
  unsigned int D.20098;
  _Bool D.20103;
  long int D.20104;
  long int D.20105;
  unsigned int D.20108;
  guint32 * D.20111;
  unsigned int D.20112;
  long unsigned int D.20113;
  long unsigned int D.20114;
  guint32 * D.20115;
  unsigned int D.20116;
  int slot.26;
  int D.20118;
  int D.20119;
  unsigned int D.20120;
  unsigned int D.20121;
  unsigned char D.20124;
  void * * D.20127;
  long unsigned int D.20128;
  long unsigned int D.20129;
  void * * D.20130;
  void * D.20131;
  void * * D.20134;
  _Bool D.20135;
  int D.20136;
  unsigned int D.20138;
  long unsigned int D.20139;
  long unsigned int D.20140;
  guint32 * D.20141;
  unsigned int D.20142;
  int D.20143;
  unsigned int D.20144;
  unsigned int D.20145;
  struct MonoPerfCounters * mono_perfcounters.27;
  unsigned int D.20148;
  unsigned int D.20149;
  _Bool D.20152;
  long int D.20153;
  long int D.20154;
  int D.20157;
  long unsigned int D.20158;
  guint slot;
  guint type;
  struct HandleData * handles;

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

    ret = pthread_mutex_lock (&handle_section.mutex);
    if (ret != 0) goto <D.20101>; else goto <D.20102>;
    <D.20101>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20102>:
    D.20103 = ret != 0;
    D.20104 = (long int) D.20103;
    D.20105 = __builtin_expect (D.20104, 0);
    if (D.20105 != 0) goto <D.20106>; else goto <D.20107>;
    <D.20106>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 906, "ret == 0");
    <D.20107>:
  }
  D.20108 = handles->size;
  if (D.20108 > slot) goto <D.20109>; else goto <D.20110>;
  <D.20109>:
  D.20111 = handles->bitmap;
  D.20112 = slot / 32;
  D.20113 = (long unsigned int) D.20112;
  D.20114 = D.20113 * 4;
  D.20115 = D.20111 + D.20114;
  D.20116 = *D.20115;
  slot.26 = (int) slot;
  D.20118 = slot.26 & 31;
  D.20119 = 1 << D.20118;
  D.20120 = (unsigned int) D.20119;
  D.20121 = D.20116 & D.20120;
  if (D.20121 != 0) goto <D.20122>; else goto <D.20123>;
  <D.20122>:
  D.20124 = handles->type;
  if (D.20124 <= 1) goto <D.20125>; else goto <D.20126>;
  <D.20125>:
  D.20127 = handles->entries;
  D.20128 = (long unsigned int) slot;
  D.20129 = D.20128 * 8;
  D.20130 = D.20127 + D.20129;
  D.20131 = *D.20130;
  if (D.20131 != 0B) goto <D.20132>; else goto <D.20133>;
  <D.20132>:
  D.20127 = handles->entries;
  D.20128 = (long unsigned int) slot;
  D.20129 = D.20128 * 8;
  D.20134 = D.20127 + D.20129;
  D.20124 = handles->type;
  D.20135 = D.20124 == 1;
  D.20136 = (int) D.20135;
  mono_gc_weak_link_remove (D.20134, D.20136);
  <D.20133>:
  goto <D.20137>;
  <D.20126>:
  D.20127 = handles->entries;
  D.20128 = (long unsigned int) slot;
  D.20129 = D.20128 * 8;
  D.20130 = D.20127 + D.20129;
  *D.20130 = 0B;
  <D.20137>:
  D.20111 = handles->bitmap;
  D.20138 = slot / 32;
  D.20139 = (long unsigned int) D.20138;
  D.20140 = D.20139 * 4;
  D.20141 = D.20111 + D.20140;
  D.20111 = handles->bitmap;
  D.20139 = (long unsigned int) D.20138;
  D.20140 = D.20139 * 4;
  D.20141 = D.20111 + D.20140;
  D.20142 = *D.20141;
  slot.26 = (int) slot;
  D.20118 = slot.26 & 31;
  D.20119 = 1 << D.20118;
  D.20143 = ~D.20119;
  D.20144 = (unsigned int) D.20143;
  D.20145 = D.20142 & D.20144;
  *D.20141 = D.20145;
  goto <D.20146>;
  <D.20123>:
  <D.20146>:
  <D.20110>:
  mono_perfcounters.27 = mono_perfcounters;
  D.20148 = mono_perfcounters.27->gc_num_handles;
  D.20149 = D.20148 + 4294967295;
  mono_perfcounters.27->gc_num_handles = D.20149;
  {
    int ret;

    ret = pthread_mutex_unlock (&handle_section.mutex);
    if (ret != 0) goto <D.20150>; else goto <D.20151>;
    <D.20150>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20151>:
    D.20152 = ret != 0;
    D.20153 = (long int) D.20152;
    D.20154 = __builtin_expect (D.20153, 0);
    if (D.20154 != 0) goto <D.20155>; else goto <D.20156>;
    <D.20155>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 922, "ret == 0");
    <D.20156>:
  }
  D.20124 = handles->type;
  D.20157 = (int) D.20124;
  D.20158 = (long unsigned int) gchandle;
  mono_profiler_gc_handle (1, D.20157, D.20158, 0B);
}


mono_gchandle_free_domain (struct MonoDomain * domain)
{
  _Bool D.20162;
  long int D.20163;
  long int D.20164;
  guint32 * D.20167;
  unsigned int D.20168;
  long unsigned int D.20169;
  long unsigned int D.20170;
  guint32 * D.20171;
  unsigned int D.20172;
  int slot.28;
  int D.20174;
  int D.20175;
  unsigned int D.20176;
  unsigned int D.20177;
  int D.20182;
  guint16 * D.20183;
  long unsigned int D.20184;
  long unsigned int D.20185;
  guint16 * D.20186;
  short unsigned int D.20187;
  int D.20188;
  unsigned int D.20191;
  long unsigned int D.20192;
  long unsigned int D.20193;
  guint32 * D.20194;
  unsigned int D.20195;
  int D.20196;
  unsigned int D.20197;
  unsigned int D.20198;
  void * * D.20199;
  long unsigned int D.20200;
  void * * D.20201;
  void * D.20202;
  void * * D.20205;
  unsigned char D.20206;
  _Bool D.20207;
  int D.20208;
  struct MonoVTable * D.20212;
  struct MonoDomain * D.20213;
  unsigned int D.20216;
  long unsigned int D.20217;
  long unsigned int D.20218;
  guint32 * D.20219;
  unsigned int D.20220;
  unsigned int D.20221;
  unsigned int D.20222;
  _Bool D.20225;
  long int D.20226;
  long int D.20227;
  guint type;

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

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

      ret = pthread_mutex_lock (&handle_section.mutex);
      if (ret != 0) goto <D.20160>; else goto <D.20161>;
      <D.20160>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
      <D.20161>:
      D.20162 = ret != 0;
      D.20163 = (long int) D.20162;
      D.20164 = __builtin_expect (D.20163, 0);
      if (D.20164 != 0) goto <D.20165>; else goto <D.20166>;
      <D.20165>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 941, "ret == 0");
      <D.20166>:
    }
    slot = 0;
    goto <D.19398>;
    <D.19397>:
    D.20167 = handles->bitmap;
    D.20168 = slot / 32;
    D.20169 = (long unsigned int) D.20168;
    D.20170 = D.20169 * 4;
    D.20171 = D.20167 + D.20170;
    D.20172 = *D.20171;
    slot.28 = (int) slot;
    D.20174 = slot.28 & 31;
    D.20175 = 1 << D.20174;
    D.20176 = (unsigned int) D.20175;
    D.20177 = D.20172 & D.20176;
    if (D.20177 == 0) goto <D.20178>; else goto <D.20179>;
    <D.20178>:
    // predicted unlikely by continue predictor.
    goto <D.19396>;
    <D.20179>:
    if (type <= 1) goto <D.20180>; else goto <D.20181>;
    <D.20180>:
    D.20182 = domain->domain_id;
    D.20183 = handles->domain_ids;
    D.20184 = (long unsigned int) slot;
    D.20185 = D.20184 * 2;
    D.20186 = D.20183 + D.20185;
    D.20187 = *D.20186;
    D.20188 = (int) D.20187;
    if (D.20182 == D.20188) goto <D.20189>; else goto <D.20190>;
    <D.20189>:
    D.20167 = handles->bitmap;
    D.20191 = slot / 32;
    D.20192 = (long unsigned int) D.20191;
    D.20193 = D.20192 * 4;
    D.20194 = D.20167 + D.20193;
    D.20167 = handles->bitmap;
    D.20192 = (long unsigned int) D.20191;
    D.20193 = D.20192 * 4;
    D.20194 = D.20167 + D.20193;
    D.20195 = *D.20194;
    slot.28 = (int) slot;
    D.20174 = slot.28 & 31;
    D.20175 = 1 << D.20174;
    D.20196 = ~D.20175;
    D.20197 = (unsigned int) D.20196;
    D.20198 = D.20195 & D.20197;
    *D.20194 = D.20198;
    D.20199 = handles->entries;
    D.20184 = (long unsigned int) slot;
    D.20200 = D.20184 * 8;
    D.20201 = D.20199 + D.20200;
    D.20202 = *D.20201;
    if (D.20202 != 0B) goto <D.20203>; else goto <D.20204>;
    <D.20203>:
    D.20199 = handles->entries;
    D.20184 = (long unsigned int) slot;
    D.20200 = D.20184 * 8;
    D.20205 = D.20199 + D.20200;
    D.20206 = handles->type;
    D.20207 = D.20206 == 1;
    D.20208 = (int) D.20207;
    mono_gc_weak_link_remove (D.20205, D.20208);
    <D.20204>:
    <D.20190>:
    goto <D.20209>;
    <D.20181>:
    D.20199 = handles->entries;
    D.20184 = (long unsigned int) slot;
    D.20200 = D.20184 * 8;
    D.20201 = D.20199 + D.20200;
    D.20202 = *D.20201;
    if (D.20202 != 0B) goto <D.20210>; else goto <D.20211>;
    <D.20210>:
    D.20199 = handles->entries;
    D.20184 = (long unsigned int) slot;
    D.20200 = D.20184 * 8;
    D.20201 = D.20199 + D.20200;
    D.20202 = *D.20201;
    D.20212 = MEM[(struct MonoObject *)D.20202].vtable;
    D.20213 = D.20212->domain;
    if (D.20213 == domain) goto <D.20214>; else goto <D.20215>;
    <D.20214>:
    D.20167 = handles->bitmap;
    D.20216 = slot / 32;
    D.20217 = (long unsigned int) D.20216;
    D.20218 = D.20217 * 4;
    D.20219 = D.20167 + D.20218;
    D.20167 = handles->bitmap;
    D.20217 = (long unsigned int) D.20216;
    D.20218 = D.20217 * 4;
    D.20219 = D.20167 + D.20218;
    D.20220 = *D.20219;
    slot.28 = (int) slot;
    D.20174 = slot.28 & 31;
    D.20175 = 1 << D.20174;
    D.20196 = ~D.20175;
    D.20197 = (unsigned int) D.20196;
    D.20221 = D.20220 & D.20197;
    *D.20219 = D.20221;
    D.20199 = handles->entries;
    D.20184 = (long unsigned int) slot;
    D.20200 = D.20184 * 8;
    D.20201 = D.20199 + D.20200;
    *D.20201 = 0B;
    <D.20215>:
    <D.20211>:
    <D.20209>:
    <D.19396>:
    slot = slot + 1;
    <D.19398>:
    D.20222 = handles->size;
    if (D.20222 > slot) goto <D.19397>; else goto <D.19399>;
    <D.19399>:
    {
      int ret;

      ret = pthread_mutex_unlock (&handle_section.mutex);
      if (ret != 0) goto <D.20223>; else goto <D.20224>;
      <D.20223>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.20224>:
      D.20225 = ret != 0;
      D.20226 = (long int) D.20225;
      D.20227 = __builtin_expect (D.20226, 0);
      if (D.20227 != 0) goto <D.20228>; else goto <D.20229>;
      <D.20228>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 958, "ret == 0");
      <D.20229>:
    }
  }
  type = type + 1;
  <D.19402>:
  if (type <= 2) goto <D.19401>; else goto <D.19403>;
  <D.19403>:
}


GCHandle_CheckCurrentDomain (guint32 gchandle)
{
  MonoBoolean D.20230;
  struct MonoDomain * D.20231;
  int D.20232;

  D.20231 = mono_domain_get ();
  D.20232 = mono_gchandle_is_in_domain (gchandle, D.20231);
  D.20230 = (MonoBoolean) D.20232;
  return D.20230;
}


mono_gc_finalize_notify ()
{
  mono_sem_post (&finalizer_sem);
}


mono_gc_init ()
{
  int D.20234;
  int D.20237;
  int D.20240;
  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.20234 = mono_gc_is_moving ();
  if (D.20234 == 0) goto <D.20235>; else goto <D.20236>;
  <D.20235>:
  mono_gc_register_root (&gc_handles[2].entries, 8, 0B);
  <D.20236>:
  D.20237 = mono_gc_is_moving ();
  if (D.20237 == 0) goto <D.20238>; else goto <D.20239>;
  <D.20238>:
  mono_gc_register_root (&gc_handles[3].entries, 8, 0B);
  <D.20239>:
  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.20240 = mono_gc_is_disabled ();
  if (D.20240 != 0) goto <D.20241>; else goto <D.20242>;
  <D.20241>:
  gc_disabled = 1;
  return;
  <D.20242>:
  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.20246>; else goto <D.20249>;
  <D.20249>:
  pending_done_event.33 = pending_done_event;
  if (pending_done_event.33 == 0B) goto <D.20246>; else goto <D.20251>;
  <D.20251>:
  shutdown_event.34 = shutdown_event;
  if (shutdown_event.34 == 0B) goto <D.20246>; else goto <D.20247>;
  <D.20246>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "gc.c", 1152);
  <D.20247>:
  sem_init (&finalizer_sem, 0, 0);
  mono_gc_init_finalizer_thread ();
}


mono_gc_init_finalizer_thread ()
{
  struct MonoDomain * D.20254;
  struct MonoInternalThread * gc_thread.35;
  struct MonoInternalThread * gc_thread.36;
  struct MonoDomain * D.20257;
  struct MonoString * D.20258;

  D.20254 = mono_domain_get ();
  gc_thread.35 = mono_thread_create_internal (D.20254, finalizer_thread, 0B, 0, 1, 0);
  gc_thread = gc_thread.35;
  gc_thread.36 = gc_thread;
  D.20257 = mono_domain_get ();
  D.20258 = mono_string_new (D.20257, "Finalizer");
  ves_icall_System_Threading_Thread_SetName_internal (gc_thread.36, D.20258);
}


finalizer_thread (void * unused)
{
  struct MonoDomain * D.20259;
  struct MonoDomain * D.20260;
  _Bool D.20261;
  long int D.20262;
  long int D.20263;
  struct GSList * domains_to_finalize.37;
  _Bool D.20271;
  long int D.20272;
  long int D.20273;
  struct GSList * domains_to_finalize.38;
  _Bool D.20281;
  long int D.20282;
  long int D.20283;
  _Bool D.20289;
  long int D.20290;
  long int D.20291;
  void * pending_done_event.39;
  int finished.40;
  void * shutdown_event.41;
  guint32 D.20297;

  goto <D.19434>;
  <D.19433>:
  D.20259 = mono_domain_get ();
  D.20260 = mono_get_root_domain ();
  D.20261 = D.20259 != D.20260;
  D.20262 = (long int) D.20261;
  D.20263 = __builtin_expect (D.20262, 0);
  if (D.20263 != 0) goto <D.20264>; else goto <D.20265>;
  <D.20264>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1069, "mono_domain_get () == mono_get_root_domain ()");
  <D.20265>:
  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.20267>; else goto <D.20268>;
  <D.20267>:
  {
    int ret;

    ret = pthread_mutex_lock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.20269>; else goto <D.20270>;
    <D.20269>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20270>:
    D.20271 = ret != 0;
    D.20272 = (long int) D.20271;
    D.20273 = __builtin_expect (D.20272, 0);
    if (D.20273 != 0) goto <D.20274>; else goto <D.20275>;
    <D.20274>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1087, "ret == 0");
    <D.20275>:
  }
  domains_to_finalize.37 = domains_to_finalize;
  if (domains_to_finalize.37 != 0B) goto <D.20276>; else goto <D.20277>;
  <D.20276>:
  {
    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.20279>; else goto <D.20280>;
      <D.20279>:
      monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
      <D.20280>:
      D.20281 = ret != 0;
      D.20282 = (long int) D.20281;
      D.20283 = __builtin_expect (D.20282, 0);
      if (D.20283 != 0) goto <D.20284>; else goto <D.20285>;
      <D.20284>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1091, "ret == 0");
      <D.20285>:
    }
    finalize_domain_objects (req);
  }
  goto <D.20286>;
  <D.20277>:
  {
    int ret;

    ret = pthread_mutex_unlock (&finalizer_mutex.mutex);
    if (ret != 0) goto <D.20287>; else goto <D.20288>;
    <D.20287>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20288>:
    D.20289 = ret != 0;
    D.20290 = (long int) D.20289;
    D.20291 = __builtin_expect (D.20290, 0);
    if (D.20291 != 0) goto <D.20292>; else goto <D.20293>;
    <D.20292>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1095, "ret == 0");
    <D.20293>:
  }
  <D.20286>:
  <D.20268>:
  mono_gc_invoke_finalizers ();
  reference_queue_proccess_all ();
  pending_done_event.39 = pending_done_event;
  SetEvent (pending_done_event.39);
  <D.19434>:
  finished.40 = finished;
  if (finished.40 == 0) goto <D.19433>; else goto <D.19435>;
  <D.19435>:
  shutdown_event.41 = shutdown_event;
  SetEvent (shutdown_event.41);
  D.20297 = 0;
  return D.20297;
}


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

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

        i = 0;
        goto <D.19421>;
        <D.19420>:
        D.20299 = to_finalize[i];
        mono_gc_run_finalize (D.20299, 0B);
        i = i + 1;
        <D.19421>:
        if (i < count) goto <D.19420>; else goto <D.19422>;
        <D.19422>:
      }
      <D.19424>:
      count = mono_gc_finalizers_for_domain (domain, &to_finalize, 64);
      if (count != 0) goto <D.19423>; else goto <D.19425>;
      <D.19425>:
      reference_queue_clear_for_domain (domain);
      D.20300 = req->done_event;
      SetEvent (D.20300);
      monoeg_g_free (req);
    }
  finally
    {
      to_finalize = {CLOBBER};
    }
}


reference_queue_clear_for_domain (struct MonoDomain * domain)
{
  struct MonoDomain * D.20301;
  void * * D.20304;
  void (*<Tbf>) (void *) D.20305;
  void * D.20306;
  struct MonoReferenceQueue * queue;

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

    iter = &queue->queue;
    goto <D.19526>;
    <D.19525>:
    D.20301 = entry->domain;
    if (D.20301 == domain) goto <D.20302>; else goto <D.20303>;
    <D.20302>:
    D.20304 = &entry->dis_link;
    mono_gc_weak_link_remove (D.20304, 1);
    ref_list_remove_element (iter, entry);
    D.20305 = queue->callback;
    D.20306 = entry->user_data;
    D.20305 (D.20306);
    monoeg_g_free (entry);
    goto <D.20307>;
    <D.20303>:
    iter = &entry->next;
    <D.20307>:
    <D.19526>:
    entry = *iter;
    if (entry != 0B) goto <D.19525>; else goto <D.19527>;
    <D.19527>:
  }
  queue = queue->next;
  <D.19529>:
  if (queue != 0B) goto <D.19528>; else goto <D.19530>;
  <D.19530>:
}


ref_list_remove_element (struct RefQueueEntry * * prev, struct RefQueueEntry * element)
{
  struct RefQueueEntry * D.20308;
  struct RefQueueEntry * D.20310;
  void * D.20311;

  <D.19480>:
  goto <D.19478>;
  <D.19477>:
  D.20308 = *prev;
  prev = &D.20308->next;
  <D.19478>:
  D.20308 = *prev;
  if (D.20308 != element) goto <D.19477>; else goto <D.19479>;
  <D.19479>:
  if (prev != 0B) goto <D.20309>; else goto <D.19481>;
  <D.20309>:
  D.20310 = element->next;
  D.20311 = InterlockedCompareExchangePointer (prev, D.20310, element);
  if (D.20311 != element) goto <D.19480>; else goto <D.19481>;
  <D.19481>:
}


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

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


reference_queue_proccess_all ()
{
  _Bool D.20319;
  long int D.20320;
  long int D.20321;
  int D.20324;
  struct RefQueueEntry * D.20327;
  _Bool D.20332;
  long int D.20333;
  long int D.20334;
  struct MonoReferenceQueue * D.20337;
  struct MonoReferenceQueue * D.20338;
  _Bool D.20341;
  long int D.20342;
  long int D.20343;
  struct MonoReferenceQueue * * iter;
  struct MonoReferenceQueue * queue;
  void restart = <<< error >>>;

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

    ret = pthread_mutex_lock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.20317>; else goto <D.20318>;
    <D.20317>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20318>:
    D.20319 = ret != 0;
    D.20320 = (long int) D.20319;
    D.20321 = __builtin_expect (D.20320, 0);
    if (D.20321 != 0) goto <D.20322>; else goto <D.20323>;
    <D.20322>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1424, "ret == 0");
    <D.20323>:
  }
  iter = &ref_queues;
  goto <D.19507>;
  <D.19509>:
  queue = *iter;
  D.20324 = queue->should_be_deleted;
  if (D.20324 == 0) goto <D.20325>; else goto <D.20326>;
  <D.20325>:
  iter = &queue->next;
  // predicted unlikely by continue predictor.
  goto <D.19507>;
  <D.20326>:
  D.20327 = queue->queue;
  if (D.20327 != 0B) goto <D.20328>; else goto <D.20329>;
  <D.20328>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.20330>; else goto <D.20331>;
    <D.20330>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20331>:
    D.20332 = ret != 0;
    D.20333 = (long int) D.20332;
    D.20334 = __builtin_expect (D.20333, 0);
    if (D.20334 != 0) goto <D.20335>; else goto <D.20336>;
    <D.20335>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1432, "ret == 0");
    <D.20336>:
  }
  reference_queue_proccess (queue);
  goto restart;
  <D.20329>:
  D.20337 = queue->next;
  *iter = D.20337;
  monoeg_g_free (queue);
  <D.19507>:
  D.20338 = *iter;
  if (D.20338 != 0B) goto <D.19509>; else goto <D.19510>;
  <D.19510>:
  {
    int ret;

    ret = pthread_mutex_unlock (&reference_queue_mutex.mutex);
    if (ret != 0) goto <D.20339>; else goto <D.20340>;
    <D.20339>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20340>:
    D.20341 = ret != 0;
    D.20342 = (long int) D.20341;
    D.20343 = __builtin_expect (D.20342, 0);
    if (D.20343 != 0) goto <D.20344>; else goto <D.20345>;
    <D.20344>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1439, "ret == 0");
    <D.20345>:
  }
}


reference_queue_proccess (struct MonoReferenceQueue * queue)
{
  int D.20349;
  void * * D.20351;
  struct MonoObject * D.20352;
  void (*<Tbf>) (void *) D.20353;
  void * D.20354;
  struct RefQueueEntry * * iter;
  struct RefQueueEntry * entry;

  iter = &queue->queue;
  goto <D.19495>;
  <D.19494>:
  D.20349 = queue->should_be_deleted;
  if (D.20349 != 0) goto <D.20346>; else goto <D.20350>;
  <D.20350>:
  D.20351 = &entry->dis_link;
  D.20352 = mono_gc_weak_link_get (D.20351);
  if (D.20352 == 0B) goto <D.20346>; else goto <D.20347>;
  <D.20346>:
  D.20351 = &entry->dis_link;
  mono_gc_weak_link_remove (D.20351, 1);
  ref_list_remove_element (iter, entry);
  D.20353 = queue->callback;
  D.20354 = entry->user_data;
  D.20353 (D.20354);
  monoeg_g_free (entry);
  goto <D.20348>;
  <D.20347>:
  iter = &entry->next;
  <D.20348>:
  <D.19495>:
  entry = *iter;
  if (entry != 0B) goto <D.19494>; else goto <D.19496>;
  <D.19496>:
}


mono_gc_cleanup ()
{
  int gc_disabled.44;
  void * shutdown_event.45;
  struct MonoInternalThread * D.20359;
  struct MonoInternalThread * gc_thread.46;
  unsigned int D.20363;
  void * D.20366;
  unsigned int D.20367;
  unsigned int D.20372;
  _Bool D.20373;
  long int D.20374;
  long int D.20375;
  long unsigned int D.20378;

  gc_disabled.44 = gc_disabled;
  if (gc_disabled.44 == 0) goto <D.20356>; else goto <D.20357>;
  <D.20356>:
  shutdown_event.45 = shutdown_event;
  ResetEvent (shutdown_event.45);
  finished = 1;
  D.20359 = mono_thread_internal_current ();
  gc_thread.46 = gc_thread;
  if (D.20359 != gc_thread.46) goto <D.20361>; else goto <D.20362>;
  <D.20361>:
  mono_gc_finalize_notify ();
  shutdown_event.45 = shutdown_event;
  D.20363 = WaitForSingleObjectEx (shutdown_event.45, 2000, 0);
  if (D.20363 == 258) goto <D.20364>; else goto <D.20365>;
  <D.20364>:
  {
    int ret;

    suspend_finalizers = 1;
    gc_thread.46 = gc_thread;
    mono_thread_internal_stop (gc_thread.46);
    gc_thread.46 = gc_thread;
    D.20366 = gc_thread.46->handle;
    D.20367 = WaitForSingleObjectEx (D.20366, 100, 1);
    ret = (int) D.20367;
    if (ret == 258) goto <D.20368>; else goto <D.20369>;
    <D.20368>:
    monoeg_g_log (0B, 16, "Shutting down finalizer thread timed out.");
    goto <D.20370>;
    <D.20369>:
    Sleep (100);
    <D.20370>:
  }
  goto <D.20371>;
  <D.20365>:
  {
    int ret;

    gc_thread.46 = gc_thread;
    D.20366 = gc_thread.46->handle;
    D.20372 = WaitForSingleObjectEx (D.20366, 4294967295, 1);
    ret = (int) D.20372;
    D.20373 = ret != 0;
    D.20374 = (long int) D.20373;
    D.20375 = __builtin_expect (D.20374, 0);
    if (D.20375 != 0) goto <D.20376>; else goto <D.20377>;
    <D.20376>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1208, "ret == WAIT_OBJECT_0");
    <D.20377>:
    gc_thread.46 = gc_thread;
    D.20378 = gc_thread.46->tid;
    ret = pthread_join (D.20378, 0B);
    D.20373 = ret != 0;
    D.20374 = (long int) D.20373;
    D.20375 = __builtin_expect (D.20374, 0);
    if (D.20375 != 0) goto <D.20379>; else goto <D.20380>;
    <D.20379>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1216, "ret == 0");
    <D.20380>:
  }
  <D.20371>:
  <D.20362>:
  gc_thread = 0B;
  <D.20357>:
  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.19517>;
  <D.19516>:
  queue->should_be_deleted = 1;
  queue = queue->next;
  <D.19517>:
  if (queue != 0B) goto <D.19516>; else goto <D.19518>;
  <D.19518>:
  reference_queue_proccess_all ();
}


mono_gc_is_finalizer_internal_thread (struct MonoInternalThread * thread)
{
  gboolean D.20381;
  struct MonoInternalThread * gc_thread.47;
  _Bool D.20383;

  gc_thread.47 = gc_thread;
  D.20383 = thread == gc_thread.47;
  D.20381 = (gboolean) D.20383;
  return D.20381;
}


mono_gc_is_finalizer_thread (struct MonoThread * thread)
{
  gboolean D.20385;
  struct _MonoInternalThread * D.20386;

  D.20386 = thread->internal_thread;
  D.20385 = mono_gc_is_finalizer_internal_thread (D.20386);
  return D.20385;
}


mono_gc_parse_environment_string_extract_number (const char * str, glong * out)
{
  long unsigned int D.20388;
  gboolean D.20391;
  sizetype D.20392;
  sizetype D.20393;
  const char * D.20394;
  int D.20395;
  const short unsigned int * * D.20396;
  const short unsigned int * D.20397;
  long unsigned int D.20398;
  long unsigned int D.20399;
  const short unsigned int * D.20400;
  short unsigned int D.20401;
  int D.20402;
  int D.20403;
  int * D.20406;
  int D.20411;
  unsigned long val.48;
  unsigned long D.20414;
  char * endptr.49;
  char * D.20421;
  char D.20422;
  long unsigned int val.50;
  long unsigned int D.20428;
  char * endptr;
  int len;
  int shift;
  glong val;
  gboolean is_suffix;
  char suffix;

  try
    {
      D.20388 = strlen (str);
      len = (int) D.20388;
      shift = 0;
      is_suffix = 0;
      if (len == 0) goto <D.20389>; else goto <D.20390>;
      <D.20389>:
      D.20391 = 0;
      return D.20391;
      <D.20390>:
      D.20392 = (sizetype) len;
      D.20393 = D.20392 + 18446744073709551615;
      D.20394 = str + D.20393;
      suffix = *D.20394;
      D.20395 = (int) suffix;
      switch (D.20395) <default: <D.19470>, case 71: <D.19464>, case 75: <D.19468>, case 77: <D.19466>, case 103: <D.19463>, case 107: <D.19467>, case 109: <D.19465>>
      <D.19463>:
      <D.19464>:
      shift = shift + 10;
      <D.19465>:
      <D.19466>:
      shift = shift + 10;
      <D.19467>:
      <D.19468>:
      shift = shift + 10;
      is_suffix = 1;
      goto <D.19469>;
      <D.19470>:
      D.20396 = __ctype_b_loc ();
      D.20397 = *D.20396;
      D.20398 = (long unsigned int) suffix;
      D.20399 = D.20398 * 2;
      D.20400 = D.20397 + D.20399;
      D.20401 = *D.20400;
      D.20402 = (int) D.20401;
      D.20403 = D.20402 & 2048;
      if (D.20403 == 0) goto <D.20404>; else goto <D.20405>;
      <D.20404>:
      D.20391 = 0;
      return D.20391;
      <D.20405>:
      goto <D.19469>;
      <D.19469>:
      D.20406 = __errno_location ();
      *D.20406 = 0;
      val = strtol (str, &endptr, 10);
      D.20406 = __errno_location ();
      D.20411 = *D.20406;
      if (D.20411 == 34) goto <D.20412>; else goto <D.20407>;
      <D.20412>:
      val.48 = (unsigned long) val;
      D.20414 = val.48 + 9223372036854775807;
      if (D.20414 > 18446744073709551613) goto <D.20408>; else goto <D.20407>;
      <D.20407>:
      D.20406 = __errno_location ();
      D.20411 = *D.20406;
      if (D.20411 != 0) goto <D.20415>; else goto <D.20409>;
      <D.20415>:
      if (val == 0) goto <D.20408>; else goto <D.20409>;
      <D.20409>:
      endptr.49 = endptr;
      if (endptr.49 == str) goto <D.20408>; else goto <D.20410>;
      <D.20408>:
      D.20391 = 0;
      return D.20391;
      <D.20410>:
      if (is_suffix != 0) goto <D.20417>; else goto <D.20418>;
      <D.20417>:
      {
        gulong unshifted;

        if (val < 0) goto <D.20419>; else goto <D.20420>;
        <D.20419>:
        D.20391 = 0;
        return D.20391;
        <D.20420>:
        endptr.49 = endptr;
        D.20421 = endptr.49 + 1;
        D.20422 = *D.20421;
        if (D.20422 != 0) goto <D.20423>; else goto <D.20424>;
        <D.20423>:
        D.20391 = 0;
        return D.20391;
        <D.20424>:
        unshifted = (gulong) val;
        val = val << shift;
        if (val < 0) goto <D.20425>; else goto <D.20426>;
        <D.20425>:
        D.20391 = 0;
        return D.20391;
        <D.20426>:
        val.50 = (long unsigned int) val;
        D.20428 = val.50 >> shift;
        if (D.20428 != unshifted) goto <D.20429>; else goto <D.20430>;
        <D.20429>:
        D.20391 = 0;
        return D.20391;
        <D.20430>:
      }
      <D.20418>:
      *out = val;
      D.20391 = 1;
      return D.20391;
    }
  finally
    {
      endptr = {CLOBBER};
    }
}


mono_gc_reference_queue_new (void (*mono_reference_queue_callback) (void *) callback)
{
  _Bool D.20435;
  long int D.20436;
  long int D.20437;
  struct MonoReferenceQueue * ref_queues.51;
  _Bool D.20443;
  long int D.20444;
  long int D.20445;
  struct MonoReferenceQueue * D.20448;
  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.20433>; else goto <D.20434>;
    <D.20433>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.20434>:
    D.20435 = ret != 0;
    D.20436 = (long int) D.20435;
    D.20437 = __builtin_expect (D.20436, 0);
    if (D.20437 != 0) goto <D.20438>; else goto <D.20439>;
    <D.20438>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1497, "ret == 0");
    <D.20439>:
  }
  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.20441>; else goto <D.20442>;
    <D.20441>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.20442>:
    D.20443 = ret != 0;
    D.20444 = (long int) D.20443;
    D.20445 = __builtin_expect (D.20444, 0);
    if (D.20445 != 0) goto <D.20446>; else goto <D.20447>;
    <D.20446>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "gc.c", 1500, "ret == 0");
    <D.20447>:
  }
  D.20448 = res;
  return D.20448;
}


mono_gc_reference_queue_add (struct MonoReferenceQueue * queue, struct MonoObject * obj, void * user_data)
{
  int D.20450;
  mono_bool D.20453;
  struct MonoVTable * D.20454;
  struct MonoDomain * D.20455;
  void * * D.20456;
  struct RefQueueEntry * * D.20457;
  struct RefQueueEntry * entry;

  D.20450 = queue->should_be_deleted;
  if (D.20450 != 0) goto <D.20451>; else goto <D.20452>;
  <D.20451>:
  D.20453 = 0;
  return D.20453;
  <D.20452>:
  entry = monoeg_malloc0 (40);
  entry->user_data = user_data;
  D.20454 = obj->vtable;
  D.20455 = D.20454->domain;
  entry->domain = D.20455;
  D.20456 = &entry->dis_link;
  mono_gc_weak_link_add (D.20456, obj, 1);
  D.20457 = &queue->queue;
  ref_list_push (D.20457, entry);
  D.20453 = 1;
  return D.20453;
}


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

  <D.19487>:
  current = *head;
  value->next = current;
  mono_memory_write_barrier ();
  D.20459 = InterlockedCompareExchangePointer (head, value, current);
  if (D.20459 != current) goto <D.19487>; else goto <D.19488>;
  <D.19488>:
}


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;
}


