mono_lock_free_alloc (struct MonoLockFreeAllocator * heap)
{
  void * D.5896;
  void * addr;

  <D.5840>:
  addr = alloc_from_active_or_partial (heap);
  if (addr != 0B) goto <D.5839>; else goto <D.5894>;
  <D.5894>:
  addr = alloc_from_new_sb (heap);
  if (addr != 0B) goto <D.5839>; else goto <D.5895>;
  <D.5895>:
  goto <D.5840>;
  <D.5839>:
  D.5896 = addr;
  return D.5896;
}


alloc_from_active_or_partial (struct MonoLockFreeAllocator * heap)
{
  struct _MonoLockFreeAllocDescriptor * * D.5900;
  void * D.5901;
  void * D.5906;
  volatile gint32 * D.5907;
  unsigned int D.5908;
  unsigned int D.5909;
  _Bool D.5912;
  long int D.5913;
  long int D.5914;
  <unnamed-unsigned:15> D.5917;
  int D.5918;
  _Bool D.5919;
  long int D.5920;
  long int D.5921;
  void * D.5924;
  <unnamed-unsigned:15> D.5925;
  unsigned int D.5926;
  unsigned int D.5927;
  unsigned int D.5928;
  sizetype D.5929;
  unsigned int D.5930;
  _Bool D.5931;
  long int D.5932;
  long int D.5933;
  short unsigned int D.5936;
  <unnamed-unsigned:15> D.5937;
  <unnamed-unsigned:15> D.5938;
  <unnamed-unsigned:15> D.5939;
  unsigned int D.5940;
  unsigned int D.5941;
  int D.5944;
  unsigned int D.5945;
  void * D.5948;
  struct Descriptor * desc;
  union Anchor old_anchor;
  union Anchor new_anchor;
  void * addr;
  void retry = <<< error >>>;

  try
    {
      retry:
      desc = heap->active;
      if (desc != 0B) goto <D.5898>; else goto <D.5899>;
      <D.5898>:
      D.5900 = &heap->active;
      D.5901 = InterlockedCompareExchangePointer (D.5900, 0B, desc);
      if (D.5901 != desc) goto retry; else goto <D.5902>;
      <D.5902>:
      goto <D.5903>;
      <D.5899>:
      desc = heap_get_partial (heap);
      if (desc == 0B) goto <D.5904>; else goto <D.5905>;
      <D.5904>:
      D.5906 = 0B;
      return D.5906;
      <D.5905>:
      <D.5903>:
      <D.5823>:
      {
        unsigned int next;

        D.5907 = &desc->anchor.value;
        old_anchor = MEM[(volatile union Anchor *)D.5907];
        new_anchor = old_anchor;
        D.5908 = BIT_FIELD_REF <old_anchor, 32, 0>;
        D.5909 = D.5908 & 3221225472;
        if (D.5909 == 2147483648) goto <D.5910>; else goto <D.5911>;
        <D.5910>:
        desc_retire (desc);
        goto retry;
        <D.5911>:
        D.5908 = BIT_FIELD_REF <old_anchor, 32, 0>;
        D.5909 = D.5908 & 3221225472;
        D.5912 = D.5909 != 1073741824;
        D.5913 = (long int) D.5912;
        D.5914 = __builtin_expect (D.5913, 0);
        if (D.5914 != 0) goto <D.5915>; else goto <D.5916>;
        <D.5915>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 383, "old_anchor.data.state == STATE_PARTIAL");
        <D.5916>:
        D.5917 = old_anchor.data.count;
        D.5918 = (int) D.5917;
        D.5919 = D.5918 <= 0;
        D.5920 = (long int) D.5919;
        D.5921 = __builtin_expect (D.5920, 0);
        if (D.5921 != 0) goto <D.5922>; else goto <D.5923>;
        <D.5922>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 384, "old_anchor.data.count > 0");
        <D.5923>:
        D.5924 = desc->sb;
        D.5925 = old_anchor.data.avail;
        D.5926 = (unsigned int) D.5925;
        D.5927 = desc->slot_size;
        D.5928 = D.5926 * D.5927;
        D.5929 = (sizetype) D.5928;
        addr = D.5924 + D.5929;
        mono_memory_read_barrier ();
        next = MEM[(unsigned int *)addr];
        D.5927 = desc->slot_size;
        D.5930 = 16368 / D.5927;
        D.5931 = D.5930 <= next;
        D.5932 = (long int) D.5931;
        D.5933 = __builtin_expect (D.5932, 0);
        if (D.5933 != 0) goto <D.5934>; else goto <D.5935>;
        <D.5934>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 391, "next < SB_USABLE_SIZE / desc->slot_size");
        <D.5935>:
        D.5936 = (short unsigned int) next;
        D.5937 = (<unnamed-unsigned:15>) D.5936;
        new_anchor.data.avail = D.5937;
        D.5938 = new_anchor.data.count;
        D.5939 = D.5938 + 32767;
        new_anchor.data.count = D.5939;
        D.5940 = BIT_FIELD_REF <new_anchor, 32, 0>;
        D.5941 = D.5940 & 1073709056;
        if (D.5941 == 0) goto <D.5942>; else goto <D.5943>;
        <D.5942>:
        new_anchor.data.state = 0;
        <D.5943>:
      }
      D.5944 = set_anchor (desc, old_anchor, new_anchor);
      if (D.5944 == 0) goto <D.5823>; else goto <D.5824>;
      <D.5824>:
      D.5940 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.5945 = D.5940 & 3221225472;
      if (D.5945 == 1073741824) goto <D.5946>; else goto <D.5947>;
      <D.5946>:
      D.5900 = &heap->active;
      D.5948 = InterlockedCompareExchangePointer (D.5900, desc, 0B);
      if (D.5948 != 0B) goto <D.5949>; else goto <D.5950>;
      <D.5949>:
      heap_put_partial (desc);
      <D.5950>:
      <D.5947>:
      D.5906 = addr;
      return D.5906;
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


