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

  <D.7597>:
  addr = alloc_from_active_or_partial (heap);
  if (addr != 0B) goto <D.7596>; else goto <D.7653>;
  <D.7653>:
  addr = alloc_from_new_sb (heap);
  if (addr != 0B) goto <D.7596>; else goto <D.7654>;
  <D.7654>:
  goto <D.7597>;
  <D.7596>:
  D.7655 = addr;
  return D.7655;
}


alloc_from_active_or_partial (struct MonoLockFreeAllocator * heap)
{
  struct _MonoLockFreeAllocDescriptor * * D.7659;
  void * D.7660;
  void * D.7665;
  volatile gint32 * D.7666;
  unsigned char D.7667;
  unsigned char D.7668;
  _Bool D.7671;
  long int D.7672;
  long int D.7673;
  <unnamed-unsigned:15> D.7676;
  int D.7677;
  _Bool D.7678;
  long int D.7679;
  long int D.7680;
  void * D.7683;
  <unnamed-unsigned:15> D.7684;
  unsigned int D.7685;
  unsigned int D.7686;
  unsigned int D.7687;
  unsigned int D.7688;
  _Bool D.7689;
  long int D.7690;
  long int D.7691;
  short unsigned int D.7694;
  <unnamed-unsigned:15> D.7695;
  <unnamed-unsigned:15> D.7696;
  <unnamed-unsigned:15> D.7697;
  unsigned int D.7698;
  unsigned int D.7699;
  int D.7702;
  unsigned char D.7703;
  unsigned char D.7704;
  void * D.7707;
  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.7657>; else goto <D.7658>;
      <D.7657>:
      D.7659 = &heap->active;
      D.7660 = InterlockedCompareExchangePointer (D.7659, 0B, desc);
      if (D.7660 != desc) goto retry; else goto <D.7661>;
      <D.7661>:
      goto <D.7662>;
      <D.7658>:
      desc = heap_get_partial (heap);
      if (desc == 0B) goto <D.7663>; else goto <D.7664>;
      <D.7663>:
      D.7665 = 0B;
      return D.7665;
      <D.7664>:
      <D.7662>:
      <D.7580>:
      {
        unsigned int next;

        D.7666 = &desc->anchor.value;
        old_anchor = MEM[(volatile union Anchor *)D.7666];
        new_anchor = old_anchor;
        D.7667 = BIT_FIELD_REF <old_anchor, 8, 24>;
        D.7668 = D.7667 & 192;
        if (D.7668 == 128) goto <D.7669>; else goto <D.7670>;
        <D.7669>:
        desc_retire (desc);
        goto retry;
        <D.7670>:
        D.7667 = BIT_FIELD_REF <old_anchor, 8, 24>;
        D.7668 = D.7667 & 192;
        D.7671 = D.7668 != 64;
        D.7672 = (long int) D.7671;
        D.7673 = __builtin_expect (D.7672, 0);
        if (D.7673 != 0) goto <D.7674>; else goto <D.7675>;
        <D.7674>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 383, "old_anchor.data.state == STATE_PARTIAL");
        <D.7675>:
        D.7676 = old_anchor.data.count;
        D.7677 = (int) D.7676;
        D.7678 = D.7677 <= 0;
        D.7679 = (long int) D.7678;
        D.7680 = __builtin_expect (D.7679, 0);
        if (D.7680 != 0) goto <D.7681>; else goto <D.7682>;
        <D.7681>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 384, "old_anchor.data.count > 0");
        <D.7682>:
        D.7683 = desc->sb;
        D.7684 = old_anchor.data.avail;
        D.7685 = (unsigned int) D.7684;
        D.7686 = desc->slot_size;
        D.7687 = D.7685 * D.7686;
        addr = D.7683 + D.7687;
        mono_memory_read_barrier ();
        next = MEM[(unsigned int *)addr];
        D.7686 = desc->slot_size;
        D.7688 = 16368 / D.7686;
        D.7689 = D.7688 <= next;
        D.7690 = (long int) D.7689;
        D.7691 = __builtin_expect (D.7690, 0);
        if (D.7691 != 0) goto <D.7692>; else goto <D.7693>;
        <D.7692>:
        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.7693>:
        D.7694 = (short unsigned int) next;
        D.7695 = (<unnamed-unsigned:15>) D.7694;
        new_anchor.data.avail = D.7695;
        D.7696 = new_anchor.data.count;
        D.7697 = D.7696 + 32767;
        new_anchor.data.count = D.7697;
        D.7698 = BIT_FIELD_REF <new_anchor, 32, 0>;
        D.7699 = D.7698 & 1073709056;
        if (D.7699 == 0) goto <D.7700>; else goto <D.7701>;
        <D.7700>:
        new_anchor.data.state = 0;
        <D.7701>:
      }
      D.7702 = set_anchor (desc, old_anchor, new_anchor);
      if (D.7702 == 0) goto <D.7580>; else goto <D.7581>;
      <D.7581>:
      D.7703 = BIT_FIELD_REF <new_anchor, 8, 24>;
      D.7704 = D.7703 & 192;
      if (D.7704 == 64) goto <D.7705>; else goto <D.7706>;
      <D.7705>:
      D.7659 = &heap->active;
      D.7707 = InterlockedCompareExchangePointer (D.7659, desc, 0B);
      if (D.7707 != 0B) goto <D.7708>; else goto <D.7709>;
      <D.7708>:
      heap_put_partial (desc);
      <D.7709>:
      <D.7706>:
      D.7665 = addr;
      return D.7665;
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


