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

  <D.5010>:
  addr = alloc_from_active_or_partial (heap);
  if (addr != 0B) goto <D.5009>; else goto <D.5064>;
  <D.5064>:
  addr = alloc_from_new_sb (heap);
  if (addr != 0B) goto <D.5009>; else goto <D.5065>;
  <D.5065>:
  goto <D.5010>;
  <D.5009>:
  D.5066 = addr;
  return D.5066;
}


alloc_from_active_or_partial (struct MonoLockFreeAllocator * heap)
{
  struct _MonoLockFreeAllocDescriptor * * D.5070;
  void * D.5071;
  void * D.5076;
  volatile gint32 * D.5077;
  unsigned int D.5078;
  unsigned int D.5079;
  _Bool D.5082;
  long int D.5083;
  long int D.5084;
  <unnamed-unsigned:15> D.5087;
  int D.5088;
  _Bool D.5089;
  long int D.5090;
  long int D.5091;
  void * D.5094;
  <unnamed-unsigned:15> D.5095;
  unsigned int D.5096;
  unsigned int D.5097;
  unsigned int D.5098;
  unsigned int D.5099;
  _Bool D.5100;
  long int D.5101;
  long int D.5102;
  short unsigned int D.5105;
  <unnamed-unsigned:15> D.5106;
  <unnamed-unsigned:15> D.5107;
  <unnamed-unsigned:15> D.5108;
  unsigned int D.5109;
  unsigned int D.5110;
  int D.5113;
  unsigned int D.5114;
  void * D.5117;
  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.5068>; else goto <D.5069>;
      <D.5068>:
      D.5070 = &heap->active;
      D.5071 = InterlockedCompareExchangePointer (D.5070, 0B, desc);
      if (D.5071 != desc) goto retry; else goto <D.5072>;
      <D.5072>:
      goto <D.5073>;
      <D.5069>:
      desc = heap_get_partial (heap);
      if (desc == 0B) goto <D.5074>; else goto <D.5075>;
      <D.5074>:
      D.5076 = 0B;
      return D.5076;
      <D.5075>:
      <D.5073>:
      <D.4993>:
      {
        unsigned int next;

        D.5077 = &desc->anchor.value;
        old_anchor = MEM[(volatile union Anchor *)D.5077];
        new_anchor = old_anchor;
        D.5078 = BIT_FIELD_REF <old_anchor, 32, 0>;
        D.5079 = D.5078 & 3221225472;
        if (D.5079 == 2147483648) goto <D.5080>; else goto <D.5081>;
        <D.5080>:
        desc_retire (desc);
        goto retry;
        <D.5081>:
        D.5078 = BIT_FIELD_REF <old_anchor, 32, 0>;
        D.5079 = D.5078 & 3221225472;
        D.5082 = D.5079 != 1073741824;
        D.5083 = (long int) D.5082;
        D.5084 = __builtin_expect (D.5083, 0);
        if (D.5084 != 0) goto <D.5085>; else goto <D.5086>;
        <D.5085>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 383, "old_anchor.data.state == STATE_PARTIAL");
        <D.5086>:
        D.5087 = old_anchor.data.count;
        D.5088 = (int) D.5087;
        D.5089 = D.5088 <= 0;
        D.5090 = (long int) D.5089;
        D.5091 = __builtin_expect (D.5090, 0);
        if (D.5091 != 0) goto <D.5092>; else goto <D.5093>;
        <D.5092>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 384, "old_anchor.data.count > 0");
        <D.5093>:
        D.5094 = desc->sb;
        D.5095 = old_anchor.data.avail;
        D.5096 = (unsigned int) D.5095;
        D.5097 = desc->slot_size;
        D.5098 = D.5096 * D.5097;
        addr = D.5094 + D.5098;
        mono_memory_read_barrier ();
        next = MEM[(unsigned int *)addr];
        D.5097 = desc->slot_size;
        D.5099 = 16368 / D.5097;
        D.5100 = D.5099 <= next;
        D.5101 = (long int) D.5100;
        D.5102 = __builtin_expect (D.5101, 0);
        if (D.5102 != 0) goto <D.5103>; else goto <D.5104>;
        <D.5103>:
        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.5104>:
        D.5105 = (short unsigned int) next;
        D.5106 = (<unnamed-unsigned:15>) D.5105;
        new_anchor.data.avail = D.5106;
        D.5107 = new_anchor.data.count;
        D.5108 = D.5107 + 32767;
        new_anchor.data.count = D.5108;
        D.5109 = BIT_FIELD_REF <new_anchor, 32, 0>;
        D.5110 = D.5109 & 1073709056;
        if (D.5110 == 0) goto <D.5111>; else goto <D.5112>;
        <D.5111>:
        new_anchor.data.state = 0;
        <D.5112>:
      }
      D.5113 = set_anchor (desc, old_anchor, new_anchor);
      if (D.5113 == 0) goto <D.4993>; else goto <D.4994>;
      <D.4994>:
      D.5109 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.5114 = D.5109 & 3221225472;
      if (D.5114 == 1073741824) goto <D.5115>; else goto <D.5116>;
      <D.5115>:
      D.5070 = &heap->active;
      D.5117 = InterlockedCompareExchangePointer (D.5070, desc, 0B);
      if (D.5117 != 0B) goto <D.5118>; else goto <D.5119>;
      <D.5118>:
      heap_put_partial (desc);
      <D.5119>:
      <D.5116>:
      D.5076 = addr;
      return D.5076;
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