heap_get_partial (struct MonoLockFreeAllocator * heap)
{
  struct Descriptor * D.5953;
  struct MonoLockFreeAllocSizeClass * D.5954;

  D.5954 = heap->sc;
  D.5953 = list_get_partial (D.5954);
  return D.5953;
}


list_get_partial (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.5956;
  struct Descriptor * D.5959;
  <unnamed-unsigned:2> D.5960;

  <D.5789>:
  {
    struct Descriptor * desc;

    D.5956 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.5956);
    if (desc == 0B) goto <D.5957>; else goto <D.5958>;
    <D.5957>:
    D.5959 = 0B;
    return D.5959;
    <D.5958>:
    D.5960 = desc->anchor.data.state;
    if (D.5960 != 2) goto <D.5961>; else goto <D.5962>;
    <D.5961>:
    D.5959 = desc;
    return D.5959;
    <D.5962>:
    desc_retire (desc);
  }
  goto <D.5789>;
}


desc_retire (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.5964;
  _Bool D.5965;
  long int D.5966;
  long int D.5967;
  int D.5970;
  _Bool D.5971;
  long int D.5972;
  long int D.5973;
  void * D.5976;

  D.5964 = desc->anchor.data.state;
  D.5965 = D.5964 != 2;
  D.5966 = (long int) D.5965;
  D.5967 = __builtin_expect (D.5966, 0);
  if (D.5967 != 0) goto <D.5968>; else goto <D.5969>;
  <D.5968>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 251, "desc->anchor.data.state == STATE_EMPTY");
  <D.5969>:
  D.5970 = desc->in_use;
  D.5971 = D.5970 == 0;
  D.5972 = (long int) D.5971;
  D.5973 = __builtin_expect (D.5972, 0);
  if (D.5973 != 0) goto <D.5974>; else goto <D.5975>;
  <D.5974>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 252, "desc->in_use");
  <D.5975>:
  desc->in_use = 0;
  D.5976 = desc->sb;
  free_sb (D.5976);
  mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, 0, 1);
}


desc_enqueue_avail (void * _desc)
{
  <unnamed-unsigned:2> D.5977;
  _Bool D.5978;
  long int D.5979;
  long int D.5980;
  int D.5983;
  _Bool D.5984;
  long int D.5985;
  long int D.5986;
  void * D.5989;
  struct Descriptor * desc;
  struct Descriptor * old_head;

  desc = _desc;
  D.5977 = desc->anchor.data.state;
  D.5978 = D.5977 != 2;
  D.5979 = (long int) D.5978;
  D.5980 = __builtin_expect (D.5979, 0);
  if (D.5980 != 0) goto <D.5981>; else goto <D.5982>;
  <D.5981>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 238, "desc->anchor.data.state == STATE_EMPTY");
  <D.5982>:
  D.5983 = desc->in_use;
  D.5984 = D.5983 != 0;
  D.5985 = (long int) D.5984;
  D.5986 = __builtin_expect (D.5985, 0);
  if (D.5986 != 0) goto <D.5987>; else goto <D.5988>;
  <D.5987>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 239, "!desc->in_use");
  <D.5988>:
  <D.5780>:
  old_head = desc_avail;
  desc->next = old_head;
  mono_memory_write_barrier ();
  D.5989 = InterlockedCompareExchangePointer (&desc_avail, desc, old_head);
  if (D.5989 != old_head) goto <D.5780>; else goto <D.5781>;
  <D.5781>:
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


free_sb (void * sb)
{
  long unsigned int sb.0;
  long unsigned int D.5991;
  void * D.5992;
  _Bool D.5993;
  long int D.5994;
  long int D.5995;
  void * sb_header;

  sb.0 = (long unsigned int) sb;
  D.5991 = sb.0 & 18446744073709535232;
  sb_header = (void *) D.5991;
  D.5992 = sb_header + 16;
  D.5993 = D.5992 != sb;
  D.5994 = (long int) D.5993;
  D.5995 = __builtin_expect (D.5994, 0);
  if (D.5995 != 0) goto <D.5996>; else goto <D.5997>;
  <D.5996>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 175, "(char*)sb_header + SB_HEADER_SIZE == sb");
  <D.5997>:
  mono_sgen_free_os_memory (sb_header, 16384);
}


mono_sgen_free_os_memory (void * addr, size_t size)
{
  mono_vfree (addr, size);
}


mono_memory_read_barrier ()
{
  mono_memory_barrier ();
}


