mono_monitor_init ()
{
  InitializeCriticalSection (&monitor_mutex);
}


mono_monitor_cleanup ()
{
  struct MonoThreadsSync * mon;

  mon = monitor_freelist;
  goto <D.18273>;
  <D.18272>:
  mon->wait_list = -1B;
  mon = mon->data;
  <D.18273>:
  if (mon != 0B) goto <D.18272>; else goto <D.18274>;
  <D.18274>:
}


mono_monitor_init_tls ()
{
  long unsigned int tls_pthread_self.0;

  tls_pthread_self.0 = pthread_self ();
  tls_pthread_self = tls_pthread_self.0;
}


mono_locks_dump (gboolean include_untaken)
{
  int D.18535;
  void * D.18536;
  int D.18539;
  int D.18543;
  void * * D.18546;
  long unsigned int D.18547;
  unsigned int D.18550;
  void * D.18551;
  void * D.18552;
  int D.18555;
  int i;
  int used;
  int on_freelist;
  int to_recycle;
  int total;
  int num_arrays;
  struct MonoThreadsSync * mon;
  struct MonitorArray * marray;

  used = 0;
  on_freelist = 0;
  to_recycle = 0;
  total = 0;
  num_arrays = 0;
  mon = monitor_freelist;
  goto <D.18297>;
  <D.18296>:
  on_freelist = on_freelist + 1;
  mon = mon->data;
  <D.18297>:
  if (mon != 0B) goto <D.18296>; else goto <D.18298>;
  <D.18298>:
  marray = monitor_allocated;
  goto <D.18304>;
  <D.18303>:
  D.18535 = marray->num_monitors;
  total = D.18535 + total;
  num_arrays = num_arrays + 1;
  i = 0;
  goto <D.18301>;
  <D.18300>:
  mon = &marray->monitors[i];
  D.18536 = mon->data;
  if (D.18536 == 0B) goto <D.18537>; else goto <D.18538>;
  <D.18537>:
  D.18535 = marray->num_monitors;
  D.18539 = D.18535 + -1;
  if (D.18539 > i) goto <D.18540>; else goto <D.18541>;
  <D.18540>:
  to_recycle = to_recycle + 1;
  <D.18541>:
  goto <D.18542>;
  <D.18538>:
  D.18536 = mon->data;
  D.18543 = monitor_is_on_freelist (D.18536);
  if (D.18543 == 0) goto <D.18544>; else goto <D.18545>;
  <D.18544>:
  {
    struct MonoObject * holder;

    D.18546 = &mon->data;
    holder = mono_gc_weak_link_get (D.18546);
    D.18547 = mon->owner;
    if (D.18547 != 0) goto <D.18548>; else goto <D.18549>;
    <D.18548>:
    D.18550 = mon->nest;
    D.18547 = mon->owner;
    D.18551 = (void *) D.18547;
    monoeg_g_print ("Lock %p in object %p held by thread %p, nest level: %d\n", mon, holder, D.18551, D.18550);
    D.18552 = mon->entry_sem;
    if (D.18552 != 0B) goto <D.18553>; else goto <D.18554>;
    <D.18553>:
    D.18555 = mon->entry_count;
    D.18552 = mon->entry_sem;
    monoeg_g_print ("\tWaiting on semaphore %p: %d\n", D.18552, D.18555);
    <D.18554>:
    goto <D.18556>;
    <D.18549>:
    if (include_untaken != 0) goto <D.18557>; else goto <D.18558>;
    <D.18557>:
    monoeg_g_print ("Lock %p in object %p untaken\n", mon, holder);
    <D.18558>:
    <D.18556>:
    used = used + 1;
  }
  <D.18545>:
  <D.18542>:
  i = i + 1;
  <D.18301>:
  D.18535 = marray->num_monitors;
  if (D.18535 > i) goto <D.18300>; else goto <D.18302>;
  <D.18302>:
  marray = marray->next;
  <D.18304>:
  if (marray != 0B) goto <D.18303>; else goto <D.18305>;
  <D.18305>:
  monoeg_g_print ("Total locks (in %d array(s)): %d, used: %d, on freelist: %d, to recycle: %d\n", num_arrays, total, used, on_freelist, to_recycle);
}


monitor_is_on_freelist (struct MonoThreadsSync * mon)
{
  struct MonoThreadsSync[0:] * D.18559;
  int D.18562;
  struct MonoThreadsSync * D.18563;
  int D.18566;
  struct MonitorArray * marray;

  marray = monitor_allocated;
  goto <D.18283>;
  <D.18282>:
  D.18559 = &marray->monitors;
  if (D.18559 <= mon) goto <D.18560>; else goto <D.18561>;
  <D.18560>:
  D.18562 = marray->num_monitors;
  D.18563 = &marray->monitors[D.18562];
  if (D.18563 > mon) goto <D.18564>; else goto <D.18565>;
  <D.18564>:
  D.18566 = 1;
  return D.18566;
  <D.18565>:
  <D.18561>:
  marray = marray->next;
  <D.18283>:
  if (marray != 0B) goto <D.18282>; else goto <D.18284>;
  <D.18284>:
  D.18566 = 0;
  return D.18566;
}


