mono_monitor_init ()
{
  InitializeCriticalSection (&monitor_mutex);
}


mono_monitor_cleanup ()
{
  struct MonoThreadsSync * mon;

  mon = monitor_freelist;
  goto <D.18803>;
  <D.18802>:
  mon->wait_list = -1B;
  mon = mon->data;
  <D.18803>:
  if (mon != 0B) goto <D.18802>; else goto <D.18804>;
  <D.18804>:
}


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.19065;
  void * D.19066;
  int D.19069;
  int D.19073;
  void * * D.19076;
  long unsigned int D.19077;
  void * D.19080;
  unsigned int D.19081;
  void * D.19082;
  int D.19085;
  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.18827>;
  <D.18826>:
  on_freelist = on_freelist + 1;
  mon = mon->data;
  <D.18827>:
  if (mon != 0B) goto <D.18826>; else goto <D.18828>;
  <D.18828>:
  marray = monitor_allocated;
  goto <D.18834>;
  <D.18833>:
  D.19065 = marray->num_monitors;
  total = D.19065 + total;
  num_arrays = num_arrays + 1;
  i = 0;
  goto <D.18831>;
  <D.18830>:
  mon = &marray->monitors[i];
  D.19066 = mon->data;
  if (D.19066 == 0B) goto <D.19067>; else goto <D.19068>;
  <D.19067>:
  D.19065 = marray->num_monitors;
  D.19069 = D.19065 + -1;
  if (D.19069 > i) goto <D.19070>; else goto <D.19071>;
  <D.19070>:
  to_recycle = to_recycle + 1;
  <D.19071>:
  goto <D.19072>;
  <D.19068>:
  D.19066 = mon->data;
  D.19073 = monitor_is_on_freelist (D.19066);
  if (D.19073 == 0) goto <D.19074>; else goto <D.19075>;
  <D.19074>:
  {
    struct MonoObject * holder;

    D.19076 = &mon->data;
    holder = mono_gc_weak_link_get (D.19076);
    D.19077 = mon->owner;
    if (D.19077 != 0) goto <D.19078>; else goto <D.19079>;
    <D.19078>:
    D.19077 = mon->owner;
    D.19080 = (void *) D.19077;
    D.19081 = mon->nest;
    monoeg_g_print ("Lock %p in object %p held by thread %p, nest level: %d\n", mon, holder, D.19080, D.19081);
    D.19082 = mon->entry_sem;
    if (D.19082 != 0B) goto <D.19083>; else goto <D.19084>;
    <D.19083>:
    D.19082 = mon->entry_sem;
    D.19085 = mon->entry_count;
    monoeg_g_print ("\tWaiting on semaphore %p: %d\n", D.19082, D.19085);
    <D.19084>:
    goto <D.19086>;
    <D.19079>:
    if (include_untaken != 0) goto <D.19087>; else goto <D.19088>;
    <D.19087>:
    monoeg_g_print ("Lock %p in object %p untaken\n", mon, holder);
    <D.19088>:
    <D.19086>:
    used = used + 1;
  }
  <D.19075>:
  <D.19072>:
  i = i + 1;
  <D.18831>:
  D.19065 = marray->num_monitors;
  if (D.19065 > i) goto <D.18830>; else goto <D.18832>;
  <D.18832>:
  marray = marray->next;
  <D.18834>:
  if (marray != 0B) goto <D.18833>; else goto <D.18835>;
  <D.18835>:
  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.19089;
  int D.19092;
  struct MonoThreadsSync * D.19093;
  int D.19096;
  struct MonitorArray * marray;

  marray = monitor_allocated;
  goto <D.18813>;
  <D.18812>:
  D.19089 = &marray->monitors;
  if (D.19089 <= mon) goto <D.19090>; else goto <D.19091>;
  <D.19090>:
  D.19092 = marray->num_monitors;
  D.19093 = &marray->monitors[D.19092];
  if (D.19093 > mon) goto <D.19094>; else goto <D.19095>;
  <D.19094>:
  D.19096 = 1;
  return D.19096;
  <D.19095>:
  <D.19091>:
  marray = marray->next;
  <D.18813>:
  if (marray != 0B) goto <D.18812>; else goto <D.18814>;
  <D.18814>:
  D.19096 = 0;
  return D.19096;
}