set_anchor (struct Descriptor * desc, union Anchor old_anchor, union Anchor new_anchor)
{
  unsigned int D.5998;
  unsigned int D.5999;
  unsigned int D.6002;
  unsigned int D.6003;
  _Bool D.6004;
  long int D.6005;
  long int D.6006;
  gboolean D.6009;
  volatile gint32 * D.6010;
  int D.6011;
  int D.6012;
  int D.6013;
  _Bool D.6014;

  D.5998 = BIT_FIELD_REF <old_anchor, 32, 0>;
  D.5999 = D.5998 & 3221225472;
  if (D.5999 == 2147483648) goto <D.6000>; else goto <D.6001>;
  <D.6000>:
  D.6002 = BIT_FIELD_REF <new_anchor, 32, 0>;
  D.6003 = D.6002 & 3221225472;
  D.6004 = D.6003 != 2147483648;
  D.6005 = (long int) D.6004;
  D.6006 = __builtin_expect (D.6005, 0);
  if (D.6006 != 0) goto <D.6007>; else goto <D.6008>;
  <D.6007>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 349, "new_anchor.data.state == STATE_EMPTY");
  <D.6008>:
  <D.6001>:
  D.6010 = &desc->anchor.value;
  D.6011 = new_anchor.value;
  D.6012 = old_anchor.value;
  D.6013 = InterlockedCompareExchange (D.6010, D.6011, D.6012);
  D.6012 = old_anchor.value;
  D.6014 = D.6013 == D.6012;
  D.6009 = (gboolean) D.6014;
  return D.6009;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.6016;
  unsigned int comp.1;
  unsigned int exch.2;
  unsigned int D.6019;

  comp.1 = (unsigned int) comp;
  exch.2 = (unsigned int) exch;
  D.6019 = __sync_val_compare_and_swap_4 (dest, comp.1, exch.2);
  D.6016 = (gint32) D.6019;
  return D.6016;
}


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

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


heap_put_partial (struct Descriptor * desc)
{
  list_put_partial (desc);
}


list_put_partial (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.6026;
  _Bool D.6027;
  long int D.6028;
  long int D.6029;

  D.6026 = desc->anchor.data.state;
  D.6027 = D.6026 == 0;
  D.6028 = (long int) D.6027;
  D.6029 = __builtin_expect (D.6028, 0);
  if (D.6029 != 0) goto <D.6030>; else goto <D.6031>;
  <D.6030>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 306, "desc->anchor.data.state != STATE_FULL");
  <D.6031>:
  mono_thread_hazardous_free_or_queue (desc, desc_put_partial, 0, 1);
}


desc_put_partial (void * _desc)
{
  <unnamed-unsigned:2> D.6032;
  _Bool D.6033;
  long int D.6034;
  long int D.6035;
  struct MonoLockFreeQueueNode * D.6038;
  struct MonoLockFreeAllocator * D.6039;
  struct MonoLockFreeAllocSizeClass * D.6040;
  struct MonoLockFreeQueue * D.6041;
  struct Descriptor * desc;

  desc = _desc;
  D.6032 = desc->anchor.data.state;
  D.6033 = D.6032 == 0;
  D.6034 = (long int) D.6033;
  D.6035 = __builtin_expect (D.6034, 0);
  if (D.6035 != 0) goto <D.6036>; else goto <D.6037>;
  <D.6036>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 297, "desc->anchor.data.state != STATE_FULL");
  <D.6037>:
  D.6038 = &desc->node;
  mono_lock_free_queue_node_free (D.6038);
  D.6039 = desc->heap;
  D.6040 = D.6039->sc;
  D.6041 = &D.6040->partial;
  D.6038 = &desc->node;
  mono_lock_free_queue_enqueue (D.6041, D.6038);
}


alloc_from_new_sb (struct MonoLockFreeAllocator * heap)
{
  void * D.6042;
  struct MonoLockFreeAllocSizeClass * D.6043;
  unsigned int D.6044;
  void * D.6045;
  unsigned int D.6046;
  sizetype D.6047;
  unsigned int * D.6048;
  unsigned int D.6049;
  unsigned int D.6050;
  unsigned int D.6051;
  short unsigned int D.6052;
  short unsigned int D.6053;
  <unnamed-unsigned:15> D.6054;
  struct _MonoLockFreeAllocDescriptor * * D.6055;
  void * D.6056;
  void * D.6059;
  unsigned int slot_size;
  unsigned int count;
  unsigned int i;
  struct Descriptor * desc;

  desc = desc_alloc ();
  D.6042 = alloc_sb (desc);
  desc->sb = D.6042;
  D.6043 = heap->sc;
  D.6044 = D.6043->slot_size;
  desc->slot_size = D.6044;
  slot_size = desc->slot_size;
  count = 16368 / slot_size;
  i = 1;
  goto <D.5833>;
  <D.5832>:
  D.6045 = desc->sb;
  D.6046 = i * slot_size;
  D.6047 = (sizetype) D.6046;
  D.6048 = D.6045 + D.6047;
  D.6049 = i + 1;
  *D.6048 = D.6049;
  i = i + 1;
  <D.5833>:
  D.6050 = count + 4294967295;
  if (D.6050 > i) goto <D.5832>; else goto <D.5834>;
  <D.5834>:
  desc->heap = heap;
  desc->anchor.data.avail = 1;
  D.6043 = heap->sc;
  D.6044 = D.6043->slot_size;
  desc->slot_size = D.6044;
  desc->max_count = count;
  D.6051 = desc->max_count;
  D.6052 = (short unsigned int) D.6051;
  D.6053 = D.6052 + 65535;
  D.6054 = (<unnamed-unsigned:15>) D.6053;
  desc->anchor.data.count = D.6054;
  desc->anchor.data.state = 1;
  mono_memory_write_barrier ();
  D.6055 = &heap->active;
  D.6056 = InterlockedCompareExchangePointer (D.6055, desc, 0B);
  if (D.6056 == 0B) goto <D.6057>; else goto <D.6058>;
  <D.6057>:
  D.6059 = desc->sb;
  return D.6059;
  <D.6058>:
  desc->anchor.data.state = 2;
  desc_retire (desc);
  D.6059 = 0B;
  return D.6059;
}