heap_get_partial (struct MonoLockFreeAllocator * heap)
{
  struct Descriptor * D.7712;
  struct MonoLockFreeAllocSizeClass * D.7713;

  D.7713 = heap->sc;
  D.7712 = list_get_partial (D.7713);
  return D.7712;
}


list_get_partial (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.7715;
  struct Descriptor * D.7718;
  <unnamed-unsigned:2> D.7719;

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

    D.7715 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.7715);
    if (desc == 0B) goto <D.7716>; else goto <D.7717>;
    <D.7716>:
    D.7718 = 0B;
    return D.7718;
    <D.7717>:
    D.7719 = desc->anchor.data.state;
    if (D.7719 != 2) goto <D.7720>; else goto <D.7721>;
    <D.7720>:
    D.7718 = desc;
    return D.7718;
    <D.7721>:
    desc_retire (desc);
  }
  goto <D.7546>;
}


desc_retire (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.7723;
  _Bool D.7724;
  long int D.7725;
  long int D.7726;
  int D.7729;
  _Bool D.7730;
  long int D.7731;
  long int D.7732;
  void * D.7735;

  D.7723 = desc->anchor.data.state;
  D.7724 = D.7723 != 2;
  D.7725 = (long int) D.7724;
  D.7726 = __builtin_expect (D.7725, 0);
  if (D.7726 != 0) goto <D.7727>; else goto <D.7728>;
  <D.7727>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 251, "desc->anchor.data.state == STATE_EMPTY");
  <D.7728>:
  D.7729 = desc->in_use;
  D.7730 = D.7729 == 0;
  D.7731 = (long int) D.7730;
  D.7732 = __builtin_expect (D.7731, 0);
  if (D.7732 != 0) goto <D.7733>; else goto <D.7734>;
  <D.7733>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 252, "desc->in_use");
  <D.7734>:
  desc->in_use = 0;
  D.7735 = desc->sb;
  free_sb (D.7735);
  mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, 0, 1);
}


desc_enqueue_avail (void * _desc)
{
  <unnamed-unsigned:2> D.7736;
  _Bool D.7737;
  long int D.7738;
  long int D.7739;
  int D.7742;
  _Bool D.7743;
  long int D.7744;
  long int D.7745;
  void * D.7748;
  struct Descriptor * desc;
  struct Descriptor * old_head;

  desc = _desc;
  D.7736 = desc->anchor.data.state;
  D.7737 = D.7736 != 2;
  D.7738 = (long int) D.7737;
  D.7739 = __builtin_expect (D.7738, 0);
  if (D.7739 != 0) goto <D.7740>; else goto <D.7741>;
  <D.7740>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 238, "desc->anchor.data.state == STATE_EMPTY");
  <D.7741>:
  D.7742 = desc->in_use;
  D.7743 = D.7742 != 0;
  D.7744 = (long int) D.7743;
  D.7745 = __builtin_expect (D.7744, 0);
  if (D.7745 != 0) goto <D.7746>; else goto <D.7747>;
  <D.7746>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 239, "!desc->in_use");
  <D.7747>:
  <D.7537>:
  old_head = desc_avail;
  desc->next = old_head;
  mono_memory_write_barrier ();
  D.7748 = InterlockedCompareExchangePointer (&desc_avail, desc, old_head);
  if (D.7748 != old_head) goto <D.7537>; else goto <D.7538>;
  <D.7538>:
}


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.7750;
  void * D.7751;
  _Bool D.7752;
  long int D.7753;
  long int D.7754;
  void * sb_header;

  sb.0 = (long unsigned int) sb;
  D.7750 = sb.0 & 4294950912;
  sb_header = (void *) D.7750;
  D.7751 = sb_header + 16;
  D.7752 = D.7751 != sb;
  D.7753 = (long int) D.7752;
  D.7754 = __builtin_expect (D.7753, 0);
  if (D.7754 != 0) goto <D.7755>; else goto <D.7756>;
  <D.7755>:
  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.7756>:
  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 char D.7757;
  unsigned char D.7758;
  unsigned char D.7761;
  unsigned char D.7762;
  _Bool D.7763;
  long int D.7764;
  long int D.7765;
  gboolean D.7768;
  volatile gint32 * D.7769;
  int D.7770;
  int D.7771;
  int D.7772;
  _Bool D.7773;

  D.7757 = BIT_FIELD_REF <old_anchor, 8, 24>;
  D.7758 = D.7757 & 192;
  if (D.7758 == 128) goto <D.7759>; else goto <D.7760>;
  <D.7759>:
  D.7761 = BIT_FIELD_REF <new_anchor, 8, 24>;
  D.7762 = D.7761 & 192;
  D.7763 = D.7762 != 128;
  D.7764 = (long int) D.7763;
  D.7765 = __builtin_expect (D.7764, 0);
  if (D.7765 != 0) goto <D.7766>; else goto <D.7767>;
  <D.7766>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 349, "new_anchor.data.state == STATE_EMPTY");
  <D.7767>:
  <D.7760>:
  D.7769 = &desc->anchor.value;
  D.7770 = new_anchor.value;
  D.7771 = old_anchor.value;
  D.7772 = InterlockedCompareExchange (D.7769, D.7770, D.7771);
  D.7771 = old_anchor.value;
  D.7773 = D.7772 == D.7771;
  D.7768 = (gboolean) D.7773;
  return D.7768;
}


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

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


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

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


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