mono_object_hash (struct MonoObject * obj)
{
  int D.18570;
  struct MonoThreadsSync * D.18571;
  long unsigned int D.18572;
  long unsigned int D.18573;
  unsigned int D.18576;
  unsigned int D.18577;
  long unsigned int D.18578;
  long unsigned int D.18581;
  struct MonoThreadsSync * D.18582;
  long int obj.1;
  unsigned int D.18584;
  unsigned int D.18585;
  int hash.2;
  long unsigned int D.18589;
  unsigned int D.18591;
  unsigned int D.18592;
  long unsigned int D.18593;
  struct MonoThreadsSync * * D.18594;
  void * D.18595;
  union LockWord lw;
  unsigned int hash;

  try
    {
      if (obj == 0B) goto <D.18568>; else goto <D.18569>;
      <D.18568>:
      D.18570 = 0;
      return D.18570;
      <D.18569>:
      D.18571 = obj->synchronisation;
      lw.sync = D.18571;
      D.18572 = lw.lock_word;
      D.18573 = D.18572 & 1;
      if (D.18573 != 0) goto <D.18574>; else goto <D.18575>;
      <D.18574>:
      D.18572 = lw.lock_word;
      D.18576 = (unsigned int) D.18572;
      D.18577 = D.18576 >> 2;
      D.18570 = (int) D.18577;
      return D.18570;
      <D.18575>:
      D.18572 = lw.lock_word;
      D.18578 = D.18572 & 2;
      if (D.18578 != 0) goto <D.18579>; else goto <D.18580>;
      <D.18579>:
      D.18572 = lw.lock_word;
      D.18581 = D.18572 & 18446744073709551612;
      lw.lock_word = D.18581;
      D.18582 = lw.sync;
      D.18570 = D.18582->hash_code;
      return D.18570;
      <D.18580>:
      obj.1 = (long int) obj;
      D.18584 = (unsigned int) obj.1;
      D.18585 = D.18584 >> 3;
      hash = D.18585 * 2654435761;
      hash = hash & 1073741823;
      D.18582 = lw.sync;
      if (D.18582 != 0B) goto <D.18586>; else goto <D.18587>;
      <D.18586>:
      D.18582 = lw.sync;
      hash.2 = (int) hash;
      D.18582->hash_code = hash.2;
      D.18572 = lw.lock_word;
      D.18589 = D.18572 | 2;
      lw.lock_word = D.18589;
      D.18582 = lw.sync;
      obj->synchronisation = D.18582;
      goto <D.18590>;
      <D.18587>:
      D.18591 = hash << 2;
      D.18592 = D.18591 | 1;
      D.18593 = (long unsigned int) D.18592;
      lw.lock_word = D.18593;
      D.18582 = lw.sync;
      D.18594 = &obj->synchronisation;
      D.18595 = InterlockedCompareExchangePointer (D.18594, D.18582, 0B);
      if (D.18595 == 0B) goto <D.18596>; else goto <D.18597>;
      <D.18596>:
      D.18570 = (int) hash;
      return D.18570;
      <D.18597>:
      D.18571 = obj->synchronisation;
      lw.sync = D.18571;
      D.18572 = lw.lock_word;
      D.18573 = D.18572 & 1;
      if (D.18573 != 0) goto <D.18598>; else goto <D.18599>;
      <D.18598>:
      D.18570 = (int) hash;
      return D.18570;
      <D.18599>:
      D.18572 = lw.lock_word;
      D.18581 = D.18572 & 18446744073709551612;
      lw.lock_word = D.18581;
      D.18582 = lw.sync;
      hash.2 = (int) hash;
      D.18582->hash_code = hash.2;
      D.18572 = lw.lock_word;
      D.18589 = D.18572 | 2;
      lw.lock_word = D.18589;
      D.18582 = lw.sync;
      obj->synchronisation = D.18582;
      <D.18590>:
      D.18570 = (int) hash;
      return D.18570;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.18602;
  long unsigned int exch.3;
  long unsigned int comp.4;
  long unsigned int D.18605;

  exch.3 = (long unsigned int) exch;
  comp.4 = (long unsigned int) comp;
  D.18605 = __sync_val_compare_and_swap_8 (dest, comp.4, exch.3);
  D.18602 = (void *) D.18605;
  return D.18602;
}


mono_monitor_enter (struct MonoObject * obj)
{
  mono_bool D.18607;
  int D.18608;
  _Bool D.18609;

  D.18608 = mono_monitor_try_enter_internal (obj, 4294967295, 0);
  D.18609 = D.18608 == 1;
  D.18607 = (mono_bool) D.18609;
  return D.18607;
}


mono_monitor_try_enter_internal (struct MonoObject * obj, guint32 ms, gboolean allow_interruption)
{
  _Bool D.18611;
  long int D.18612;
  long int D.18613;
  struct MonoException * D.18616;
  gint32 D.18617;
  _Bool D.18618;
  long int D.18619;
  long int D.18620;
  _Bool D.18625;
  long int D.18626;
  long int D.18627;
  struct MonoThreadsSync * * D.18630;
  void * D.18631;
  void * * D.18634;
  _Bool D.18637;
  long int D.18638;
  long int D.18639;
  struct MonoThreadsSync * D.18642;
  long unsigned int D.18643;
  long unsigned int D.18644;
  long unsigned int D.18647;
  int D.18648;
  long unsigned int D.18649;
  struct MonoThreadsSync * D.18650;
  void * D.18651;
  _Bool D.18656;
  long int D.18657;
  long int D.18658;
  _Bool D.18663;
  long int D.18664;
  long int D.18665;
  long unsigned int D.18668;
  _Bool D.18673;
  long int D.18674;
  long int D.18675;
  long unsigned int D.18678;
  _Bool D.18682;
  long int D.18683;
  long int D.18684;
  long unsigned int D.18688;
  long unsigned int D.18689;
  _Bool D.18694;
  long int D.18695;
  long int D.18696;
  long unsigned int D.18699;
  int D.18700;
  long unsigned int D.18701;
  struct MonoThreadsSync * D.18702;
  void * D.18703;
  _Bool D.18708;
  long int D.18709;
  long int D.18710;
  _Bool D.18715;
  long int D.18716;
  long int D.18717;
  long unsigned int D.18720;
  long unsigned int D.18721;
  long unsigned int D.18722;
  _Bool D.18723;
  long int D.18724;
  long int D.18725;
  void * id.5;
  gsize * D.18729;
  void * D.18730;
  _Bool D.18731;
  long int D.18732;
  long int D.18733;
  unsigned int D.18735;
  _Bool D.18736;
  long int D.18737;
  long int D.18738;
  unsigned int D.18743;
  struct MonoPerfCounters * mono_perfcounters.6;
  unsigned int D.18745;
  unsigned int D.18746;
  void * D.18751;
  _Bool D.18752;
  long int D.18753;
  long int D.18754;
  void * D.18761;
  _Bool D.18764;
  long int D.18765;
  long int D.18766;
  void * * D.18769;
  void * D.18770;
  volatile gint32 * D.18779;
  unsigned int D.18780;
  unsigned int D.18781;
  unsigned int D.18782;
  unsigned int D.18783;
  volatile gint32 * D.18784;
  unsigned int D.18785;
  unsigned int D.18790;
  _Bool D.18797;
  _Bool D.18798;
  _Bool D.18799;
  struct MonoInternalThread * D.18807;
  int D.18808;
  struct MonoThreadsSync * mon;
  gsize id;
  void * sem;
  guint32 then;
  guint32 now;
  guint32 delta;
  guint32 waitms;
  guint32 ret;
  struct MonoInternalThread * thread;
  void retry = <<< error >>>;
  void retry_contended = <<< error >>>;

  id = tls_pthread_self;
  then = 0;
  D.18611 = obj == 0B;
  D.18612 = (long int) D.18611;
  D.18613 = __builtin_expect (D.18612, 0);
  if (D.18613 != 0) goto <D.18614>; else goto <D.18615>;
  <D.18614>:
  D.18616 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18616);
  D.18617 = 0;
  return D.18617;
  <D.18615>:
  retry:
  mon = obj->synchronisation;
  D.18618 = mon == 0B;
  D.18619 = (long int) D.18618;
  D.18620 = __builtin_expect (D.18619, 0);
  if (D.18620 != 0) goto <D.18621>; else goto <D.18622>;
  <D.18621>:
  {
    int ret;

    ret = pthread_mutex_lock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.18623>; else goto <D.18624>;
    <D.18623>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18624>:
    D.18625 = ret != 0;
    D.18626 = (long int) D.18625;
    D.18627 = __builtin_expect (D.18626, 0);
    if (D.18627 != 0) goto <D.18628>; else goto <D.18629>;
    <D.18628>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 439, "ret == 0");
    <D.18629>:
  }
  mon = mon_new (id);
  D.18630 = &obj->synchronisation;
  D.18631 = InterlockedCompareExchangePointer (D.18630, mon, 0B);
  if (D.18631 == 0B) goto <D.18632>; else goto <D.18633>;
  <D.18632>:
  D.18634 = &mon->data;
  mono_gc_weak_link_add (D.18634, obj, 0);
  {
    int ret;

    ret = pthread_mutex_unlock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.18635>; else goto <D.18636>;
    <D.18635>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18636>:
    D.18637 = ret != 0;
    D.18638 = (long int) D.18637;
    D.18639 = __builtin_expect (D.18638, 0);
    if (D.18639 != 0) goto <D.18640>; else goto <D.18641>;
    <D.18640>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 443, "ret == 0");
    <D.18641>:
  }
  D.18617 = 1;
  return D.18617;
  <D.18633>:
  {
    union LockWord lw;

    try
      {
        D.18642 = obj->synchronisation;
        lw.sync = D.18642;
        D.18643 = lw.lock_word;
        D.18644 = D.18643 & 1;
        if (D.18644 != 0) goto <D.18645>; else goto <D.18646>;
        <D.18645>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          D.18643 = lw.lock_word;
          D.18647 = D.18643 >> 2;
          D.18648 = (int) D.18647;
          mon->hash_code = D.18648;
          lw.sync = mon;
          D.18643 = lw.lock_word;
          D.18649 = D.18643 | 2;
          lw.lock_word = D.18649;
          D.18650 = lw.sync;
          D.18630 = &obj->synchronisation;
          D.18651 = InterlockedCompareExchangePointer (D.18630, D.18650, oldlw);
          if (D.18651 == oldlw) goto <D.18652>; else goto <D.18653>;
          <D.18652>:
          D.18634 = &mon->data;
          mono_gc_weak_link_add (D.18634, obj, 0);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18654>; else goto <D.18655>;
            <D.18654>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18655>:
            D.18656 = ret != 0;
            D.18657 = (long int) D.18656;
            D.18658 = __builtin_expect (D.18657, 0);
            if (D.18658 != 0) goto <D.18659>; else goto <D.18660>;
            <D.18659>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 458, "ret == 0");
            <D.18660>:
          }
          D.18617 = 1;
          return D.18617;
          <D.18653>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18661>; else goto <D.18662>;
            <D.18661>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18662>:
            D.18663 = ret != 0;
            D.18664 = (long int) D.18663;
            D.18665 = __builtin_expect (D.18664, 0);
            if (D.18665 != 0) goto <D.18666>; else goto <D.18667>;
            <D.18666>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 463, "ret == 0");
            <D.18667>:
          }
          goto retry;
        }
        <D.18646>:
        D.18643 = lw.lock_word;
        D.18668 = D.18643 & 2;
        if (D.18668 != 0) goto <D.18669>; else goto <D.18670>;
        <D.18669>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.18671>; else goto <D.18672>;
          <D.18671>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.18672>:
          D.18673 = ret != 0;
          D.18674 = (long int) D.18673;
          D.18675 = __builtin_expect (D.18674, 0);
          if (D.18675 != 0) goto <D.18676>; else goto <D.18677>;
          <D.18676>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 468, "ret == 0");
          <D.18677>:
        }
        D.18643 = lw.lock_word;
        D.18678 = D.18643 & 18446744073709551612;
        lw.lock_word = D.18678;
        mon = lw.sync;
        goto <D.18679>;
        <D.18670>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.18680>; else goto <D.18681>;
          <D.18680>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.18681>:
          D.18682 = ret != 0;
          D.18683 = (long int) D.18682;
          D.18684 = __builtin_expect (D.18683, 0);
          if (D.18684 != 0) goto <D.18685>; else goto <D.18686>;
          <D.18685>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 474, "ret == 0");
          <D.18686>:
        }
        mon = obj->synchronisation;
        <D.18679>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  goto <D.18687>;
  <D.18622>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18688 = lw.lock_word;
        D.18689 = D.18688 & 1;
        if (D.18689 != 0) goto <D.18690>; else goto <D.18691>;
        <D.18690>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          {
            int ret;

            ret = pthread_mutex_lock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18692>; else goto <D.18693>;
            <D.18692>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
            <D.18693>:
            D.18694 = ret != 0;
            D.18695 = (long int) D.18694;
            D.18696 = __builtin_expect (D.18695, 0);
            if (D.18696 != 0) goto <D.18697>; else goto <D.18698>;
            <D.18697>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 489, "ret == 0");
            <D.18698>:
          }
          mon = mon_new (id);
          D.18688 = lw.lock_word;
          D.18699 = D.18688 >> 2;
          D.18700 = (int) D.18699;
          mon->hash_code = D.18700;
          lw.sync = mon;
          D.18688 = lw.lock_word;
          D.18701 = D.18688 | 2;
          lw.lock_word = D.18701;
          D.18702 = lw.sync;
          D.18630 = &obj->synchronisation;
          D.18703 = InterlockedCompareExchangePointer (D.18630, D.18702, oldlw);
          if (D.18703 == oldlw) goto <D.18704>; else goto <D.18705>;
          <D.18704>:
          D.18634 = &mon->data;
          mono_gc_weak_link_add (D.18634, obj, 1);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18706>; else goto <D.18707>;
            <D.18706>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18707>:
            D.18708 = ret != 0;
            D.18709 = (long int) D.18708;
            D.18710 = __builtin_expect (D.18709, 0);
            if (D.18710 != 0) goto <D.18711>; else goto <D.18712>;
            <D.18711>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 497, "ret == 0");
            <D.18712>:
          }
          D.18617 = 1;
          return D.18617;
          <D.18705>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18713>; else goto <D.18714>;
            <D.18713>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18714>:
            D.18715 = ret != 0;
            D.18716 = (long int) D.18715;
            D.18717 = __builtin_expect (D.18716, 0);
            if (D.18717 != 0) goto <D.18718>; else goto <D.18719>;
            <D.18718>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 502, "ret == 0");
            <D.18719>:
          }
          goto retry;
        }
        <D.18691>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  <D.18687>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18720 = lw.lock_word;
        D.18721 = D.18720 & 18446744073709551612;
        lw.lock_word = D.18721;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.18722 = mon->owner;
  D.18723 = D.18722 == 0;
  D.18724 = (long int) D.18723;
  D.18725 = __builtin_expect (D.18724, 1);
  if (D.18725 != 0) goto <D.18726>; else goto <D.18727>;
  <D.18726>:
  id.5 = (void *) id;
  D.18729 = &mon->owner;
  D.18730 = InterlockedCompareExchangePointer (D.18729, id.5, 0B);
  D.18731 = D.18730 == 0B;
  D.18732 = (long int) D.18731;
  D.18733 = __builtin_expect (D.18732, 1);
  if (D.18733 != 0) goto <D.18734>; else goto retry;
  <D.18734>:
  D.18735 = mon->nest;
  D.18736 = D.18735 != 1;
  D.18737 = (long int) D.18736;
  D.18738 = __builtin_expect (D.18737, 0);
  if (D.18738 != 0) goto <D.18739>; else goto <D.18740>;
  <D.18739>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 530, "mon->nest == 1");
  <D.18740>:
  D.18617 = 1;
  return D.18617;
  <D.18727>:
  D.18722 = mon->owner;
  if (D.18722 == id) goto <D.18741>; else goto <D.18742>;
  <D.18741>:
  D.18735 = mon->nest;
  D.18743 = D.18735 + 1;
  mon->nest = D.18743;
  D.18617 = 1;
  return D.18617;
  <D.18742>:
  mono_perfcounters.6 = mono_perfcounters;
  D.18745 = mono_perfcounters.6->thread_contentions;
  D.18746 = D.18745 + 1;
  mono_perfcounters.6->thread_contentions = D.18746;
  if (ms == 0) goto <D.18747>; else goto <D.18748>;
  <D.18747>:
  D.18617 = 0;
  return D.18617;
  <D.18748>:
  mono_profiler_monitor_event (obj, 1);
  retry_contended:
  D.18722 = mon->owner;
  D.18723 = D.18722 == 0;
  D.18724 = (long int) D.18723;
  D.18725 = __builtin_expect (D.18724, 1);
  if (D.18725 != 0) goto <D.18749>; else goto <D.18750>;
  <D.18749>:
  id.5 = (void *) id;
  D.18729 = &mon->owner;
  D.18751 = InterlockedCompareExchangePointer (D.18729, id.5, 0B);
  D.18752 = D.18751 == 0B;
  D.18753 = (long int) D.18752;
  D.18754 = __builtin_expect (D.18753, 1);
  if (D.18754 != 0) goto <D.18755>; else goto <D.18756>;
  <D.18755>:
  D.18735 = mon->nest;
  D.18736 = D.18735 != 1;
  D.18737 = (long int) D.18736;
  D.18738 = __builtin_expect (D.18737, 0);
  if (D.18738 != 0) goto <D.18757>; else goto <D.18758>;
  <D.18757>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 574, "mon->nest == 1");
  <D.18758>:
  mono_profiler_monitor_event (obj, 2);
  D.18617 = 1;
  return D.18617;
  <D.18756>:
  <D.18750>:
  D.18722 = mon->owner;
  if (D.18722 == id) goto <D.18759>; else goto <D.18760>;
  <D.18759>:
  D.18735 = mon->nest;
  D.18743 = D.18735 + 1;
  mon->nest = D.18743;
  mono_profiler_monitor_event (obj, 2);
  D.18617 = 1;
  return D.18617;
  <D.18760>:
  D.18761 = mon->entry_sem;
  if (D.18761 == 0B) goto <D.18762>; else goto <D.18763>;
  <D.18762>:
  sem = CreateSemaphore (0B, 0, 2147483647, 0B);
  D.18764 = sem == 0B;
  D.18765 = (long int) D.18764;
  D.18766 = __builtin_expect (D.18765, 0);
  if (D.18766 != 0) goto <D.18767>; else goto <D.18768>;
  <D.18767>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 593, "sem != NULL");
  <D.18768>:
  D.18769 = &mon->entry_sem;
  D.18770 = InterlockedCompareExchangePointer (D.18769, sem, 0B);
  if (D.18770 != 0B) goto <D.18771>; else goto <D.18772>;
  <D.18771>:
  CloseHandle (sem);
  <D.18772>:
  <D.18763>:
  if (ms != 4294967295) goto <D.18773>; else goto <D.18774>;
  <D.18773>:
  then = mono_msec_ticks ();
  if (ms <= 99) goto <D.18775>; else goto <D.18776>;
  <D.18775>:
  waitms = ms;
  goto <D.18777>;
  <D.18776>:
  waitms = 100;
  <D.18777>:
  goto <D.18778>;
  <D.18774>:
  waitms = 100;
  <D.18778>:
  D.18779 = &mon->entry_count;
  InterlockedIncrement (D.18779);
  mono_perfcounters.6 = mono_perfcounters;
  D.18780 = mono_perfcounters.6->thread_queue_len;
  D.18781 = D.18780 + 1;
  mono_perfcounters.6->thread_queue_len = D.18781;
  mono_perfcounters.6 = mono_perfcounters;
  D.18782 = mono_perfcounters.6->thread_queue_max;
  D.18783 = D.18782 + 1;
  mono_perfcounters.6->thread_queue_max = D.18783;
  thread = mono_thread_internal_current ();
  mono_thread_set_state (thread, 32);
  D.18761 = mon->entry_sem;
  ret = WaitForSingleObjectEx (D.18761, waitms, 1);
  mono_thread_clr_state (thread, 32);
  D.18784 = &mon->entry_count;
  InterlockedDecrement (D.18784);
  mono_perfcounters.6 = mono_perfcounters;
  D.18780 = mono_perfcounters.6->thread_queue_len;
  D.18785 = D.18780 + 4294967295;
  mono_perfcounters.6->thread_queue_len = D.18785;
  if (ms != 4294967295) goto <D.18786>; else goto <D.18787>;
  <D.18786>:
  now = mono_msec_ticks ();
  if (now < then) goto <D.18788>; else goto <D.18789>;
  <D.18788>:
  D.18790 = now - then;
  now = D.18790 - 1;
  then = 0;
  <D.18789>:
  delta = now - then;
  if (delta >= ms) goto <D.18791>; else goto <D.18792>;
  <D.18791>:
  ms = 0;
  goto <D.18793>;
  <D.18792>:
  ms = ms - delta;
  <D.18793>:
  if (ret == 258) goto <D.18794>; else goto <D.18796>;
  <D.18796>:
  D.18797 = ret == 192;
  D.18798 = allow_interruption == 0;
  D.18799 = D.18797 & D.18798;
  if (D.18799 != 0) goto <D.18794>; else goto <D.18795>;
  <D.18794>:
  if (ms != 0) goto retry_contended; else goto <D.18800>;
  <D.18800>:
  <D.18795>:
  goto <D.18801>;
  <D.18787>:
  if (ret == 258) goto <D.18802>; else goto <D.18804>;
  <D.18804>:
  D.18797 = ret == 192;
  D.18798 = allow_interruption == 0;
  D.18799 = D.18797 & D.18798;
  if (D.18799 != 0) goto <D.18802>; else goto <D.18803>;
  <D.18802>:
  if (ret == 192) goto <D.18805>; else goto <D.18806>;
  <D.18805>:
  D.18807 = mono_thread_internal_current ();
  D.18808 = mono_thread_test_state (D.18807, 3);
  if (D.18808 != 0) goto <D.18809>; else goto <D.18810>;
  <D.18809>:
  mono_profiler_monitor_event (obj, 3);
  D.18617 = -1;
  return D.18617;
  <D.18810>:
  <D.18806>:
  goto retry_contended;
  <D.18803>:
  <D.18801>:
  if (ret == 0) goto retry_contended; else goto <D.18811>;
  <D.18811>:
  mono_profiler_monitor_event (obj, 3);
  if (ret == 192) goto <D.18812>; else goto <D.18813>;
  <D.18812>:
  D.18617 = -1;
  return D.18617;
  <D.18813>:
  D.18617 = 0;
  return D.18617;
}