desc_alloc ()
{
  void * D.6063;
  _Bool D.6064;
  long unsigned int D.6066;
  struct Descriptor * iftmp.5;
  int D.6070;
  long unsigned int D.6071;
  long unsigned int D.6072;
  struct MonoLockFreeQueueNode * D.6074;
  struct Descriptor * D.6075;
  void * D.6076;
  _Bool D.6077;
  int D.6083;
  _Bool D.6084;
  long int D.6085;
  long int D.6086;
  struct Descriptor * D.6089;
  struct MonoThreadHazardPointers * hp;
  struct Descriptor * desc;

  hp = mono_hazard_pointer_get ();
  <D.5774>:
  {
    gboolean success;

    desc = get_hazardous_pointer (&desc_avail, hp, 1);
    if (desc != 0B) goto <D.6061>; else goto <D.6062>;
    <D.6061>:
    {
      struct Descriptor * next;

      next = desc->next;
      D.6063 = InterlockedCompareExchangePointer (&desc_avail, next, desc);
      D.6064 = D.6063 == desc;
      success = (gboolean) D.6064;
    }
    goto <D.6065>;
    <D.6062>:
    {
      size_t desc_size;
      struct Descriptor * d;
      int i;

      desc_size = 56;
      D.6066 = desc_size * 64;
      desc = mono_sgen_alloc_os_memory (D.6066, 1);
      d = desc;
      i = 0;
      goto <D.5771>;
      <D.5770>:
      {
        struct Descriptor * next;

        if (i != 63) goto <D.6068>; else goto <D.6069>;
        <D.6068>:
        D.6070 = i + 1;
        D.6071 = (long unsigned int) D.6070;
        D.6072 = D.6071 * desc_size;
        iftmp.5 = desc + D.6072;
        goto <D.6073>;
        <D.6069>:
        iftmp.5 = 0B;
        <D.6073>:
        next = iftmp.5;
        d->next = next;
        D.6074 = &d->node;
        mono_lock_free_queue_node_init (D.6074, 1);
        d = next;
      }
      i = i + 1;
      <D.5771>:
      if (i <= 63) goto <D.5770>; else goto <D.5772>;
      <D.5772>:
      mono_memory_write_barrier ();
      D.6075 = desc->next;
      D.6076 = InterlockedCompareExchangePointer (&desc_avail, D.6075, 0B);
      D.6077 = D.6076 == 0B;
      success = (gboolean) D.6077;
      if (success == 0) goto <D.6078>; else goto <D.6079>;
      <D.6078>:
      D.6066 = desc_size * 64;
      mono_sgen_free_os_memory (desc, D.6066);
      <D.6079>:
    }
    <D.6065>:
    if (0 != 0) goto <D.6080>; else goto <D.6081>;
    <D.6080>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 220, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
    <D.6081>:
    hp->hazard_pointers[1] = 0B;
    if (success != 0) goto <D.5773>; else goto <D.6082>;
    <D.6082>:
  }
  goto <D.5774>;
  <D.5773>:
  D.6083 = desc->in_use;
  D.6084 = D.6083 != 0;
  D.6085 = (long int) D.6084;
  D.6086 = __builtin_expect (D.6085, 0);
  if (D.6086 != 0) goto <D.6087>; else goto <D.6088>;
  <D.6087>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 226, "!desc->in_use");
  <D.6088>:
  desc->in_use = 1;
  D.6089 = desc;
  return D.6089;
}


mono_sgen_alloc_os_memory (size_t size, int activate)
{
  void * D.6091;
  long unsigned int D.6092;
  int D.6093;

  D.6092 = prot_flags_for_activate (activate);
  D.6093 = (int) D.6092;
  D.6091 = mono_valloc (0B, size, D.6093);
  return D.6091;
}


prot_flags_for_activate (int activate)
{
  long unsigned int iftmp.6;
  long unsigned int D.6099;
  long unsigned int prot_flags;

  if (activate != 0) goto <D.6096>; else goto <D.6097>;
  <D.6096>:
  iftmp.6 = 3;
  goto <D.6098>;
  <D.6097>:
  iftmp.6 = 0;
  <D.6098>:
  prot_flags = iftmp.6;
  D.6099 = prot_flags | 80;
  return D.6099;
}


