mono_monitor_init ()
{
  InitializeCriticalSection (&monitor_mutex);
}


mono_monitor_cleanup ()
{
  struct MonoThreadsSync * mon;

  mon = monitor_freelist;
  goto <D.17909>;
  <D.17908>:
  mon->wait_list = 4294967295B;
  mon = mon->data;
  <D.17909>:
  if (mon != 0B) goto <D.17908>; else goto <D.17910>;
  <D.17910>:
}


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.18171;
  void * D.18172;
  int D.18175;
  int D.18179;
  void * * D.18182;
  unsigned int D.18183;
  unsigned int D.18186;
  void * D.18187;
  void * D.18188;
  int D.18191;
  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.17933>;
  <D.17932>:
  on_freelist = on_freelist + 1;
  mon = mon->data;
  <D.17933>:
  if (mon != 0B) goto <D.17932>; else goto <D.17934>;
  <D.17934>:
  marray = monitor_allocated;
  goto <D.17940>;
  <D.17939>:
  D.18171 = marray->num_monitors;
  total = D.18171 + total;
  num_arrays = num_arrays + 1;
  i = 0;
  goto <D.17937>;
  <D.17936>:
  mon = &marray->monitors[i];
  D.18172 = mon->data;
  if (D.18172 == 0B) goto <D.18173>; else goto <D.18174>;
  <D.18173>:
  D.18171 = marray->num_monitors;
  D.18175 = D.18171 + -1;
  if (D.18175 > i) goto <D.18176>; else goto <D.18177>;
  <D.18176>:
  to_recycle = to_recycle + 1;
  <D.18177>:
  goto <D.18178>;
  <D.18174>:
  D.18172 = mon->data;
  D.18179 = monitor_is_on_freelist (D.18172);
  if (D.18179 == 0) goto <D.18180>; else goto <D.18181>;
  <D.18180>:
  {
    struct MonoObject * holder;

    D.18182 = &mon->data;
    holder = mono_gc_weak_link_get (D.18182);
    D.18183 = mon->owner;
    if (D.18183 != 0) goto <D.18184>; else goto <D.18185>;
    <D.18184>:
    D.18186 = mon->nest;
    D.18183 = mon->owner;
    D.18187 = (void *) D.18183;
    monoeg_g_print ("Lock %p in object %p held by thread %p, nest level: %d\n", mon, holder, D.18187, D.18186);
    D.18188 = mon->entry_sem;
    if (D.18188 != 0B) goto <D.18189>; else goto <D.18190>;
    <D.18189>:
    D.18191 = mon->entry_count;
    D.18188 = mon->entry_sem;
    monoeg_g_print ("\tWaiting on semaphore %p: %d\n", D.18188, D.18191);
    <D.18190>:
    goto <D.18192>;
    <D.18185>:
    if (include_untaken != 0) goto <D.18193>; else goto <D.18194>;
    <D.18193>:
    monoeg_g_print ("Lock %p in object %p untaken\n", mon, holder);
    <D.18194>:
    <D.18192>:
    used = used + 1;
  }
  <D.18181>:
  <D.18178>:
  i = i + 1;
  <D.17937>:
  D.18171 = marray->num_monitors;
  if (D.18171 > i) goto <D.17936>; else goto <D.17938>;
  <D.17938>:
  marray = marray->next;
  <D.17940>:
  if (marray != 0B) goto <D.17939>; else goto <D.17941>;
  <D.17941>:
  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.18195;
  int D.18198;
  struct MonoThreadsSync * D.18199;
  int D.18202;
  struct MonitorArray * marray;

  marray = monitor_allocated;
  goto <D.17919>;
  <D.17918>:
  D.18195 = &marray->monitors;
  if (D.18195 <= mon) goto <D.18196>; else goto <D.18197>;
  <D.18196>:
  D.18198 = marray->num_monitors;
  D.18199 = &marray->monitors[D.18198];
  if (D.18199 > mon) goto <D.18200>; else goto <D.18201>;
  <D.18200>:
  D.18202 = 1;
  return D.18202;
  <D.18201>:
  <D.18197>:
  marray = marray->next;
  <D.17919>:
  if (marray != 0B) goto <D.17918>; else goto <D.17920>;
  <D.17920>:
  D.18202 = 0;
  return D.18202;
}