mono_object_hash (struct MonoObject * obj)
{
  int D.19100;
  struct MonoThreadsSync * D.19101;
  long unsigned int D.19102;
  long unsigned int D.19103;
  unsigned int D.19106;
  unsigned int D.19107;
  long unsigned int D.19108;
  long unsigned int D.19111;
  struct MonoThreadsSync * D.19112;
  long int obj.1;
  unsigned int D.19114;
  unsigned int D.19115;
  int hash.2;
  long unsigned int D.19119;
  unsigned int D.19121;
  unsigned int D.19122;
  long unsigned int D.19123;
  struct MonoThreadsSync * * D.19124;
  void * D.19125;
  union LockWord lw;
  unsigned int hash;

  try
    {
      if (obj == 0B) goto <D.19098>; else goto <D.19099>;
      <D.19098>:
      D.19100 = 0;
      return D.19100;
      <D.19099>:
      D.19101 = obj->synchronisation;
      lw.sync = D.19101;
      D.19102 = lw.lock_word;
      D.19103 = D.19102 & 1;
      if (D.19103 != 0) goto <D.19104>; else goto <D.19105>;
      <D.19104>:
      D.19102 = lw.lock_word;
      D.19106 = (unsigned int) D.19102;
      D.19107 = D.19106 >> 2;
      D.19100 = (int) D.19107;
      return D.19100;
      <D.19105>:
      D.19102 = lw.lock_word;
      D.19108 = D.19102 & 2;
      if (D.19108 != 0) goto <D.19109>; else goto <D.19110>;
      <D.19109>:
      D.19102 = lw.lock_word;
      D.19111 = D.19102 & 18446744073709551612;
      lw.lock_word = D.19111;
      D.19112 = lw.sync;
      D.19100 = D.19112->hash_code;
      return D.19100;
      <D.19110>:
      obj.1 = (long int) obj;
      D.19114 = (unsigned int) obj.1;
      D.19115 = D.19114 >> 3;
      hash = D.19115 * 2654435761;
      hash = hash & 1073741823;
      D.19112 = lw.sync;
      if (D.19112 != 0B) goto <D.19116>; else goto <D.19117>;
      <D.19116>:
      D.19112 = lw.sync;
      hash.2 = (int) hash;
      D.19112->hash_code = hash.2;
      D.19102 = lw.lock_word;
      D.19119 = D.19102 | 2;
      lw.lock_word = D.19119;
      D.19112 = lw.sync;
      obj->synchronisation = D.19112;
      goto <D.19120>;
      <D.19117>:
      D.19121 = hash << 2;
      D.19122 = D.19121 | 1;
      D.19123 = (long unsigned int) D.19122;
      lw.lock_word = D.19123;
      D.19124 = &obj->synchronisation;
      D.19112 = lw.sync;
      D.19125 = InterlockedCompareExchangePointer (D.19124, D.19112, 0B);
      if (D.19125 == 0B) goto <D.19126>; else goto <D.19127>;
      <D.19126>:
      D.19100 = (int) hash;
      return D.19100;
      <D.19127>:
      D.19101 = obj->synchronisation;
      lw.sync = D.19101;
      D.19102 = lw.lock_word;
      D.19103 = D.19102 & 1;
      if (D.19103 != 0) goto <D.19128>; else goto <D.19129>;
      <D.19128>:
      D.19100 = (int) hash;
      return D.19100;
      <D.19129>:
      D.19102 = lw.lock_word;
      D.19111 = D.19102 & 18446744073709551612;
      lw.lock_word = D.19111;
      D.19112 = lw.sync;
      hash.2 = (int) hash;
      D.19112->hash_code = hash.2;
      D.19102 = lw.lock_word;
      D.19119 = D.19102 | 2;
      lw.lock_word = D.19119;
      D.19112 = lw.sync;
      obj->synchronisation = D.19112;
      <D.19120>:
      D.19100 = (int) hash;
      return D.19100;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


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

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


mono_monitor_enter (struct MonoObject * obj)
{
  mono_bool D.19137;
  int D.19138;
  _Bool D.19139;

  D.19138 = mono_monitor_try_enter_internal (obj, 4294967295, 0);
  D.19139 = D.19138 == 1;
  D.19137 = (mono_bool) D.19139;
  return D.19137;
}


mono_monitor_try_enter_internal (struct MonoObject * obj, guint32 ms, gboolean allow_interruption)
{
  _Bool D.19141;
  long int D.19142;
  long int D.19143;
  struct MonoException * D.19146;
  gint32 D.19147;
  _Bool D.19148;
  long int D.19149;
  long int D.19150;
  _Bool D.19155;
  long int D.19156;
  long int D.19157;
  struct MonoThreadsSync * * D.19160;
  void * D.19161;
  void * * D.19164;
  _Bool D.19167;
  long int D.19168;
  long int D.19169;
  struct MonoThreadsSync * D.19172;
  long unsigned int D.19173;
  long unsigned int D.19174;
  long unsigned int D.19177;
  int D.19178;
  long unsigned int D.19179;
  struct MonoThreadsSync * D.19180;
  void * D.19181;
  _Bool D.19186;
  long int D.19187;
  long int D.19188;
  _Bool D.19193;
  long int D.19194;
  long int D.19195;
  long unsigned int D.19198;
  _Bool D.19203;
  long int D.19204;
  long int D.19205;
  long unsigned int D.19208;
  _Bool D.19212;
  long int D.19213;
  long int D.19214;
  long unsigned int D.19218;
  long unsigned int D.19219;
  _Bool D.19224;
  long int D.19225;
  long int D.19226;
  long unsigned int D.19229;
  int D.19230;
  long unsigned int D.19231;
  struct MonoThreadsSync * D.19232;
  void * D.19233;
  _Bool D.19238;
  long int D.19239;
  long int D.19240;
  _Bool D.19245;
  long int D.19246;
  long int D.19247;
  long unsigned int D.19250;
  long unsigned int D.19251;
  long unsigned int D.19252;
  _Bool D.19253;
  long int D.19254;
  long int D.19255;
  gsize * D.19258;
  void * id.5;
  void * D.19260;
  _Bool D.19261;
  long int D.19262;
  long int D.19263;
  unsigned int D.19265;
  _Bool D.19266;
  long int D.19267;
  long int D.19268;
  unsigned int D.19273;
  struct MonoPerfCounters * mono_perfcounters.6;
  unsigned int D.19275;
  unsigned int D.19276;
  void * D.19281;
  _Bool D.19282;
  long int D.19283;
  long int D.19284;
  void * D.19291;
  _Bool D.19294;
  long int D.19295;
  long int D.19296;
  void * * D.19299;
  void * D.19300;
  volatile gint32 * D.19309;
  unsigned int D.19310;
  unsigned int D.19311;
  unsigned int D.19312;
  unsigned int D.19313;
  volatile gint32 * D.19314;
  unsigned int D.19315;
  unsigned int D.19320;
  struct MonoInternalThread * D.19336;
  int D.19337;
  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.19141 = obj == 0B;
  D.19142 = (long int) D.19141;
  D.19143 = __builtin_expect (D.19142, 0);
  if (D.19143 != 0) goto <D.19144>; else goto <D.19145>;
  <D.19144>:
  D.19146 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19146);
  D.19147 = 0;
  return D.19147;
  <D.19145>:
  retry:
  mon = obj->synchronisation;
  D.19148 = mon == 0B;
  D.19149 = (long int) D.19148;
  D.19150 = __builtin_expect (D.19149, 0);
  if (D.19150 != 0) goto <D.19151>; else goto <D.19152>;
  <D.19151>:
  {
    int ret;

    ret = pthread_mutex_lock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.19153>; else goto <D.19154>;
    <D.19153>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.19154>:
    D.19155 = ret != 0;
    D.19156 = (long int) D.19155;
    D.19157 = __builtin_expect (D.19156, 0);
    if (D.19157 != 0) goto <D.19158>; else goto <D.19159>;
    <D.19158>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 439, "ret == 0");
    <D.19159>:
  }
  mon = mon_new (id);
  D.19160 = &obj->synchronisation;
  D.19161 = InterlockedCompareExchangePointer (D.19160, mon, 0B);
  if (D.19161 == 0B) goto <D.19162>; else goto <D.19163>;
  <D.19162>:
  D.19164 = &mon->data;
  mono_gc_weak_link_add (D.19164, obj, 0);
  {
    int ret;

    ret = pthread_mutex_unlock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.19165>; else goto <D.19166>;
    <D.19165>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.19166>:
    D.19167 = ret != 0;
    D.19168 = (long int) D.19167;
    D.19169 = __builtin_expect (D.19168, 0);
    if (D.19169 != 0) goto <D.19170>; else goto <D.19171>;
    <D.19170>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 443, "ret == 0");
    <D.19171>:
  }
  D.19147 = 1;
  return D.19147;
  <D.19163>:
  {
    union LockWord lw;

    try
      {
        D.19172 = obj->synchronisation;
        lw.sync = D.19172;
        D.19173 = lw.lock_word;
        D.19174 = D.19173 & 1;
        if (D.19174 != 0) goto <D.19175>; else goto <D.19176>;
        <D.19175>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          D.19173 = lw.lock_word;
          D.19177 = D.19173 >> 2;
          D.19178 = (int) D.19177;
          mon->hash_code = D.19178;
          lw.sync = mon;
          D.19173 = lw.lock_word;
          D.19179 = D.19173 | 2;
          lw.lock_word = D.19179;
          D.19160 = &obj->synchronisation;
          D.19180 = lw.sync;
          D.19181 = InterlockedCompareExchangePointer (D.19160, D.19180, oldlw);
          if (D.19181 == oldlw) goto <D.19182>; else goto <D.19183>;
          <D.19182>:
          D.19164 = &mon->data;
          mono_gc_weak_link_add (D.19164, obj, 0);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.19184>; else goto <D.19185>;
            <D.19184>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.19185>:
            D.19186 = ret != 0;
            D.19187 = (long int) D.19186;
            D.19188 = __builtin_expect (D.19187, 0);
            if (D.19188 != 0) goto <D.19189>; else goto <D.19190>;
            <D.19189>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 458, "ret == 0");
            <D.19190>:
          }
          D.19147 = 1;
          return D.19147;
          <D.19183>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.19191>; else goto <D.19192>;
            <D.19191>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.19192>:
            D.19193 = ret != 0;
            D.19194 = (long int) D.19193;
            D.19195 = __builtin_expect (D.19194, 0);
            if (D.19195 != 0) goto <D.19196>; else goto <D.19197>;
            <D.19196>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 463, "ret == 0");
            <D.19197>:
          }
          goto retry;
        }
        <D.19176>:
        D.19173 = lw.lock_word;
        D.19198 = D.19173 & 2;
        if (D.19198 != 0) goto <D.19199>; else goto <D.19200>;
        <D.19199>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.19201>; else goto <D.19202>;
          <D.19201>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.19202>:
          D.19203 = ret != 0;
          D.19204 = (long int) D.19203;
          D.19205 = __builtin_expect (D.19204, 0);
          if (D.19205 != 0) goto <D.19206>; else goto <D.19207>;
          <D.19206>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 468, "ret == 0");
          <D.19207>:
        }
        D.19173 = lw.lock_word;
        D.19208 = D.19173 & 18446744073709551612;
        lw.lock_word = D.19208;
        mon = lw.sync;
        goto <D.19209>;
        <D.19200>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.19210>; else goto <D.19211>;
          <D.19210>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.19211>:
          D.19212 = ret != 0;
          D.19213 = (long int) D.19212;
          D.19214 = __builtin_expect (D.19213, 0);
          if (D.19214 != 0) goto <D.19215>; else goto <D.19216>;
          <D.19215>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 474, "ret == 0");
          <D.19216>:
        }
        mon = obj->synchronisation;
        <D.19209>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  goto <D.19217>;
  <D.19152>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19218 = lw.lock_word;
        D.19219 = D.19218 & 1;
        if (D.19219 != 0) goto <D.19220>; else goto <D.19221>;
        <D.19220>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          {
            int ret;

            ret = pthread_mutex_lock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.19222>; else goto <D.19223>;
            <D.19222>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
            <D.19223>:
            D.19224 = ret != 0;
            D.19225 = (long int) D.19224;
            D.19226 = __builtin_expect (D.19225, 0);
            if (D.19226 != 0) goto <D.19227>; else goto <D.19228>;
            <D.19227>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 489, "ret == 0");
            <D.19228>:
          }
          mon = mon_new (id);
          D.19218 = lw.lock_word;
          D.19229 = D.19218 >> 2;
          D.19230 = (int) D.19229;
          mon->hash_code = D.19230;
          lw.sync = mon;
          D.19218 = lw.lock_word;
          D.19231 = D.19218 | 2;
          lw.lock_word = D.19231;
          D.19160 = &obj->synchronisation;
          D.19232 = lw.sync;
          D.19233 = InterlockedCompareExchangePointer (D.19160, D.19232, oldlw);
          if (D.19233 == oldlw) goto <D.19234>; else goto <D.19235>;
          <D.19234>:
          D.19164 = &mon->data;
          mono_gc_weak_link_add (D.19164, obj, 1);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.19236>; else goto <D.19237>;
            <D.19236>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.19237>:
            D.19238 = ret != 0;
            D.19239 = (long int) D.19238;
            D.19240 = __builtin_expect (D.19239, 0);
            if (D.19240 != 0) goto <D.19241>; else goto <D.19242>;
            <D.19241>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 497, "ret == 0");
            <D.19242>:
          }
          D.19147 = 1;
          return D.19147;
          <D.19235>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.19243>; else goto <D.19244>;
            <D.19243>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.19244>:
            D.19245 = ret != 0;
            D.19246 = (long int) D.19245;
            D.19247 = __builtin_expect (D.19246, 0);
            if (D.19247 != 0) goto <D.19248>; else goto <D.19249>;
            <D.19248>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 502, "ret == 0");
            <D.19249>:
          }
          goto retry;
        }
        <D.19221>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  <D.19217>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19250 = lw.lock_word;
        D.19251 = D.19250 & 18446744073709551612;
        lw.lock_word = D.19251;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.19252 = mon->owner;
  D.19253 = D.19252 == 0;
  D.19254 = (long int) D.19253;
  D.19255 = __builtin_expect (D.19254, 1);
  if (D.19255 != 0) goto <D.19256>; else goto <D.19257>;
  <D.19256>:
  D.19258 = &mon->owner;
  id.5 = (void *) id;
  D.19260 = InterlockedCompareExchangePointer (D.19258, id.5, 0B);
  D.19261 = D.19260 == 0B;
  D.19262 = (long int) D.19261;
  D.19263 = __builtin_expect (D.19262, 1);
  if (D.19263 != 0) goto <D.19264>; else goto retry;
  <D.19264>:
  D.19265 = mon->nest;
  D.19266 = D.19265 != 1;
  D.19267 = (long int) D.19266;
  D.19268 = __builtin_expect (D.19267, 0);
  if (D.19268 != 0) goto <D.19269>; else goto <D.19270>;
  <D.19269>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 530, "mon->nest == 1");
  <D.19270>:
  D.19147 = 1;
  return D.19147;
  <D.19257>:
  D.19252 = mon->owner;
  if (D.19252 == id) goto <D.19271>; else goto <D.19272>;
  <D.19271>:
  D.19265 = mon->nest;
  D.19273 = D.19265 + 1;
  mon->nest = D.19273;
  D.19147 = 1;
  return D.19147;
  <D.19272>:
  mono_perfcounters.6 = mono_perfcounters;
  D.19275 = mono_perfcounters.6->thread_contentions;
  D.19276 = D.19275 + 1;
  mono_perfcounters.6->thread_contentions = D.19276;
  if (ms == 0) goto <D.19277>; else goto <D.19278>;
  <D.19277>:
  D.19147 = 0;
  return D.19147;
  <D.19278>:
  mono_profiler_monitor_event (obj, 1);
  retry_contended:
  D.19252 = mon->owner;
  D.19253 = D.19252 == 0;
  D.19254 = (long int) D.19253;
  D.19255 = __builtin_expect (D.19254, 1);
  if (D.19255 != 0) goto <D.19279>; else goto <D.19280>;
  <D.19279>:
  D.19258 = &mon->owner;
  id.5 = (void *) id;
  D.19281 = InterlockedCompareExchangePointer (D.19258, id.5, 0B);
  D.19282 = D.19281 == 0B;
  D.19283 = (long int) D.19282;
  D.19284 = __builtin_expect (D.19283, 1);
  if (D.19284 != 0) goto <D.19285>; else goto <D.19286>;
  <D.19285>:
  D.19265 = mon->nest;
  D.19266 = D.19265 != 1;
  D.19267 = (long int) D.19266;
  D.19268 = __builtin_expect (D.19267, 0);
  if (D.19268 != 0) goto <D.19287>; else goto <D.19288>;
  <D.19287>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 574, "mon->nest == 1");
  <D.19288>:
  mono_profiler_monitor_event (obj, 2);
  D.19147 = 1;
  return D.19147;
  <D.19286>:
  <D.19280>:
  D.19252 = mon->owner;
  if (D.19252 == id) goto <D.19289>; else goto <D.19290>;
  <D.19289>:
  D.19265 = mon->nest;
  D.19273 = D.19265 + 1;
  mon->nest = D.19273;
  mono_profiler_monitor_event (obj, 2);
  D.19147 = 1;
  return D.19147;
  <D.19290>:
  D.19291 = mon->entry_sem;
  if (D.19291 == 0B) goto <D.19292>; else goto <D.19293>;
  <D.19292>:
  sem = CreateSemaphore (0B, 0, 2147483647, 0B);
  D.19294 = sem == 0B;
  D.19295 = (long int) D.19294;
  D.19296 = __builtin_expect (D.19295, 0);
  if (D.19296 != 0) goto <D.19297>; else goto <D.19298>;
  <D.19297>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 593, "sem != NULL");
  <D.19298>:
  D.19299 = &mon->entry_sem;
  D.19300 = InterlockedCompareExchangePointer (D.19299, sem, 0B);
  if (D.19300 != 0B) goto <D.19301>; else goto <D.19302>;
  <D.19301>:
  CloseHandle (sem);
  <D.19302>:
  <D.19293>:
  if (ms != 4294967295) goto <D.19303>; else goto <D.19304>;
  <D.19303>:
  then = mono_msec_ticks ();
  if (ms <= 99) goto <D.19305>; else goto <D.19306>;
  <D.19305>:
  waitms = ms;
  goto <D.19307>;
  <D.19306>:
  waitms = 100;
  <D.19307>:
  goto <D.19308>;
  <D.19304>:
  waitms = 100;
  <D.19308>:
  D.19309 = &mon->entry_count;
  InterlockedIncrement (D.19309);
  mono_perfcounters.6 = mono_perfcounters;
  D.19310 = mono_perfcounters.6->thread_queue_len;
  D.19311 = D.19310 + 1;
  mono_perfcounters.6->thread_queue_len = D.19311;
  mono_perfcounters.6 = mono_perfcounters;
  D.19312 = mono_perfcounters.6->thread_queue_max;
  D.19313 = D.19312 + 1;
  mono_perfcounters.6->thread_queue_max = D.19313;
  thread = mono_thread_internal_current ();
  mono_thread_set_state (thread, 32);
  D.19291 = mon->entry_sem;
  ret = WaitForSingleObjectEx (D.19291, waitms, 1);
  mono_thread_clr_state (thread, 32);
  D.19314 = &mon->entry_count;
  InterlockedDecrement (D.19314);
  mono_perfcounters.6 = mono_perfcounters;
  D.19310 = mono_perfcounters.6->thread_queue_len;
  D.19315 = D.19310 + 4294967295;
  mono_perfcounters.6->thread_queue_len = D.19315;
  if (ms != 4294967295) goto <D.19316>; else goto <D.19317>;
  <D.19316>:
  now = mono_msec_ticks ();
  if (now < then) goto <D.19318>; else goto <D.19319>;
  <D.19318>:
  D.19320 = now - then;
  now = D.19320 - 1;
  then = 0;
  <D.19319>:
  delta = now - then;
  if (delta >= ms) goto <D.19321>; else goto <D.19322>;
  <D.19321>:
  ms = 0;
  goto <D.19323>;
  <D.19322>:
  ms = ms - delta;
  <D.19323>:
  if (ret == 258) goto <D.19324>; else goto <D.19326>;
  <D.19326>:
  if (ret == 192) goto <D.19327>; else goto <D.19325>;
  <D.19327>:
  if (allow_interruption == 0) goto <D.19324>; else goto <D.19325>;
  <D.19324>:
  if (ms != 0) goto retry_contended; else goto <D.19328>;
  <D.19328>:
  <D.19325>:
  goto <D.19329>;
  <D.19317>:
  if (ret == 258) goto <D.19330>; else goto <D.19332>;
  <D.19332>:
  if (ret == 192) goto <D.19333>; else goto <D.19331>;
  <D.19333>:
  if (allow_interruption == 0) goto <D.19330>; else goto <D.19331>;
  <D.19330>:
  if (ret == 192) goto <D.19334>; else goto <D.19335>;
  <D.19334>:
  D.19336 = mono_thread_internal_current ();
  D.19337 = mono_thread_test_state (D.19336, 3);
  if (D.19337 != 0) goto <D.19338>; else goto <D.19339>;
  <D.19338>:
  mono_profiler_monitor_event (obj, 3);
  D.19147 = -1;
  return D.19147;
  <D.19339>:
  <D.19335>:
  goto retry_contended;
  <D.19331>:
  <D.19329>:
  if (ret == 0) goto retry_contended; else goto <D.19340>;
  <D.19340>:
  mono_profiler_monitor_event (obj, 3);
  if (ret == 192) goto <D.19341>; else goto <D.19342>;
  <D.19341>:
  D.19147 = -1;
  return D.19147;
  <D.19342>:
  D.19147 = 0;
  return D.19147;
}