alloc_sb (struct Descriptor * desc)
{
  long unsigned int sb_header.7;
  long unsigned int D.6102;
  void * D.6103;
  _Bool D.6104;
  long int D.6105;
  long int D.6106;
  struct Descriptor * * D.6109;
  void * D.6110;
  void * sb_header;

  sb_header = mono_sgen_alloc_os_memory_aligned (16384, 16384, 1);
  sb_header.7 = (long unsigned int) sb_header;
  D.6102 = sb_header.7 & 18446744073709535232;
  D.6103 = (void *) D.6102;
  D.6104 = D.6103 != sb_header;
  D.6105 = (long int) D.6104;
  D.6106 = __builtin_expect (D.6105, 0);
  if (D.6106 != 0) goto <D.6107>; else goto <D.6108>;
  <D.6107>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 165, "sb_header == SB_HEADER_FOR_ADDR (sb_header)");
  <D.6108>:
  sb_header.7 = (long unsigned int) sb_header;
  D.6102 = sb_header.7 & 18446744073709535232;
  D.6109 = (struct Descriptor * *) D.6102;
  *D.6109 = desc;
  D.6110 = sb_header + 16;
  return D.6110;
}


mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate)
{
  void * D.6112;
  long unsigned int D.6113;
  int D.6114;

  D.6113 = prot_flags_for_activate (activate);
  D.6114 = (int) D.6113;
  D.6112 = mono_valloc_aligned (size, alignment, D.6114);
  return D.6112;
}


mono_lock_free_free (void * ptr)
{
  long unsigned int ptr.8;
  long unsigned int D.6117;
  struct Descriptor * * D.6118;
  long unsigned int sb.9;
  long unsigned int D.6120;
  long unsigned int D.6121;
  _Bool D.6122;
  long int D.6123;
  long int D.6124;
  volatile gint32 * D.6127;
  <unnamed-unsigned:15> D.6128;
  unsigned int D.6129;
  long int ptr.10;
  long int sb.11;
  long int D.6132;
  unsigned int D.6133;
  long int D.6134;
  long int D.6135;
  short unsigned int D.6136;
  <unnamed-unsigned:15> D.6137;
  <unnamed-unsigned:15> D.6138;
  unsigned int D.6139;
  unsigned int D.6140;
  _Bool D.6141;
  long int D.6142;
  long int D.6143;
  unsigned int D.6146;
  unsigned int D.6147;
  <unnamed-unsigned:15> D.6150;
  <unnamed-unsigned:15> D.6151;
  unsigned int D.6152;
  unsigned int D.6153;
  int D.6156;
  unsigned int D.6157;
  unsigned int D.6158;
  _Bool D.6161;
  long int D.6162;
  long int D.6163;
  struct _MonoLockFreeAllocDescriptor * * D.6166;
  void * D.6167;
  struct MonoLockFreeAllocSizeClass * D.6171;
  _Bool D.6175;
  long int D.6176;
  long int D.6177;
  struct MonoLockFreeAllocator * D.6180;
  struct _MonoLockFreeAllocDescriptor * * D.6181;
  void * D.6182;
  union Anchor old_anchor;
  union Anchor new_anchor;
  struct Descriptor * desc;
  void * sb;
  struct MonoLockFreeAllocator * heap;

  try
    {
      heap = 0B;
      ptr.8 = (long unsigned int) ptr;
      D.6117 = ptr.8 & 18446744073709535232;
      D.6118 = (struct Descriptor * *) D.6117;
      desc = *D.6118;
      sb = desc->sb;
      ptr.8 = (long unsigned int) ptr;
      sb.9 = (long unsigned int) sb;
      D.6120 = ptr.8 ^ sb.9;
      D.6121 = D.6120 & 18446744073709535232;
      D.6122 = D.6121 != 0;
      D.6123 = (long int) D.6122;
      D.6124 = __builtin_expect (D.6123, 0);
      if (D.6124 != 0) goto <D.6125>; else goto <D.6126>;
      <D.6125>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 477, "SB_HEADER_FOR_ADDR (ptr) == SB_HEADER_FOR_ADDR (sb)");
      <D.6126>:
      <D.5849>:
      D.6127 = &desc->anchor.value;
      old_anchor = MEM[(volatile union Anchor *)D.6127];
      new_anchor = old_anchor;
      D.6128 = old_anchor.data.avail;
      D.6129 = (unsigned int) D.6128;
      MEM[(unsigned int *)ptr] = D.6129;
      ptr.10 = (long int) ptr;
      sb.11 = (long int) sb;
      D.6132 = ptr.10 - sb.11;
      D.6133 = desc->slot_size;
      D.6134 = (long int) D.6133;
      D.6135 = D.6132 / D.6134;
      D.6136 = (short unsigned int) D.6135;
      D.6137 = (<unnamed-unsigned:15>) D.6136;
      new_anchor.data.avail = D.6137;
      D.6138 = new_anchor.data.avail;
      D.6139 = (unsigned int) D.6138;
      D.6133 = desc->slot_size;
      D.6140 = 16368 / D.6133;
      D.6141 = D.6139 >= D.6140;
      D.6142 = (long int) D.6141;
      D.6143 = __builtin_expect (D.6142, 0);
      if (D.6143 != 0) goto <D.6144>; else goto <D.6145>;
      <D.6144>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 483, "new_anchor.data.avail < SB_USABLE_SIZE / desc->slot_size");
      <D.6145>:
      D.6146 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.6147 = D.6146 & 3221225472;
      if (D.6147 == 0) goto <D.6148>; else goto <D.6149>;
      <D.6148>:
      new_anchor.data.state = 1;
      <D.6149>:
      D.6150 = new_anchor.data.count;
      D.6151 = D.6150 + 1;
      new_anchor.data.count = D.6151;
      D.6150 = new_anchor.data.count;
      D.6152 = (unsigned int) D.6150;
      D.6153 = desc->max_count;
      if (D.6152 == D.6153) goto <D.6154>; else goto <D.6155>;
      <D.6154>:
      heap = desc->heap;
      new_anchor.data.state = 2;
      <D.6155>:
      D.6156 = set_anchor (desc, old_anchor, new_anchor);
      if (D.6156 == 0) goto <D.5849>; else goto <D.5850>;
      <D.5850>:
      D.6157 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.6158 = D.6157 & 3221225472;
      if (D.6158 == 2147483648) goto <D.6159>; else goto <D.6160>;
      <D.6159>:
      D.6146 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.6147 = D.6146 & 3221225472;
      D.6161 = D.6147 == 2147483648;
      D.6162 = (long int) D.6161;
      D.6163 = __builtin_expect (D.6162, 0);
      if (D.6163 != 0) goto <D.6164>; else goto <D.6165>;
      <D.6164>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 495, "old_anchor.data.state != STATE_EMPTY");
      <D.6165>:
      D.6166 = &heap->active;
      D.6167 = InterlockedCompareExchangePointer (D.6166, 0B, desc);
      if (D.6167 == desc) goto <D.6168>; else goto <D.6169>;
      <D.6168>:
      desc_retire (desc);
      goto <D.6170>;
      <D.6169>:
      D.6171 = heap->sc;
      list_remove_empty_desc (D.6171);
      <D.6170>:
      goto <D.6172>;
      <D.6160>:
      D.6146 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.6147 = D.6146 & 3221225472;
      if (D.6147 == 0) goto <D.6173>; else goto <D.6174>;
      <D.6173>:
      D.6157 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.6158 = D.6157 & 3221225472;
      D.6175 = D.6158 != 1073741824;
      D.6176 = (long int) D.6175;
      D.6177 = __builtin_expect (D.6176, 0);
      if (D.6177 != 0) goto <D.6178>; else goto <D.6179>;
      <D.6178>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 513, "new_anchor.data.state == STATE_PARTIAL");
      <D.6179>:
      D.6180 = desc->heap;
      D.6181 = &D.6180->active;
      D.6182 = InterlockedCompareExchangePointer (D.6181, desc, 0B);
      if (D.6182 != 0B) goto <D.6183>; else goto <D.6184>;
      <D.6183>:
      heap_put_partial (desc);
      <D.6184>:
      <D.6174>:
      <D.6172>:
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