list_put_partial (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.7785;
  _Bool D.7786;
  long int D.7787;
  long int D.7788;

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


desc_put_partial (void * _desc)
{
  <unnamed-unsigned:2> D.7791;
  _Bool D.7792;
  long int D.7793;
  long int D.7794;
  struct MonoLockFreeQueueNode * D.7797;
  struct MonoLockFreeAllocator * D.7798;
  struct MonoLockFreeAllocSizeClass * D.7799;
  struct MonoLockFreeQueue * D.7800;
  struct Descriptor * desc;

  desc = _desc;
  D.7791 = desc->anchor.data.state;
  D.7792 = D.7791 == 0;
  D.7793 = (long int) D.7792;
  D.7794 = __builtin_expect (D.7793, 0);
  if (D.7794 != 0) goto <D.7795>; else goto <D.7796>;
  <D.7795>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 297, "desc->anchor.data.state != STATE_FULL");
  <D.7796>:
  D.7797 = &desc->node;
  mono_lock_free_queue_node_free (D.7797);
  D.7798 = desc->heap;
  D.7799 = D.7798->sc;
  D.7800 = &D.7799->partial;
  D.7797 = &desc->node;
  mono_lock_free_queue_enqueue (D.7800, D.7797);
}


alloc_from_new_sb (struct MonoLockFreeAllocator * heap)
{
  void * D.7801;
  struct MonoLockFreeAllocSizeClass * D.7802;
  unsigned int D.7803;
  void * D.7804;
  unsigned int D.7805;
  unsigned int * D.7806;
  unsigned int D.7807;
  unsigned int D.7808;
  unsigned int D.7809;
  short unsigned int D.7810;
  short unsigned int D.7811;
  <unnamed-unsigned:15> D.7812;
  struct _MonoLockFreeAllocDescriptor * * D.7813;
  void * D.7814;
  void * D.7817;
  unsigned int slot_size;
  unsigned int count;
  unsigned int i;
  struct Descriptor * desc;

  desc = desc_alloc ();
  D.7801 = alloc_sb (desc);
  desc->sb = D.7801;
  D.7802 = heap->sc;
  D.7803 = D.7802->slot_size;
  desc->slot_size = D.7803;
  slot_size = desc->slot_size;
  count = 16368 / slot_size;
  i = 1;
  goto <D.7590>;
  <D.7589>:
  D.7804 = desc->sb;
  D.7805 = i * slot_size;
  D.7806 = D.7804 + D.7805;
  D.7807 = i + 1;
  *D.7806 = D.7807;
  i = i + 1;
  <D.7590>:
  D.7808 = count + 4294967295;
  if (D.7808 > i) goto <D.7589>; else goto <D.7591>;
  <D.7591>:
  desc->heap = heap;
  desc->anchor.data.avail = 1;
  D.7802 = heap->sc;
  D.7803 = D.7802->slot_size;
  desc->slot_size = D.7803;
  desc->max_count = count;
  D.7809 = desc->max_count;
  D.7810 = (short unsigned int) D.7809;
  D.7811 = D.7810 + 65535;
  D.7812 = (<unnamed-unsigned:15>) D.7811;
  desc->anchor.data.count = D.7812;
  desc->anchor.data.state = 1;
  mono_memory_write_barrier ();
  D.7813 = &heap->active;
  D.7814 = InterlockedCompareExchangePointer (D.7813, desc, 0B);
  if (D.7814 == 0B) goto <D.7815>; else goto <D.7816>;
  <D.7815>:
  D.7817 = desc->sb;
  return D.7817;
  <D.7816>:
  desc->anchor.data.state = 2;
  desc_retire (desc);
  D.7817 = 0B;
  return D.7817;
}