heap_get_partial (struct MonoLockFreeAllocator * heap)
{
  struct Descriptor * D.5122;
  struct MonoLockFreeAllocSizeClass * D.5123;

  D.5123 = heap->sc;
  D.5122 = list_get_partial (D.5123);
  return D.5122;
}


list_get_partial (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.5125;
  struct Descriptor * D.5128;
  <unnamed-unsigned:2> D.5129;

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

    D.5125 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.5125);
    if (desc == 0B) goto <D.5126>; else goto <D.5127>;
    <D.5126>:
    D.5128 = 0B;
    return D.5128;
    <D.5127>:
    D.5129 = desc->anchor.data.state;
    if (D.5129 != 2) goto <D.5130>; else goto <D.5131>;
    <D.5130>:
    D.5128 = desc;
    return D.5128;
    <D.5131>:
    desc_retire (desc);
  }
  goto <D.4959>;
}


desc_retire (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.5133;
  _Bool D.5134;
  long int D.5135;
  long int D.5136;
  int D.5139;
  _Bool D.5140;
  long int D.5141;
  long int D.5142;
  void * D.5145;

  D.5133 = desc->anchor.data.state;
  D.5134 = D.5133 != 2;
  D.5135 = (long int) D.5134;
  D.5136 = __builtin_expect (D.5135, 0);
  if (D.5136 != 0) goto <D.5137>; else goto <D.5138>;
  <D.5137>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 251, "desc->anchor.data.state == STATE_EMPTY");
  <D.5138>:
  D.5139 = desc->in_use;
  D.5140 = D.5139 == 0;
  D.5141 = (long int) D.5140;
  D.5142 = __builtin_expect (D.5141, 0);
  if (D.5142 != 0) goto <D.5143>; else goto <D.5144>;
  <D.5143>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 252, "desc->in_use");
  <D.5144>:
  desc->in_use = 0;
  D.5145 = desc->sb;
  free_sb (D.5145);
  mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, 0, 1);
}


desc_enqueue_avail (void * _desc)
{
  <unnamed-unsigned:2> D.5146;
  _Bool D.5147;
  long int D.5148;
  long int D.5149;
  int D.5152;
  _Bool D.5153;
  long int D.5154;
  long int D.5155;
  void * D.5158;
  struct Descriptor * desc;
  struct Descriptor * old_head;

  desc = _desc;
  D.5146 = desc->anchor.data.state;
  D.5147 = D.5146 != 2;
  D.5148 = (long int) D.5147;
  D.5149 = __builtin_expect (D.5148, 0);
  if (D.5149 != 0) goto <D.5150>; else goto <D.5151>;
  <D.5150>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 238, "desc->anchor.data.state == STATE_EMPTY");
  <D.5151>:
  D.5152 = desc->in_use;
  D.5153 = D.5152 != 0;
  D.5154 = (long int) D.5153;
  D.5155 = __builtin_expect (D.5154, 0);
  if (D.5155 != 0) goto <D.5156>; else goto <D.5157>;
  <D.5156>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 239, "!desc->in_use");
  <D.5157>:
  <D.4950>:
  old_head = desc_avail;
  desc->next = old_head;
  mono_memory_write_barrier ();
  D.5158 = InterlockedCompareExchangePointer (&desc_avail, desc, old_head);
  if (D.5158 != old_head) goto <D.4950>; else goto <D.4951>;
  <D.4951>:
}


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.5160;
  void * D.5161;
  _Bool D.5162;
  long int D.5163;
  long int D.5164;
  void * sb_header;

  sb.0 = (long unsigned int) sb;
  D.5160 = sb.0 & 4294950912;
  sb_header = (void *) D.5160;
  D.5161 = sb_header + 16;
  D.5162 = D.5161 != sb;
  D.5163 = (long int) D.5162;
  D.5164 = __builtin_expect (D.5163, 0);
  if (D.5164 != 0) goto <D.5165>; else goto <D.5166>;
  <D.5165>:
  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.5166>:
  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.5167;
  unsigned int D.5168;
  unsigned int D.5171;
  unsigned int D.5172;
  _Bool D.5173;
  long int D.5174;
  long int D.5175;
  gboolean D.5178;
  volatile gint32 * D.5179;
  int D.5180;
  int D.5181;
  int D.5182;
  _Bool D.5183;

  D.5167 = BIT_FIELD_REF <old_anchor, 32, 0>;
  D.5168 = D.5167 & 3221225472;
  if (D.5168 == 2147483648) goto <D.5169>; else goto <D.5170>;
  <D.5169>:
  D.5171 = BIT_FIELD_REF <new_anchor, 32, 0>;
  D.5172 = D.5171 & 3221225472;
  D.5173 = D.5172 != 2147483648;
  D.5174 = (long int) D.5173;
  D.5175 = __builtin_expect (D.5174, 0);
  if (D.5175 != 0) goto <D.5176>; else goto <D.5177>;
  <D.5176>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 349, "new_anchor.data.state == STATE_EMPTY");
  <D.5177>:
  <D.5170>:
  D.5179 = &desc->anchor.value;
  D.5180 = new_anchor.value;
  D.5181 = old_anchor.value;
  D.5182 = InterlockedCompareExchange (D.5179, D.5180, D.5181);
  D.5181 = old_anchor.value;
  D.5183 = D.5182 == D.5181;
  D.5178 = (gboolean) D.5183;
  return D.5178;
}


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

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


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

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


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