list_remove_empty_desc (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.6185;
  <unnamed-unsigned:2> D.6188;
  struct MonoLockFreeAllocator * D.6192;
  struct MonoLockFreeAllocSizeClass * D.6193;
  _Bool D.6194;
  long int D.6195;
  long int D.6196;
  int num_non_empty;

  num_non_empty = 0;
  <D.5802>:
  {
    struct Descriptor * desc;

    D.6185 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.6185);
    if (desc == 0B) goto <D.6186>; else goto <D.6187>;
    <D.6186>:
    return;
    <D.6187>:
    D.6188 = desc->anchor.data.state;
    if (D.6188 == 2) goto <D.6189>; else goto <D.6190>;
    <D.6189>:
    desc_retire (desc);
    goto <D.6191>;
    <D.6190>:
    D.6192 = desc->heap;
    D.6193 = D.6192->sc;
    D.6194 = D.6193 != sc;
    D.6195 = (long int) D.6194;
    D.6196 = __builtin_expect (D.6195, 0);
    if (D.6196 != 0) goto <D.6197>; else goto <D.6198>;
    <D.6197>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 325, "desc->heap->sc == sc");
    <D.6198>:
    mono_thread_hazardous_free_or_queue (desc, desc_put_partial, 0, 1);
    num_non_empty = num_non_empty + 1;
    if (num_non_empty > 1) goto <D.6199>; else goto <D.6200>;
    <D.6199>:
    return;
    <D.6200>:
    <D.6191>:
  }
  goto <D.5802>;
}


mono_lock_free_allocator_check_consistency (struct MonoLockFreeAllocator * heap)
{
  <unnamed-unsigned:2> D.6204;
  _Bool D.6205;
  long int D.6206;
  long int D.6207;
  int iftmp.12;
  <unnamed-unsigned:2> D.6213;
  <unnamed-unsigned:2> D.6215;
  _Bool D.6217;
  long int D.6218;
  long int D.6219;
  struct MonoLockFreeAllocSizeClass * D.6222;
  struct MonoLockFreeQueue * D.6223;
  gboolean D.6224;
  struct Descriptor * active;
  struct Descriptor * desc;

  active = heap->active;
  if (active != 0B) goto <D.6202>; else goto <D.6203>;
  <D.6202>:
  D.6204 = active->anchor.data.state;
  D.6205 = D.6204 != 1;
  D.6206 = (long int) D.6205;
  D.6207 = __builtin_expect (D.6206, 0);
  if (D.6207 != 0) goto <D.6208>; else goto <D.6209>;
  <D.6208>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 599, "active->anchor.data.state == STATE_PARTIAL");
  <D.6209>:
  descriptor_check_consistency (active, 0);
  <D.6203>:
  goto <D.5883>;
  <D.5882>:
  D.6213 = desc->anchor.data.state;
  if (D.6213 != 1) goto <D.6214>; else goto <D.6211>;
  <D.6214>:
  D.6215 = desc->anchor.data.state;
  if (D.6215 != 2) goto <D.6216>; else goto <D.6211>;
  <D.6216>:
  iftmp.12 = 1;
  goto <D.6212>;
  <D.6211>:
  iftmp.12 = 0;
  <D.6212>:
  D.6217 = iftmp.12 != 0;
  D.6218 = (long int) D.6217;
  D.6219 = __builtin_expect (D.6218, 0);
  if (D.6219 != 0) goto <D.6220>; else goto <D.6221>;
  <D.6220>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 603, "desc->anchor.data.state == STATE_PARTIAL || desc->anchor.data.state == STATE_EMPTY");
  <D.6221>:
  descriptor_check_consistency (desc, 0);
  <D.5883>:
  D.6222 = heap->sc;
  D.6223 = &D.6222->partial;
  desc = mono_lock_free_queue_dequeue (D.6223);
  if (desc != 0B) goto <D.5882>; else goto <D.5884>;
  <D.5884>:
  D.6224 = 1;
  return D.6224;
}