mon_new (gsize id)
{
  struct MonoThreadsSync * monitor_freelist.7;
  void * D.19353;
  struct GSList * D.19356;
  void * D.19359;
  struct GSList * D.19360;
  void * * D.19361;
  int D.19362;
  int array_size.8;
  long unsigned int D.19367;
  long unsigned int D.19368;
  long unsigned int D.19369;
  int array_size.9;
  int D.19371;
  struct MonoThreadsSync * D.19372;
  int D.19373;
  struct MonoThreadsSync * monitor_freelist.10;
  struct MonitorArray * monitor_allocated.11;
  struct MonitorArray * D.19379;
  void * monitor_freelist.12;
  struct MonoPerfCounters * mono_perfcounters.13;
  unsigned int D.19382;
  unsigned int D.19383;
  struct MonoThreadsSync * D.19384;
  struct MonoThreadsSync * new;

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

    new = 0B;
    marray = monitor_allocated;
    goto <D.18853>;
    <D.18852>:
    i = 0;
    goto <D.18849>;
    <D.18848>:
    D.19353 = marray->monitors[i].data;
    if (D.19353 == 0B) goto <D.19354>; else goto <D.19355>;
    <D.19354>:
    new = &marray->monitors[i];
    D.19356 = new->wait_list;
    if (D.19356 != 0B) goto <D.19357>; else goto <D.19358>;
    <D.19357>:
    goto <D.18846>;
    <D.18845>:
    D.19356 = new->wait_list;
    D.19359 = D.19356->data;
    CloseHandle (D.19359);
    D.19356 = new->wait_list;
    D.19356 = new->wait_list;
    D.19359 = D.19356->data;
    D.19360 = monoeg_g_slist_remove (D.19356, D.19359);
    new->wait_list = D.19360;
    <D.18846>:
    D.19356 = new->wait_list;
    if (D.19356 != 0B) goto <D.18845>; else goto <D.18847>;
    <D.18847>:
    <D.19358>:
    D.19361 = &new->data;
    mono_gc_weak_link_remove (D.19361, 0);
    monitor_freelist.7 = monitor_freelist;
    new->data = monitor_freelist.7;
    monitor_freelist = new;
    <D.19355>:
    i = i + 1;
    <D.18849>:
    D.19362 = marray->num_monitors;
    if (D.19362 > i) goto <D.18848>; else goto <D.18850>;
    <D.18850>:
    if (new != 0B) goto <D.18851>; else goto <D.19363>;
    <D.19363>:
    marray = marray->next;
    <D.18853>:
    if (marray != 0B) goto <D.18852>; else goto <D.18851>;
    <D.18851>:
    monitor_freelist.7 = monitor_freelist;
    if (monitor_freelist.7 == 0B) goto <D.19364>; else goto <D.19365>;
    <D.19364>:
    {
      struct MonitorArray * last;

      array_size.8 = array_size;
      D.19367 = (long unsigned int) array_size.8;
      D.19368 = D.19367 * 48;
      D.19369 = D.19368 + 32;
      marray = monoeg_malloc0 (D.19369);
      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.18856>;
      <D.18855>:
      D.19371 = i + 1;
      D.19372 = &marray->monitors[D.19371];
      marray->monitors[i].data = D.19372;
      i = i + 1;
      <D.18856>:
      D.19362 = marray->num_monitors;
      D.19373 = D.19362 + -1;
      if (D.19373 > i) goto <D.18855>; else goto <D.18857>;
      <D.18857>:
      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.19376>; else goto <D.19377>;
      <D.19376>:
      monitor_allocated = marray;
      goto <D.19378>;
      <D.19377>:
      last = monitor_allocated;
      goto <D.18859>;
      <D.18858>:
      last = last->next;
      <D.18859>:
      D.19379 = last->next;
      if (D.19379 != 0B) goto <D.18858>; else goto <D.18860>;
      <D.18860>:
      last->next = marray;
      <D.19378>:
    }
    <D.19365>:
  }
  <D.19352>:
  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.19382 = mono_perfcounters.13->gc_sync_blocks;
  D.19383 = D.19382 + 1;
  mono_perfcounters.13->gc_sync_blocks = D.19383;
  D.19384 = new;
  return D.19384;
}