mon_new (gsize id)
{
  struct MonoThreadsSync * monitor_freelist.7;
  void * D.18824;
  struct GSList * D.18827;
  void * D.18830;
  struct GSList * D.18831;
  void * * D.18832;
  int D.18833;
  int array_size.8;
  long unsigned int D.18838;
  long unsigned int D.18839;
  long unsigned int D.18840;
  int array_size.9;
  int D.18842;
  struct MonoThreadsSync * D.18843;
  int D.18844;
  struct MonoThreadsSync * monitor_freelist.10;
  struct MonitorArray * monitor_allocated.11;
  struct MonitorArray * D.18850;
  void * monitor_freelist.12;
  struct MonoPerfCounters * mono_perfcounters.13;
  unsigned int D.18853;
  unsigned int D.18854;
  struct MonoThreadsSync * D.18855;
  struct MonoThreadsSync * new;

  monitor_freelist.7 = monitor_freelist;
  if (monitor_freelist.7 == 0B) goto <D.18822>; else goto <D.18823>;
  <D.18822>:
  {
    struct MonitorArray * marray;
    int i;

    new = 0B;
    marray = monitor_allocated;
    goto <D.18323>;
    <D.18322>:
    i = 0;
    goto <D.18319>;
    <D.18318>:
    D.18824 = marray->monitors[i].data;
    if (D.18824 == 0B) goto <D.18825>; else goto <D.18826>;
    <D.18825>:
    new = &marray->monitors[i];
    D.18827 = new->wait_list;
    if (D.18827 != 0B) goto <D.18828>; else goto <D.18829>;
    <D.18828>:
    goto <D.18316>;
    <D.18315>:
    D.18827 = new->wait_list;
    D.18830 = D.18827->data;
    CloseHandle (D.18830);
    D.18827 = new->wait_list;
    D.18830 = D.18827->data;
    D.18827 = new->wait_list;
    D.18831 = monoeg_g_slist_remove (D.18827, D.18830);
    new->wait_list = D.18831;
    <D.18316>:
    D.18827 = new->wait_list;
    if (D.18827 != 0B) goto <D.18315>; else goto <D.18317>;
    <D.18317>:
    <D.18829>:
    D.18832 = &new->data;
    mono_gc_weak_link_remove (D.18832, 0);
    monitor_freelist.7 = monitor_freelist;
    new->data = monitor_freelist.7;
    monitor_freelist = new;
    <D.18826>:
    i = i + 1;
    <D.18319>:
    D.18833 = marray->num_monitors;
    if (D.18833 > i) goto <D.18318>; else goto <D.18320>;
    <D.18320>:
    if (new != 0B) goto <D.18321>; else goto <D.18834>;
    <D.18834>:
    marray = marray->next;
    <D.18323>:
    if (marray != 0B) goto <D.18322>; else goto <D.18321>;
    <D.18321>:
    monitor_freelist.7 = monitor_freelist;
    if (monitor_freelist.7 == 0B) goto <D.18835>; else goto <D.18836>;
    <D.18835>:
    {
      struct MonitorArray * last;

      array_size.8 = array_size;
      D.18838 = (long unsigned int) array_size.8;
      D.18839 = D.18838 * 48;
      D.18840 = D.18839 + 32;
      marray = monoeg_malloc0 (D.18840);
      array_size.8 = array_size;
      marray->num_monitors = array_size.8;
      array_size.8 = array_size;
      array_size.9 = array_size.8 * 2;
      array_size = array_size.9;
      i = 0;
      goto <D.18326>;
      <D.18325>:
      D.18842 = i + 1;
      D.18843 = &marray->monitors[D.18842];
      marray->monitors[i].data = D.18843;
      i = i + 1;
      <D.18326>:
      D.18833 = marray->num_monitors;
      D.18844 = D.18833 + -1;
      if (D.18844 > i) goto <D.18325>; else goto <D.18327>;
      <D.18327>:
      marray->monitors[i].data = 0B;
      monitor_freelist.10 = &marray->monitors[0];
      monitor_freelist = monitor_freelist.10;
      monitor_allocated.11 = monitor_allocated;
      if (monitor_allocated.11 == 0B) goto <D.18847>; else goto <D.18848>;
      <D.18847>:
      monitor_allocated = marray;
      goto <D.18849>;
      <D.18848>:
      last = monitor_allocated;
      goto <D.18329>;
      <D.18328>:
      last = last->next;
      <D.18329>:
      D.18850 = last->next;
      if (D.18850 != 0B) goto <D.18328>; else goto <D.18330>;
      <D.18330>:
      last->next = marray;
      <D.18849>:
    }
    <D.18836>:
  }
  <D.18823>:
  new = monitor_freelist;
  monitor_freelist.12 = new->data;
  monitor_freelist = monitor_freelist.12;
  new->owner = id;
  new->nest = 1;
  new->data = 0B;
  mono_perfcounters.13 = mono_perfcounters;
  D.18853 = mono_perfcounters.13->gc_sync_blocks;
  D.18854 = D.18853 + 1;
  mono_perfcounters.13->gc_sync_blocks = D.18854;
  D.18855 = new;
  return D.18855;
}