mono_object_hash (struct MonoObject * obj)
{
  int D.18206;
  struct MonoThreadsSync * D.18207;
  unsigned int D.18208;
  unsigned int D.18209;
  unsigned int D.18212;
  unsigned int D.18213;
  unsigned int D.18216;
  struct MonoThreadsSync * D.18217;
  unsigned int obj.1;
  unsigned int D.18219;
  int hash.2;
  unsigned int D.18223;
  unsigned int D.18225;
  unsigned int D.18226;
  struct MonoThreadsSync * * D.18227;
  void * D.18228;
  union LockWord lw;
  unsigned int hash;

  try
    {
      if (obj == 0B) goto <D.18204>; else goto <D.18205>;
      <D.18204>:
      D.18206 = 0;
      return D.18206;
      <D.18205>:
      D.18207 = obj->synchronisation;
      lw.sync = D.18207;
      D.18208 = lw.lock_word;
      D.18209 = D.18208 & 1;
      if (D.18209 != 0) goto <D.18210>; else goto <D.18211>;
      <D.18210>:
      D.18208 = lw.lock_word;
      D.18212 = D.18208 >> 2;
      D.18206 = (int) D.18212;
      return D.18206;
      <D.18211>:
      D.18208 = lw.lock_word;
      D.18213 = D.18208 & 2;
      if (D.18213 != 0) goto <D.18214>; else goto <D.18215>;
      <D.18214>:
      D.18208 = lw.lock_word;
      D.18216 = D.18208 & 4294967292;
      lw.lock_word = D.18216;
      D.18217 = lw.sync;
      D.18206 = D.18217->hash_code;
      return D.18206;
      <D.18215>:
      obj.1 = (unsigned int) obj;
      D.18219 = obj.1 >> 3;
      hash = D.18219 * 2654435761;
      hash = hash & 1073741823;
      D.18217 = lw.sync;
      if (D.18217 != 0B) goto <D.18220>; else goto <D.18221>;
      <D.18220>:
      D.18217 = lw.sync;
      hash.2 = (int) hash;
      D.18217->hash_code = hash.2;
      D.18208 = lw.lock_word;
      D.18223 = D.18208 | 2;
      lw.lock_word = D.18223;
      D.18217 = lw.sync;
      obj->synchronisation = D.18217;
      goto <D.18224>;
      <D.18221>:
      D.18225 = hash << 2;
      D.18226 = D.18225 | 1;
      lw.lock_word = D.18226;
      D.18217 = lw.sync;
      D.18227 = &obj->synchronisation;
      D.18228 = InterlockedCompareExchangePointer (D.18227, D.18217, 0B);
      if (D.18228 == 0B) goto <D.18229>; else goto <D.18230>;
      <D.18229>:
      D.18206 = (int) hash;
      return D.18206;
      <D.18230>:
      D.18207 = obj->synchronisation;
      lw.sync = D.18207;
      D.18208 = lw.lock_word;
      D.18209 = D.18208 & 1;
      if (D.18209 != 0) goto <D.18231>; else goto <D.18232>;
      <D.18231>:
      D.18206 = (int) hash;
      return D.18206;
      <D.18232>:
      D.18208 = lw.lock_word;
      D.18216 = D.18208 & 4294967292;
      lw.lock_word = D.18216;
      D.18217 = lw.sync;
      hash.2 = (int) hash;
      D.18217->hash_code = hash.2;
      D.18208 = lw.lock_word;
      D.18223 = D.18208 | 2;
      lw.lock_word = D.18223;
      D.18217 = lw.sync;
      obj->synchronisation = D.18217;
      <D.18224>:
      D.18206 = (int) hash;
      return D.18206;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.18235;
  unsigned int exch.3;
  unsigned int comp.4;
  unsigned int D.18238;

  exch.3 = (unsigned int) exch;
  comp.4 = (unsigned int) comp;
  D.18238 = __sync_val_compare_and_swap_4 (dest, comp.4, exch.3);
  D.18235 = (void *) D.18238;
  return D.18235;
}


mono_monitor_enter (struct MonoObject * obj)
{
  mono_bool D.18240;
  int D.18241;
  _Bool D.18242;

  D.18241 = mono_monitor_try_enter_internal (obj, 4294967295, 0);
  D.18242 = D.18241 == 1;
  D.18240 = (mono_bool) D.18242;
  return D.18240;
}


mono_monitor_try_enter_internal (struct MonoObject * obj, guint32 ms, gboolean allow_interruption)
{
  _Bool D.18244;
  long int D.18245;
  long int D.18246;
  struct MonoException * D.18249;
  gint32 D.18250;
  _Bool D.18251;
  long int D.18252;
  long int D.18253;
  _Bool D.18258;
  long int D.18259;
  long int D.18260;
  struct MonoThreadsSync * * D.18263;
  void * D.18264;
  void * * D.18267;
  _Bool D.18270;
  long int D.18271;
  long int D.18272;
  struct MonoThreadsSync * D.18275;
  unsigned int D.18276;
  unsigned int D.18277;
  unsigned int D.18280;
  int D.18281;
  unsigned int D.18282;
  struct MonoThreadsSync * D.18283;
  void * D.18284;
  _Bool D.18289;
  long int D.18290;
  long int D.18291;
  _Bool D.18296;
  long int D.18297;
  long int D.18298;
  unsigned int D.18301;
  _Bool D.18306;
  long int D.18307;
  long int D.18308;
  unsigned int D.18311;
  _Bool D.18315;
  long int D.18316;
  long int D.18317;
  unsigned int D.18321;
  unsigned int D.18322;
  _Bool D.18327;
  long int D.18328;
  long int D.18329;
  unsigned int D.18332;
  int D.18333;
  unsigned int D.18334;
  struct MonoThreadsSync * D.18335;
  void * D.18336;
  _Bool D.18341;
  long int D.18342;
  long int D.18343;
  _Bool D.18348;
  long int D.18349;
  long int D.18350;
  unsigned int D.18353;
  unsigned int D.18354;
  unsigned int D.18355;
  _Bool D.18356;
  long int D.18357;
  long int D.18358;
  void * id.5;
  gsize * D.18362;
  void * D.18363;
  _Bool D.18364;
  long int D.18365;
  long int D.18366;
  unsigned int D.18368;
  _Bool D.18369;
  long int D.18370;
  long int D.18371;
  unsigned int D.18376;
  struct MonoPerfCounters * mono_perfcounters.6;
  unsigned int D.18378;
  unsigned int D.18379;
  void * D.18384;
  _Bool D.18385;
  long int D.18386;
  long int D.18387;
  void * D.18394;
  _Bool D.18397;
  long int D.18398;
  long int D.18399;
  void * * D.18402;
  void * D.18403;
  volatile gint32 * D.18412;
  unsigned int D.18413;
  unsigned int D.18414;
  unsigned int D.18415;
  unsigned int D.18416;
  volatile gint32 * D.18417;
  unsigned int D.18418;
  unsigned int D.18423;
  _Bool D.18430;
  _Bool D.18431;
  _Bool D.18432;
  struct MonoInternalThread * D.18440;
  int D.18441;
  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.18244 = obj == 0B;
  D.18245 = (long int) D.18244;
  D.18246 = __builtin_expect (D.18245, 0);
  if (D.18246 != 0) goto <D.18247>; else goto <D.18248>;
  <D.18247>:
  D.18249 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18249);
  D.18250 = 0;
  return D.18250;
  <D.18248>:
  retry:
  mon = obj->synchronisation;
  D.18251 = mon == 0B;
  D.18252 = (long int) D.18251;
  D.18253 = __builtin_expect (D.18252, 0);
  if (D.18253 != 0) goto <D.18254>; else goto <D.18255>;
  <D.18254>:
  {
    int ret;

    ret = pthread_mutex_lock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.18256>; else goto <D.18257>;
    <D.18256>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.18257>:
    D.18258 = ret != 0;
    D.18259 = (long int) D.18258;
    D.18260 = __builtin_expect (D.18259, 0);
    if (D.18260 != 0) goto <D.18261>; else goto <D.18262>;
    <D.18261>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 439, "ret == 0");
    <D.18262>:
  }
  mon = mon_new (id);
  D.18263 = &obj->synchronisation;
  D.18264 = InterlockedCompareExchangePointer (D.18263, mon, 0B);
  if (D.18264 == 0B) goto <D.18265>; else goto <D.18266>;
  <D.18265>:
  D.18267 = &mon->data;
  mono_gc_weak_link_add (D.18267, obj, 0);
  {
    int ret;

    ret = pthread_mutex_unlock (&monitor_mutex.mutex);
    if (ret != 0) goto <D.18268>; else goto <D.18269>;
    <D.18268>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.18269>:
    D.18270 = ret != 0;
    D.18271 = (long int) D.18270;
    D.18272 = __builtin_expect (D.18271, 0);
    if (D.18272 != 0) goto <D.18273>; else goto <D.18274>;
    <D.18273>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 443, "ret == 0");
    <D.18274>:
  }
  D.18250 = 1;
  return D.18250;
  <D.18266>:
  {
    union LockWord lw;

    try
      {
        D.18275 = obj->synchronisation;
        lw.sync = D.18275;
        D.18276 = lw.lock_word;
        D.18277 = D.18276 & 1;
        if (D.18277 != 0) goto <D.18278>; else goto <D.18279>;
        <D.18278>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          D.18276 = lw.lock_word;
          D.18280 = D.18276 >> 2;
          D.18281 = (int) D.18280;
          mon->hash_code = D.18281;
          lw.sync = mon;
          D.18276 = lw.lock_word;
          D.18282 = D.18276 | 2;
          lw.lock_word = D.18282;
          D.18283 = lw.sync;
          D.18263 = &obj->synchronisation;
          D.18284 = InterlockedCompareExchangePointer (D.18263, D.18283, oldlw);
          if (D.18284 == oldlw) goto <D.18285>; else goto <D.18286>;
          <D.18285>:
          D.18267 = &mon->data;
          mono_gc_weak_link_add (D.18267, obj, 0);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18287>; else goto <D.18288>;
            <D.18287>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18288>:
            D.18289 = ret != 0;
            D.18290 = (long int) D.18289;
            D.18291 = __builtin_expect (D.18290, 0);
            if (D.18291 != 0) goto <D.18292>; else goto <D.18293>;
            <D.18292>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 458, "ret == 0");
            <D.18293>:
          }
          D.18250 = 1;
          return D.18250;
          <D.18286>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18294>; else goto <D.18295>;
            <D.18294>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18295>:
            D.18296 = ret != 0;
            D.18297 = (long int) D.18296;
            D.18298 = __builtin_expect (D.18297, 0);
            if (D.18298 != 0) goto <D.18299>; else goto <D.18300>;
            <D.18299>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 463, "ret == 0");
            <D.18300>:
          }
          goto retry;
        }
        <D.18279>:
        D.18276 = lw.lock_word;
        D.18301 = D.18276 & 2;
        if (D.18301 != 0) goto <D.18302>; else goto <D.18303>;
        <D.18302>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.18304>; else goto <D.18305>;
          <D.18304>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.18305>:
          D.18306 = ret != 0;
          D.18307 = (long int) D.18306;
          D.18308 = __builtin_expect (D.18307, 0);
          if (D.18308 != 0) goto <D.18309>; else goto <D.18310>;
          <D.18309>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 468, "ret == 0");
          <D.18310>:
        }
        D.18276 = lw.lock_word;
        D.18311 = D.18276 & 4294967292;
        lw.lock_word = D.18311;
        mon = lw.sync;
        goto <D.18312>;
        <D.18303>:
        mon_finalize (mon);
        {
          int ret;

          ret = pthread_mutex_unlock (&monitor_mutex.mutex);
          if (ret != 0) goto <D.18313>; else goto <D.18314>;
          <D.18313>:
          monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
          <D.18314>:
          D.18315 = ret != 0;
          D.18316 = (long int) D.18315;
          D.18317 = __builtin_expect (D.18316, 0);
          if (D.18317 != 0) goto <D.18318>; else goto <D.18319>;
          <D.18318>:
          monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 474, "ret == 0");
          <D.18319>:
        }
        mon = obj->synchronisation;
        <D.18312>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  goto <D.18320>;
  <D.18255>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18321 = lw.lock_word;
        D.18322 = D.18321 & 1;
        if (D.18322 != 0) goto <D.18323>; else goto <D.18324>;
        <D.18323>:
        {
          struct MonoThreadsSync * oldlw;

          oldlw = lw.sync;
          {
            int ret;

            ret = pthread_mutex_lock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18325>; else goto <D.18326>;
            <D.18325>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
            <D.18326>:
            D.18327 = ret != 0;
            D.18328 = (long int) D.18327;
            D.18329 = __builtin_expect (D.18328, 0);
            if (D.18329 != 0) goto <D.18330>; else goto <D.18331>;
            <D.18330>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 489, "ret == 0");
            <D.18331>:
          }
          mon = mon_new (id);
          D.18321 = lw.lock_word;
          D.18332 = D.18321 >> 2;
          D.18333 = (int) D.18332;
          mon->hash_code = D.18333;
          lw.sync = mon;
          D.18321 = lw.lock_word;
          D.18334 = D.18321 | 2;
          lw.lock_word = D.18334;
          D.18335 = lw.sync;
          D.18263 = &obj->synchronisation;
          D.18336 = InterlockedCompareExchangePointer (D.18263, D.18335, oldlw);
          if (D.18336 == oldlw) goto <D.18337>; else goto <D.18338>;
          <D.18337>:
          D.18267 = &mon->data;
          mono_gc_weak_link_add (D.18267, obj, 1);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18339>; else goto <D.18340>;
            <D.18339>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18340>:
            D.18341 = ret != 0;
            D.18342 = (long int) D.18341;
            D.18343 = __builtin_expect (D.18342, 0);
            if (D.18343 != 0) goto <D.18344>; else goto <D.18345>;
            <D.18344>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 497, "ret == 0");
            <D.18345>:
          }
          D.18250 = 1;
          return D.18250;
          <D.18338>:
          mon_finalize (mon);
          {
            int ret;

            ret = pthread_mutex_unlock (&monitor_mutex.mutex);
            if (ret != 0) goto <D.18346>; else goto <D.18347>;
            <D.18346>:
            monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
            <D.18347>:
            D.18348 = ret != 0;
            D.18349 = (long int) D.18348;
            D.18350 = __builtin_expect (D.18349, 0);
            if (D.18350 != 0) goto <D.18351>; else goto <D.18352>;
            <D.18351>:
            monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 502, "ret == 0");
            <D.18352>:
          }
          goto retry;
        }
        <D.18324>:
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  <D.18320>:
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18353 = lw.lock_word;
        D.18354 = D.18353 & 4294967292;
        lw.lock_word = D.18354;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.18355 = mon->owner;
  D.18356 = D.18355 == 0;
  D.18357 = (long int) D.18356;
  D.18358 = __builtin_expect (D.18357, 1);
  if (D.18358 != 0) goto <D.18359>; else goto <D.18360>;
  <D.18359>:
  id.5 = (void *) id;
  D.18362 = &mon->owner;
  D.18363 = InterlockedCompareExchangePointer (D.18362, id.5, 0B);
  D.18364 = D.18363 == 0B;
  D.18365 = (long int) D.18364;
  D.18366 = __builtin_expect (D.18365, 1);
  if (D.18366 != 0) goto <D.18367>; else goto retry;
  <D.18367>:
  D.18368 = mon->nest;
  D.18369 = D.18368 != 1;
  D.18370 = (long int) D.18369;
  D.18371 = __builtin_expect (D.18370, 0);
  if (D.18371 != 0) goto <D.18372>; else goto <D.18373>;
  <D.18372>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 530, "mon->nest == 1");
  <D.18373>:
  D.18250 = 1;
  return D.18250;
  <D.18360>:
  D.18355 = mon->owner;
  if (D.18355 == id) goto <D.18374>; else goto <D.18375>;
  <D.18374>:
  D.18368 = mon->nest;
  D.18376 = D.18368 + 1;
  mon->nest = D.18376;
  D.18250 = 1;
  return D.18250;
  <D.18375>:
  mono_perfcounters.6 = mono_perfcounters;
  D.18378 = mono_perfcounters.6->thread_contentions;
  D.18379 = D.18378 + 1;
  mono_perfcounters.6->thread_contentions = D.18379;
  if (ms == 0) goto <D.18380>; else goto <D.18381>;
  <D.18380>:
  D.18250 = 0;
  return D.18250;
  <D.18381>:
  mono_profiler_monitor_event (obj, 1);
  retry_contended:
  D.18355 = mon->owner;
  D.18356 = D.18355 == 0;
  D.18357 = (long int) D.18356;
  D.18358 = __builtin_expect (D.18357, 1);
  if (D.18358 != 0) goto <D.18382>; else goto <D.18383>;
  <D.18382>:
  id.5 = (void *) id;
  D.18362 = &mon->owner;
  D.18384 = InterlockedCompareExchangePointer (D.18362, id.5, 0B);
  D.18385 = D.18384 == 0B;
  D.18386 = (long int) D.18385;
  D.18387 = __builtin_expect (D.18386, 1);
  if (D.18387 != 0) goto <D.18388>; else goto <D.18389>;
  <D.18388>:
  D.18368 = mon->nest;
  D.18369 = D.18368 != 1;
  D.18370 = (long int) D.18369;
  D.18371 = __builtin_expect (D.18370, 0);
  if (D.18371 != 0) goto <D.18390>; else goto <D.18391>;
  <D.18390>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 574, "mon->nest == 1");
  <D.18391>:
  mono_profiler_monitor_event (obj, 2);
  D.18250 = 1;
  return D.18250;
  <D.18389>:
  <D.18383>:
  D.18355 = mon->owner;
  if (D.18355 == id) goto <D.18392>; else goto <D.18393>;
  <D.18392>:
  D.18368 = mon->nest;
  D.18376 = D.18368 + 1;
  mon->nest = D.18376;
  mono_profiler_monitor_event (obj, 2);
  D.18250 = 1;
  return D.18250;
  <D.18393>:
  D.18394 = mon->entry_sem;
  if (D.18394 == 0B) goto <D.18395>; else goto <D.18396>;
  <D.18395>:
  sem = CreateSemaphore (0B, 0, 2147483647, 0B);
  D.18397 = sem == 0B;
  D.18398 = (long int) D.18397;
  D.18399 = __builtin_expect (D.18398, 0);
  if (D.18399 != 0) goto <D.18400>; else goto <D.18401>;
  <D.18400>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 593, "sem != NULL");
  <D.18401>:
  D.18402 = &mon->entry_sem;
  D.18403 = InterlockedCompareExchangePointer (D.18402, sem, 0B);
  if (D.18403 != 0B) goto <D.18404>; else goto <D.18405>;
  <D.18404>:
  CloseHandle (sem);
  <D.18405>:
  <D.18396>:
  if (ms != 4294967295) goto <D.18406>; else goto <D.18407>;
  <D.18406>:
  then = mono_msec_ticks ();
  if (ms <= 99) goto <D.18408>; else goto <D.18409>;
  <D.18408>:
  waitms = ms;
  goto <D.18410>;
  <D.18409>:
  waitms = 100;
  <D.18410>:
  goto <D.18411>;
  <D.18407>:
  waitms = 100;
  <D.18411>:
  D.18412 = &mon->entry_count;
  InterlockedIncrement (D.18412);
  mono_perfcounters.6 = mono_perfcounters;
  D.18413 = mono_perfcounters.6->thread_queue_len;
  D.18414 = D.18413 + 1;
  mono_perfcounters.6->thread_queue_len = D.18414;
  mono_perfcounters.6 = mono_perfcounters;
  D.18415 = mono_perfcounters.6->thread_queue_max;
  D.18416 = D.18415 + 1;
  mono_perfcounters.6->thread_queue_max = D.18416;
  thread = mono_thread_internal_current ();
  mono_thread_set_state (thread, 32);
  D.18394 = mon->entry_sem;
  ret = WaitForSingleObjectEx (D.18394, waitms, 1);
  mono_thread_clr_state (thread, 32);
  D.18417 = &mon->entry_count;
  InterlockedDecrement (D.18417);
  mono_perfcounters.6 = mono_perfcounters;
  D.18413 = mono_perfcounters.6->thread_queue_len;
  D.18418 = D.18413 + 4294967295;
  mono_perfcounters.6->thread_queue_len = D.18418;
  if (ms != 4294967295) goto <D.18419>; else goto <D.18420>;
  <D.18419>:
  now = mono_msec_ticks ();
  if (now < then) goto <D.18421>; else goto <D.18422>;
  <D.18421>:
  D.18423 = now - then;
  now = D.18423 - 1;
  then = 0;
  <D.18422>:
  delta = now - then;
  if (delta >= ms) goto <D.18424>; else goto <D.18425>;
  <D.18424>:
  ms = 0;
  goto <D.18426>;
  <D.18425>:
  ms = ms - delta;
  <D.18426>:
  if (ret == 258) goto <D.18427>; else goto <D.18429>;
  <D.18429>:
  D.18430 = ret == 192;
  D.18431 = allow_interruption == 0;
  D.18432 = D.18430 & D.18431;
  if (D.18432 != 0) goto <D.18427>; else goto <D.18428>;
  <D.18427>:
  if (ms != 0) goto retry_contended; else goto <D.18433>;
  <D.18433>:
  <D.18428>:
  goto <D.18434>;
  <D.18420>:
  if (ret == 258) goto <D.18435>; else goto <D.18437>;
  <D.18437>:
  D.18430 = ret == 192;
  D.18431 = allow_interruption == 0;
  D.18432 = D.18430 & D.18431;
  if (D.18432 != 0) goto <D.18435>; else goto <D.18436>;
  <D.18435>:
  if (ret == 192) goto <D.18438>; else goto <D.18439>;
  <D.18438>:
  D.18440 = mono_thread_internal_current ();
  D.18441 = mono_thread_test_state (D.18440, 3);
  if (D.18441 != 0) goto <D.18442>; else goto <D.18443>;
  <D.18442>:
  mono_profiler_monitor_event (obj, 3);
  D.18250 = -1;
  return D.18250;
  <D.18443>:
  <D.18439>:
  goto retry_contended;
  <D.18436>:
  <D.18434>:
  if (ret == 0) goto retry_contended; else goto <D.18444>;
  <D.18444>:
  mono_profiler_monitor_event (obj, 3);
  if (ret == 192) goto <D.18445>; else goto <D.18446>;
  <D.18445>:
  D.18250 = -1;
  return D.18250;
  <D.18446>:
  D.18250 = 0;
  return D.18250;
}