desc_alloc ()
{
  void * D.7821;
  _Bool D.7822;
  unsigned int D.7824;
  struct Descriptor * iftmp.5;
  int D.7828;
  unsigned int D.7829;
  unsigned int D.7830;
  struct MonoLockFreeQueueNode * D.7832;
  struct Descriptor * D.7833;
  void * D.7834;
  _Bool D.7835;
  int D.7841;
  _Bool D.7842;
  long int D.7843;
  long int D.7844;
  struct Descriptor * D.7847;
  struct MonoThreadHazardPointers * hp;
  struct Descriptor * desc;

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

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

      next = desc->next;
      D.7821 = InterlockedCompareExchangePointer (&desc_avail, next, desc);
      D.7822 = D.7821 == desc;
      success = (gboolean) D.7822;
    }
    goto <D.7823>;
    <D.7820>:
    {
      size_t desc_size;
      struct Descriptor * d;
      int i;

      desc_size = 32;
      D.7824 = desc_size * 64;
      desc = mono_sgen_alloc_os_memory (D.7824, 1);
      d = desc;
      i = 0;
      goto <D.7528>;
      <D.7527>:
      {
        struct Descriptor * next;

        if (i != 63) goto <D.7826>; else goto <D.7827>;
        <D.7826>:
        D.7828 = i + 1;
        D.7829 = (unsigned int) D.7828;
        D.7830 = D.7829 * desc_size;
        iftmp.5 = desc + D.7830;
        goto <D.7831>;
        <D.7827>:
        iftmp.5 = 0B;
        <D.7831>:
        next = iftmp.5;
        d->next = next;
        D.7832 = &d->node;
        mono_lock_free_queue_node_init (D.7832, 1);
        d = next;
      }
      i = i + 1;
      <D.7528>:
      if (i <= 63) goto <D.7527>; else goto <D.7529>;
      <D.7529>:
      mono_memory_write_barrier ();
      D.7833 = desc->next;
      D.7834 = InterlockedCompareExchangePointer (&desc_avail, D.7833, 0B);
      D.7835 = D.7834 == 0B;
      success = (gboolean) D.7835;
      if (success == 0) goto <D.7836>; else goto <D.7837>;
      <D.7836>:
      D.7824 = desc_size * 64;
      mono_sgen_free_os_memory (desc, D.7824);
      <D.7837>:
    }
    <D.7823>:
    if (0 != 0) goto <D.7838>; else goto <D.7839>;
    <D.7838>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 220, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
    <D.7839>:
    hp->hazard_pointers[1] = 0B;
    if (success != 0) goto <D.7530>; else goto <D.7840>;
    <D.7840>:
  }
  goto <D.7531>;
  <D.7530>:
  D.7841 = desc->in_use;
  D.7842 = D.7841 != 0;
  D.7843 = (long int) D.7842;
  D.7844 = __builtin_expect (D.7843, 0);
  if (D.7844 != 0) goto <D.7845>; else goto <D.7846>;
  <D.7845>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 226, "!desc->in_use");
  <D.7846>:
  desc->in_use = 1;
  D.7847 = desc;
  return D.7847;
}


mono_sgen_alloc_os_memory (size_t size, int activate)
{
  void * D.7849;
  long unsigned int D.7850;
  int D.7851;

  D.7850 = prot_flags_for_activate (activate);
  D.7851 = (int) D.7850;
  D.7849 = mono_valloc (0B, size, D.7851);
  return D.7849;
}


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

  if (activate != 0) goto <D.7854>; else goto <D.7855>;
  <D.7854>:
  iftmp.6 = 3;
  goto <D.7856>;
  <D.7855>:
  iftmp.6 = 0;
  <D.7856>:
  prot_flags = iftmp.6;
  D.7857 = prot_flags | 80;
  return D.7857;
}


alloc_sb (struct Descriptor * desc)
{
  long unsigned int sb_header.7;
  long unsigned int D.7860;
  void * D.7861;
  _Bool D.7862;
  long int D.7863;
  long int D.7864;
  struct Descriptor * * D.7867;
  void * D.7868;
  void * sb_header;

  sb_header = mono_sgen_alloc_os_memory_aligned (16384, 16384, 1);
  sb_header.7 = (long unsigned int) sb_header;
  D.7860 = sb_header.7 & 4294950912;
  D.7861 = (void *) D.7860;
  D.7862 = D.7861 != sb_header;
  D.7863 = (long int) D.7862;
  D.7864 = __builtin_expect (D.7863, 0);
  if (D.7864 != 0) goto <D.7865>; else goto <D.7866>;
  <D.7865>:
  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.7866>:
  sb_header.7 = (long unsigned int) sb_header;
  D.7860 = sb_header.7 & 4294950912;
  D.7867 = (struct Descriptor * *) D.7860;
  *D.7867 = desc;
  D.7868 = sb_header + 16;
  return D.7868;
}


mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate)
{
  void * D.7870;
  long unsigned int D.7871;
  int D.7872;

  D.7871 = prot_flags_for_activate (activate);
  D.7872 = (int) D.7871;
  D.7870 = mono_valloc_aligned (size, alignment, D.7872);
  return D.7870;
}


mono_lock_free_free (void * ptr)
{
  long unsigned int ptr.8;
  long unsigned int D.7875;
  struct Descriptor * * D.7876;
  long unsigned int sb.9;
  long unsigned int D.7878;
  long unsigned int D.7879;
  _Bool D.7880;
  long int D.7881;
  long int D.7882;
  volatile gint32 * D.7885;
  <unnamed-unsigned:15> D.7886;
  unsigned int D.7887;
  int ptr.10;
  int sb.11;
  int D.7890;
  unsigned int D.7891;
  unsigned int D.7892;
  unsigned int D.7893;
  short unsigned int D.7894;
  <unnamed-unsigned:15> D.7895;
  <unnamed-unsigned:15> D.7896;
  unsigned int D.7897;
  unsigned int D.7898;
  _Bool D.7899;
  long int D.7900;
  long int D.7901;
  unsigned char D.7904;
  unsigned char D.7905;
  <unnamed-unsigned:15> D.7908;
  <unnamed-unsigned:15> D.7909;
  unsigned int D.7910;
  unsigned int D.7911;
  int D.7914;
  unsigned char D.7915;
  unsigned char D.7916;
  _Bool D.7919;
  long int D.7920;
  long int D.7921;
  struct _MonoLockFreeAllocDescriptor * * D.7924;
  void * D.7925;
  struct MonoLockFreeAllocSizeClass * D.7929;
  _Bool D.7933;
  long int D.7934;
  long int D.7935;
  struct MonoLockFreeAllocator * D.7938;
  struct _MonoLockFreeAllocDescriptor * * D.7939;
  void * D.7940;
  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.7875 = ptr.8 & 4294950912;
      D.7876 = (struct Descriptor * *) D.7875;
      desc = *D.7876;
      sb = desc->sb;
      ptr.8 = (long unsigned int) ptr;
      sb.9 = (long unsigned int) sb;
      D.7878 = ptr.8 ^ sb.9;
      D.7879 = D.7878 & 4294950912;
      D.7880 = D.7879 != 0;
      D.7881 = (long int) D.7880;
      D.7882 = __builtin_expect (D.7881, 0);
      if (D.7882 != 0) goto <D.7883>; else goto <D.7884>;
      <D.7883>:
      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.7884>:
      <D.7606>:
      D.7885 = &desc->anchor.value;
      old_anchor = MEM[(volatile union Anchor *)D.7885];
      new_anchor = old_anchor;
      D.7886 = old_anchor.data.avail;
      D.7887 = (unsigned int) D.7886;
      MEM[(unsigned int *)ptr] = D.7887;
      ptr.10 = (int) ptr;
      sb.11 = (int) sb;
      D.7890 = ptr.10 - sb.11;
      D.7891 = (unsigned int) D.7890;
      D.7892 = desc->slot_size;
      D.7893 = D.7891 / D.7892;
      D.7894 = (short unsigned int) D.7893;
      D.7895 = (<unnamed-unsigned:15>) D.7894;
      new_anchor.data.avail = D.7895;
      D.7896 = new_anchor.data.avail;
      D.7897 = (unsigned int) D.7896;
      D.7892 = desc->slot_size;
      D.7898 = 16368 / D.7892;
      D.7899 = D.7897 >= D.7898;
      D.7900 = (long int) D.7899;
      D.7901 = __builtin_expect (D.7900, 0);
      if (D.7901 != 0) goto <D.7902>; else goto <D.7903>;
      <D.7902>:
      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.7903>:
      D.7904 = BIT_FIELD_REF <old_anchor, 8, 24>;
      D.7905 = D.7904 & 192;
      if (D.7905 == 0) goto <D.7906>; else goto <D.7907>;
      <D.7906>:
      new_anchor.data.state = 1;
      <D.7907>:
      D.7908 = new_anchor.data.count;
      D.7909 = D.7908 + 1;
      new_anchor.data.count = D.7909;
      D.7908 = new_anchor.data.count;
      D.7910 = (unsigned int) D.7908;
      D.7911 = desc->max_count;
      if (D.7910 == D.7911) goto <D.7912>; else goto <D.7913>;
      <D.7912>:
      heap = desc->heap;
      new_anchor.data.state = 2;
      <D.7913>:
      D.7914 = set_anchor (desc, old_anchor, new_anchor);
      if (D.7914 == 0) goto <D.7606>; else goto <D.7607>;
      <D.7607>:
      D.7915 = BIT_FIELD_REF <new_anchor, 8, 24>;
      D.7916 = D.7915 & 192;
      if (D.7916 == 128) goto <D.7917>; else goto <D.7918>;
      <D.7917>:
      D.7904 = BIT_FIELD_REF <old_anchor, 8, 24>;
      D.7905 = D.7904 & 192;
      D.7919 = D.7905 == 128;
      D.7920 = (long int) D.7919;
      D.7921 = __builtin_expect (D.7920, 0);
      if (D.7921 != 0) goto <D.7922>; else goto <D.7923>;
      <D.7922>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 495, "old_anchor.data.state != STATE_EMPTY");
      <D.7923>:
      D.7924 = &heap->active;
      D.7925 = InterlockedCompareExchangePointer (D.7924, 0B, desc);
      if (D.7925 == desc) goto <D.7926>; else goto <D.7927>;
      <D.7926>:
      desc_retire (desc);
      goto <D.7928>;
      <D.7927>:
      D.7929 = heap->sc;
      list_remove_empty_desc (D.7929);
      <D.7928>:
      goto <D.7930>;
      <D.7918>:
      D.7904 = BIT_FIELD_REF <old_anchor, 8, 24>;
      D.7905 = D.7904 & 192;
      if (D.7905 == 0) goto <D.7931>; else goto <D.7932>;
      <D.7931>:
      D.7915 = BIT_FIELD_REF <new_anchor, 8, 24>;
      D.7916 = D.7915 & 192;
      D.7933 = D.7916 != 64;
      D.7934 = (long int) D.7933;
      D.7935 = __builtin_expect (D.7934, 0);
      if (D.7935 != 0) goto <D.7936>; else goto <D.7937>;
      <D.7936>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 513, "new_anchor.data.state == STATE_PARTIAL");
      <D.7937>:
      D.7938 = desc->heap;
      D.7939 = &D.7938->active;
      D.7940 = InterlockedCompareExchangePointer (D.7939, desc, 0B);
      if (D.7940 != 0B) goto <D.7941>; else goto <D.7942>;
      <D.7941>:
      heap_put_partial (desc);
      <D.7942>:
      <D.7932>:
      <D.7930>:
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