list_put_partial (struct Descriptor * desc)
{
  <unnamed-unsigned:2> D.5195;
  _Bool D.5196;
  long int D.5197;
  long int D.5198;

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


desc_put_partial (void * _desc)
{
  <unnamed-unsigned:2> D.5201;
  _Bool D.5202;
  long int D.5203;
  long int D.5204;
  struct MonoLockFreeQueueNode * D.5207;
  struct MonoLockFreeAllocator * D.5208;
  struct MonoLockFreeAllocSizeClass * D.5209;
  struct MonoLockFreeQueue * D.5210;
  struct Descriptor * desc;

  desc = _desc;
  D.5201 = desc->anchor.data.state;
  D.5202 = D.5201 == 0;
  D.5203 = (long int) D.5202;
  D.5204 = __builtin_expect (D.5203, 0);
  if (D.5204 != 0) goto <D.5205>; else goto <D.5206>;
  <D.5205>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 297, "desc->anchor.data.state != STATE_FULL");
  <D.5206>:
  D.5207 = &desc->node;
  mono_lock_free_queue_node_free (D.5207);
  D.5208 = desc->heap;
  D.5209 = D.5208->sc;
  D.5210 = &D.5209->partial;
  D.5207 = &desc->node;
  mono_lock_free_queue_enqueue (D.5210, D.5207);
}


alloc_from_new_sb (struct MonoLockFreeAllocator * heap)
{
  void * D.5211;
  struct MonoLockFreeAllocSizeClass * D.5212;
  unsigned int D.5213;
  void * D.5214;
  unsigned int D.5215;
  unsigned int * D.5216;
  unsigned int D.5217;
  unsigned int D.5218;
  unsigned int D.5219;
  short unsigned int D.5220;
  short unsigned int D.5221;
  <unnamed-unsigned:15> D.5222;
  struct _MonoLockFreeAllocDescriptor * * D.5223;
  void * D.5224;
  void * D.5227;
  unsigned int slot_size;
  unsigned int count;
  unsigned int i;
  struct Descriptor * desc;

  desc = desc_alloc ();
  D.5211 = alloc_sb (desc);
  desc->sb = D.5211;
  D.5212 = heap->sc;
  D.5213 = D.5212->slot_size;
  desc->slot_size = D.5213;
  slot_size = desc->slot_size;
  count = 16368 / slot_size;
  i = 1;
  goto <D.5003>;
  <D.5002>:
  D.5214 = desc->sb;
  D.5215 = i * slot_size;
  D.5216 = D.5214 + D.5215;
  D.5217 = i + 1;
  *D.5216 = D.5217;
  i = i + 1;
  <D.5003>:
  D.5218 = count + 4294967295;
  if (D.5218 > i) goto <D.5002>; else goto <D.5004>;
  <D.5004>:
  desc->heap = heap;
  desc->anchor.data.avail = 1;
  D.5212 = heap->sc;
  D.5213 = D.5212->slot_size;
  desc->slot_size = D.5213;
  desc->max_count = count;
  D.5219 = desc->max_count;
  D.5220 = (short unsigned int) D.5219;
  D.5221 = D.5220 + 65535;
  D.5222 = (<unnamed-unsigned:15>) D.5221;
  desc->anchor.data.count = D.5222;
  desc->anchor.data.state = 1;
  mono_memory_write_barrier ();
  D.5223 = &heap->active;
  D.5224 = InterlockedCompareExchangePointer (D.5223, desc, 0B);
  if (D.5224 == 0B) goto <D.5225>; else goto <D.5226>;
  <D.5225>:
  D.5227 = desc->sb;
  return D.5227;
  <D.5226>:
  desc->anchor.data.state = 2;
  desc_retire (desc);
  D.5227 = 0B;
  return D.5227;
}