mon_new (gsize id)
{
  struct MonoThreadsSync * monitor_freelist.7;
  void * D.18457;
  struct GSList * D.18460;
  void * D.18463;
  struct GSList * D.18464;
  void * * D.18465;
  int D.18466;
  int array_size.8;
  unsigned int array_size.9;
  unsigned int D.18472;
  unsigned int D.18473;
  int array_size.10;
  int D.18475;
  struct MonoThreadsSync * D.18476;
  int D.18477;
  struct MonoThreadsSync * monitor_freelist.11;
  struct MonitorArray * monitor_allocated.12;
  struct MonitorArray * D.18483;
  void * monitor_freelist.13;
  struct MonoPerfCounters * mono_perfcounters.14;
  unsigned int D.18486;
  unsigned int D.18487;
  struct MonoThreadsSync * D.18488;
  struct MonoThreadsSync * new;

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

    new = 0B;
    marray = monitor_allocated;
    goto <D.17959>;
    <D.17958>:
    i = 0;
    goto <D.17955>;
    <D.17954>:
    D.18457 = marray->monitors[i].data;
    if (D.18457 == 0B) goto <D.18458>; else goto <D.18459>;
    <D.18458>:
    new = &marray->monitors[i];
    D.18460 = new->wait_list;
    if (D.18460 != 0B) goto <D.18461>; else goto <D.18462>;
    <D.18461>:
    goto <D.17952>;
    <D.17951>:
    D.18460 = new->wait_list;
    D.18463 = D.18460->data;
    CloseHandle (D.18463);
    D.18460 = new->wait_list;
    D.18463 = D.18460->data;
    D.18460 = new->wait_list;
    D.18464 = monoeg_g_slist_remove (D.18460, D.18463);
    new->wait_list = D.18464;
    <D.17952>:
    D.18460 = new->wait_list;
    if (D.18460 != 0B) goto <D.17951>; else goto <D.17953>;
    <D.17953>:
    <D.18462>:
    D.18465 = &new->data;
    mono_gc_weak_link_remove (D.18465, 0);
    monitor_freelist.7 = monitor_freelist;
    new->data = monitor_freelist.7;
    monitor_freelist = new;
    <D.18459>:
    i = i + 1;
    <D.17955>:
    D.18466 = marray->num_monitors;
    if (D.18466 > i) goto <D.17954>; else goto <D.17956>;
    <D.17956>:
    if (new != 0B) goto <D.17957>; else goto <D.18467>;
    <D.18467>:
    marray = marray->next;
    <D.17959>:
    if (marray != 0B) goto <D.17958>; else goto <D.17957>;
    <D.17957>:
    monitor_freelist.7 = monitor_freelist;
    if (monitor_freelist.7 == 0B) goto <D.18468>; else goto <D.18469>;
    <D.18468>:
    {
      struct MonitorArray * last;

      array_size.8 = array_size;
      array_size.9 = (unsigned int) array_size.8;
      D.18472 = array_size.9 * 28;
      D.18473 = D.18472 + 16;
      marray = monoeg_malloc0 (D.18473);
      array_size.8 = array_size;
      marray->num_monitors = array_size.8;
      array_size.8 = array_size;
      array_size.10 = array_size.8 * 2;
      array_size = array_size.10;
      i = 0;
      goto <D.17962>;
      <D.17961>:
      D.18475 = i + 1;
      D.18476 = &marray->monitors[D.18475];
      marray->monitors[i].data = D.18476;
      i = i + 1;
      <D.17962>:
      D.18466 = marray->num_monitors;
      D.18477 = D.18466 + -1;
      if (D.18477 > i) goto <D.17961>; else goto <D.17963>;
      <D.17963>:
      marray->monitors[i].data = 0B;
      monitor_freelist.11 = &marray->monitors[0];
      monitor_freelist = monitor_freelist.11;
      monitor_allocated.12 = monitor_allocated;
      if (monitor_allocated.12 == 0B) goto <D.18480>; else goto <D.18481>;
      <D.18480>:
      monitor_allocated = marray;
      goto <D.18482>;
      <D.18481>:
      last = monitor_allocated;
      goto <D.17965>;
      <D.17964>:
      last = last->next;
      <D.17965>:
      D.18483 = last->next;
      if (D.18483 != 0B) goto <D.17964>; else goto <D.17966>;
      <D.17966>:
      last->next = marray;
      <D.18482>:
    }
    <D.18469>:
  }
  <D.18456>:
  new = monitor_freelist;
  monitor_freelist.13 = new->data;
  monitor_freelist = monitor_freelist.13;
  new->owner = id;
  new->nest = 1;
  new->data = 0B;
  mono_perfcounters.14 = mono_perfcounters;
  D.18486 = mono_perfcounters.14->gc_sync_blocks;
  D.18487 = D.18486 + 1;
  mono_perfcounters.14->gc_sync_blocks = D.18487;
  D.18488 = new;
  return D.18488;
}