mon_finalize (struct MonoThreadsSync * mon)
{
  void * D.19386;
  struct GSList * D.19389;
  _Bool D.19390;
  long int D.19391;
  long int D.19392;
  struct MonoThreadsSync * monitor_freelist.14;
  struct MonoPerfCounters * mono_perfcounters.15;
  unsigned int D.19397;
  unsigned int D.19398;

  D.19386 = mon->entry_sem;
  if (D.19386 != 0B) goto <D.19387>; else goto <D.19388>;
  <D.19387>:
  D.19386 = mon->entry_sem;
  CloseHandle (D.19386);
  mon->entry_sem = 0B;
  <D.19388>:
  D.19389 = mon->wait_list;
  D.19390 = D.19389 != 0B;
  D.19391 = (long int) D.19390;
  D.19392 = __builtin_expect (D.19391, 0);
  if (D.19392 != 0) goto <D.19393>; else goto <D.19394>;
  <D.19393>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 239, "mon->wait_list == NULL");
  <D.19394>:
  mon->entry_count = 0;
  monitor_freelist.14 = monitor_freelist;
  mon->data = monitor_freelist.14;
  monitor_freelist = mon;
  mono_perfcounters.15 = mono_perfcounters;
  D.19397 = mono_perfcounters.15->gc_sync_blocks;
  D.19398 = D.19397 + 4294967295;
  mono_perfcounters.15->gc_sync_blocks = D.19398;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.19399;
  unsigned int D.19400;

  D.19400 = __sync_add_and_fetch_4 (val, 1);
  D.19399 = (gint32) D.19400;
  return D.19399;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.19402;
  unsigned int D.19403;

  D.19403 = __sync_sub_and_fetch_4 (val, 1);
  D.19402 = (gint32) D.19403;
  return D.19402;
}