desc_alloc ()
{
  void * D.5231;
  _Bool D.5232;
  unsigned int D.5234;
  struct Descriptor * iftmp.5;
  int D.5238;
  unsigned int D.5239;
  unsigned int D.5240;
  struct MonoLockFreeQueueNode * D.5242;
  struct Descriptor * D.5243;
  void * D.5244;
  _Bool D.5245;
  int D.5251;
  _Bool D.5252;
  long int D.5253;
  long int D.5254;
  struct Descriptor * D.5257;
  struct MonoThreadHazardPointers * hp;
  struct Descriptor * desc;

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

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

      next = desc->next;
      D.5231 = InterlockedCompareExchangePointer (&desc_avail, next, desc);
      D.5232 = D.5231 == desc;
      success = (gboolean) D.5232;
    }
    goto <D.5233>;
    <D.5230>:
    {
      size_t desc_size;
      struct Descriptor * d;
      int i;

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

        if (i != 63) goto <D.5236>; else goto <D.5237>;
        <D.5236>:
        D.5238 = i + 1;
        D.5239 = (unsigned int) D.5238;
        D.5240 = D.5239 * desc_size;
        iftmp.5 = desc + D.5240;
        goto <D.5241>;
        <D.5237>:
        iftmp.5 = 0B;
        <D.5241>:
        next = iftmp.5;
        d->next = next;
        D.5242 = &d->node;
        mono_lock_free_queue_node_init (D.5242, 1);
        d = next;
      }
      i = i + 1;
      <D.4941>:
      if (i <= 63) goto <D.4940>; else goto <D.4942>;
      <D.4942>:
      mono_memory_write_barrier ();
      D.5243 = desc->next;
      D.5244 = InterlockedCompareExchangePointer (&desc_avail, D.5243, 0B);
      D.5245 = D.5244 == 0B;
      success = (gboolean) D.5245;
      if (success == 0) goto <D.5246>; else goto <D.5247>;
      <D.5246>:
      D.5234 = desc_size * 64;
      mono_sgen_free_os_memory (desc, D.5234);
      <D.5247>:
    }
    <D.5233>:
    if (0 != 0) goto <D.5248>; else goto <D.5249>;
    <D.5248>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 220, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
    <D.5249>:
    hp->hazard_pointers[1] = 0B;
    if (success != 0) goto <D.4943>; else goto <D.5250>;
    <D.5250>:
  }
  goto <D.4944>;
  <D.4943>:
  D.5251 = desc->in_use;
  D.5252 = D.5251 != 0;
  D.5253 = (long int) D.5252;
  D.5254 = __builtin_expect (D.5253, 0);
  if (D.5254 != 0) goto <D.5255>; else goto <D.5256>;
  <D.5255>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 226, "!desc->in_use");
  <D.5256>:
  desc->in_use = 1;
  D.5257 = desc;
  return D.5257;
}


mono_sgen_alloc_os_memory (size_t size, int activate)
{
  void * D.5259;
  long unsigned int D.5260;
  int D.5261;

  D.5260 = prot_flags_for_activate (activate);
  D.5261 = (int) D.5260;
  D.5259 = mono_valloc (0B, size, D.5261);
  return D.5259;
}


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

  if (activate != 0) goto <D.5264>; else goto <D.5265>;
  <D.5264>:
  iftmp.6 = 3;
  goto <D.5266>;
  <D.5265>:
  iftmp.6 = 0;
  <D.5266>:
  prot_flags = iftmp.6;
  D.5267 = prot_flags | 80;
  return D.5267;
}


alloc_sb (struct Descriptor * desc)
{
  long unsigned int sb_header.7;
  long unsigned int D.5270;
  void * D.5271;
  _Bool D.5272;
  long int D.5273;
  long int D.5274;
  struct Descriptor * * D.5277;
  void * D.5278;
  void * sb_header;

  sb_header = mono_sgen_alloc_os_memory_aligned (16384, 16384, 1);
  sb_header.7 = (long unsigned int) sb_header;
  D.5270 = sb_header.7 & 4294950912;
  D.5271 = (void *) D.5270;
  D.5272 = D.5271 != sb_header;
  D.5273 = (long int) D.5272;
  D.5274 = __builtin_expect (D.5273, 0);
  if (D.5274 != 0) goto <D.5275>; else goto <D.5276>;
  <D.5275>:
  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.5276>:
  sb_header.7 = (long unsigned int) sb_header;
  D.5270 = sb_header.7 & 4294950912;
  D.5277 = (struct Descriptor * *) D.5270;
  *D.5277 = desc;
  D.5278 = sb_header + 16;
  return D.5278;
}


mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate)
{
  void * D.5280;
  long unsigned int D.5281;
  int D.5282;

  D.5281 = prot_flags_for_activate (activate);
  D.5282 = (int) D.5281;
  D.5280 = mono_valloc_aligned (size, alignment, D.5282);
  return D.5280;
}


mono_lock_free_free (void * ptr)
{
  long unsigned int ptr.8;
  long unsigned int D.5285;
  struct Descriptor * * D.5286;
  long unsigned int sb.9;
  long unsigned int D.5288;
  long unsigned int D.5289;
  _Bool D.5290;
  long int D.5291;
  long int D.5292;
  volatile gint32 * D.5295;
  <unnamed-unsigned:15> D.5296;
  unsigned int D.5297;
  int ptr.10;
  int sb.11;
  int D.5300;
  unsigned int D.5301;
  unsigned int D.5302;
  unsigned int D.5303;
  short unsigned int D.5304;
  <unnamed-unsigned:15> D.5305;
  <unnamed-unsigned:15> D.5306;
  unsigned int D.5307;
  unsigned int D.5308;
  _Bool D.5309;
  long int D.5310;
  long int D.5311;
  unsigned int D.5314;
  unsigned int D.5315;
  <unnamed-unsigned:15> D.5318;
  <unnamed-unsigned:15> D.5319;
  unsigned int D.5320;
  unsigned int D.5321;
  int D.5324;
  unsigned int D.5325;
  unsigned int D.5326;
  _Bool D.5329;
  long int D.5330;
  long int D.5331;
  struct _MonoLockFreeAllocDescriptor * * D.5334;
  void * D.5335;
  struct MonoLockFreeAllocSizeClass * D.5339;
  _Bool D.5343;
  long int D.5344;
  long int D.5345;
  struct MonoLockFreeAllocator * D.5348;
  struct _MonoLockFreeAllocDescriptor * * D.5349;
  void * D.5350;
  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.5285 = ptr.8 & 4294950912;
      D.5286 = (struct Descriptor * *) D.5285;
      desc = *D.5286;
      sb = desc->sb;
      ptr.8 = (long unsigned int) ptr;
      sb.9 = (long unsigned int) sb;
      D.5288 = ptr.8 ^ sb.9;
      D.5289 = D.5288 & 4294950912;
      D.5290 = D.5289 != 0;
      D.5291 = (long int) D.5290;
      D.5292 = __builtin_expect (D.5291, 0);
      if (D.5292 != 0) goto <D.5293>; else goto <D.5294>;
      <D.5293>:
      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.5294>:
      <D.5019>:
      D.5295 = &desc->anchor.value;
      old_anchor = MEM[(volatile union Anchor *)D.5295];
      new_anchor = old_anchor;
      D.5296 = old_anchor.data.avail;
      D.5297 = (unsigned int) D.5296;
      MEM[(unsigned int *)ptr] = D.5297;
      ptr.10 = (int) ptr;
      sb.11 = (int) sb;
      D.5300 = ptr.10 - sb.11;
      D.5301 = (unsigned int) D.5300;
      D.5302 = desc->slot_size;
      D.5303 = D.5301 / D.5302;
      D.5304 = (short unsigned int) D.5303;
      D.5305 = (<unnamed-unsigned:15>) D.5304;
      new_anchor.data.avail = D.5305;
      D.5306 = new_anchor.data.avail;
      D.5307 = (unsigned int) D.5306;
      D.5302 = desc->slot_size;
      D.5308 = 16368 / D.5302;
      D.5309 = D.5307 >= D.5308;
      D.5310 = (long int) D.5309;
      D.5311 = __builtin_expect (D.5310, 0);
      if (D.5311 != 0) goto <D.5312>; else goto <D.5313>;
      <D.5312>:
      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.5313>:
      D.5314 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.5315 = D.5314 & 3221225472;
      if (D.5315 == 0) goto <D.5316>; else goto <D.5317>;
      <D.5316>:
      new_anchor.data.state = 1;
      <D.5317>:
      D.5318 = new_anchor.data.count;
      D.5319 = D.5318 + 1;
      new_anchor.data.count = D.5319;
      D.5318 = new_anchor.data.count;
      D.5320 = (unsigned int) D.5318;
      D.5321 = desc->max_count;
      if (D.5320 == D.5321) goto <D.5322>; else goto <D.5323>;
      <D.5322>:
      heap = desc->heap;
      new_anchor.data.state = 2;
      <D.5323>:
      D.5324 = set_anchor (desc, old_anchor, new_anchor);
      if (D.5324 == 0) goto <D.5019>; else goto <D.5020>;
      <D.5020>:
      D.5325 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.5326 = D.5325 & 3221225472;
      if (D.5326 == 2147483648) goto <D.5327>; else goto <D.5328>;
      <D.5327>:
      D.5314 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.5315 = D.5314 & 3221225472;
      D.5329 = D.5315 == 2147483648;
      D.5330 = (long int) D.5329;
      D.5331 = __builtin_expect (D.5330, 0);
      if (D.5331 != 0) goto <D.5332>; else goto <D.5333>;
      <D.5332>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 495, "old_anchor.data.state != STATE_EMPTY");
      <D.5333>:
      D.5334 = &heap->active;
      D.5335 = InterlockedCompareExchangePointer (D.5334, 0B, desc);
      if (D.5335 == desc) goto <D.5336>; else goto <D.5337>;
      <D.5336>:
      desc_retire (desc);
      goto <D.5338>;
      <D.5337>:
      D.5339 = heap->sc;
      list_remove_empty_desc (D.5339);
      <D.5338>:
      goto <D.5340>;
      <D.5328>:
      D.5314 = BIT_FIELD_REF <old_anchor, 32, 0>;
      D.5315 = D.5314 & 3221225472;
      if (D.5315 == 0) goto <D.5341>; else goto <D.5342>;
      <D.5341>:
      D.5325 = BIT_FIELD_REF <new_anchor, 32, 0>;
      D.5326 = D.5325 & 3221225472;
      D.5343 = D.5326 != 1073741824;
      D.5344 = (long int) D.5343;
      D.5345 = __builtin_expect (D.5344, 0);
      if (D.5345 != 0) goto <D.5346>; else goto <D.5347>;
      <D.5346>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 513, "new_anchor.data.state == STATE_PARTIAL");
      <D.5347>:
      D.5348 = desc->heap;
      D.5349 = &D.5348->active;
      D.5350 = InterlockedCompareExchangePointer (D.5349, desc, 0B);
      if (D.5350 != 0B) goto <D.5351>; else goto <D.5352>;
      <D.5351>:
      heap_put_partial (desc);
      <D.5352>:
      <D.5342>:
      <D.5340>:
    }
  finally
    {
      old_anchor = {CLOBBER};
      new_anchor = {CLOBBER};
    }
}