mon_finalize (struct MonoThreadsSync * mon)
{
  void * D.18490;
  struct GSList * D.18493;
  _Bool D.18494;
  long int D.18495;
  long int D.18496;
  struct MonoThreadsSync * monitor_freelist.15;
  struct MonoPerfCounters * mono_perfcounters.16;
  unsigned int D.18501;
  unsigned int D.18502;

  D.18490 = mon->entry_sem;
  if (D.18490 != 0B) goto <D.18491>; else goto <D.18492>;
  <D.18491>:
  D.18490 = mon->entry_sem;
  CloseHandle (D.18490);
  mon->entry_sem = 0B;
  <D.18492>:
  D.18493 = mon->wait_list;
  D.18494 = D.18493 != 0B;
  D.18495 = (long int) D.18494;
  D.18496 = __builtin_expect (D.18495, 0);
  if (D.18496 != 0) goto <D.18497>; else goto <D.18498>;
  <D.18497>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 239, "mon->wait_list == NULL");
  <D.18498>:
  mon->entry_count = 0;
  monitor_freelist.15 = monitor_freelist;
  mon->data = monitor_freelist.15;
  monitor_freelist = mon;
  mono_perfcounters.16 = mono_perfcounters;
  D.18501 = mono_perfcounters.16->gc_sync_blocks;
  D.18502 = D.18501 + 4294967295;
  mono_perfcounters.16->gc_sync_blocks = D.18502;
}


InterlockedIncrement (volatile gint32 * val)
{
  gint32 D.18503;
  unsigned int D.18504;

  D.18504 = __sync_add_and_fetch_4 (val, 1);
  D.18503 = (gint32) D.18504;
  return D.18503;
}


InterlockedDecrement (volatile gint32 * val)
{
  gint32 D.18506;
  unsigned int D.18507;

  D.18507 = __sync_sub_and_fetch_4 (val, 1);
  D.18506 = (gint32) D.18507;
  return D.18506;
}


mono_monitor_try_enter (struct MonoObject * obj, guint32 ms)
{
  mono_bool D.18509;
  int D.18510;
  _Bool D.18511;

  D.18510 = mono_monitor_try_enter_internal (obj, ms, 0);
  D.18511 = D.18510 == 1;
  D.18509 = (mono_bool) D.18511;
  return D.18509;
}