mon_finalize (struct MonoThreadsSync * mon)
{
  void * D.18857;
  struct GSList * D.18860;
  _Bool D.18861;
  long int D.18862;
  long int D.18863;
  struct MonoThreadsSync * monitor_freelist.14;
  struct MonoPerfCounters * mono_perfcounters.15;
  unsigned int D.18868;
  unsigned int D.18869;

  D.18857 = mon->entry_sem;
  if (D.18857 != 0B) goto <D.18858>; else goto <D.18859>;
  <D.18858>:
  D.18857 = mon->entry_sem;
  CloseHandle (D.18857);
  mon->entry_sem = 0B;
  <D.18859>:
  D.18860 = mon->wait_list;
  D.18861 = D.18860 != 0B;
  D.18862 = (long int) D.18861;
  D.18863 = __builtin_expect (D.18862, 0);
  if (D.18863 != 0) goto <D.18864>; else goto <D.18865>;
  <D.18864>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 239, "mon->wait_list == NULL");
  <D.18865>:
  mon->entry_count = 0;
  monitor_freelist.14 = monitor_freelist;
  mon->data = monitor_freelist.14;
  monitor_freelist = mon;
  mono_perfcounters.15 = mono_perfcounters;
  D.18868 = mono_perfcounters.15->gc_sync_blocks;
  D.18869 = D.18868 + 4294967295;
  mono_perfcounters.15->gc_sync_blocks = D.18869;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.18870;
  unsigned int D.18871;

  D.18871 = __sync_add_and_fetch_4 (val, 1);
  D.18870 = (gint32) D.18871;
  return D.18870;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.18873;
  unsigned int D.18874;

  D.18874 = __sync_sub_and_fetch_4 (val, 1);
  D.18873 = (gint32) D.18874;
  return D.18873;
}


mono_monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  mono_bool D.18876;
  int D.18877;
  _Bool D.18878;

  D.18877 = mono_monitor_try_enter_internal (obj, ms, 0);
  D.18878 = D.18877 == 1;
  D.18876 = (mono_bool) D.18878;
  return D.18876;
}


mono_monitor_exit (struct MonoObject * obj)
{
  _Bool D.18880;
  long int D.18881;
  long int D.18882;
  struct MonoException * D.18885;
  long unsigned int D.18886;
  long unsigned int D.18887;
  long unsigned int D.18890;
  _Bool D.18891;
  long int D.18892;
  long int D.18893;
  long unsigned int D.18896;
  long unsigned int tls_pthread_self.16;
  _Bool D.18898;
  long int D.18899;
  long int D.18900;
  unsigned int D.18903;
  int D.18906;
  void * D.18909;
  struct MonoThreadsSync * mon;
  guint32 nest;

  D.18880 = obj == 0B;
  D.18881 = (long int) D.18880;
  D.18882 = __builtin_expect (D.18881, 0);
  if (D.18882 != 0) goto <D.18883>; else goto <D.18884>;
  <D.18883>:
  D.18885 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18885);
  return;
  <D.18884>:
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18886 = lw.lock_word;
        D.18887 = D.18886 & 1;
        if (D.18887 != 0) goto <D.18888>; else goto <D.18889>;
        <D.18888>:
        return;
        <D.18889>:
        D.18886 = lw.lock_word;
        D.18890 = D.18886 & 18446744073709551612;
        lw.lock_word = D.18890;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.18891 = mon == 0B;
  D.18892 = (long int) D.18891;
  D.18893 = __builtin_expect (D.18892, 0);
  if (D.18893 != 0) goto <D.18894>; else goto <D.18895>;
  <D.18894>:
  return;
  <D.18895>:
  D.18896 = mon->owner;
  tls_pthread_self.16 = tls_pthread_self;
  D.18898 = D.18896 != tls_pthread_self.16;
  D.18899 = (long int) D.18898;
  D.18900 = __builtin_expect (D.18899, 0);
  if (D.18900 != 0) goto <D.18901>; else goto <D.18902>;
  <D.18901>:
  return;
  <D.18902>:
  D.18903 = mon->nest;
  nest = D.18903 + 4294967295;
  if (nest == 0) goto <D.18904>; else goto <D.18905>;
  <D.18904>:
  mon->owner = 0;
  D.18906 = mon->entry_count;
  if (D.18906 > 0) goto <D.18907>; else goto <D.18908>;
  <D.18907>:
  D.18909 = mon->entry_sem;
  ReleaseSemaphore (D.18909, 1, 0B);
  <D.18908>:
  goto <D.18910>;
  <D.18905>:
  mon->nest = nest;
  <D.18910>:
}