list_remove_empty_desc (struct MonoLockFreeAllocSizeClass * sc)
{
  struct MonoLockFreeQueue * D.5353;
  <unnamed-unsigned:2> D.5356;
  struct MonoLockFreeAllocator * D.5360;
  struct MonoLockFreeAllocSizeClass * D.5361;
  _Bool D.5362;
  long int D.5363;
  long int D.5364;
  int num_non_empty;

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

    D.5353 = &sc->partial;
    desc = mono_lock_free_queue_dequeue (D.5353);
    if (desc == 0B) goto <D.5354>; else goto <D.5355>;
    <D.5354>:
    return;
    <D.5355>:
    D.5356 = desc->anchor.data.state;
    if (D.5356 == 2) goto <D.5357>; else goto <D.5358>;
    <D.5357>:
    desc_retire (desc);
    goto <D.5359>;
    <D.5358>:
    D.5360 = desc->heap;
    D.5361 = D.5360->sc;
    D.5362 = D.5361 != sc;
    D.5363 = (long int) D.5362;
    D.5364 = __builtin_expect (D.5363, 0);
    if (D.5364 != 0) goto <D.5365>; else goto <D.5366>;
    <D.5365>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 325, "desc->heap->sc == sc");
    <D.5366>:
    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.5367>; else goto <D.5368>;
    <D.5367>:
    return;
    <D.5368>:
    <D.5359>:
  }
  goto <D.4972>;
}


mono_lock_free_allocator_check_consistency (struct MonoLockFreeAllocator * heap)
{
  <unnamed-unsigned:2> D.5372;
  _Bool D.5373;
  long int D.5374;
  long int D.5375;
  int iftmp.12;
  <unnamed-unsigned:2> D.5381;
  <unnamed-unsigned:2> D.5383;
  _Bool D.5385;
  long int D.5386;
  long int D.5387;
  struct MonoLockFreeAllocSizeClass * D.5390;
  struct MonoLockFreeQueue * D.5391;
  gboolean D.5392;
  struct Descriptor * active;
  struct Descriptor * desc;

  active = heap->active;
  if (active != 0B) goto <D.5370>; else goto <D.5371>;
  <D.5370>:
  D.5372 = active->anchor.data.state;
  D.5373 = D.5372 != 1;
  D.5374 = (long int) D.5373;
  D.5375 = __builtin_expect (D.5374, 0);
  if (D.5375 != 0) goto <D.5376>; else goto <D.5377>;
  <D.5376>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 599, "active->anchor.data.state == STATE_PARTIAL");
  <D.5377>:
  descriptor_check_consistency (active, 0);
  <D.5371>:
  goto <D.5053>;
  <D.5052>:
  D.5381 = desc->anchor.data.state;
  if (D.5381 != 1) goto <D.5382>; else goto <D.5379>;
  <D.5382>:
  D.5383 = desc->anchor.data.state;
  if (D.5383 != 2) goto <D.5384>; else goto <D.5379>;
  <D.5384>:
  iftmp.12 = 1;
  goto <D.5380>;
  <D.5379>:
  iftmp.12 = 0;
  <D.5380>:
  D.5385 = iftmp.12 != 0;
  D.5386 = (long int) D.5385;
  D.5387 = __builtin_expect (D.5386, 0);
  if (D.5387 != 0) goto <D.5388>; else goto <D.5389>;
  <D.5388>:
  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.5389>:
  descriptor_check_consistency (desc, 0);
  <D.5053>:
  D.5390 = heap->sc;
  D.5391 = &D.5390->partial;
  desc = mono_lock_free_queue_dequeue (D.5391);
  if (desc != 0B) goto <D.5052>; else goto <D.5054>;
  <D.5054>:
  D.5392 = 1;
  return D.5392;
}