mono_monitor_exit (struct MonoObject * obj)
{
  _Bool D.18513;
  long int D.18514;
  long int D.18515;
  struct MonoException * D.18518;
  unsigned int D.18519;
  unsigned int D.18520;
  unsigned int D.18523;
  _Bool D.18524;
  long int D.18525;
  long int D.18526;
  unsigned int D.18529;
  unsigned int tls_pthread_self.17;
  _Bool D.18531;
  long int D.18532;
  long int D.18533;
  unsigned int D.18536;
  int D.18539;
  void * D.18542;
  struct MonoThreadsSync * mon;
  guint32 nest;

  D.18513 = obj == 0B;
  D.18514 = (long int) D.18513;
  D.18515 = __builtin_expect (D.18514, 0);
  if (D.18515 != 0) goto <D.18516>; else goto <D.18517>;
  <D.18516>:
  D.18518 = mono_get_exception_argument_null ("obj");
  mono_raise_exception (D.18518);
  return;
  <D.18517>:
  mon = obj->synchronisation;
  {
    union LockWord lw;

    try
      {
        lw.sync = mon;
        D.18519 = lw.lock_word;
        D.18520 = D.18519 & 1;
        if (D.18520 != 0) goto <D.18521>; else goto <D.18522>;
        <D.18521>:
        return;
        <D.18522>:
        D.18519 = lw.lock_word;
        D.18523 = D.18519 & 4294967292;
        lw.lock_word = D.18523;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  D.18524 = mon == 0B;
  D.18525 = (long int) D.18524;
  D.18526 = __builtin_expect (D.18525, 0);
  if (D.18526 != 0) goto <D.18527>; else goto <D.18528>;
  <D.18527>:
  return;
  <D.18528>:
  D.18529 = mon->owner;
  tls_pthread_self.17 = tls_pthread_self;
  D.18531 = D.18529 != tls_pthread_self.17;
  D.18532 = (long int) D.18531;
  D.18533 = __builtin_expect (D.18532, 0);
  if (D.18533 != 0) goto <D.18534>; else goto <D.18535>;
  <D.18534>:
  return;
  <D.18535>:
  D.18536 = mon->nest;
  nest = D.18536 + 4294967295;
  if (nest == 0) goto <D.18537>; else goto <D.18538>;
  <D.18537>:
  mon->owner = 0;
  D.18539 = mon->entry_count;
  if (D.18539 > 0) goto <D.18540>; else goto <D.18541>;
  <D.18540>:
  D.18542 = mon->entry_sem;
  ReleaseSemaphore (D.18542, 1, 0B);
  <D.18541>:
  goto <D.18543>;
  <D.18538>:
  mon->nest = nest;
  <D.18543>:
}


mono_monitor_get_object_monitor_weak_link (struct MonoObject * object)
{
  struct MonoThreadsSync * D.18547;
  unsigned int D.18548;
  unsigned int D.18549;
  unsigned int D.18552;
  unsigned int D.18554;
  void * D.18559;
  void * * D.18562;
  union LockWord lw;
  struct MonoThreadsSync * sync;

  try
    {
      sync = 0B;
      D.18547 = object->synchronisation;
      lw.sync = D.18547;
      D.18548 = lw.lock_word;
      D.18549 = D.18548 & 2;
      if (D.18549 != 0) goto <D.18550>; else goto <D.18551>;
      <D.18550>:
      D.18548 = lw.lock_word;
      D.18552 = D.18548 & 4294967292;
      lw.lock_word = D.18552;
      sync = lw.sync;
      goto <D.18553>;
      <D.18551>:
      D.18548 = lw.lock_word;
      D.18554 = D.18548 & 1;
      if (D.18554 == 0) goto <D.18555>; else goto <D.18556>;
      <D.18555>:
      sync = lw.sync;
      <D.18556>:
      <D.18553>:
      if (sync != 0B) goto <D.18557>; else goto <D.18558>;
      <D.18557>:
      D.18559 = sync->data;
      if (D.18559 != 0B) goto <D.18560>; else goto <D.18561>;
      <D.18560>:
      D.18562 = &sync->data;
      return D.18562;
      <D.18561>:
      <D.18558>:
      D.18562 = 0B;
      return D.18562;
    }
  finally
    {
      lw = {CLOBBER};
    }
}


mono_monitor_is_il_fastpath_wrapper (struct MonoMethod * method)
{
  struct MonoMethod * D.18565;
  gboolean D.18568;
  int i;

  i = 0;
  goto <D.18044>;
  <D.18043>:
  D.18565 = monitor_il_fastpaths[i];
  if (D.18565 == method) goto <D.18566>; else goto <D.18567>;
  <D.18566>:
  D.18568 = 1;
  return D.18568;
  <D.18567>:
  i = i + 1;
  <D.18044>:
  if (i <= 2) goto <D.18043>; else goto <D.18045>;
  <D.18045>:
  D.18568 = 0;
  return D.18568;
}


mono_monitor_get_fast_path (struct MonoMethod * enter_or_exit)
{
  int D.18101;
  int iftmp.18;
  int D.18100;
  const char[6] * D.18573;
  unsigned char D.18574;
  int D.18575;
  unsigned char D.18576;
  int D.18577;
  _Bool D.18578;
  _Bool D.18579;
  _Bool D.18580;
  const unsigned char * D.18583;
  unsigned char D.18584;
  int D.18585;
  const unsigned char * D.18586;
  unsigned char D.18587;
  int D.18588;
  _Bool D.18589;
  _Bool D.18590;
  const unsigned char * D.18593;
  unsigned char D.18594;
  int D.18595;
  const unsigned char * D.18596;
  unsigned char D.18597;
  int D.18598;
  _Bool D.18599;
  _Bool D.18600;
  const unsigned char * D.18603;
  unsigned char D.18604;
  int D.18605;
  const unsigned char * D.18606;
  unsigned char D.18607;
  int D.18608;
  const char * D.18610;
  struct MonoMethod * D.18613;
  int D.18110;
  int iftmp.19;
  int D.18109;
  const char[5] * D.18617;
  unsigned char D.18618;
  int D.18619;
  unsigned char D.18620;
  int D.18621;
  _Bool D.18622;
  _Bool D.18623;
  _Bool D.18624;
  const unsigned char * D.18627;
  unsigned char D.18628;
  int D.18629;
  const unsigned char * D.18630;
  unsigned char D.18631;
  int D.18632;
  _Bool D.18633;
  _Bool D.18634;
  const unsigned char * D.18637;
  unsigned char D.18638;
  int D.18639;
  const unsigned char * D.18640;
  unsigned char D.18641;
  int D.18642;
  _Bool D.18643;
  _Bool D.18644;
  const unsigned char * D.18647;
  unsigned char D.18648;
  int D.18649;
  const unsigned char * D.18650;
  unsigned char D.18651;
  int D.18652;

  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = enter_or_exit->name;
      D.18573 = "Enter";
      D.18574 = MEM[(const unsigned char *)D.18573];
      D.18575 = (int) D.18574;
      D.18576 = *__s2;
      D.18577 = (int) D.18576;
      __result = D.18575 - D.18577;
      {
        D.18578 = __s2_len != 0;
        D.18579 = __result == 0;
        D.18580 = D.18578 & D.18579;
        if (D.18580 != 0) goto <D.18581>; else goto <D.18582>;
        <D.18581>:
        D.18583 = &MEM[(void *)"Enter" + 1B];
        D.18584 = *D.18583;
        D.18585 = (int) D.18584;
        D.18586 = __s2 + 1;
        D.18587 = *D.18586;
        D.18588 = (int) D.18587;
        __result = D.18585 - D.18588;
        D.18589 = __s2_len > 1;
        D.18579 = __result == 0;
        D.18590 = D.18589 & D.18579;
        if (D.18590 != 0) goto <D.18591>; else goto <D.18592>;
        <D.18591>:
        D.18593 = &MEM[(void *)"Enter" + 2B];
        D.18594 = *D.18593;
        D.18595 = (int) D.18594;
        D.18596 = __s2 + 2;
        D.18597 = *D.18596;
        D.18598 = (int) D.18597;
        __result = D.18595 - D.18598;
        D.18599 = __s2_len > 2;
        D.18579 = __result == 0;
        D.18600 = D.18599 & D.18579;
        if (D.18600 != 0) goto <D.18601>; else goto <D.18602>;
        <D.18601>:
        D.18603 = &MEM[(void *)"Enter" + 3B];
        D.18604 = *D.18603;
        D.18605 = (int) D.18604;
        D.18606 = __s2 + 3;
        D.18607 = *D.18606;
        D.18608 = (int) D.18607;
        __result = D.18605 - D.18608;
        <D.18602>:
        <D.18592>:
        <D.18582>:
      }
      D.18100 = __result;
    }
    iftmp.18 = -D.18100;
    goto <D.18609>;
    <D.18572>:
    D.18610 = enter_or_exit->name;
    iftmp.18 = __builtin_strcmp (D.18610, "Enter");
    <D.18609>:
    D.18101 = iftmp.18;
  }
  if (D.18101 == 0) goto <D.18611>; else goto <D.18612>;
  <D.18611>:
  D.18613 = mono_monitor_get_fast_enter_method (enter_or_exit);
  return D.18613;
  <D.18612>:
  {
    size_t __s1_len;
    size_t __s2_len;

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

      __s2 = enter_or_exit->name;
      D.18617 = "Exit";
      D.18618 = MEM[(const unsigned char *)D.18617];
      D.18619 = (int) D.18618;
      D.18620 = *__s2;
      D.18621 = (int) D.18620;
      __result = D.18619 - D.18621;
      {
        D.18622 = __s2_len != 0;
        D.18623 = __result == 0;
        D.18624 = D.18622 & D.18623;
        if (D.18624 != 0) goto <D.18625>; else goto <D.18626>;
        <D.18625>:
        D.18627 = &MEM[(void *)"Exit" + 1B];
        D.18628 = *D.18627;
        D.18629 = (int) D.18628;
        D.18630 = __s2 + 1;
        D.18631 = *D.18630;
        D.18632 = (int) D.18631;
        __result = D.18629 - D.18632;
        D.18633 = __s2_len > 1;
        D.18623 = __result == 0;
        D.18634 = D.18633 & D.18623;
        if (D.18634 != 0) goto <D.18635>; else goto <D.18636>;
        <D.18635>:
        D.18637 = &MEM[(void *)"Exit" + 2B];
        D.18638 = *D.18637;
        D.18639 = (int) D.18638;
        D.18640 = __s2 + 2;
        D.18641 = *D.18640;
        D.18642 = (int) D.18641;
        __result = D.18639 - D.18642;
        D.18643 = __s2_len > 2;
        D.18623 = __result == 0;
        D.18644 = D.18643 & D.18623;
        if (D.18644 != 0) goto <D.18645>; else goto <D.18646>;
        <D.18645>:
        D.18647 = &MEM[(void *)"Exit" + 3B];
        D.18648 = *D.18647;
        D.18649 = (int) D.18648;
        D.18650 = __s2 + 3;
        D.18651 = *D.18650;
        D.18652 = (int) D.18651;
        __result = D.18649 - D.18652;
        <D.18646>:
        <D.18636>:
        <D.18626>:
      }
      D.18109 = __result;
    }
    iftmp.19 = -D.18109;
    goto <D.18653>;
    <D.18616>:
    D.18610 = enter_or_exit->name;
    iftmp.19 = __builtin_strcmp (D.18610, "Exit");
    <D.18653>:
    D.18110 = iftmp.19;
  }
  if (D.18110 == 0) goto <D.18654>; else goto <D.18655>;
  <D.18654>:
  D.18613 = mono_monitor_get_fast_exit_method (enter_or_exit);
  return D.18613;
  <D.18655>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "monitor.c", 1227);
  D.18613 = 0B;
  return D.18613;
}