mono_monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  mono_bool D.19405;
  int D.19406;
  _Bool D.19407;

  D.19406 = mono_monitor_try_enter_internal (obj, ms, 0);
  D.19407 = D.19406 == 1;
  D.19405 = (mono_bool) D.19407;
  return D.19405;
}


mono_monitor_exit (struct MonoObject * obj)
{
  _Bool D.19409;
  long int D.19410;
  long int D.19411;
  struct MonoException * D.19414;
  long unsigned int D.19415;
  long unsigned int D.19416;
  long unsigned int D.19419;
  _Bool D.19420;
  long int D.19421;
  long int D.19422;
  long unsigned int D.19425;
  long unsigned int tls_pthread_self.16;
  _Bool D.19427;
  long int D.19428;
  long int D.19429;
  unsigned int D.19432;
  int D.19435;
  void * D.19438;
  struct MonoThreadsSync * mon;
  guint32 nest;

  D.19409 = obj == 0B;
  D.19410 = (long int) D.19409;
  D.19411 = __builtin_expect (D.19410, 0);
  if (D.19411 != 0) goto <D.19412>; else goto <D.19413>;
  <D.19412>:
  D.19414 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.19414);
  return;
  <D.19413>:
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.19415 = lw.lock_word;
        D.19416 = D.19415 & 1;
        if (D.19416 != 0) goto <D.19417>; else goto <D.19418>;
        <D.19417>:
        return;
        <D.19418>:
        D.19415 = lw.lock_word;
        D.19419 = D.19415 & 18446744073709551612;
        lw.lock_word = D.19419;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.19420 = mon == 0B;
  D.19421 = (long int) D.19420;
  D.19422 = __builtin_expect (D.19421, 0);
  if (D.19422 != 0) goto <D.19423>; else goto <D.19424>;
  <D.19423>:
  return;
  <D.19424>:
  D.19425 = mon->owner;
  tls_pthread_self.16 = tls_pthread_self;
  D.19427 = D.19425 != tls_pthread_self.16;
  D.19428 = (long int) D.19427;
  D.19429 = __builtin_expect (D.19428, 0);
  if (D.19429 != 0) goto <D.19430>; else goto <D.19431>;
  <D.19430>:
  return;
  <D.19431>:
  D.19432 = mon->nest;
  nest = D.19432 + 4294967295;
  if (nest == 0) goto <D.19433>; else goto <D.19434>;
  <D.19433>:
  mon->owner = 0;
  D.19435 = mon->entry_count;
  if (D.19435 > 0) goto <D.19436>; else goto <D.19437>;
  <D.19436>:
  D.19438 = mon->entry_sem;
  ReleaseSemaphore (D.19438, 1, 0B);
  <D.19437>:
  goto <D.19439>;
  <D.19434>:
  mon->nest = nest;
  <D.19439>:
}


mono_monitor_get_object_monitor_weak_link (struct MonoObject * object)
{
  struct MonoThreadsSync * D.19443;
  long unsigned int D.19444;
  long unsigned int D.19445;
  long unsigned int D.19448;
  long unsigned int D.19450;
  void * D.19455;
  void * * D.19458;
  union LockWord lw;
  struct MonoThreadsSync * sync;

  try
    {
      sync = 0B;
      D.19443 = object->synchronisation;
      lw.sync = D.19443;
      D.19444 = lw.lock_word;
      D.19445 = D.19444 & 2;
      if (D.19445 != 0) goto <D.19446>; else goto <D.19447>;
      <D.19446>:
      D.19444 = lw.lock_word;
      D.19448 = D.19444 & 18446744073709551612;
      lw.lock_word = D.19448;
      sync = lw.sync;
      goto <D.19449>;
      <D.19447>:
      D.19444 = lw.lock_word;
      D.19450 = D.19444 & 1;
      if (D.19450 == 0) goto <D.19451>; else goto <D.19452>;
      <D.19451>:
      sync = lw.sync;
      <D.19452>:
      <D.19449>:
      if (sync != 0B) goto <D.19453>; else goto <D.19454>;
      <D.19453>:
      D.19455 = sync->data;
      if (D.19455 != 0B) goto <D.19456>; else goto <D.19457>;
      <D.19456>:
      D.19458 = &sync->data;
      return D.19458;
      <D.19457>:
      <D.19454>:
      D.19458 = 0B;
      return D.19458;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


mono_monitor_is_il_fastpath_wrapper (struct MonoMethod * method)
{
  struct MonoMethod * D.19461;
  gboolean D.19464;
  int i;

  i = 0;
  goto <D.18938>;
  <D.18937>:
  D.19461 = monitor_il_fastpaths[i];
  if (D.19461 == method) goto <D.19462>; else goto <D.19463>;
  <D.19462>:
  D.19464 = 1;
  return D.19464;
  <D.19463>:
  i = i + 1;
  <D.18938>:
  if (i <= 2) goto <D.18937>; else goto <D.18939>;
  <D.18939>:
  D.19464 = 0;
  return D.19464;
}


mono_monitor_get_fast_path (struct MonoMethod * enter_or_exit)
{
  int D.18995;
  int iftmp.17;
  int D.18994;
  const char[6] * D.19469;
  unsigned char D.19470;
  int D.19471;
  unsigned char D.19472;
  int D.19473;
  const unsigned char * D.19478;
  unsigned char D.19479;
  int D.19480;
  const unsigned char * D.19481;
  unsigned char D.19482;
  int D.19483;
  const unsigned char * D.19488;
  unsigned char D.19489;
  int D.19490;
  const unsigned char * D.19491;
  unsigned char D.19492;
  int D.19493;
  const unsigned char * D.19498;
  unsigned char D.19499;
  int D.19500;
  const unsigned char * D.19501;
  unsigned char D.19502;
  int D.19503;
  const char * D.19505;
  struct MonoMethod * D.19508;
  int D.19004;
  int iftmp.18;
  int D.19003;
  const char[5] * D.19512;
  unsigned char D.19513;
  int D.19514;
  unsigned char D.19515;
  int D.19516;
  const unsigned char * D.19521;
  unsigned char D.19522;
  int D.19523;
  const unsigned char * D.19524;
  unsigned char D.19525;
  int D.19526;
  const unsigned char * D.19531;
  unsigned char D.19532;
  int D.19533;
  const unsigned char * D.19534;
  unsigned char D.19535;
  int D.19536;
  const unsigned char * D.19541;
  unsigned char D.19542;
  int D.19543;
  const unsigned char * D.19544;
  unsigned char D.19545;
  int D.19546;

  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = enter_or_exit->name;
      D.19469 = "Enter";
      D.19470 = MEM[(const unsigned char *)D.19469];
      D.19471 = (int) D.19470;
      D.19472 = *__s2;
      D.19473 = (int) D.19472;
      __result = D.19471 - D.19473;
      {
        if (__s2_len != 0) goto <D.19474>; else goto <D.19475>;
        <D.19474>:
        if (__result == 0) goto <D.19476>; else goto <D.19477>;
        <D.19476>:
        D.19478 = &MEM[(void *)"Enter" + 1B];
        D.19479 = *D.19478;
        D.19480 = (int) D.19479;
        D.19481 = __s2 + 1;
        D.19482 = *D.19481;
        D.19483 = (int) D.19482;
        __result = D.19480 - D.19483;
        if (__s2_len > 1) goto <D.19484>; else goto <D.19485>;
        <D.19484>:
        if (__result == 0) goto <D.19486>; else goto <D.19487>;
        <D.19486>:
        D.19488 = &MEM[(void *)"Enter" + 2B];
        D.19489 = *D.19488;
        D.19490 = (int) D.19489;
        D.19491 = __s2 + 2;
        D.19492 = *D.19491;
        D.19493 = (int) D.19492;
        __result = D.19490 - D.19493;
        if (__s2_len > 2) goto <D.19494>; else goto <D.19495>;
        <D.19494>:
        if (__result == 0) goto <D.19496>; else goto <D.19497>;
        <D.19496>:
        D.19498 = &MEM[(void *)"Enter" + 3B];
        D.19499 = *D.19498;
        D.19500 = (int) D.19499;
        D.19501 = __s2 + 3;
        D.19502 = *D.19501;
        D.19503 = (int) D.19502;
        __result = D.19500 - D.19503;
        <D.19497>:
        <D.19495>:
        <D.19487>:
        <D.19485>:
        <D.19477>:
        <D.19475>:
      }
      D.18994 = __result;
    }
    iftmp.17 = -D.18994;
    goto <D.19504>;
    <D.19468>:
    D.19505 = enter_or_exit->name;
    iftmp.17 = __builtin_strcmp (D.19505, "Enter");
    <D.19504>:
    D.18995 = iftmp.17;
  }
  if (D.18995 == 0) goto <D.19506>; else goto <D.19507>;
  <D.19506>:
  D.19508 = mono_monitor_get_fast_enter_method (enter_or_exit);
  return D.19508;
  <D.19507>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = enter_or_exit->name;
      D.19512 = "Exit";
      D.19513 = MEM[(const unsigned char *)D.19512];
      D.19514 = (int) D.19513;
      D.19515 = *__s2;
      D.19516 = (int) D.19515;
      __result = D.19514 - D.19516;
      {
        if (__s2_len != 0) goto <D.19517>; else goto <D.19518>;
        <D.19517>:
        if (__result == 0) goto <D.19519>; else goto <D.19520>;
        <D.19519>:
        D.19521 = &MEM[(void *)"Exit" + 1B];
        D.19522 = *D.19521;
        D.19523 = (int) D.19522;
        D.19524 = __s2 + 1;
        D.19525 = *D.19524;
        D.19526 = (int) D.19525;
        __result = D.19523 - D.19526;
        if (__s2_len > 1) goto <D.19527>; else goto <D.19528>;
        <D.19527>:
        if (__result == 0) goto <D.19529>; else goto <D.19530>;
        <D.19529>:
        D.19531 = &MEM[(void *)"Exit" + 2B];
        D.19532 = *D.19531;
        D.19533 = (int) D.19532;
        D.19534 = __s2 + 2;
        D.19535 = *D.19534;
        D.19536 = (int) D.19535;
        __result = D.19533 - D.19536;
        if (__s2_len > 2) goto <D.19537>; else goto <D.19538>;
        <D.19537>:
        if (__result == 0) goto <D.19539>; else goto <D.19540>;
        <D.19539>:
        D.19541 = &MEM[(void *)"Exit" + 3B];
        D.19542 = *D.19541;
        D.19543 = (int) D.19542;
        D.19544 = __s2 + 3;
        D.19545 = *D.19544;
        D.19546 = (int) D.19545;
        __result = D.19543 - D.19546;
        <D.19540>:
        <D.19538>:
        <D.19530>:
        <D.19528>:
        <D.19520>:
        <D.19518>:
      }
      D.19003 = __result;
    }
    iftmp.18 = -D.19003;
    goto <D.19547>;
    <D.19511>:
    D.19505 = enter_or_exit->name;
    iftmp.18 = __builtin_strcmp (D.19505, "Exit");
    <D.19547>:
    D.19004 = iftmp.18;
  }
  if (D.19004 == 0) goto <D.19548>; else goto <D.19549>;
  <D.19548>:
  D.19508 = mono_monitor_get_fast_exit_method (enter_or_exit);
  return D.19508;
  <D.19549>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "monitor.c", 1227);
  D.19508 = 0B;
  return D.19508;
}