mono_monitor_get_object_monitor_weak_link (struct MonoObject * object)
{
  struct MonoThreadsSync * D.18914;
  long unsigned int D.18915;
  long unsigned int D.18916;
  long unsigned int D.18919;
  long unsigned int D.18921;
  void * D.18926;
  void * * D.18929;
  union LockWord lw;
  struct MonoThreadsSync * sync;

  try
    {
      sync = 0B;
      D.18914 = object->synchronisation;
      lw.sync = D.18914;
      D.18915 = lw.lock_word;
      D.18916 = D.18915 & 2;
      if (D.18916 != 0) goto <D.18917>; else goto <D.18918>;
      <D.18917>:
      D.18915 = lw.lock_word;
      D.18919 = D.18915 & 18446744073709551612;
      lw.lock_word = D.18919;
      sync = lw.sync;
      goto <D.18920>;
      <D.18918>:
      D.18915 = lw.lock_word;
      D.18921 = D.18915 & 1;
      if (D.18921 == 0) goto <D.18922>; else goto <D.18923>;
      <D.18922>:
      sync = lw.sync;
      <D.18923>:
      <D.18920>:
      if (sync != 0B) goto <D.18924>; else goto <D.18925>;
      <D.18924>:
      D.18926 = sync->data;
      if (D.18926 != 0B) goto <D.18927>; else goto <D.18928>;
      <D.18927>:
      D.18929 = &sync->data;
      return D.18929;
      <D.18928>:
      <D.18925>:
      D.18929 = 0B;
      return D.18929;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


mono_monitor_is_il_fastpath_wrapper (struct MonoMethod * method)
{
  struct MonoMethod * D.18932;
  gboolean D.18935;
  int i;

  i = 0;
  goto <D.18408>;
  <D.18407>:
  D.18932 = monitor_il_fastpaths[i];
  if (D.18932 == method) goto <D.18933>; else goto <D.18934>;
  <D.18933>:
  D.18935 = 1;
  return D.18935;
  <D.18934>:
  i = i + 1;
  <D.18408>:
  if (i <= 2) goto <D.18407>; else goto <D.18409>;
  <D.18409>:
  D.18935 = 0;
  return D.18935;
}


mono_monitor_get_fast_path (struct MonoMethod * enter_or_exit)
{
  int D.18465;
  int iftmp.17;
  int D.18464;
  const char[6] * D.18940;
  unsigned char D.18941;
  int D.18942;
  unsigned char D.18943;
  int D.18944;
  _Bool D.18945;
  _Bool D.18946;
  _Bool D.18947;
  const unsigned char * D.18950;
  unsigned char D.18951;
  int D.18952;
  const unsigned char * D.18953;
  unsigned char D.18954;
  int D.18955;
  _Bool D.18956;
  _Bool D.18957;
  const unsigned char * D.18960;
  unsigned char D.18961;
  int D.18962;
  const unsigned char * D.18963;
  unsigned char D.18964;
  int D.18965;
  _Bool D.18966;
  _Bool D.18967;
  const unsigned char * D.18970;
  unsigned char D.18971;
  int D.18972;
  const unsigned char * D.18973;
  unsigned char D.18974;
  int D.18975;
  const char * D.18977;
  struct MonoMethod * D.18980;
  int D.18474;
  int iftmp.18;
  int D.18473;
  const char[5] * D.18984;
  unsigned char D.18985;
  int D.18986;
  unsigned char D.18987;
  int D.18988;
  _Bool D.18989;
  _Bool D.18990;
  _Bool D.18991;
  const unsigned char * D.18994;
  unsigned char D.18995;
  int D.18996;
  const unsigned char * D.18997;
  unsigned char D.18998;
  int D.18999;
  _Bool D.19000;
  _Bool D.19001;
  const unsigned char * D.19004;
  unsigned char D.19005;
  int D.19006;
  const unsigned char * D.19007;
  unsigned char D.19008;
  int D.19009;
  _Bool D.19010;
  _Bool D.19011;
  const unsigned char * D.19014;
  unsigned char D.19015;
  int D.19016;
  const unsigned char * D.19017;
  unsigned char D.19018;
  int D.19019;

  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 5;
    if (__s2_len <= 3) goto <D.18938>; else goto <D.18939>;
    <D.18938>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = enter_or_exit->name;
      D.18940 = "Enter";
      D.18941 = MEM[(const unsigned char *)D.18940];
      D.18942 = (int) D.18941;
      D.18943 = *__s2;
      D.18944 = (int) D.18943;
      __result = D.18942 - D.18944;
      {
        D.18945 = __s2_len != 0;
        D.18946 = __result == 0;
        D.18947 = D.18945 & D.18946;
        if (D.18947 != 0) goto <D.18948>; else goto <D.18949>;
        <D.18948>:
        D.18950 = &MEM[(void *)"Enter" + 1B];
        D.18951 = *D.18950;
        D.18952 = (int) D.18951;
        D.18953 = __s2 + 1;
        D.18954 = *D.18953;
        D.18955 = (int) D.18954;
        __result = D.18952 - D.18955;
        D.18956 = __s2_len > 1;
        D.18946 = __result == 0;
        D.18957 = D.18956 & D.18946;
        if (D.18957 != 0) goto <D.18958>; else goto <D.18959>;
        <D.18958>:
        D.18960 = &MEM[(void *)"Enter" + 2B];
        D.18961 = *D.18960;
        D.18962 = (int) D.18961;
        D.18963 = __s2 + 2;
        D.18964 = *D.18963;
        D.18965 = (int) D.18964;
        __result = D.18962 - D.18965;
        D.18966 = __s2_len > 2;
        D.18946 = __result == 0;
        D.18967 = D.18966 & D.18946;
        if (D.18967 != 0) goto <D.18968>; else goto <D.18969>;
        <D.18968>:
        D.18970 = &MEM[(void *)"Enter" + 3B];
        D.18971 = *D.18970;
        D.18972 = (int) D.18971;
        D.18973 = __s2 + 3;
        D.18974 = *D.18973;
        D.18975 = (int) D.18974;
        __result = D.18972 - D.18975;
        <D.18969>:
        <D.18959>:
        <D.18949>:
      }
      D.18464 = __result;
    }
    iftmp.17 = -D.18464;
    goto <D.18976>;
    <D.18939>:
    D.18977 = enter_or_exit->name;
    iftmp.17 = __builtin_strcmp (D.18977, "Enter");
    <D.18976>:
    D.18465 = iftmp.17;
  }
  if (D.18465 == 0) goto <D.18978>; else goto <D.18979>;
  <D.18978>:
  D.18980 = mono_monitor_get_fast_enter_method (enter_or_exit);
  return D.18980;
  <D.18979>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 4;
    if (__s2_len <= 3) goto <D.18982>; else goto <D.18983>;
    <D.18982>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = enter_or_exit->name;
      D.18984 = "Exit";
      D.18985 = MEM[(const unsigned char *)D.18984];
      D.18986 = (int) D.18985;
      D.18987 = *__s2;
      D.18988 = (int) D.18987;
      __result = D.18986 - D.18988;
      {
        D.18989 = __s2_len != 0;
        D.18990 = __result == 0;
        D.18991 = D.18989 & D.18990;
        if (D.18991 != 0) goto <D.18992>; else goto <D.18993>;
        <D.18992>:
        D.18994 = &MEM[(void *)"Exit" + 1B];
        D.18995 = *D.18994;
        D.18996 = (int) D.18995;
        D.18997 = __s2 + 1;
        D.18998 = *D.18997;
        D.18999 = (int) D.18998;
        __result = D.18996 - D.18999;
        D.19000 = __s2_len > 1;
        D.18990 = __result == 0;
        D.19001 = D.19000 & D.18990;
        if (D.19001 != 0) goto <D.19002>; else goto <D.19003>;
        <D.19002>:
        D.19004 = &MEM[(void *)"Exit" + 2B];
        D.19005 = *D.19004;
        D.19006 = (int) D.19005;
        D.19007 = __s2 + 2;
        D.19008 = *D.19007;
        D.19009 = (int) D.19008;
        __result = D.19006 - D.19009;
        D.19010 = __s2_len > 2;
        D.18990 = __result == 0;
        D.19011 = D.19010 & D.18990;
        if (D.19011 != 0) goto <D.19012>; else goto <D.19013>;
        <D.19012>:
        D.19014 = &MEM[(void *)"Exit" + 3B];
        D.19015 = *D.19014;
        D.19016 = (int) D.19015;
        D.19017 = __s2 + 3;
        D.19018 = *D.19017;
        D.19019 = (int) D.19018;
        __result = D.19016 - D.19019;
        <D.19013>:
        <D.19003>:
        <D.18993>:
      }
      D.18473 = __result;
    }
    iftmp.18 = -D.18473;
    goto <D.19020>;
    <D.18983>:
    D.18977 = enter_or_exit->name;
    iftmp.18 = __builtin_strcmp (D.18977, "Exit");
    <D.19020>:
    D.18474 = iftmp.18;
  }
  if (D.18474 == 0) goto <D.19021>; else goto <D.19022>;
  <D.19021>:
  D.18980 = mono_monitor_get_fast_exit_method (enter_or_exit);
  return D.18980;
  <D.19022>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "monitor.c", 1227);
  D.18980 = 0B;
  return D.18980;
}