descriptor_check_consistency (struct Descriptor * desc, gboolean print)
{
  <unnamed-unsigned:15> D.5394;
  unsigned int D.5395;
  unsigned int D.5396;
  int max_count.13;
  int D.5398;
  sizetype D.5399;
  sizetype max_count.14;
  bitsizetype D.5401;
  bitsizetype D.5402;
  sizetype D.5403;
  gboolean[0:D.5399] * linked.15;
  struct MonoLockFreeAllocator * D.5412;
  struct MonoLockFreeAllocSizeClass * D.5413;
  unsigned int D.5414;
  <unnamed-unsigned:2> D.5424;
  int D.5425;
  <unnamed-unsigned:15> D.5460;
  void * D.5461;
  unsigned int D.5462;
  unsigned int max_count.16;
  int D.5471;
  void * saved_stack.17;
  int count;
  int max_count;
  gboolean linked[0:D.5399] [value-expr: *linked.15];
  int i;
  int last;
  unsigned int index;
  struct Descriptor * avail;

  saved_stack.17 = __builtin_stack_save ();
  try
    {
      D.5394 = desc->anchor.data.count;
      count = (int) D.5394;
      D.5395 = desc->slot_size;
      D.5396 = 16368 / D.5395;
      max_count = (int) D.5396;
      max_count.13 = max_count;
      D.5398 = max_count.13 + -1;
      D.5399 = (sizetype) D.5398;
      max_count.14 = (sizetype) max_count.13;
      D.5401 = (bitsizetype) max_count.14;
      D.5402 = D.5401 * 32;
      max_count.14 = (sizetype) max_count.13;
      D.5403 = max_count.14 * 4;
      max_count.14 = (sizetype) max_count.13;
      D.5401 = (bitsizetype) max_count.14;
      D.5402 = D.5401 * 32;
      max_count.14 = (sizetype) max_count.13;
      D.5403 = max_count.14 * 4;
      linked.15 = __builtin_alloca_with_align (D.5403, 32);
      avail = desc_avail;
      goto <D.5033>;
      <D.5032>:
      if (desc == avail) goto <D.5405>; else goto <D.5406>;
      <D.5405>:
      if (print != 0) goto <D.5407>; else goto <D.5408>;
      <D.5407>:
      monoeg_g_print ("descriptor is in the available list\n");
      goto <D.5409>;
      <D.5408>:
      if (1 != 0) goto <D.5410>; else goto <D.5411>;
      <D.5410>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 546, "FALSE");
      <D.5411>:
      <D.5409>:
      <D.5406>:
      avail = avail->next;
      <D.5033>:
      if (avail != 0B) goto <D.5032>; else goto <D.5034>;
      <D.5034>:
      D.5395 = desc->slot_size;
      D.5412 = desc->heap;
      D.5413 = D.5412->sc;
      D.5414 = D.5413->slot_size;
      if (D.5395 != D.5414) goto <D.5415>; else goto <D.5416>;
      <D.5415>:
      if (print != 0) goto <D.5417>; else goto <D.5418>;
      <D.5417>:
      monoeg_g_print ("slot size doesn\'t match size class\n");
      goto <D.5419>;
      <D.5418>:
      if (1 != 0) goto <D.5420>; else goto <D.5421>;
      <D.5420>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 549, "FALSE");
      <D.5421>:
      <D.5419>:
      <D.5416>:
      if (print != 0) goto <D.5422>; else goto <D.5423>;
      <D.5422>:
      monoeg_g_print ("descriptor %p is ", desc);
      <D.5423>:
      D.5424 = desc->anchor.data.state;
      D.5425 = (int) D.5424;
      switch (D.5425) <default: <D.5039>, case 0: <D.5035>, case 1: <D.5037>, case 2: <D.5038>>
      <D.5035>:
      if (print != 0) goto <D.5426>; else goto <D.5427>;
      <D.5426>:
      monoeg_g_print ("full\n");
      <D.5427>:
      if (count != 0) goto <D.5428>; else goto <D.5429>;
      <D.5428>:
      if (print != 0) goto <D.5430>; else goto <D.5431>;
      <D.5430>:
      monoeg_g_print ("count is not zero: %d\n", count);
      goto <D.5432>;
      <D.5431>:
      if (1 != 0) goto <D.5433>; else goto <D.5434>;
      <D.5433>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 558, "FALSE");
      <D.5434>:
      <D.5432>:
      <D.5429>:
      goto <D.5036>;
      <D.5037>:
      if (print != 0) goto <D.5435>; else goto <D.5436>;
      <D.5435>:
      monoeg_g_print ("partial\n");
      <D.5436>:
      if (count >= max_count) goto <D.5437>; else goto <D.5438>;
      <D.5437>:
      if (print != 0) goto <D.5439>; else goto <D.5440>;
      <D.5439>:
      monoeg_g_print ("count too high: is %d but must be below %d\n", count, max_count);
      goto <D.5441>;
      <D.5440>:
      if (1 != 0) goto <D.5442>; else goto <D.5443>;
      <D.5442>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 563, "FALSE");
      <D.5443>:
      <D.5441>:
      <D.5438>:
      goto <D.5036>;
      <D.5038>:
      if (print != 0) goto <D.5444>; else goto <D.5445>;
      <D.5444>:
      monoeg_g_print ("empty\n");
      <D.5445>:
      if (count != max_count) goto <D.5446>; else goto <D.5447>;
      <D.5446>:
      if (print != 0) goto <D.5448>; else goto <D.5449>;
      <D.5448>:
      monoeg_g_print ("count is wrong: is %d but should be %d\n", count, max_count);
      goto <D.5450>;
      <D.5449>:
      if (1 != 0) goto <D.5451>; else goto <D.5452>;
      <D.5451>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 568, "FALSE");
      <D.5452>:
      <D.5450>:
      <D.5447>:
      goto <D.5036>;
      <D.5039>:
      if (1 != 0) goto <D.5453>; else goto <D.5454>;
      <D.5453>:
      if (print != 0) goto <D.5455>; else goto <D.5456>;
      <D.5455>:
      monoeg_g_print ("invalid state\n");
      goto <D.5457>;
      <D.5456>:
      if (1 != 0) goto <D.5458>; else goto <D.5459>;
      <D.5458>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 571, "FALSE");
      <D.5459>:
      <D.5457>:
      <D.5454>:
      <D.5036>:
      i = 0;
      goto <D.5041>;
      <D.5040>:
      *linked.15[i] = 0;
      i = i + 1;
      <D.5041>:
      if (i < max_count) goto <D.5040>; else goto <D.5042>;
      <D.5042>:
      D.5460 = desc->anchor.data.avail;
      index = (unsigned int) D.5460;
      last = -1;
      i = 0;
      goto <D.5046>;
      <D.5045>:
      {
        void * addr;

        D.5461 = desc->sb;
        D.5395 = desc->slot_size;
        D.5462 = D.5395 * index;
        addr = D.5461 + D.5462;
        max_count.16 = (unsigned int) max_count;
        if (max_count.16 <= index) goto <D.5464>; else goto <D.5465>;
        <D.5464>:
        if (print != 0) goto <D.5466>; else goto <D.5467>;
        <D.5466>:
        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.5468>;
        <D.5467>:
        if (1 != 0) goto <D.5469>; else goto <D.5470>;
        <D.5469>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 583, "FALSE");
        <D.5470>:
        <D.5468>:
        <D.5465>:
        D.5471 = *linked.15[index];
        if (D.5471 != 0) goto <D.5472>; else goto <D.5473>;
        <D.5472>:
        if (print != 0) goto <D.5474>; else goto <D.5475>;
        <D.5474>:
        monoeg_g_print ("%dth available slot %d linked twice\n", i, index);
        goto <D.5476>;
        <D.5475>:
        if (1 != 0) goto <D.5477>; else goto <D.5478>;
        <D.5477>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "lock-free-alloc.c", 584, "FALSE");
        <D.5478>:
        <D.5476>:
        <D.5473>:
        D.5471 = *linked.15[index];
        if (D.5471 != 0) goto <D.5044>; else goto <D.5479>;
        <D.5479>:
        *linked.15[index] = 1;
        last = (int) index;
        index = MEM[(unsigned int *)addr];
      }
      i = i + 1;
      <D.5046>:
      if (i < count) goto <D.5045>; else goto <D.5044>;
      <D.5044>:
    }
  finally
    {
      __builtin_stack_restore (saved_stack.17);
    }
}


mono_lock_free_allocator_init_size_class (struct MonoLockFreeAllocSizeClass * sc, unsigned int slot_size)
{
  _Bool D.5482;
  long int D.5483;
  long int D.5484;
  struct MonoLockFreeQueue * D.5487;

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


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