mono_monitor_get_fast_enter_method (struct MonoMethod * monitor_enter_method)
{
  struct MonoMethodSignature * D.18657;
  short unsigned int D.18658;
  _Bool D.18659;
  _Bool D.18660;
  _Bool D.18661;
  long int D.18662;
  long int D.18663;
  struct MonoMethod * D.18668;
  struct MonoMethod * D.18669;
  struct MonoMethod * compare_exchange_method.20;
  struct MonoImage * D.18675;
  struct MonoMethod * compare_exchange_method.21;
  const char * iftmp.22;
  struct MonoClass * D.18683;
  struct MonoMethod * D.18684;
  struct MonoClass * D.18685;
  struct MonoType * D.18686;
  int * iftmp.23;
  unsigned int tid_loc.24;
  unsigned int syncp_loc.25;
  unsigned int owner_loc.26;
  unsigned int D.18694;
  unsigned int D.18695;
  unsigned int tid_branch.27;
  unsigned int D.18699;
  int thin_hash_branch.28;
  unsigned int thin_hash_branch.29;
  int obj_null_branch.30;
  unsigned int obj_null_branch.31;
  int syncp_null_branch.32;
  unsigned int syncp_null_branch.33;
  unsigned int has_owner_branch.34;
  unsigned int other_owner_branch.35;
  int true_locktaken_branch.36;
  unsigned int true_locktaken_branch.37;
  struct MonoMethodSignature * D.18718;
  struct MonoMethod * D.18719;
  WrapperSubtype iftmp.38;
  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.18657 = mono_method_signature (monitor_enter_method);
      D.18658 = D.18657->param_count;
      D.18659 = D.18658 == 2;
      is_v4 = (gboolean) D.18659;
      D.18660 = is_v4 != 0;
      fast_path_idx = (int) D.18660;
      D.18661 = is_v4 == 0;
      D.18662 = (long int) D.18661;
      D.18663 = __builtin_expect (D.18662, 0);
      if (D.18663 != 0) goto <D.18664>; else goto <D.18665>;
      <D.18664>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "monitor.c", 898, "is_v4");
      <D.18665>:
      thread_tls_offset = mono_thread_get_tls_offset ();
      if (thread_tls_offset == -1) goto <D.18666>; else goto <D.18667>;
      <D.18666>:
      D.18668 = 0B;
      return D.18668;
      <D.18667>:
      D.18669 = monitor_il_fastpaths[fast_path_idx];
      if (D.18669 != 0B) goto <D.18670>; else goto <D.18671>;
      <D.18670>:
      D.18668 = monitor_il_fastpaths[fast_path_idx];
      return D.18668;
      <D.18671>:
      compare_exchange_method.20 = compare_exchange_method;
      if (compare_exchange_method.20 == 0B) goto <D.18673>; else goto <D.18674>;
      <D.18673>:
      {
        struct MonoMethodDesc * desc;
        struct MonoClass * class;

        desc = mono_method_desc_new ("Interlocked:CompareExchange(intptr&,intptr,intptr)", 0);
        D.18675 = mono_defaults.corlib;
        class = mono_class_from_name (D.18675, "System.Threading", "Interlocked");
        compare_exchange_method.21 = mono_method_desc_search_in_class (desc, class);
        compare_exchange_method = compare_exchange_method.21;
        mono_method_desc_free (desc);
        compare_exchange_method.20 = compare_exchange_method;
        if (compare_exchange_method.20 == 0B) goto <D.18677>; else goto <D.18678>;
        <D.18677>:
        D.18668 = 0B;
        return D.18668;
        <D.18678>:
      }
      <D.18674>:
      if (is_v4 != 0) goto <D.18680>; else goto <D.18681>;
      <D.18680>:
      iftmp.22 = "FastMonitorEnterV4";
      goto <D.18682>;
      <D.18681>:
      iftmp.22 = "FastMonitorEnter";
      <D.18682>:
      D.18683 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.18683, iftmp.22, 25);
      D.18684 = mb->method;
      D.18684->slot = -1;
      D.18684 = mb->method;
      D.18684->flags = 182;
      D.18685 = mono_defaults.int_class;
      D.18686 = &D.18685->byval_arg;
      tid_loc = mono_mb_add_local (mb, D.18686);
      D.18685 = mono_defaults.int_class;
      D.18686 = &D.18685->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.18686);
      D.18685 = mono_defaults.int_class;
      D.18686 = &D.18685->byval_arg;
      owner_loc = mono_mb_add_local (mb, D.18686);
      if (is_v4 != 0) goto <D.18688>; else goto <D.18689>;
      <D.18688>:
      iftmp.23 = &true_locktaken_branch;
      goto <D.18690>;
      <D.18689>:
      iftmp.23 = 0B;
      <D.18690>:
      emit_obj_syncp_check (mb, syncp_loc, &obj_null_branch, iftmp.23, &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, 40);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_stloc (mb, tid_loc.24);
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_stloc (mb, owner_loc.26);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.26);
      D.18694 = mono_mb_emit_short_branch (mb, 45);
      tid_branch = (int) D.18694;
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 0);
      mono_mb_emit_byte (mb, 88);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.24);
      mono_mb_emit_byte (mb, 22);
      compare_exchange_method.20 = compare_exchange_method;
      mono_mb_emit_managed_call (mb, compare_exchange_method.20, 0B);
      D.18695 = mono_mb_emit_short_branch (mb, 45);
      has_owner_branch = (int) D.18695;
      if (is_v4 != 0) goto <D.18696>; else goto <D.18697>;
      <D.18696>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.18697>:
      mono_mb_emit_byte (mb, 42);
      tid_branch.27 = (unsigned int) tid_branch;
      mono_mb_patch_short_branch (mb, tid_branch.27);
      owner_loc.26 = (unsigned int) owner_loc;
      mono_mb_emit_ldloc (mb, owner_loc.26);
      tid_loc.24 = (unsigned int) tid_loc;
      mono_mb_emit_ldloc (mb, tid_loc.24);
      D.18699 = mono_mb_emit_short_branch (mb, 51);
      other_owner_branch = (int) D.18699;
      syncp_loc.25 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.25);
      mono_mb_emit_icon (mb, 4);
      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.18700>; else goto <D.18701>;
      <D.18700>:
      mono_mb_emit_byte (mb, 3);
      mono_mb_emit_byte (mb, 23);
      mono_mb_emit_byte (mb, 82);
      <D.18701>:
      mono_mb_emit_byte (mb, 42);
      thin_hash_branch.28 = thin_hash_branch;
      if (thin_hash_branch.28 != 0) goto <D.18703>; else goto <D.18704>;
      <D.18703>:
      thin_hash_branch.28 = thin_hash_branch;
      thin_hash_branch.29 = (unsigned int) thin_hash_branch.28;
      mono_mb_patch_short_branch (mb, thin_hash_branch.29);
      <D.18704>:
      obj_null_branch.30 = obj_null_branch;
      obj_null_branch.31 = (unsigned int) obj_null_branch.30;
      mono_mb_patch_short_branch (mb, obj_null_branch.31);
      syncp_null_branch.32 = syncp_null_branch;
      syncp_null_branch.33 = (unsigned int) syncp_null_branch.32;
      mono_mb_patch_short_branch (mb, syncp_null_branch.33);
      has_owner_branch.34 = (unsigned int) has_owner_branch;
      mono_mb_patch_short_branch (mb, has_owner_branch.34);
      other_owner_branch.35 = (unsigned int) other_owner_branch;
      mono_mb_patch_short_branch (mb, other_owner_branch.35);
      true_locktaken_branch.36 = true_locktaken_branch;
      if (true_locktaken_branch.36 != 0) goto <D.18713>; else goto <D.18714>;
      <D.18713>:
      true_locktaken_branch.36 = true_locktaken_branch;
      true_locktaken_branch.37 = (unsigned int) true_locktaken_branch.36;
      mono_mb_patch_short_branch (mb, true_locktaken_branch.37);
      <D.18714>:
      mono_mb_emit_byte (mb, 2);
      if (is_v4 != 0) goto <D.18716>; else goto <D.18717>;
      <D.18716>:
      mono_mb_emit_byte (mb, 3);
      <D.18717>:
      mono_mb_emit_managed_call (mb, monitor_enter_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.18718 = mono_signature_no_pinvoke (monitor_enter_method);
      D.18719 = mono_mb_create_method (mb, D.18718, 5);
      res = register_fastpath (D.18719, fast_path_idx);
      D.18675 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.18675, 12);
      if (is_v4 != 0) goto <D.18721>; else goto <D.18722>;
      <D.18721>:
      iftmp.38 = 5;
      goto <D.18723>;
      <D.18722>:
      iftmp.38 = 4;
      <D.18723>:
      info->subtype = iftmp.38;
      mono_marshal_set_wrapper_info (res, info);
      mono_mb_free (mb);
      D.18668 = res;
      return D.18668;
    }
  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.18726;
  int D.18727;
  unsigned int D.18730;
  int D.18731;
  unsigned int syncp_loc.39;
  int D.18733;
  unsigned int D.18736;
  int D.18737;
  int iftmp.40;
  unsigned int D.18743;
  int D.18744;

  mono_mb_emit_byte (mb, 2);
  D.18726 = mono_mb_emit_short_branch (mb, 44);
  D.18727 = (int) D.18726;
  *obj_null_branch = D.18727;
  if (true_locktaken_branch != 0B) goto <D.18728>; else goto <D.18729>;
  <D.18728>:
  mono_mb_emit_byte (mb, 3);
  mono_mb_emit_byte (mb, 70);
  D.18730 = mono_mb_emit_short_branch (mb, 45);
  D.18731 = (int) D.18730;
  *true_locktaken_branch = D.18731;
  <D.18729>:
  mono_mb_emit_byte (mb, 2);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_icon (mb, 4);
  mono_mb_emit_byte (mb, 88);
  mono_mb_emit_byte (mb, 77);
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.39);
  D.18733 = mono_gc_is_moving ();
  if (D.18733 != 0) goto <D.18734>; else goto <D.18735>;
  <D.18734>:
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  mono_mb_emit_icon (mb, 1);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  D.18736 = mono_mb_emit_short_branch (mb, 45);
  D.18737 = (int) D.18736;
  *thin_hash_branch = D.18737;
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  mono_mb_emit_icon (mb, -4);
  mono_mb_emit_byte (mb, 211);
  mono_mb_emit_byte (mb, 95);
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_stloc (mb, syncp_loc.39);
  goto <D.18738>;
  <D.18735>:
  *thin_hash_branch = 0;
  <D.18738>:
  syncp_loc.39 = (unsigned int) syncp_loc;
  mono_mb_emit_ldloc (mb, syncp_loc.39);
  if (branch_on_true != 0) goto <D.18740>; else goto <D.18741>;
  <D.18740>:
  iftmp.40 = 45;
  goto <D.18742>;
  <D.18741>:
  iftmp.40 = 44;
  <D.18742>:
  D.18743 = mono_mb_emit_short_branch (mb, iftmp.40);
  D.18744 = (int) D.18743;
  *syncp_true_false_branch = D.18744;
}


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

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


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_monitor_get_fast_exit_method (struct MonoMethod * monitor_exit_method)
{
  struct MonoMethod * D.18749;
  struct MonoMethod * D.18750;
  struct MonoClass * D.18753;
  struct MonoMethod * D.18754;
  struct MonoClass * D.18755;
  struct MonoType * D.18756;
  int has_syncp_branch.41;
  unsigned int has_syncp_branch.42;
  unsigned int syncp_loc.43;
  unsigned int D.18760;
  unsigned int owned_branch.44;
  unsigned int D.18762;
  unsigned int D.18763;
  unsigned int nested_branch.45;
  int thin_hash_branch.46;
  unsigned int thin_hash_branch.47;
  int obj_null_branch.48;
  unsigned int obj_null_branch.49;
  unsigned int has_waiting_branch.50;
  struct MonoMethodSignature * D.18772;
  struct MonoMethod * D.18773;
  struct MonoImage * D.18774;
  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.18747>; else goto <D.18748>;
      <D.18747>:
      D.18749 = 0B;
      return D.18749;
      <D.18748>:
      D.18750 = monitor_il_fastpaths[2];
      if (D.18750 != 0B) goto <D.18751>; else goto <D.18752>;
      <D.18751>:
      D.18749 = monitor_il_fastpaths[2];
      return D.18749;
      <D.18752>:
      D.18753 = mono_defaults.monitor_class;
      mb = mono_mb_new (D.18753, "FastMonitorExit", 25);
      D.18754 = mb->method;
      D.18754->slot = -1;
      D.18754 = mb->method;
      D.18754->flags = 182;
      D.18755 = mono_defaults.int_class;
      D.18756 = &D.18755->byval_arg;
      syncp_loc = mono_mb_add_local (mb, D.18756);
      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.41 = has_syncp_branch;
      has_syncp_branch.42 = (unsigned int) has_syncp_branch.41;
      mono_mb_patch_short_branch (mb, has_syncp_branch.42);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      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, 40);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 77);
      D.18760 = mono_mb_emit_short_branch (mb, 46);
      owned_branch = (int) D.18760;
      mono_mb_emit_byte (mb, 42);
      owned_branch.44 = (unsigned int) owned_branch;
      mono_mb_patch_short_branch (mb, owned_branch.44);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 4);
      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.18762 = mono_mb_emit_short_branch (mb, 53);
      nested_branch = (int) D.18762;
      mono_mb_emit_byte (mb, 38);
      mono_mb_emit_byte (mb, 38);
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      mono_mb_emit_icon (mb, 12);
      mono_mb_emit_byte (mb, 88);
      mono_mb_emit_byte (mb, 74);
      D.18763 = mono_mb_emit_short_branch (mb, 45);
      has_waiting_branch = (int) D.18763;
      syncp_loc.43 = (unsigned int) syncp_loc;
      mono_mb_emit_ldloc (mb, syncp_loc.43);
      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.45 = (unsigned int) nested_branch;
      mono_mb_patch_short_branch (mb, nested_branch.45);
      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.46 = thin_hash_branch;
      if (thin_hash_branch.46 != 0) goto <D.18766>; else goto <D.18767>;
      <D.18766>:
      thin_hash_branch.46 = thin_hash_branch;
      thin_hash_branch.47 = (unsigned int) thin_hash_branch.46;
      mono_mb_patch_short_branch (mb, thin_hash_branch.47);
      <D.18767>:
      obj_null_branch.48 = obj_null_branch;
      obj_null_branch.49 = (unsigned int) obj_null_branch.48;
      mono_mb_patch_short_branch (mb, obj_null_branch.49);
      has_waiting_branch.50 = (unsigned int) has_waiting_branch;
      mono_mb_patch_short_branch (mb, has_waiting_branch.50);
      mono_mb_emit_byte (mb, 2);
      mono_mb_emit_managed_call (mb, monitor_exit_method, 0B);
      mono_mb_emit_byte (mb, 42);
      D.18772 = mono_signature_no_pinvoke (monitor_exit_method);
      D.18773 = mono_mb_create_method (mb, D.18772, 5);
      res = register_fastpath (D.18773, 2);
      mono_mb_free (mb);
      D.18774 = mono_defaults.corlib;
      info = mono_image_alloc0 (D.18774, 12);
      info->subtype = 6;
      mono_marshal_set_wrapper_info (res, info);
      D.18749 = res;
      return D.18749;
    }
  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 = 4;
      *nest_offset = 1028;
      *entry_count_offset = 3076;
    }
  finally
    {
      ts = {CLOBBER};
    }
}


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

  <D.18122>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.18777>; else goto <D.18778>;
  <D.18777>:
  mono_thread_interruption_checkpoint ();
  <D.18778>:
  if (res == -1) goto <D.18122>; else goto <D.18123>;
  <D.18123>:
  D.18780 = res == 1;
  D.18779 = (gboolean) D.18780;
  return D.18779;
}


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

  <D.18130>:
  res = mono_monitor_try_enter_internal (obj, ms, 1);
  if (res == -1) goto <D.18782>; else goto <D.18783>;
  <D.18782>:
  mono_thread_interruption_checkpoint ();
  <D.18783>:
  if (res == -1) goto <D.18130>; else goto <D.18131>;
  <D.18131>:
  D.18784 = res == 1;
  D.18785 = (char) D.18784;
  *lockTaken = D.18785;
}