mono_monitor_get_fast_enter_method (struct MonoMethod * monitor_enter_method)
{
  struct MonoMethodSignature * D.19551;
  short unsigned int D.19552;
  _Bool D.19553;
  _Bool D.19554;
  _Bool D.19555;
  long int D.19556;
  long int D.19557;
  struct MonoMethod * D.19562;
  struct MonoMethod * D.19563;
  struct MonoMethod * compare_exchange_method.19;
  struct MonoImage * D.19569;
  struct MonoMethod * compare_exchange_method.20;
  struct MonoClass * D.19573;
  const char * iftmp.21;
  struct MonoMethod * D.19578;
  struct MonoClass * D.19579;
  struct MonoType * D.19580;
  int * iftmp.22;
  unsigned int tid_loc.23;
  unsigned int syncp_loc.24;
  unsigned int owner_loc.25;
  unsigned int D.19588;
  unsigned int D.19589;
  unsigned int tid_branch.26;
  unsigned int D.19593;
  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.19612;
  struct MonoMethod * D.19613;
  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.19551 = mono_method_signature (monitor_enter_method);
      D.19552 = D.19551->param_count;
      D.19553 = D.19552 == 2;
      is_v4 = (gboolean) D.19553;
      D.19554 = is_v4 != 0;
      fast_path_idx = (int) D.19554;
      D.19555 = is_v4 == 0;
      D.19556 = (long int) D.19555;
      D.19557 = __builtin_expect (D.19556, 0);
      if (D.19557 != 0) goto <D.19558>; else goto <D.19559>;
      <D.19558>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 898, "is_v4");
      <D.19559>:
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.19560>; else goto <D.19561>;
      <D.19560>:
      D.19562 = 0B;
      return D.19562;
      <D.19561>:
      D.19563 = monitor_il_fastpaths[fast_path_idx];
      if (D.19563 != 0B) goto <D.19564>; else goto <D.19565>;
      <D.19564>:
      D.19562 = monitor_il_fastpaths[fast_path_idx];
      return D.19562;
      <D.19565>:
      compare_exchange_method.19 = compare_exchange_method;
      if (compare_exchange_method.19 == 0B) goto <D.19567>; else goto <D.19568>;
      <D.19567>:
      {
        struct MonoMethodDesc * desc;
        struct MonoClass * class;

        desc = mono_method_desc_new ("Interlocked:CompareExchange(intptr&,intptr,intptr)", 0);
        D.19569 = mono_defaults.corlib;
        class = mono_class_from_name (D.19569, "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.19571>; else goto <D.19572>;
        <D.19571>:
        D.19562 = 0B;
        return D.19562;
        <D.19572>:
      }
      <D.19568>:
      D.19573 = mono_defaults.monitor_class;
      if (is_v4 != 0) goto <D.19575>; else goto <D.19576>;
      <D.19575>:
      iftmp.21 = "FastMonitorEnterV4";
      goto <D.19577>;
      <D.19576>:
      iftmp.21 = "FastMonitorEnter";
      <D.19577>:
      mb = mono_mb_new (D.19573, iftmp.21, 25);
      D.19578 = mb->method;
      D.19578->slot = -1;
      D.19578 = mb->method;
      D.19578->flags = 182;
      D.19579 = mono_defaults.int_class;
      D.19580 = &D.19579->byval_arg;
      tid_loc = mono_mb_add_local (mb, D.19580);
      D.19579 = mono_defaults.int_class;
      D.19580 = &D.19579->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.19580);
      D.19579 = mono_defaults.int_class;
      D.19580 = &D.19579->byval_arg;
      owner_loc = mono_mb_add_local (mb, D.19580);
      if (is_v4 != 0) goto <D.19582>; else goto <D.19583>;
      <D.19582>:
      iftmp.22 = &true_locktaken_branch;
      goto <D.19584>;
      <D.19583>:
      iftmp.22 = 0B;
      <D.19584>:
      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.19588 = mono_mb_emit_short_branch (mb, 45);
      tid_branch = (int) D.19588;
      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.19589 = mono_mb_emit_short_branch (mb, 45);
      has_owner_branch = (int) D.19589;
      if (is_v4 != 0) goto <D.19590>; else goto <D.19591>;
      <D.19590>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.19591>:
      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.19593 = mono_mb_emit_short_branch (mb, 51);
      other_owner_branch = (int) D.19593;
      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.19594>; else goto <D.19595>;
      <D.19594>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.19595>:
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.27 = thin_hash_branch;
      if (thin_hash_branch.27 != 0) goto <D.19597>; else goto <D.19598>;
      <D.19597>:
      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.19598>:
      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.19607>; else goto <D.19608>;
      <D.19607>:
      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.19608>:
      mono_mb_emit_byte (mb, 2);
      if (is_v4 != 0) goto <D.19610>; else goto <D.19611>;
      <D.19610>:
      mono_mb_emit_byte (mb, 3);
      <D.19611>:
      mono_mb_emit_managed_call (mb, monitor_enter_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.19612 = mono_signature_no_pinvoke (monitor_enter_method);
      D.19613 = mono_mb_create_method (mb, D.19612, 5);
      res = register_fastpath (D.19613, fast_path_idx);
      D.19569 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.19569, 24);
      if (is_v4 != 0) goto <D.19615>; else goto <D.19616>;
      <D.19615>:
      iftmp.37 = 5;
      goto <D.19617>;
      <D.19616>:
      iftmp.37 = 4;
      <D.19617>:
      info->subtype = iftmp.37;
      mono_marshal_set_wrapper_info (res, info);
      mono_mb_free (mb);
      D.19562 = res;
      return D.19562;
    }
  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.19620;
  int D.19621;
  unsigned int D.19624;
  int D.19625;
  unsigned int syncp_loc.38;
  int D.19627;
  unsigned int D.19630;
  int D.19631;
  guint8 iftmp.39;
  unsigned int D.19637;
  int D.19638;

  mono_mb_emit_byte (mb, 2);
  D.19620 = mono_mb_emit_short_branch (mb, 44);
  D.19621 = (int) D.19620;
  *obj_null_branch = D.19621;
  if (true_locktaken_branch != 0B) goto <D.19622>; else goto <D.19623>;
  <D.19622>:
  mono_mb_emit_byte (mb, 3);
  mono_mb_emit_byte (mb, 70);
  D.19624 = mono_mb_emit_short_branch (mb, 45);
  D.19625 = (int) D.19624;
  *true_locktaken_branch = D.19625;
  <D.19623>:
  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.19627 = mono_gc_is_moving ();
  if (D.19627 != 0) goto <D.19628>; else goto <D.19629>;
  <D.19628>:
  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.19630 = mono_mb_emit_short_branch (mb, 45);
  D.19631 = (int) D.19630;
  *thin_hash_branch = D.19631;
  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.19632>;
  <D.19629>:
  *thin_hash_branch = 0;
  <D.19632>:
  syncp_loc.38 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.38);
  if (branch_on_true != 0) goto <D.19634>; else goto <D.19635>;
  <D.19634>:
  iftmp.39 = 45;
  goto <D.19636>;
  <D.19635>:
  iftmp.39 = 44;
  <D.19636>:
  D.19637 = mono_mb_emit_short_branch (mb, iftmp.39);
  D.19638 = (int) D.19637;
  *syncp_true_false_branch = D.19638;
}


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

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


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_monitor_get_fast_exit_method (struct MonoMethod * monitor_exit_method)
{
  struct MonoMethod * D.19643;
  struct MonoMethod * D.19644;
  struct MonoClass * D.19647;
  struct MonoMethod * D.19648;
  struct MonoClass * D.19649;
  struct MonoType * D.19650;
  int has_syncp_branch.40;
  unsigned int has_syncp_branch.41;
  unsigned int syncp_loc.42;
  unsigned int D.19654;
  unsigned int owned_branch.43;
  unsigned int D.19656;
  unsigned int D.19657;
  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.19666;
  struct MonoMethod * D.19667;
  struct MonoImage * D.19668;
  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.19641>; else goto <D.19642>;
      <D.19641>:
      D.19643 = 0B;
      return D.19643;
      <D.19642>:
      D.19644 = monitor_il_fastpaths[2];
      if (D.19644 != 0B) goto <D.19645>; else goto <D.19646>;
      <D.19645>:
      D.19643 = monitor_il_fastpaths[2];
      return D.19643;
      <D.19646>:
      D.19647 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.19647, "FastMonitorExit", 25);
      D.19648 = mb->method;
      D.19648->slot = -1;
      D.19648 = mb->method;
      D.19648->flags = 182;
      D.19649 = mono_defaults.int_class;
      D.19650 = &D.19649->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.19650);
      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.19654 = mono_mb_emit_short_branch (mb, 46);
      owned_branch = (int) D.19654;
      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.19656 = mono_mb_emit_short_branch (mb, 53);
      nested_branch = (int) D.19656;
      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.19657 = mono_mb_emit_short_branch (mb, 45);
      has_waiting_branch = (int) D.19657;
      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.19660>; else goto <D.19661>;
      <D.19660>:
      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.19661>:
      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.19666 = mono_signature_no_pinvoke (monitor_exit_method);
      D.19667 = mono_mb_create_method (mb, D.19666, 5);
      res = register_fastpath (D.19667, 2);
      mono_mb_free (mb);
      D.19668 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.19668, 24);
      info->subtype = 6;
      mono_marshal_set_wrapper_info (res, info);
      D.19643 = res;
      return D.19643;
    }
  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.19673;
  _Bool D.19674;
  gint32 res;

  <D.19016>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.19671>; else goto <D.19672>;
  <D.19671>:
  mono_thread_interruption_checkpoint ();
  <D.19672>:
  if (res == -1) goto <D.19016>; else goto <D.19017>;
  <D.19017>:
  D.19674 = res == 1;
  D.19673 = (gboolean) D.19674;
  return D.19673;
}


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

  <D.19024>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.19676>; else goto <D.19677>;
  <D.19676>:
  mono_thread_interruption_checkpoint ();
  <D.19677>:
  if (res == -1) goto <D.19024>; else goto <D.19025>;
  <D.19025>:
  D.19678 = res == 1;
  D.19679 = (char) D.19678;
  *lockTaken = D.19679;
}