mono_monitor_get_fast_enter_method (struct MonoMethod * monitor_enter_method)
{
  struct MonoMethodSignature * D.19024;
  short unsigned int D.19025;
  _Bool D.19026;
  _Bool D.19027;
  _Bool D.19028;
  long int D.19029;
  long int D.19030;
  struct MonoMethod * D.19035;
  struct MonoMethod * D.19036;
  struct MonoMethod * compare_exchange_method.19;
  struct MonoImage * D.19042;
  struct MonoMethod * compare_exchange_method.20;
  const char * iftmp.21;
  struct MonoClass * D.19050;
  struct MonoMethod * D.19051;
  struct MonoClass * D.19052;
  struct MonoType * D.19053;
  int * iftmp.22;
  unsigned int tid_loc.23;
  unsigned int syncp_loc.24;
  unsigned int owner_loc.25;
  unsigned int D.19061;
  unsigned int D.19062;
  unsigned int tid_branch.26;
  unsigned int D.19066;
  int thin_hash_branch.27;
  unsigned int thin_hash_branch.28;
  int obj_null_branch.29;
  unsigned int obj_null_branch.30;
  int syncp_null_branch.31;
  unsigned int syncp_null_branch.32;
  unsigned int has_owner_branch.33;
  unsigned int other_owner_branch.34;
  int true_locktaken_branch.35;
  unsigned int true_locktaken_branch.36;
  struct MonoMethodSignature * D.19085;
  struct MonoMethod * D.19086;
  WrapperSubtype iftmp.37;
  struct MonoMethodBuilder * mb;
  struct MonoMethod * res;
  static struct MonoMethod * compare_exchange_method;
  int obj_null_branch;
  int true_locktaken_branch;
  int syncp_null_branch;
  int has_owner_branch;
  int other_owner_branch;
  int tid_branch;
  int thin_hash_branch;
  int tid_loc;
  int syncp_loc;
  int owner_loc;
  int thread_tls_offset;
  gboolean is_v4;
  int fast_path_idx;
  struct WrapperInfo * info;

  try
    {
      true_locktaken_branch = 0;
      D.19024 = mono_method_signature (monitor_enter_method);
      D.19025 = D.19024->param_count;
      D.19026 = D.19025 == 2;
      is_v4 = (gboolean) D.19026;
      D.19027 = is_v4 != 0;
      fast_path_idx = (int) D.19027;
      D.19028 = is_v4 == 0;
      D.19029 = (long int) D.19028;
      D.19030 = __builtin_expect (D.19029, 0);
      if (D.19030 != 0) goto <D.19031>; else goto <D.19032>;
      <D.19031>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 898, "is_v4");
      <D.19032>:
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.19033>; else goto <D.19034>;
      <D.19033>:
      D.19035 = 0B;
      return D.19035;
      <D.19034>:
      D.19036 = monitor_il_fastpaths[fast_path_idx];
      if (D.19036 != 0B) goto <D.19037>; else goto <D.19038>;
      <D.19037>:
      D.19035 = monitor_il_fastpaths[fast_path_idx];
      return D.19035;
      <D.19038>:
      compare_exchange_method.19 = compare_exchange_method;
      if (compare_exchange_method.19 == 0B) goto <D.19040>; else goto <D.19041>;
      <D.19040>:
      {
        struct MonoMethodDesc * desc;
        struct MonoClass * class;

        desc = mono_method_desc_new ("Interlocked:CompareExchange(intptr&,intptr,intptr)", 0);
        D.19042 = mono_defaults.corlib;
        class = mono_class_from_name (D.19042, "System.Threading", "Interlocked");
        compare_exchange_method.20 = mono_method_desc_search_in_class (desc, class);
        compare_exchange_method = compare_exchange_method.20;
        mono_method_desc_free (desc);
        compare_exchange_method.19 = compare_exchange_method;
        if (compare_exchange_method.19 == 0B) goto <D.19044>; else goto <D.19045>;
        <D.19044>:
        D.19035 = 0B;
        return D.19035;
        <D.19045>:
      }
      <D.19041>:
      if (is_v4 != 0) goto <D.19047>; else goto <D.19048>;
      <D.19047>:
      iftmp.21 = "FastMonitorEnterV4";
      goto <D.19049>;
      <D.19048>:
      iftmp.21 = "FastMonitorEnter";
      <D.19049>:
      D.19050 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.19050, iftmp.21, 25);
      D.19051 = mb->method;
      D.19051->slot = -1;
      D.19051 = mb->method;
      D.19051->flags = 182;
      D.19052 = mono_defaults.int_class;
      D.19053 = &D.19052->byval_arg;
      tid_loc = mono_mb_add_local (mb, D.19053);
      D.19052 = mono_defaults.int_class;
      D.19053 = &D.19052->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.19053);
      D.19052 = mono_defaults.int_class;
      D.19053 = &D.19052->byval_arg;
      owner_loc = mono_mb_add_local (mb, D.19053);
      if (is_v4 != 0) goto <D.19055>; else goto <D.19056>;
      <D.19055>:
      iftmp.22 = &true_locktaken_branch;
      goto <D.19057>;
      <D.19056>:
      iftmp.22 = 0B;
      <D.19057>:
      emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, iftmp.22, &syncp_null_branch, &thin_hash_branch, 0);
      mono_mb_emit_byte (mb, 240);
      mono_mb_emit_byte (mb, 13);
      mono_mb_emit_i4 (mb, 0);
      mono_mb_emit_icon (mb, 72);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      tid_loc.23 = (unsigned int) tid_loc;
      mono_mb_emit_stloc (mb, tid_loc.23);
      syncp_loc.24 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.24);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      owner_loc.25 = (unsigned int) owner_loc;
      mono_mb_emit_stloc (mb, owner_loc.25);
      owner_loc.25 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.25);
      D.19061 = mono_mb_emit_short_branch (mb, 45);
      tid_branch = (int) D.19061;
      syncp_loc.24 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.24);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      tid_loc.23 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.23);
      mono_mb_emit_byte (mb, 22);
      compare_exchange_method.19 = compare_exchange_method;
      mono_mb_emit_managed_call (mb, compare_exchange_method.19, 0B);
      D.19062 = mono_mb_emit_short_branch (mb, 45);
      has_owner_branch = (int) D.19062;
      if (is_v4 != 0) goto <D.19063>; else goto <D.19064>;
      <D.19063>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.19064>:
      mono_mb_emit_byte (mb, 42);
      tid_branch.26 = (unsigned int) tid_branch;
      mono_mb_patch_short_branch (mb, tid_branch.26);
      owner_loc.25 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.25);
      tid_loc.23 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.23);
      D.19066 = mono_mb_emit_short_branch (mb, 51);
      other_owner_branch = (int) D.19066;
      syncp_loc.24 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.24);
      mono_mb_emit_icon (mb, 8);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 74);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 84);
      if (is_v4 != 0) goto <D.19067>; else goto <D.19068>;
      <D.19067>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.19068>:
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.27 = thin_hash_branch;
      if (thin_hash_branch.27 != 0) goto <D.19070>; else goto <D.19071>;
      <D.19070>:
      thin_hash_branch.27 = thin_hash_branch;
      thin_hash_branch.28 = (unsigned int) thin_hash_branch.27;
      mono_mb_patch_short_branch (mb, thin_hash_branch.28);
      <D.19071>:
      obj_null_branch.29 = obj_null_branch;
      obj_null_branch.30 = (unsigned int) obj_null_branch.29;
      mono_mb_patch_short_branch (mb, obj_null_branch.30);
      syncp_null_branch.31 = syncp_null_branch;
      syncp_null_branch.32 = (unsigned int) syncp_null_branch.31;
      mono_mb_patch_short_branch (mb, syncp_null_branch.32);
      has_owner_branch.33 = (unsigned int) has_owner_branch;
      mono_mb_patch_short_branch (mb, has_owner_branch.33);
      other_owner_branch.34 = (unsigned int) other_owner_branch;
      mono_mb_patch_short_branch (mb, other_owner_branch.34);
      true_locktaken_branch.35 = true_locktaken_branch;
      if (true_locktaken_branch.35 != 0) goto <D.19080>; else goto <D.19081>;
      <D.19080>:
      true_locktaken_branch.35 = true_locktaken_branch;
      true_locktaken_branch.36 = (unsigned int) true_locktaken_branch.35;
      mono_mb_patch_short_branch (mb, true_locktaken_branch.36);
      <D.19081>:
      mono_mb_emit_byte (mb, 2);
      if (is_v4 != 0) goto <D.19083>; else goto <D.19084>;
      <D.19083>:
      mono_mb_emit_byte (mb, 3);
      <D.19084>:
      mono_mb_emit_managed_call (mb, monitor_enter_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.19085 = mono_signature_no_pinvoke (monitor_enter_method);
      D.19086 = mono_mb_create_method (mb, D.19085, 5);
      res = register_fastpath (D.19086, fast_path_idx);
      D.19042 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.19042, 24);
      if (is_v4 != 0) goto <D.19088>; else goto <D.19089>;
      <D.19088>:
      iftmp.37 = 5;
      goto <D.19090>;
      <D.19089>:
      iftmp.37 = 4;
      <D.19090>:
      info->subtype = iftmp.37;
      mono_marshal_set_wrapper_info (res, info);
      mono_mb_free (mb);
      D.19035 = res;
      return D.19035;
    }
  finally
    {
      obj_null_branch = {CLOBBER};
      true_locktaken_branch = {CLOBBER};
      syncp_null_branch = {CLOBBER};
      thin_hash_branch = {CLOBBER};
    }
}