ves_icall_System_Threading_Monitor_Monitor_test_owner (struct MonoObject * obj)
{
  unsigned int D.18786;
  unsigned int D.18787;
  gboolean D.18790;
  unsigned int D.18791;
  unsigned int D.18794;
  unsigned int tls_pthread_self.51;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.18786 = lw.lock_word;
        D.18787 = D.18786 & 1;
        if (D.18787 != 0) goto <D.18788>; else goto <D.18789>;
        <D.18788>:
        D.18790 = 0;
        return D.18790;
        <D.18789>:
        D.18786 = lw.lock_word;
        D.18791 = D.18786 & 4294967292;
        lw.lock_word = D.18791;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.18792>; else goto <D.18793>;
  <D.18792>:
  D.18790 = 0;
  return D.18790;
  <D.18793>:
  D.18794 = mon->owner;
  tls_pthread_self.51 = tls_pthread_self;
  if (D.18794 == tls_pthread_self.51) goto <D.18796>; else goto <D.18797>;
  <D.18796>:
  D.18790 = 1;
  return D.18790;
  <D.18797>:
  D.18790 = 0;
  return D.18790;
}


ves_icall_System_Threading_Monitor_Monitor_test_synchronised (struct MonoObject * obj)
{
  unsigned int D.18801;
  unsigned int D.18802;
  gboolean D.18805;
  unsigned int D.18806;
  unsigned int D.18809;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.18801 = lw.lock_word;
        D.18802 = D.18801 & 1;
        if (D.18802 != 0) goto <D.18803>; else goto <D.18804>;
        <D.18803>:
        D.18805 = 0;
        return D.18805;
        <D.18804>:
        D.18801 = lw.lock_word;
        D.18806 = D.18801 & 4294967292;
        lw.lock_word = D.18806;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.18807>; else goto <D.18808>;
  <D.18807>:
  D.18805 = 0;
  return D.18805;
  <D.18808>:
  D.18809 = mon->owner;
  if (D.18809 != 0) goto <D.18810>; else goto <D.18811>;
  <D.18810>:
  D.18805 = 1;
  return D.18805;
  <D.18811>:
  D.18805 = 0;
  return D.18805;
}