ves_icall_System_Threading_Monitor_Monitor_test_owner (struct MonoObject * obj)
{
  long unsigned int D.19680;
  long unsigned int D.19681;
  gboolean D.19684;
  long unsigned int D.19685;
  long unsigned int D.19688;
  long unsigned int tls_pthread_self.50;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.19680 = lw.lock_word;
        D.19681 = D.19680 & 1;
        if (D.19681 != 0) goto <D.19682>; else goto <D.19683>;
        <D.19682>:
        D.19684 = 0;
        return D.19684;
        <D.19683>:
        D.19680 = lw.lock_word;
        D.19685 = D.19680 & 18446744073709551612;
        lw.lock_word = D.19685;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19686>; else goto <D.19687>;
  <D.19686>:
  D.19684 = 0;
  return D.19684;
  <D.19687>:
  D.19688 = mon->owner;
  tls_pthread_self.50 = tls_pthread_self;
  if (D.19688 == tls_pthread_self.50) goto <D.19690>; else goto <D.19691>;
  <D.19690>:
  D.19684 = 1;
  return D.19684;
  <D.19691>:
  D.19684 = 0;
  return D.19684;
}


ves_icall_System_Threading_Monitor_Monitor_test_synchronised (struct MonoObject * obj)
{
  long unsigned int D.19695;
  long unsigned int D.19696;
  gboolean D.19699;
  long unsigned int D.19700;
  long unsigned int D.19703;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.19695 = lw.lock_word;
        D.19696 = D.19695 & 1;
        if (D.19696 != 0) goto <D.19697>; else goto <D.19698>;
        <D.19697>:
        D.19699 = 0;
        return D.19699;
        <D.19698>:
        D.19695 = lw.lock_word;
        D.19700 = D.19695 & 18446744073709551612;
        lw.lock_word = D.19700;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19701>; else goto <D.19702>;
  <D.19701>:
  D.19699 = 0;
  return D.19699;
  <D.19702>:
  D.19703 = mon->owner;
  if (D.19703 != 0) goto <D.19704>; else goto <D.19705>;
  <D.19704>:
  D.19699 = 1;
  return D.19699;
  <D.19705>:
  D.19699 = 0;
  return D.19699;
}