list_remove_empty_desc (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.7943;
  <unnamed-unsigned:2> D.7946;
  struct MonoLockFreeAllocator * D.7950;
  struct MonoLockFreeAllocSizeClass * D.7951;
  _Bool D.7952;
  long int D.7953;
  long int D.7954;
  int num_non_empty;

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

    D.7943 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.7943);
    if (desc == 0B) goto <D.7944>; else goto <D.7945>;
    <D.7944>:
    return;
    <D.7945>:
    D.7946 = desc->anchor.data.state;
    if (D.7946 == 2) goto <D.7947>; else goto <D.7948>;
    <D.7947>:
    desc_retire (desc);
    goto <D.7949>;
    <D.7948>:
    D.7950 = desc->heap;
    D.7951 = D.7950->sc;
    D.7952 = D.7951 != sc;
    D.7953 = (long int) D.7952;
    D.7954 = __builtin_expect (D.7953, 0);
    if (D.7954 != 0) goto <D.7955>; else goto <D.7956>;
    <D.7955>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 325, "desc->heap->sc == sc");
    <D.7956>:
    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.7957>; else goto <D.7958>;
    <D.7957>:
    return;
    <D.7958>:
    <D.7949>:
  }
  goto <D.7559>;
}


mono_lock_free_allocator_check_consistency (struct MonoLockFreeAllocator * heap)
{
  <unnamed-unsigned:2> D.7962;
  _Bool D.7963;
  long int D.7964;
  long int D.7965;
  int iftmp.12;
  <unnamed-unsigned:2> D.7971;
  <unnamed-unsigned:2> D.7973;
  _Bool D.7975;
  long int D.7976;
  long int D.7977;
  struct MonoLockFreeAllocSizeClass * D.7980;
  struct MonoLockFreeQueue * D.7981;
  gboolean D.7982;
  struct Descriptor * active;
  struct Descriptor * desc;

  active = heap->active;
  if (active != 0B) goto <D.7960>; else goto <D.7961>;
  <D.7960>:
  D.7962 = active->anchor.data.state;
  D.7963 = D.7962 != 1;
  D.7964 = (long int) D.7963;
  D.7965 = __builtin_expect (D.7964, 0);
  if (D.7965 != 0) goto <D.7966>; else goto <D.7967>;
  <D.7966>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 599, "active->anchor.data.state == STATE_PARTIAL");
  <D.7967>:
  descriptor_check_consistency (active, 0);
  <D.7961>:
  goto <D.7640>;
  <D.7639>:
  D.7971 = desc->anchor.data.state;
  if (D.7971 != 1) goto <D.7972>; else goto <D.7969>;
  <D.7972>:
  D.7973 = desc->anchor.data.state;
  if (D.7973 != 2) goto <D.7974>; else goto <D.7969>;
  <D.7974>:
  iftmp.12 = 1;
  goto <D.7970>;
  <D.7969>:
  iftmp.12 = 0;
  <D.7970>:
  D.7975 = iftmp.12 != 0;
  D.7976 = (long int) D.7975;
  D.7977 = __builtin_expect (D.7976, 0);
  if (D.7977 != 0) goto <D.7978>; else goto <D.7979>;
  <D.7978>:
  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.7979>:
  descriptor_check_consistency (desc, 0);
  <D.7640>:
  D.7980 = heap->sc;
  D.7981 = &D.7980->partial;
  desc = mono_lock_free_queue_dequeue (D.7981);
  if (desc != 0B) goto <D.7639>; else goto <D.7641>;
  <D.7641>:
  D.7982 = 1;
  return D.7982;
}