descriptor_check_consistency (struct Descriptor * desc, gboolean print)
{
  <unnamed-unsigned:15> D.6226;
  unsigned int D.6227;
  unsigned int D.6228;
  int max_count.13;
  long int D.6230;
  long int D.6231;
  sizetype D.6232;
  sizetype D.6233;
  bitsizetype D.6234;
  bitsizetype D.6235;
  sizetype D.6236;
  gboolean[0:D.6232] * linked.14;
  struct MonoLockFreeAllocator * D.6245;
  struct MonoLockFreeAllocSizeClass * D.6246;
  unsigned int D.6247;
  <unnamed-unsigned:2> D.6257;
  int D.6258;
  <unnamed-unsigned:15> D.6293;
  void * D.6294;
  unsigned int D.6295;
  sizetype D.6296;
  unsigned int max_count.15;
  int D.6305;
  void * saved_stack.16;
  int count;
  int max_count;
  gboolean linked[0:D.6232] [value-expr: *linked.14];
  int i;
  int last;
  unsigned int index;
  struct Descriptor * avail;

  saved_stack.16 = __builtin_stack_save ();
  try
    {
      D.6226 = desc->anchor.data.count;
      count = (int) D.6226;
      D.6227 = desc->slot_size;
      D.6228 = 16368 / D.6227;
      max_count = (int) D.6228;
      max_count.13 = max_count;
      D.6230 = (long int) max_count.13;
      D.6231 = D.6230 + -1;
      D.6232 = (sizetype) D.6231;
      D.6233 = (sizetype) max_count.13;
      D.6234 = (bitsizetype) D.6233;
      D.6235 = D.6234 * 32;
      D.6233 = (sizetype) max_count.13;
      D.6236 = D.6233 * 4;
      D.6233 = (sizetype) max_count.13;
      D.6234 = (bitsizetype) D.6233;
      D.6235 = D.6234 * 32;
      D.6233 = (sizetype) max_count.13;
      D.6236 = D.6233 * 4;
      linked.14 = __builtin_alloca_with_align (D.6236, 32);
      avail = desc_avail;
      goto <D.5863>;
      <D.5862>:
      if (desc == avail) goto <D.6238>; else goto <D.6239>;
      <D.6238>:
      if (print != 0) goto <D.6240>; else goto <D.6241>;
      <D.6240>:
      monoeg_g_print ("descriptor is in the available list\n");
      goto <D.6242>;
      <D.6241>:
      if (1 != 0) goto <D.6243>; else goto <D.6244>;
      <D.6243>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 546, "FALSE");
      <D.6244>:
      <D.6242>:
      <D.6239>:
      avail = avail->next;
      <D.5863>:
      if (avail != 0B) goto <D.5862>; else goto <D.5864>;
      <D.5864>:
      D.6227 = desc->slot_size;
      D.6245 = desc->heap;
      D.6246 = D.6245->sc;
      D.6247 = D.6246->slot_size;
      if (D.6227 != D.6247) goto <D.6248>; else goto <D.6249>;
      <D.6248>:
      if (print != 0) goto <D.6250>; else goto <D.6251>;
      <D.6250>:
      monoeg_g_print ("slot size doesn\'t match size class\n");
      goto <D.6252>;
      <D.6251>:
      if (1 != 0) goto <D.6253>; else goto <D.6254>;
      <D.6253>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 549, "FALSE");
      <D.6254>:
      <D.6252>:
      <D.6249>:
      if (print != 0) goto <D.6255>; else goto <D.6256>;
      <D.6255>:
      monoeg_g_print ("descriptor %p is ", desc);
      <D.6256>:
      D.6257 = desc->anchor.data.state;
      D.6258 = (int) D.6257;
      switch (D.6258) <default: <D.5869>, case 0: <D.5865>, case 1: <D.5867>, case 2: <D.5868>>
      <D.5865>:
      if (print != 0) goto <D.6259>; else goto <D.6260>;
      <D.6259>:
      monoeg_g_print ("full\n");
      <D.6260>:
      if (count != 0) goto <D.6261>; else goto <D.6262>;
      <D.6261>:
      if (print != 0) goto <D.6263>; else goto <D.6264>;
      <D.6263>:
      monoeg_g_print ("count is not zero: %d\n", count);
      goto <D.6265>;
      <D.6264>:
      if (1 != 0) goto <D.6266>; else goto <D.6267>;
      <D.6266>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 558, "FALSE");
      <D.6267>:
      <D.6265>:
      <D.6262>:
      goto <D.5866>;
      <D.5867>:
      if (print != 0) goto <D.6268>; else goto <D.6269>;
      <D.6268>:
      monoeg_g_print ("partial\n");
      <D.6269>:
      if (count >= max_count) goto <D.6270>; else goto <D.6271>;
      <D.6270>:
      if (print != 0) goto <D.6272>; else goto <D.6273>;
      <D.6272>:
      monoeg_g_print ("count too high: is %d but must be below %d\n", count, max_count);
      goto <D.6274>;
      <D.6273>:
      if (1 != 0) goto <D.6275>; else goto <D.6276>;
      <D.6275>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 563, "FALSE");
      <D.6276>:
      <D.6274>:
      <D.6271>:
      goto <D.5866>;
      <D.5868>:
      if (print != 0) goto <D.6277>; else goto <D.6278>;
      <D.6277>:
      monoeg_g_print ("empty\n");
      <D.6278>:
      if (count != max_count) goto <D.6279>; else goto <D.6280>;
      <D.6279>:
      if (print != 0) goto <D.6281>; else goto <D.6282>;
      <D.6281>:
      monoeg_g_print ("count is wrong: is %d but should be %d\n", count, max_count);
      goto <D.6283>;
      <D.6282>:
      if (1 != 0) goto <D.6284>; else goto <D.6285>;
      <D.6284>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 568, "FALSE");
      <D.6285>:
      <D.6283>:
      <D.6280>:
      goto <D.5866>;
      <D.5869>:
      if (1 != 0) goto <D.6286>; else goto <D.6287>;
      <D.6286>:
      if (print != 0) goto <D.6288>; else goto <D.6289>;
      <D.6288>:
      monoeg_g_print ("invalid state\n");
      goto <D.6290>;
      <D.6289>:
      if (1 != 0) goto <D.6291>; else goto <D.6292>;
      <D.6291>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 571, "FALSE");
      <D.6292>:
      <D.6290>:
      <D.6287>:
      <D.5866>:
      i = 0;
      goto <D.5871>;
      <D.5870>:
      *linked.14[i] = 0;
      i = i + 1;
      <D.5871>:
      if (i < max_count) goto <D.5870>; else goto <D.5872>;
      <D.5872>:
      D.6293 = desc->anchor.data.avail;
      index = (unsigned int) D.6293;
      last = -1;
      i = 0;
      goto <D.5876>;
      <D.5875>:
      {
        void * addr;

        D.6294 = desc->sb;
        D.6227 = desc->slot_size;
        D.6295 = D.6227 * index;
        D.6296 = (sizetype) D.6295;
        addr = D.6294 + D.6296;
        max_count.15 = (unsigned int) max_count;
        if (max_count.15 <= index) goto <D.6298>; else goto <D.6299>;
        <D.6298>:
        if (print != 0) goto <D.6300>; else goto <D.6301>;
        <D.6300>:
        monoeg_g_print ("index %d for %dth available slot, linked from %d, not in range [0 .. %d)\n", index, i, last, max_count);
        goto <D.6302>;
        <D.6301>:
        if (1 != 0) goto <D.6303>; else goto <D.6304>;
        <D.6303>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 583, "FALSE");
        <D.6304>:
        <D.6302>:
        <D.6299>:
        D.6305 = *linked.14[index];
        if (D.6305 != 0) goto <D.6306>; else goto <D.6307>;
        <D.6306>:
        if (print != 0) goto <D.6308>; else goto <D.6309>;
        <D.6308>:
        monoeg_g_print ("%dth available slot %d linked twice\n", i, index);
        goto <D.6310>;
        <D.6309>:
        if (1 != 0) goto <D.6311>; else goto <D.6312>;
        <D.6311>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 584, "FALSE");
        <D.6312>:
        <D.6310>:
        <D.6307>:
        D.6305 = *linked.14[index];
        if (D.6305 != 0) goto <D.5874>; else goto <D.6313>;
        <D.6313>:
        *linked.14[index] = 1;
        last = (int) index;
        index = MEM[(unsigned int *)addr];
      }
      i = i + 1;
      <D.5876>:
      if (i < count) goto <D.5875>; else goto <D.5874>;
      <D.5874>:
    }
  finally
    {
      __builtin_stack_restore (saved_stack.16);
    }
}


mono_lock_free_allocator_init_size_class (struct MonoLockFreeAllocSizeClass * sc, unsigned int slot_size)
{
  _Bool D.6316;
  long int D.6317;
  long int D.6318;
  struct MonoLockFreeQueue * D.6321;

  D.6316 = slot_size > 8184;
  D.6317 = (long int) D.6316;
  D.6318 = __builtin_expect (D.6317, 0);
  if (D.6318 != 0) goto <D.6319>; else goto <D.6320>;
  <D.6319>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 612, "slot_size <= SB_USABLE_SIZE / 2");
  <D.6320>:
  D.6321 = &sc->partial;
  mono_lock_free_queue_init (D.6321);
  sc->slot_size = slot_size;
}


mono_lock_free_allocator_init_allocator (struct MonoLockFreeAllocator * heap, struct MonoLockFreeAllocSizeClass * sc)
{
  heap->sc = sc;
  heap->active = 0B;
}