ves_icall_System_Threading_Monitor_Monitor_pulse (struct MonoObject * obj)
{
  long unsigned int D.19709;
  long unsigned int D.19710;
  struct MonoException * D.19713;
  long unsigned int D.19714;
  struct MonoException * D.19717;
  long unsigned int D.19718;
  long unsigned int tls_pthread_self.51;
  struct MonoException * D.19722;
  struct GSList * D.19723;
  void * D.19726;
  struct GSList * D.19727;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.19709 = lw.lock_word;
        D.19710 = D.19709 & 1;
        if (D.19710 != 0) goto <D.19711>; else goto <D.19712>;
        <D.19711>:
        D.19713 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19713);
        return;
        <D.19712>:
        D.19709 = lw.lock_word;
        D.19714 = D.19709 & 18446744073709551612;
        lw.lock_word = D.19714;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19715>; else goto <D.19716>;
  <D.19715>:
  D.19717 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19717);
  return;
  <D.19716>:
  D.19718 = mon->owner;
  tls_pthread_self.51 = tls_pthread_self;
  if (D.19718 != tls_pthread_self.51) goto <D.19720>; else goto <D.19721>;
  <D.19720>:
  D.19722 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19722);
  return;
  <D.19721>:
  D.19723 = mon->wait_list;
  if (D.19723 != 0B) goto <D.19724>; else goto <D.19725>;
  <D.19724>:
  D.19723 = mon->wait_list;
  D.19726 = D.19723->data;
  SetEvent (D.19726);
  D.19723 = mon->wait_list;
  D.19723 = mon->wait_list;
  D.19726 = D.19723->data;
  D.19727 = monoeg_g_slist_remove (D.19723, D.19726);
  mon->wait_list = D.19727;
  <D.19725>:
}


ves_icall_System_Threading_Monitor_Monitor_pulse_all (struct MonoObject * obj)
{
  long unsigned int D.19731;
  long unsigned int D.19732;
  struct MonoException * D.19735;
  long unsigned int D.19736;
  struct MonoException * D.19739;
  long unsigned int D.19740;
  long unsigned int tls_pthread_self.52;
  struct MonoException * D.19744;
  struct GSList * D.19745;
  void * D.19746;
  struct GSList * D.19747;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.19731 = lw.lock_word;
        D.19732 = D.19731 & 1;
        if (D.19732 != 0) goto <D.19733>; else goto <D.19734>;
        <D.19733>:
        D.19735 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19735);
        return;
        <D.19734>:
        D.19731 = lw.lock_word;
        D.19736 = D.19731 & 18446744073709551612;
        lw.lock_word = D.19736;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19737>; else goto <D.19738>;
  <D.19737>:
  D.19739 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19739);
  return;
  <D.19738>:
  D.19740 = mon->owner;
  tls_pthread_self.52 = tls_pthread_self;
  if (D.19740 != tls_pthread_self.52) goto <D.19742>; else goto <D.19743>;
  <D.19742>:
  D.19744 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19744);
  return;
  <D.19743>:
  goto <D.19047>;
  <D.19046>:
  D.19745 = mon->wait_list;
  D.19746 = D.19745->data;
  SetEvent (D.19746);
  D.19745 = mon->wait_list;
  D.19745 = mon->wait_list;
  D.19746 = D.19745->data;
  D.19747 = monoeg_g_slist_remove (D.19745, D.19746);
  mon->wait_list = D.19747;
  <D.19047>:
  D.19745 = mon->wait_list;
  if (D.19745 != 0B) goto <D.19046>; else goto <D.19048>;
  <D.19048>:
}


ves_icall_System_Threading_Monitor_Monitor_wait (struct MonoObject * obj, guint32 ms)
{
  long unsigned int D.19751;
  long unsigned int D.19752;
  struct MonoException * D.19755;
  gboolean D.19756;
  long unsigned int D.19757;
  struct MonoException * D.19760;
  long unsigned int D.19761;
  long unsigned int tls_pthread_self.53;
  struct MonoException * D.19765;
  struct MonoException * D.19768;
  struct GSList * D.19769;
  struct GSList * D.19770;
  int D.19771;
  struct MonoException * D.19778;
  struct GSList * D.19784;
  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.19751 = lw.lock_word;
        D.19752 = D.19751 & 1;
        if (D.19752 != 0) goto <D.19753>; else goto <D.19754>;
        <D.19753>:
        D.19755 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.19755);
        D.19756 = 0;
        return D.19756;
        <D.19754>:
        D.19751 = lw.lock_word;
        D.19757 = D.19751 & 18446744073709551612;
        lw.lock_word = D.19757;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.19758>; else goto <D.19759>;
  <D.19758>:
  D.19760 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.19760);
  D.19756 = 0;
  return D.19756;
  <D.19759>:
  D.19761 = mon->owner;
  tls_pthread_self.53 = tls_pthread_self;
  if (D.19761 != tls_pthread_self.53) goto <D.19763>; else goto <D.19764>;
  <D.19763>:
  D.19765 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.19765);
  D.19756 = 0;
  return D.19756;
  <D.19764>:
  mono_thread_current_check_pending_interrupt ();
  event = CreateEvent (0B, 0, 0, 0B);
  if (event == 0B) goto <D.19766>; else goto <D.19767>;
  <D.19766>:
  D.19768 = mono_get_exception_synchronization_lock ("Failed to set up wait event");
  mono_raise_exception (D.19768);
  D.19756 = 0;
  return D.19756;
  <D.19767>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.19769 = mon->wait_list;
  D.19770 = monoeg_g_slist_append (D.19769, event);
  mon->wait_list = D.19770;
  nest = mon->nest;
  mon->nest = 1;
  mono_monitor_exit (obj);
  ret = WaitForSingleObjectEx (event, ms, 1);
  mono_thread_clr_state (thread, 32);
  D.19771 = mono_thread_interruption_requested ();
  if (D.19771 != 0) goto <D.19772>; else goto <D.19773>;
  <D.19772>:
  D.19756 = 0;
  return D.19756;
  <D.19773>:
  <D.19061>:
  regain = mono_monitor_try_enter_internal (obj, 4294967295, 1);
  if (regain == -1) goto <D.19774>; else goto <D.19775>;
  <D.19774>:
  mono_thread_interruption_checkpoint ();
  <D.19775>:
  if (regain == -1) goto <D.19061>; else goto <D.19062>;
  <D.19062>:
  if (regain == 0) goto <D.19776>; else goto <D.19777>;
  <D.19776>:
  CloseHandle (event);
  D.19778 = mono_get_exception_synchronization_lock ("Failed to regain lock");
  mono_raise_exception (D.19778);
  D.19756 = 0;
  return D.19756;
  <D.19777>:
  mon->nest = nest;
  if (ret == 258) goto <D.19779>; else goto <D.19780>;
  <D.19779>:
  ret = WaitForSingleObjectEx (event, 0, 0);
  <D.19780>:
  if (ret == 0) goto <D.19781>; else goto <D.19782>;
  <D.19781>:
  success = 1;
  goto <D.19783>;
  <D.19782>:
  D.19769 = mon->wait_list;
  D.19784 = monoeg_g_slist_remove (D.19769, event);
  mon->wait_list = D.19784;
  <D.19783>:
  CloseHandle (event);
  D.19756 = success;
  return D.19756;
}