descriptor_check_consistency (struct Descriptor * desc, gboolean print)
{
  <unnamed-unsigned:15> D.7984;
  unsigned int D.7985;
  unsigned int D.7986;
  int max_count.13;
  int D.7988;
  sizetype D.7989;
  sizetype max_count.14;
  bitsizetype D.7991;
  bitsizetype D.7992;
  sizetype D.7993;
  gboolean[0:D.7989] * linked.15;
  struct MonoLockFreeAllocator * D.8002;
  struct MonoLockFreeAllocSizeClass * D.8003;
  unsigned int D.8004;
  <unnamed-unsigned:2> D.8014;
  int D.8015;
  <unnamed-unsigned:15> D.8050;
  void * D.8051;
  unsigned int D.8052;
  unsigned int max_count.16;
  int D.8061;
  void * saved_stack.17;
  int count;
  int max_count;
  gboolean linked[0:D.7989] [value-expr: *linked.15];
  int i;
  int last;
  unsigned int index;
  struct Descriptor * avail;

  saved_stack.17 = __builtin_stack_save ();
  try
    {
      D.7984 = desc->anchor.data.count;
      count = (int) D.7984;
      D.7985 = desc->slot_size;
      D.7986 = 16368 / D.7985;
      max_count = (int) D.7986;
      max_count.13 = max_count;
      D.7988 = max_count.13 + -1;
      D.7989 = (sizetype) D.7988;
      max_count.14 = (sizetype) max_count.13;
      D.7991 = (bitsizetype) max_count.14;
      D.7992 = D.7991 * 32;
      max_count.14 = (sizetype) max_count.13;
      D.7993 = max_count.14 * 4;
      max_count.14 = (sizetype) max_count.13;
      D.7991 = (bitsizetype) max_count.14;
      D.7992 = D.7991 * 32;
      max_count.14 = (sizetype) max_count.13;
      D.7993 = max_count.14 * 4;
      linked.15 = __builtin_alloca_with_align (D.7993, 32);
      avail = desc_avail;
      goto <D.7620>;
      <D.7619>:
      if (desc == avail) goto <D.7995>; else goto <D.7996>;
      <D.7995>:
      if (print != 0) goto <D.7997>; else goto <D.7998>;
      <D.7997>:
      monoeg_g_print ("descriptor is in the available list\n");
      goto <D.7999>;
      <D.7998>:
      if (1 != 0) goto <D.8000>; else goto <D.8001>;
      <D.8000>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 546, "FALSE");
      <D.8001>:
      <D.7999>:
      <D.7996>:
      avail = avail->next;
      <D.7620>:
      if (avail != 0B) goto <D.7619>; else goto <D.7621>;
      <D.7621>:
      D.7985 = desc->slot_size;
      D.8002 = desc->heap;
      D.8003 = D.8002->sc;
      D.8004 = D.8003->slot_size;
      if (D.7985 != D.8004) goto <D.8005>; else goto <D.8006>;
      <D.8005>:
      if (print != 0) goto <D.8007>; else goto <D.8008>;
      <D.8007>:
      monoeg_g_print ("slot size doesn\'t match size class\n");
      goto <D.8009>;
      <D.8008>:
      if (1 != 0) goto <D.8010>; else goto <D.8011>;
      <D.8010>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 549, "FALSE");
      <D.8011>:
      <D.8009>:
      <D.8006>:
      if (print != 0) goto <D.8012>; else goto <D.8013>;
      <D.8012>:
      monoeg_g_print ("descriptor %p is ", desc);
      <D.8013>:
      D.8014 = desc->anchor.data.state;
      D.8015 = (int) D.8014;
      switch (D.8015) <default: <D.7626>, case 0: <D.7622>, case 1: <D.7624>, case 2: <D.7625>>
      <D.7622>:
      if (print != 0) goto <D.8016>; else goto <D.8017>;
      <D.8016>:
      monoeg_g_print ("full\n");
      <D.8017>:
      if (count != 0) goto <D.8018>; else goto <D.8019>;
      <D.8018>:
      if (print != 0) goto <D.8020>; else goto <D.8021>;
      <D.8020>:
      monoeg_g_print ("count is not zero: %d\n", count);
      goto <D.8022>;
      <D.8021>:
      if (1 != 0) goto <D.8023>; else goto <D.8024>;
      <D.8023>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 558, "FALSE");
      <D.8024>:
      <D.8022>:
      <D.8019>:
      goto <D.7623>;
      <D.7624>:
      if (print != 0) goto <D.8025>; else goto <D.8026>;
      <D.8025>:
      monoeg_g_print ("partial\n");
      <D.8026>:
      if (count >= max_count) goto <D.8027>; else goto <D.8028>;
      <D.8027>:
      if (print != 0) goto <D.8029>; else goto <D.8030>;
      <D.8029>:
      monoeg_g_print ("count too high: is %d but must be below %d\n", count, max_count);
      goto <D.8031>;
      <D.8030>:
      if (1 != 0) goto <D.8032>; else goto <D.8033>;
      <D.8032>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 563, "FALSE");
      <D.8033>:
      <D.8031>:
      <D.8028>:
      goto <D.7623>;
      <D.7625>:
      if (print != 0) goto <D.8034>; else goto <D.8035>;
      <D.8034>:
      monoeg_g_print ("empty\n");
      <D.8035>:
      if (count != max_count) goto <D.8036>; else goto <D.8037>;
      <D.8036>:
      if (print != 0) goto <D.8038>; else goto <D.8039>;
      <D.8038>:
      monoeg_g_print ("count is wrong: is %d but should be %d\n", count, max_count);
      goto <D.8040>;
      <D.8039>:
      if (1 != 0) goto <D.8041>; else goto <D.8042>;
      <D.8041>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 568, "FALSE");
      <D.8042>:
      <D.8040>:
      <D.8037>:
      goto <D.7623>;
      <D.7626>:
      if (1 != 0) goto <D.8043>; else goto <D.8044>;
      <D.8043>:
      if (print != 0) goto <D.8045>; else goto <D.8046>;
      <D.8045>:
      monoeg_g_print ("invalid state\n");
      goto <D.8047>;
      <D.8046>:
      if (1 != 0) goto <D.8048>; else goto <D.8049>;
      <D.8048>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 571, "FALSE");
      <D.8049>:
      <D.8047>:
      <D.8044>:
      <D.7623>:
      i = 0;
      goto <D.7628>;
      <D.7627>:
      *linked.15[i] = 0;
      i = i + 1;
      <D.7628>:
      if (i < max_count) goto <D.7627>; else goto <D.7629>;
      <D.7629>:
      D.8050 = desc->anchor.data.avail;
      index = (unsigned int) D.8050;
      last = -1;
      i = 0;
      goto <D.7633>;
      <D.7632>:
      {
        void * addr;

        D.8051 = desc->sb;
        D.7985 = desc->slot_size;
        D.8052 = D.7985 * index;
        addr = D.8051 + D.8052;
        max_count.16 = (unsigned int) max_count;
        if (max_count.16 <= index) goto <D.8054>; else goto <D.8055>;
        <D.8054>:
        if (print != 0) goto <D.8056>; else goto <D.8057>;
        <D.8056>:
        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.8058>;
        <D.8057>:
        if (1 != 0) goto <D.8059>; else goto <D.8060>;
        <D.8059>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 583, "FALSE");
        <D.8060>:
        <D.8058>:
        <D.8055>:
        D.8061 = *linked.15[index];
        if (D.8061 != 0) goto <D.8062>; else goto <D.8063>;
        <D.8062>:
        if (print != 0) goto <D.8064>; else goto <D.8065>;
        <D.8064>:
        monoeg_g_print ("%dth available slot %d linked twice\n", i, index);
        goto <D.8066>;
        <D.8065>:
        if (1 != 0) goto <D.8067>; else goto <D.8068>;
        <D.8067>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 584, "FALSE");
        <D.8068>:
        <D.8066>:
        <D.8063>:
        D.8061 = *linked.15[index];
        if (D.8061 != 0) goto <D.7631>; else goto <D.8069>;
        <D.8069>:
        *linked.15[index] = 1;
        last = (int) index;
        index = MEM[(unsigned int *)addr];
      }
      i = i + 1;
      <D.7633>:
      if (i < count) goto <D.7632>; else goto <D.7631>;
      <D.7631>:
    }
  finally
    {
      __builtin_stack_restore (saved_stack.17);
    }
}


mono_lock_free_allocator_init_size_class (struct MonoLockFreeAllocSizeClass * sc, unsigned int slot_size)
{
  _Bool D.8072;
  long int D.8073;
  long int D.8074;
  struct MonoLockFreeQueue * D.8077;

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


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