emit_obj_syncp_check (struct MonoMethodBuilder * mb, int syncp_loc, int * obj_null_branch, int * true_locktaken_branch, int * syncp_true_false_branch, int * thin_hash_branch, gboolean branch_on_true)
{
  unsigned int D.19093;
  int D.19094;
  unsigned int D.19097;
  int D.19098;
  unsigned int syncp_loc.38;
  int D.19100;
  unsigned int D.19103;
  int D.19104;
  int iftmp.39;
  unsigned int D.19110;
  int D.19111;

  mono_mb_emit_byte (mb, 2);
  D.19093 = mono_mb_emit_short_branch (mb, 44);
  D.19094 = (int) D.19093;
  *obj_null_branch = D.19094;
  if (true_locktaken_branch != 0B) goto <D.19095>; else goto <D.19096>;
  <D.19095>:
  mono_mb_emit_byte (mb, 3);
  mono_mb_emit_byte (mb, 70);
  D.19097 = mono_mb_emit_short_branch (mb, 45);
  D.19098 = (int) D.19097;
  *true_locktaken_branch = D.19098;
  <D.19096>:
  mono_mb_emit_byte (mb, 2);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_icon (mb, 8);
  mono_mb_emit_byte (mb, 88);
  mono_mb_emit_byte (mb, 77);
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.38);
  D.19100 = mono_gc_is_moving ();
  if (D.19100 != 0) goto <D.19101>; else goto <D.19102>;
  <D.19101>:
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.38);
  mono_mb_emit_icon (mb, 1);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  D.19103 = mono_mb_emit_short_branch (mb, 45);
  D.19104 = (int) D.19103;
  *thin_hash_branch = D.19104;
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.38);
  mono_mb_emit_icon (mb, -4);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.38);
  goto <D.19105>;
  <D.19102>:
  *thin_hash_branch = 0;
  <D.19105>:
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.38);
  if (branch_on_true != 0) goto <D.19107>; else goto <D.19108>;
  <D.19107>:
  iftmp.39 = 45;
  goto <D.19109>;
  <D.19108>:
  iftmp.39 = 44;
  <D.19109>:
  D.19110 = mono_mb_emit_short_branch (mb, iftmp.39);
  D.19111 = (int) D.19110;
  *syncp_true_false_branch = D.19111;
}


register_fastpath (struct MonoMethod * method, int idx)
{
  struct MonoMethod * D.19112;

  mono_memory_barrier ();
  monitor_il_fastpaths[idx] = method;
  D.19112 = method;
  return D.19112;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_monitor_get_fast_exit_method (struct MonoMethod * monitor_exit_method)
{
  struct MonoMethod * D.19116;
  struct MonoMethod * D.19117;
  struct MonoClass * D.19120;
  struct MonoMethod * D.19121;
  struct MonoClass * D.19122;
  struct MonoType * D.19123;
  int has_syncp_branch.40;
  unsigned int has_syncp_branch.41;
  unsigned int syncp_loc.42;
  unsigned int D.19127;
  unsigned int owned_branch.43;
  unsigned int D.19129;
  unsigned int D.19130;
  unsigned int nested_branch.44;
  int thin_hash_branch.45;
  unsigned int thin_hash_branch.46;
  int obj_null_branch.47;
  unsigned int obj_null_branch.48;
  unsigned int has_waiting_branch.49;
  struct MonoMethodSignature * D.19139;
  struct MonoMethod * D.19140;
  struct MonoImage * D.19141;
  struct MonoMethodBuilder * mb;
  struct MonoMethod * res;
  int obj_null_branch;
  int has_waiting_branch;
  int has_syncp_branch;
  int owned_branch;
  int nested_branch;
  int thin_hash_branch;
  int thread_tls_offset;
  int syncp_loc;
  struct WrapperInfo * info;

  try
    {
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.19114>; else goto <D.19115>;
      <D.19114>:
      D.19116 = 0B;
      return D.19116;
      <D.19115>:
      D.19117 = monitor_il_fastpaths[2];
      if (D.19117 != 0B) goto <D.19118>; else goto <D.19119>;
      <D.19118>:
      D.19116 = monitor_il_fastpaths[2];
      return D.19116;
      <D.19119>:
      D.19120 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.19120, "FastMonitorExit", 25);
      D.19121 = mb->method;
      D.19121->slot = -1;
      D.19121 = mb->method;
      D.19121->flags = 182;
      D.19122 = mono_defaults.int_class;
      D.19123 = &D.19122->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.19123);
      emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, 0B, &has_syncp_branch, &thin_hash_branch, 1);
      mono_mb_emit_byte (mb, 42);
      has_syncp_branch.40 = has_syncp_branch;
      has_syncp_branch.41 = (unsigned int) has_syncp_branch.40;
      mono_mb_patch_short_branch (mb, has_syncp_branch.41);
      syncp_loc.42 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.42);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      mono_mb_emit_byte (mb, 240);
      mono_mb_emit_byte (mb, 13);
      mono_mb_emit_i4 (mb, 0);
      mono_mb_emit_icon (mb, 72);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      D.19127 = mono_mb_emit_short_branch (mb, 46);
      owned_branch = (int) D.19127;
      mono_mb_emit_byte (mb, 42);
      owned_branch.43 = (unsigned int) owned_branch;
      mono_mb_patch_short_branch (mb, owned_branch.43);
      syncp_loc.42 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.42);
      mono_mb_emit_icon (mb, 8);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 74);
      mono_mb_emit_byte (mb, 37);
      mono_mb_emit_byte (mb, 23);
      D.19129 = mono_mb_emit_short_branch (mb, 53);
      nested_branch = (int) D.19129;
      mono_mb_emit_byte (mb, 38);
      mono_mb_emit_byte (mb, 38);
      syncp_loc.42 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.42);
      mono_mb_emit_icon (mb, 16);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 74);
      D.19130 = mono_mb_emit_short_branch (mb, 45);
      has_waiting_branch = (int) D.19130;
      syncp_loc.42 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.42);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 20);
      mono_mb_emit_byte (mb, 223);
      mono_mb_emit_byte (mb, 42);
      nested_branch.44 = (unsigned int) nested_branch;
      mono_mb_patch_short_branch (mb, nested_branch.44);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 89);
      mono_mb_emit_byte (mb, 84);
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.45 = thin_hash_branch;
      if (thin_hash_branch.45 != 0) goto <D.19133>; else goto <D.19134>;
      <D.19133>:
      thin_hash_branch.45 = thin_hash_branch;
      thin_hash_branch.46 = (unsigned int) thin_hash_branch.45;
      mono_mb_patch_short_branch (mb, thin_hash_branch.46);
      <D.19134>:
      obj_null_branch.47 = obj_null_branch;
      obj_null_branch.48 = (unsigned int) obj_null_branch.47;
      mono_mb_patch_short_branch (mb, obj_null_branch.48);
      has_waiting_branch.49 = (unsigned int) has_waiting_branch;
      mono_mb_patch_short_branch (mb, has_waiting_branch.49);
      mono_mb_emit_byte (mb, 2);
      mono_mb_emit_managed_call (mb, monitor_exit_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.19139 = mono_signature_no_pinvoke (monitor_exit_method);
      D.19140 = mono_mb_create_method (mb, D.19139, 5);
      res = register_fastpath (D.19140, 2);
      mono_mb_free (mb);
      D.19141 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.19141, 24);
      info->subtype = 6;
      mono_marshal_set_wrapper_info (res, info);
      D.19116 = res;
      return D.19116;
    }
  finally
    {
      obj_null_branch = {CLOBBER};
      has_syncp_branch = {CLOBBER};
      thin_hash_branch = {CLOBBER};
    }
}


mono_monitor_threads_sync_members_offset (int * owner_offset, int * nest_offset, int * entry_count_offset)
{
  struct MonoThreadsSync ts;

  try
    {
      *owner_offset = 8;
      *nest_offset = 2052;
      *entry_count_offset = 4100;
    }
  finally
    {
      ts = {CLOBBER};
    }
}


ves_icall_System_Threading_Monitor_Monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  gboolean D.19146;
  _Bool D.19147;
  gint32 res;

  <D.18486>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.19144>; else goto <D.19145>;
  <D.19144>:
  mono_thread_interruption_checkpoint ();
  <D.19145>:
  if (res == -1) goto <D.18486>; else goto <D.18487>;
  <D.18487>:
  D.19147 = res == 1;
  D.19146 = (gboolean) D.19147;
  return D.19146;
}


ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (struct MonoObject * obj, guint32 ms, char * lockTaken)
{
  _Bool D.19151;
  char D.19152;
  gint32 res;

  <D.18494>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.19149>; else goto <D.19150>;
  <D.19149>:
  mono_thread_interruption_checkpoint ();
  <D.19150>:
  if (res == -1) goto <D.18494>; else goto <D.18495>;
  <D.18495>:
  D.19151 = res == 1;
  D.19152 = (char) D.19151;
  *lockTaken = D.19152;
}