ves_icall_System_Threading_Monitor_Monitor_pulse (struct MonoObject * obj)
{
  unsigned int D.18815;
  unsigned int D.18816;
  struct MonoException * D.18819;
  unsigned int D.18820;
  struct MonoException * D.18823;
  unsigned int D.18824;
  unsigned int tls_pthread_self.52;
  struct MonoException * D.18828;
  struct GSList * D.18829;
  void * D.18832;
  struct GSList * D.18833;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.18815 = lw.lock_word;
        D.18816 = D.18815 & 1;
        if (D.18816 != 0) goto <D.18817>; else goto <D.18818>;
        <D.18817>:
        D.18819 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.18819);
        return;
        <D.18818>:
        D.18815 = lw.lock_word;
        D.18820 = D.18815 & 4294967292;
        lw.lock_word = D.18820;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.18821>; else goto <D.18822>;
  <D.18821>:
  D.18823 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.18823);
  return;
  <D.18822>:
  D.18824 = mon->owner;
  tls_pthread_self.52 = tls_pthread_self;
  if (D.18824 != tls_pthread_self.52) goto <D.18826>; else goto <D.18827>;
  <D.18826>:
  D.18828 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.18828);
  return;
  <D.18827>:
  D.18829 = mon->wait_list;
  if (D.18829 != 0B) goto <D.18830>; else goto <D.18831>;
  <D.18830>:
  D.18829 = mon->wait_list;
  D.18832 = D.18829->data;
  SetEvent (D.18832);
  D.18829 = mon->wait_list;
  D.18832 = D.18829->data;
  D.18829 = mon->wait_list;
  D.18833 = monoeg_g_slist_remove (D.18829, D.18832);
  mon->wait_list = D.18833;
  <D.18831>:
}


ves_icall_System_Threading_Monitor_Monitor_pulse_all (struct MonoObject * obj)
{
  unsigned int D.18837;
  unsigned int D.18838;
  struct MonoException * D.18841;
  unsigned int D.18842;
  struct MonoException * D.18845;
  unsigned int D.18846;
  unsigned int tls_pthread_self.53;
  struct MonoException * D.18850;
  struct GSList * D.18851;
  void * D.18852;
  struct GSList * D.18853;
  struct MonoThreadsSync * mon;

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

    try
      {
        lw.sync = mon;
        D.18837 = lw.lock_word;
        D.18838 = D.18837 & 1;
        if (D.18838 != 0) goto <D.18839>; else goto <D.18840>;
        <D.18839>:
        D.18841 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.18841);
        return;
        <D.18840>:
        D.18837 = lw.lock_word;
        D.18842 = D.18837 & 4294967292;
        lw.lock_word = D.18842;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.18843>; else goto <D.18844>;
  <D.18843>:
  D.18845 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.18845);
  return;
  <D.18844>:
  D.18846 = mon->owner;
  tls_pthread_self.53 = tls_pthread_self;
  if (D.18846 != tls_pthread_self.53) goto <D.18848>; else goto <D.18849>;
  <D.18848>:
  D.18850 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.18850);
  return;
  <D.18849>:
  goto <D.18153>;
  <D.18152>:
  D.18851 = mon->wait_list;
  D.18852 = D.18851->data;
  SetEvent (D.18852);
  D.18851 = mon->wait_list;
  D.18852 = D.18851->data;
  D.18851 = mon->wait_list;
  D.18853 = monoeg_g_slist_remove (D.18851, D.18852);
  mon->wait_list = D.18853;
  <D.18153>:
  D.18851 = mon->wait_list;
  if (D.18851 != 0B) goto <D.18152>; else goto <D.18154>;
  <D.18154>:
}


ves_icall_System_Threading_Monitor_Monitor_wait (struct MonoObject * obj, guint32 ms)
{
  unsigned int D.18857;
  unsigned int D.18858;
  struct MonoException * D.18861;
  gboolean D.18862;
  unsigned int D.18863;
  struct MonoException * D.18866;
  unsigned int D.18867;
  unsigned int tls_pthread_self.54;
  struct MonoException * D.18871;
  struct MonoException * D.18874;
  struct GSList * D.18875;
  struct GSList * D.18876;
  int D.18877;
  struct MonoException * D.18884;
  struct GSList * D.18890;
  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.18857 = lw.lock_word;
        D.18858 = D.18857 & 1;
        if (D.18858 != 0) goto <D.18859>; else goto <D.18860>;
        <D.18859>:
        D.18861 = mono_get_exception_synchronization_lock ("Not locked");
        mono_raise_exception (D.18861);
        D.18862 = 0;
        return D.18862;
        <D.18860>:
        D.18857 = lw.lock_word;
        D.18863 = D.18857 & 4294967292;
        lw.lock_word = D.18863;
        mon = lw.sync;
      }
    finally
      {
        lw = {CLOBBER};
      }
  }
  if (mon == 0B) goto <D.18864>; else goto <D.18865>;
  <D.18864>:
  D.18866 = mono_get_exception_synchronization_lock ("Not locked");
  mono_raise_exception (D.18866);
  D.18862 = 0;
  return D.18862;
  <D.18865>:
  D.18867 = mon->owner;
  tls_pthread_self.54 = tls_pthread_self;
  if (D.18867 != tls_pthread_self.54) goto <D.18869>; else goto <D.18870>;
  <D.18869>:
  D.18871 = mono_get_exception_synchronization_lock ("Not locked by this thread");
  mono_raise_exception (D.18871);
  D.18862 = 0;
  return D.18862;
  <D.18870>:
  mono_thread_current_check_pending_interrupt ();
  event = CreateEvent (0B, 0, 0, 0B);
  if (event == 0B) goto <D.18872>; else goto <D.18873>;
  <D.18872>:
  D.18874 = mono_get_exception_synchronization_lock ("Failed to set up wait event");
  mono_raise_exception (D.18874);
  D.18862 = 0;
  return D.18862;
  <D.18873>:
  mono_thread_current_check_pending_interrupt ();
  mono_thread_set_state (thread, 32);
  D.18875 = mon->wait_list;
  D.18876 = monoeg_g_slist_append (D.18875, event);
  mon->wait_list = D.18876;
  nest = mon->nest;
  mon->nest = 1;
  mono_monitor_exit (obj);
  ret = WaitForSingleObjectEx (event, ms, 1);
  mono_thread_clr_state (thread, 32);
  D.18877 = mono_thread_interruption_requested ();
  if (D.18877 != 0) goto <D.18878>; else goto <D.18879>;
  <D.18878>:
  D.18862 = 0;
  return D.18862;
  <D.18879>:
  <D.18167>:
  regain = mono_monitor_try_enter_internal (obj, 4294967295, 1);
  if (regain == -1) goto <D.18880>; else goto <D.18881>;
  <D.18880>:
  mono_thread_interruption_checkpoint ();
  <D.18881>:
  if (regain == -1) goto <D.18167>; else goto <D.18168>;
  <D.18168>:
  if (regain == 0) goto <D.18882>; else goto <D.18883>;
  <D.18882>:
  CloseHandle (event);
  D.18884 = mono_get_exception_synchronization_lock ("Failed to regain lock");
  mono_raise_exception (D.18884);
  D.18862 = 0;
  return D.18862;
  <D.18883>:
  mon->nest = nest;
  if (ret == 258) goto <D.18885>; else goto <D.18886>;
  <D.18885>:
  ret = WaitForSingleObjectEx (event, 0, 0);
  <D.18886>:
  if (ret == 0) goto <D.18887>; else goto <D.18888>;
  <D.18887>:
  success = 1;
  goto <D.18889>;
  <D.18888>:
  D.18875 = mon->wait_list;
  D.18890 = monoeg_g_slist_remove (D.18875, event);
  mon->wait_list = D.18890;
  <D.18889>:
  CloseHandle (event);
  D.18862 = success;
  return D.18862;
}