ves_icall_System_Threading_Monitor_Monitor_test_owner (struct MonoObject * obj)
{
  long unsigned int D.19153;
  long unsigned int D.19154;
  gboolean D.19157;
  long unsigned int D.19158;
  long unsigned int D.19161;
  long unsigned int tls_pthread_self.50;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19153 = lw.lock_word;
        D.19154 = D.19153 & 1;
        if (D.19154 != 0) goto <D.19155>; else goto <D.19156>;
        <D.19155>:
        D.19157 = 0;
        return D.19157;
        <D.19156>:
        D.19153 = lw.lock_word;
        D.19158 = D.19153 & 18446744073709551612;
        lw.lock_word = D.19158;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19159>; else goto <D.19160>;
  <D.19159>:
  D.19157 = 0;
  return D.19157;
  <D.19160>:
  D.19161 = mon->owner;
  tls_pthread_self.50 = tls_pthread_self;
  if (D.19161 == tls_pthread_self.50) goto <D.19163>; else goto <D.19164>;
  <D.19163>:
  D.19157 = 1;
  return D.19157;
  <D.19164>:
  D.19157 = 0;
  return D.19157;
}


ves_icall_System_Threading_Monitor_Monitor_test_synchronised (struct MonoObject * obj)
{
  long unsigned int D.19168;
  long unsigned int D.19169;
  gboolean D.19172;
  long unsigned int D.19173;
  long unsigned int D.19176;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19168 = lw.lock_word;
        D.19169 = D.19168 & 1;
        if (D.19169 != 0) goto <D.19170>; else goto <D.19171>;
        <D.19170>:
        D.19172 = 0;
        return D.19172;
        <D.19171>:
        D.19168 = lw.lock_word;
        D.19173 = D.19168 & 18446744073709551612;
        lw.lock_word = D.19173;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19174>; else goto <D.19175>;
  <D.19174>:
  D.19172 = 0;
  return D.19172;
  <D.19175>:
  D.19176 = mon->owner;
  if (D.19176 != 0) goto <D.19177>; else goto <D.19178>;
  <D.19177>:
  D.19172 = 1;
  return D.19172;
  <D.19178>:
  D.19172 = 0;
  return D.19172;
}


ves_icall_System_Threading_Monitor_Monitor_pulse (struct MonoObject * obj)
{
  long unsigned int D.19182;
  long unsigned int D.19183;
  struct MonoException * D.19186;
  long unsigned int D.19187;
  struct MonoException * D.19190;
  long unsigned int D.19191;
  long unsigned int tls_pthread_self.51;
  struct MonoException * D.19195;
  struct GSList * D.19196;
  void * D.19199;
  struct GSList * D.19200;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19182 = lw.lock_word;
        D.19183 = D.19182 & 1;
        if (D.19183 != 0) goto <D.19184>; else goto <D.19185>;
        <D.19184>:
        D.19186 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19186);
        return;
        <D.19185>:
        D.19182 = lw.lock_word;
        D.19187 = D.19182 & 18446744073709551612;
        lw.lock_word = D.19187;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19188>; else goto <D.19189>;
  <D.19188>:
  D.19190 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19190);
  return;
  <D.19189>:
  D.19191 = mon->owner;
  tls_pthread_self.51 = tls_pthread_self;
  if (D.19191 != tls_pthread_self.51) goto <D.19193>; else goto <D.19194>;
  <D.19193>:
  D.19195 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19195);
  return;
  <D.19194>:
  D.19196 = mon->wait_list;
  if (D.19196 != 0B) goto <D.19197>; else goto <D.19198>;
  <D.19197>:
  D.19196 = mon->wait_list;
  D.19199 = D.19196->data;
  SetEvent (D.19199);
  D.19196 = mon->wait_list;
  D.19199 = D.19196->data;
  D.19196 = mon->wait_list;
  D.19200 = monoeg_g_slist_remove (D.19196, D.19199);
  mon->wait_list = D.19200;
  <D.19198>:
}


ves_icall_System_Threading_Monitor_Monitor_pulse_all (struct MonoObject * obj)
{
  long unsigned int D.19204;
  long unsigned int D.19205;
  struct MonoException * D.19208;
  long unsigned int D.19209;
  struct MonoException * D.19212;
  long unsigned int D.19213;
  long unsigned int tls_pthread_self.52;
  struct MonoException * D.19217;
  struct GSList * D.19218;
  void * D.19219;
  struct GSList * D.19220;
  struct MonoThreadsSync * mon;

  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19204 = lw.lock_word;
        D.19205 = D.19204 & 1;
        if (D.19205 != 0) goto <D.19206>; else goto <D.19207>;
        <D.19206>:
        D.19208 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19208);
        return;
        <D.19207>:
        D.19204 = lw.lock_word;
        D.19209 = D.19204 & 18446744073709551612;
        lw.lock_word = D.19209;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19210>; else goto <D.19211>;
  <D.19210>:
  D.19212 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19212);
  return;
  <D.19211>:
  D.19213 = mon->owner;
  tls_pthread_self.52 = tls_pthread_self;
  if (D.19213 != tls_pthread_self.52) goto <D.19215>; else goto <D.19216>;
  <D.19215>:
  D.19217 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19217);
  return;
  <D.19216>:
  goto <D.18517>;
  <D.18516>:
  D.19218 = mon->wait_list;
  D.19219 = D.19218->data;
  SetEvent (D.19219);
  D.19218 = mon->wait_list;
  D.19219 = D.19218->data;
  D.19218 = mon->wait_list;
  D.19220 = monoeg_g_slist_remove (D.19218, D.19219);
  mon->wait_list = D.19220;
  <D.18517>:
  D.19218 = mon->wait_list;
  if (D.19218 != 0B) goto <D.18516>; else goto <D.18518>;
  <D.18518>:
}


ves_icall_System_Threading_Monitor_Monitor_wait (struct MonoObject * obj, guint32 ms)
{
  long unsigned int D.19224;
  long unsigned int D.19225;
  struct MonoException * D.19228;
  gboolean D.19229;
  long unsigned int D.19230;
  struct MonoException * D.19233;
  long unsigned int D.19234;
  long unsigned int tls_pthread_self.53;
  struct MonoException * D.19238;
  struct MonoException * D.19241;
  struct GSList * D.19242;
  struct GSList * D.19243;
  int D.19244;
  struct MonoException * D.19251;
  struct GSList * D.19257;
  struct MonoThreadsSync * mon;
  void * event;
  guint32 nest;
  guint32 ret;
  gboolean success;
  gint32 regain;
  struct MonoInternalThread * thread;

  success = 0;
  thread = mono_thread_internal_current ();
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19224 = lw.lock_word;
        D.19225 = D.19224 & 1;
        if (D.19225 != 0) goto <D.19226>; else goto <D.19227>;
        <D.19226>:
        D.19228 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19228);
        D.19229 = 0;
        return D.19229;
        <D.19227>:
        D.19224 = lw.lock_word;
        D.19230 = D.19224 & 18446744073709551612;
        lw.lock_word = D.19230;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19231>; else goto <D.19232>;
  <D.19231>:
  D.19233 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19233);
  D.19229 = 0;
  return D.19229;
  <D.19232>:
  D.19234 = mon->owner;
  tls_pthread_self.53 = tls_pthread_self;
  if (D.19234 != tls_pthread_self.53) goto <D.19236>; else goto <D.19237>;
  <D.19236>:
  D.19238 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19238);
  D.19229 = 0;
  return D.19229;
  <D.19237>:
  mono_thread_current_check_pending_interrupt ();
  event = CreateEvent (0B, 0, 0, 0B);
  if (event == 0B) goto <D.19239>; else goto <D.19240>;
  <D.19239>:
  D.19241 = mono_get_exception_synchronization_lock ("Failed to set up wait event");
  mono_raise_exception (D.19241);
  D.19229 = 0;
  return D.19229;
  <D.19240>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.19242 = mon->wait_list;
  D.19243 = monoeg_g_slist_append (D.19242, event);
  mon->wait_list = D.19243;
  nest = mon->nest;
  mon->nest = 1;
  mono_monitor_exit (obj);
  ret = WaitForSingleObjectEx (event, ms, 1);
  mono_thread_clr_state (thread, 32);
  D.19244 = mono_thread_interruption_requested ();
  if (D.19244 != 0) goto <D.19245>; else goto <D.19246>;
  <D.19245>:
  D.19229 = 0;
  return D.19229;
  <D.19246>:
  <D.18531>:
  regain = mono_monitor_try_enter_internal (obj, 4294967295, 1);
  if (regain == -1) goto <D.19247>; else goto <D.19248>;
  <D.19247>:
  mono_thread_interruption_checkpoint ();
  <D.19248>:
  if (regain == -1) goto <D.18531>; else goto <D.18532>;
  <D.18532>:
  if (regain == 0) goto <D.19249>; else goto <D.19250>;
  <D.19249>:
  CloseHandle (event);
  D.19251 = mono_get_exception_synchronization_lock ("Failed to regain lock");
  mono_raise_exception (D.19251);
  D.19229 = 0;
  return D.19229;
  <D.19250>:
  mon->nest = nest;
  if (ret == 258) goto <D.19252>; else goto <D.19253>;
  <D.19252>:
  ret = WaitForSingleObjectEx (event, 0, 0);
  <D.19253>:
  if (ret == 0) goto <D.19254>; else goto <D.19255>;
  <D.19254>:
  success = 1;
  goto <D.19256>;
  <D.19255>:
  D.19242 = mon->wait_list;
  D.19257 = monoeg_g_slist_remove (D.19242, event);
  mon->wait_list = D.19257;
  <D.19256>:
  CloseHandle (event);
  D.19229 = success;
  return D.19229;
}


