sgen_card_table_get_card_data (guint8 * data_dest, mword address, mword cards)
{
  gboolean D.17994;
  mword * start;
  mword * dest;
  mword * end;
  mword mask;

  start = sgen_card_table_get_shadow_card_address (address);
  dest = data_dest;
  end = data_dest + cards;
  mask = 0;
  goto <D.17834>;
  <D.17833>:
  {
    mword v;

    v = *start;
    *dest = v;
    mask = mask | v;
  }
  dest = dest + 8;
  start = start + 8;
  <D.17834>:
  if (dest < end) goto <D.17833>; else goto <D.17835>;
  <D.17835>:
  D.17994 = (gboolean) mask;
  return D.17994;
}


sgen_card_table_get_shadow_card_address (mword address)
{
  guint8 * D.17996;
  guint8 * sgen_shadow_cardtable.0;
  long unsigned int D.17998;
  sizetype D.17999;

  sgen_shadow_cardtable.0 = sgen_shadow_cardtable;
  D.17998 = address >> 9;
  D.17999 = D.17998 & 8388607;
  D.17996 = sgen_shadow_cardtable.0 + D.17999;
  return D.17996;
}


sgen_card_table_align_pointer (void * ptr)
{
  void * D.18001;
  long unsigned int ptr.1;
  long unsigned int D.18003;

  ptr.1 = (long unsigned int) ptr;
  D.18003 = ptr.1 & 18446744073709551104;
  D.18001 = (void *) D.18003;
  return D.18001;
}


sgen_card_table_mark_range (mword address, mword size)
{
  long unsigned int D.18005;
  guint8 * D.18006;

  D.18005 = cards_in_range (address, size);
  D.18006 = sgen_card_table_get_card_address (address);
  memset (D.18006, 1, D.18005);
}


cards_in_range (mword address, mword size)
{
  mword iftmp.2;
  long unsigned int D.18011;
  mword D.18012;
  long unsigned int D.18013;
  long unsigned int D.18014;
  long unsigned int D.18015;
  mword end;

  if (size != 0) goto <D.18008>; else goto <D.18009>;
  <D.18008>:
  iftmp.2 = size;
  goto <D.18010>;
  <D.18009>:
  iftmp.2 = 1;
  <D.18010>:
  D.18011 = iftmp.2 + address;
  end = D.18011 + 18446744073709551615;
  D.18013 = end >> 9;
  D.18014 = address >> 9;
  D.18015 = D.18013 - D.18014;
  D.18012 = D.18015 + 1;
  return D.18012;
}


sgen_card_table_get_card_address (mword address)
{
  guint8 * D.18017;
  guint8 * sgen_cardtable.3;
  long unsigned int D.18019;
  sizetype D.18020;

  sgen_cardtable.3 = sgen_cardtable;
  D.18019 = address >> 9;
  D.18020 = D.18019 & 8388607;
  D.18017 = sgen_cardtable.3 + D.18020;
  return D.18017;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.18024;
  int D.18029;
  void * D.18031;
  long unsigned int D.18032;

  D.18024 = __builtin_constant_p (__len);
  if (D.18024 != 0) goto <D.18025>; else goto <D.18026>;
  <D.18025>:
  if (__len == 0) goto <D.18027>; else goto <D.18028>;
  <D.18027>:
  D.18029 = __builtin_constant_p (__ch);
  if (D.18029 == 0) goto <D.18022>; else goto <D.18030>;
  <D.18030>:
  if (__ch != 0) goto <D.18022>; else goto <D.18023>;
  <D.18022>:
  __warn_memset_zero_len ();
  D.18031 = __dest;
  return D.18031;
  <D.18023>:
  <D.18028>:
  <D.18026>:
  D.18032 = __builtin_object_size (__dest, 0);
  D.18031 = __builtin___memset_chk (__dest, __ch, __len, D.18032);
  return D.18031;
}


sgen_card_table_update_mod_union (guint8 * dest, char * obj, mword obj_size, size_t * out_num_cards)
{
  long unsigned int obj.4;
  long unsigned int D.18035;
  long unsigned int D.18036;
  guint8 * D.18037;
  _Bool D.18038;
  guint8 * sgen_cardtable.5;
  long int edge_card.6;
  long int start_card.7;
  long int D.18044;
  guint8 * D.18045;
  long int D.18046;
  long int D.18047;
  long int end_card.8;
  long int sgen_cardtable.9;
  long int D.18052;
  long int D.18053;
  long unsigned int D.18054;
  _Bool D.18055;
  long int D.18056;
  long int D.18057;
  long int D.18061;
  guint8 * D.18066;
  guint8 * result;
  guint8 * start_card;
  guint8 * end_card;
  gboolean init;
  size_t num_cards;

  result = dest;
  obj.4 = (long unsigned int) obj;
  start_card = sgen_card_table_get_card_address (obj.4);
  obj.4 = (long unsigned int) obj;
  D.18035 = obj.4 + obj_size;
  D.18036 = D.18035 + 18446744073709551615;
  D.18037 = sgen_card_table_get_card_address (D.18036);
  end_card = D.18037 + 1;
  D.18038 = dest == 0B;
  init = (gboolean) D.18038;
  if (end_card < start_card) goto <D.18039>; else goto <D.18040>;
  <D.18039>:
  {
    guint8 * edge_card;
    size_t num_cards_to_edge;

    sgen_cardtable.5 = sgen_cardtable;
    edge_card = sgen_cardtable.5 + 8388608;
    edge_card.6 = (long int) edge_card;
    start_card.7 = (long int) start_card;
    D.18044 = edge_card.6 - start_card.7;
    num_cards_to_edge = (size_t) D.18044;
    D.18045 = end_card + 8388608;
    D.18046 = (long int) D.18045;
    start_card.7 = (long int) start_card;
    D.18047 = D.18046 - start_card.7;
    num_cards = (size_t) D.18047;
    if (init != 0) goto <D.18048>; else goto <D.18049>;
    <D.18048>:
    dest = alloc_mod_union (num_cards);
    result = dest;
    <D.18049>:
    update_mod_union (dest, init, start_card, edge_card);
    edge_card.6 = (long int) edge_card;
    start_card.7 = (long int) start_card;
    D.18044 = edge_card.6 - start_card.7;
    end_card.8 = (long int) end_card;
    sgen_cardtable.5 = sgen_cardtable;
    sgen_cardtable.9 = (long int) sgen_cardtable.5;
    D.18052 = end_card.8 - sgen_cardtable.9;
    D.18053 = D.18044 + D.18052;
    D.18054 = (long unsigned int) D.18053;
    D.18055 = D.18054 != num_cards;
    D.18056 = (long int) D.18055;
    D.18057 = __builtin_expect (D.18056, 0);
    if (D.18057 != 0) goto <D.18058>; else goto <D.18059>;
    <D.18058>:
    monoeg_g_log (0B, 4, "wrong number of cards");
    <D.17890>:
    goto <D.17890>;
    <D.18059>:
    dest = dest + num_cards_to_edge;
    start_card = sgen_cardtable;
  }
  goto <D.18060>;
  <D.18040>:
  end_card.8 = (long int) end_card;
  start_card.7 = (long int) start_card;
  D.18061 = end_card.8 - start_card.7;
  num_cards = (size_t) D.18061;
  if (init != 0) goto <D.18062>; else goto <D.18063>;
  <D.18062>:
  dest = alloc_mod_union (num_cards);
  result = dest;
  <D.18063>:
  <D.18060>:
  update_mod_union (dest, init, start_card, end_card);
  if (out_num_cards != 0B) goto <D.18064>; else goto <D.18065>;
  <D.18064>:
  *out_num_cards = num_cards;
  <D.18065>:
  D.18066 = result;
  return D.18066;
}


alloc_mod_union (size_t num_cards)
{
  guint8 * D.18068;

  D.18068 = sgen_alloc_internal_dynamic (num_cards, 28, 1);
  return D.18068;
}


update_mod_union (guint8 * dest, gboolean init, guint8 * start_card, guint8 * end_card)
{
  long int end_card.10;
  long int start_card.11;
  long int D.18072;
  sizetype D.18076;
  guint8 * D.18077;
  unsigned char D.18078;
  guint8 * D.18079;
  unsigned char D.18080;
  unsigned char D.18081;
  long unsigned int D.18082;
  size_t num_cards;

  end_card.10 = (long int) end_card;
  start_card.11 = (long int) start_card;
  D.18072 = end_card.10 - start_card.11;
  num_cards = (size_t) D.18072;
  if (init != 0) goto <D.18073>; else goto <D.18074>;
  <D.18073>:
  memcpy (dest, start_card, num_cards);
  goto <D.18075>;
  <D.18074>:
  {
    int i;

    i = 0;
    goto <D.17872>;
    <D.17871>:
    D.18076 = (sizetype) i;
    D.18077 = dest + D.18076;
    D.18076 = (sizetype) i;
    D.18077 = dest + D.18076;
    D.18078 = *D.18077;
    D.18076 = (sizetype) i;
    D.18079 = start_card + D.18076;
    D.18080 = *D.18079;
    D.18081 = D.18078 | D.18080;
    *D.18077 = D.18081;
    i = i + 1;
    <D.17872>:
    D.18082 = (long unsigned int) i;
    if (D.18082 < num_cards) goto <D.17871>; else goto <D.17873>;
    <D.17873>:
  }
  <D.18075>:
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.18083;
  long unsigned int D.18084;

  D.18084 = __builtin_object_size (__dest, 0);
  D.18083 = __builtin___memcpy_chk (__dest, __src, __len, D.18084);
  return D.18083;
}


mono_gc_get_card_table (int * shift_bits, void * * mask)
{
  guint8 * sgen_cardtable.12;
  guint8 * D.18089;

  sgen_cardtable.12 = sgen_cardtable;
  if (sgen_cardtable.12 == 0B) goto <D.18087>; else goto <D.18088>;
  <D.18087>:
  D.18089 = 0B;
  return D.18089;
  <D.18088>:
  *shift_bits = 9;
  *mask = 8388607B;
  D.18089 = sgen_cardtable;
  return D.18089;
}


mono_gc_card_table_nursery_check ()
{
  gboolean D.18091;
  int D.18092;
  _Bool D.18093;

  D.18092 = major_collector.is_concurrent;
  D.18093 = D.18092 == 0;
  D.18091 = (gboolean) D.18093;
  return D.18091;
}


sgen_cardtable_scan_object (char * obj, mword block_obj_size, guint8 * cards, gboolean mod_union, struct SgenGrayQueue * queue)
{
  long unsigned int D.18095;
  long unsigned int D.18096;
  void * D.18097;
  long unsigned int D.18098;
  int D.18099;
  unsigned char D.18102;
  unsigned int D.18105;
  struct MonoClass * D.18106;
  void * D.18107;
  long unsigned int obj.13;
  guint8 * sgen_shadow_cardtable.14;
  guint8 * D.18115;
  long int card_data_end.15;
  long int D.18119;
  long int D.18120;
  sizetype D.18121;
  long int card_data.16;
  long int card_base.17;
  long int D.18124;
  unsigned int D.18125;
  unsigned int extra_idx.18;
  unsigned int D.18127;
  int D.18128;
  sizetype D.18129;
  double[0:] * D.18132;
  long int start.19;
  char * D.18137;
  long int D.18138;
  long int D.18139;
  long int D.18140;
  long int D.18141;
  double[0:] * D.18142;
  int D.18143;
  sizetype D.18144;
  unsigned char D.18145;
  unsigned char D.18146;
  struct SgenObjectOperations * D.18149;
  sizetype D.18150;
  struct SgenObjectOperations * D.18152;
  _Bool D.18155;
  _Bool D.18156;
  _Bool D.18157;
  int D.18159;
  _Bool D.18160;
  long int D.18161;
  long int D.18162;
  int D.18163;
  _Bool D.18164;
  long int D.18165;
  long int D.18166;
  guint8 * D.18169;
  int D.18175;
  struct SgenObjectOperations * D.18178;
  void (*<T2bff>) (char *, struct SgenGrayQueue *) D.18179;
  int D.18181;
  struct SgenObjectOperations * D.18184;
  void (*<T2bff>) (char *, struct SgenGrayQueue *) D.18185;
  struct MonoVTable * vt;
  struct MonoClass * klass;
  void LOOP_HEAD = <<< error >>>;

  D.18095 = MEM[(mword *)obj];
  D.18096 = D.18095 & 18446744073709551612;
  vt = (struct MonoVTable *) D.18096;
  klass = vt->klass;
  D.18097 = vt->gc_descr;
  D.18098 = (long unsigned int) D.18097;
  D.18099 = sgen_gc_descr_has_references (D.18098);
  if (D.18099 == 0) goto <D.18100>; else goto <D.18101>;
  <D.18100>:
  return;
  <D.18101>:
  D.18102 = vt->rank;
  if (D.18102 != 0) goto <D.18103>; else goto <D.18104>;
  <D.18103>:
  {
    guint8 * card_data;
    guint8 * card_base;
    guint8 * card_data_end;
    char * obj_start;
    mword obj_size;
    char * obj_end;
    size_t card_count;
    int extra_idx;
    struct MonoArray * arr;
    mword desc;
    int elem_size;
    guint8 * overflow_scan_end;

    obj_start = sgen_card_table_align_pointer (obj);
    D.18105 = sgen_par_object_get_size (vt, obj);
    obj_size = (mword) D.18105;
    obj_end = obj + obj_size;
    extra_idx = 0;
    arr = obj;
    D.18106 = klass->element_class;
    D.18107 = D.18106->gc_descr;
    desc = (mword) D.18107;
    elem_size = mono_array_element_size (klass);
    overflow_scan_end = 0B;
    if (cards != 0B) goto <D.18108>; else goto <D.18109>;
    <D.18108>:
    card_data = cards;
    goto <D.18110>;
    <D.18109>:
    obj.13 = (long unsigned int) obj;
    card_data = sgen_card_table_get_shadow_card_address (obj.13);
    <D.18110>:
    card_base = card_data;
    obj.13 = (long unsigned int) obj;
    card_count = cards_in_range (obj.13, obj_size);
    card_data_end = card_data + card_count;
    if (cards == 0B) goto <D.18112>; else goto <D.18113>;
    <D.18112>:
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    D.18115 = sgen_shadow_cardtable.14 + 8388608;
    if (D.18115 <= card_data_end) goto <D.18116>; else goto <D.18117>;
    <D.18116>:
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    card_data_end.15 = (long int) card_data_end;
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    D.18115 = sgen_shadow_cardtable.14 + 8388608;
    D.18119 = (long int) D.18115;
    D.18120 = card_data_end.15 - D.18119;
    D.18121 = (sizetype) D.18120;
    overflow_scan_end = sgen_shadow_cardtable.14 + D.18121;
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    card_data_end = sgen_shadow_cardtable.14 + 8388608;
    <D.18117>:
    <D.18113>:
    LOOP_HEAD:
    card_data = find_next_card (card_data, card_data_end);
    goto <D.17985>;
    <D.17984>:
    {
      int index;
      int idx;
      char * start;
      char * card_end;
      char * first_elem;
      char * elem;

      card_data.16 = (long int) card_data;
      card_base.17 = (long int) card_base;
      D.18124 = card_data.16 - card_base.17;
      D.18125 = (unsigned int) D.18124;
      extra_idx.18 = (unsigned int) extra_idx;
      D.18127 = D.18125 + extra_idx.18;
      idx = (int) D.18127;
      D.18128 = idx * 512;
      D.18129 = (sizetype) D.18128;
      start = obj_start + D.18129;
      card_end = start + 512;
      if (cards == 0B) goto <D.18130>; else goto <D.18131>;
      <D.18130>:
      sgen_card_table_prepare_card_for_scanning (card_data);
      <D.18131>:
      card_end = MIN_EXPR <obj_end, card_end>;
      D.18132 = &arr->vector;
      if (D.18132 >= start) goto <D.18133>; else goto <D.18134>;
      <D.18133>:
      index = 0;
      goto <D.18135>;
      <D.18134>:
      start.19 = (long int) start;
      D.18137 = obj + 32;
      D.18138 = (long int) D.18137;
      D.18139 = start.19 - D.18138;
      D.18140 = (long int) elem_size;
      D.18141 = D.18139 / D.18140;
      index = (int) D.18141;
      <D.18135>:
      D.18142 = &MEM[(struct MonoArray *)obj].vector;
      D.18143 = elem_size * index;
      D.18144 = (sizetype) D.18143;
      first_elem = D.18142 + D.18144;
      elem = first_elem;
      D.18106 = klass->element_class;
      D.18145 = BIT_FIELD_REF <*D.18106, 8, 256>;
      D.18146 = D.18145 & 8;
      if (D.18146 != 0) goto <D.18147>; else goto <D.18148>;
      <D.18147>:
      {
        void (*ScanVTypeFunc) (char *, mword, struct SgenGrayQueue *) scan_vtype_func;

        D.18149 = sgen_get_current_object_ops ();
        scan_vtype_func = D.18149->scan_vtype;
        goto <D.17976>;
        <D.17975>:
        scan_vtype_func (elem, desc, queue);
        D.18150 = (sizetype) elem_size;
        elem = elem + D.18150;
        <D.17976>:
        if (elem < card_end) goto <D.17975>; else goto <D.17977>;
        <D.17977>:
      }
      goto <D.18151>;
      <D.18148>:
      {
        void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;

        D.18152 = sgen_get_current_object_ops ();
        copy_func = D.18152->copy_or_mark_object;
        goto <D.17982>;
        <D.17981>:
        {
          void * new;
          void * old;

          old = MEM[(void * *)elem];
          D.18155 = mod_union != 0;
          D.18156 = old != 0B;
          D.18157 = D.18155 & D.18156;
          if (D.18157 != 0) goto <D.18153>; else goto <D.18158>;
          <D.18158>:
          D.18159 = sgen_ptr_in_nursery (old);
          D.18160 = D.18159 != 0;
          D.18161 = (long int) D.18160;
          D.18162 = __builtin_expect (D.18161, 0);
          if (D.18162 != 0) goto <D.18153>; else goto <D.18154>;
          <D.18153>:
          copy_func (elem, queue);
          new = MEM[(void * *)elem];
          D.18163 = sgen_ptr_in_nursery (new);
          D.18164 = D.18163 != 0;
          D.18165 = (long int) D.18164;
          D.18166 = __builtin_expect (D.18165, 0);
          if (D.18166 != 0) goto <D.18167>; else goto <D.18168>;
          <D.18167>:
          sgen_add_to_global_remset (elem, new);
          <D.18168>:
          <D.18154>:
        }
        elem = elem + 8;
        <D.17982>:
        if (elem < card_end) goto <D.17981>; else goto <D.17983>;
        <D.17983>:
      }
      <D.18151>:
    }
    D.18169 = card_data + 1;
    card_data = find_next_card (D.18169, card_data_end);
    <D.17985>:
    if (card_data < card_data_end) goto <D.17984>; else goto <D.17986>;
    <D.17986>:
    if (overflow_scan_end != 0B) goto <D.18170>; else goto <D.18171>;
    <D.18170>:
    card_data.16 = (long int) card_data;
    card_base.17 = (long int) card_base;
    D.18124 = card_data.16 - card_base.17;
    extra_idx = (int) D.18124;
    card_data = sgen_shadow_cardtable;
    card_base = card_data;
    card_data_end = overflow_scan_end;
    overflow_scan_end = 0B;
    goto LOOP_HEAD;
    <D.18171>:
  }
  goto <D.18172>;
  <D.18104>:
  if (cards != 0B) goto <D.18173>; else goto <D.18174>;
  <D.18173>:
  obj.13 = (long unsigned int) obj;
  D.18175 = sgen_card_table_is_range_marked (cards, obj.13, block_obj_size);
  if (D.18175 != 0) goto <D.18176>; else goto <D.18177>;
  <D.18176>:
  D.18178 = sgen_get_current_object_ops ();
  D.18179 = D.18178->scan_object;
  D.18179 (obj, queue);
  <D.18177>:
  goto <D.18180>;
  <D.18174>:
  obj.13 = (long unsigned int) obj;
  D.18181 = sgen_card_table_region_begin_scanning (obj.13, block_obj_size);
  if (D.18181 != 0) goto <D.18182>; else goto <D.18183>;
  <D.18182>:
  D.18184 = sgen_get_current_object_ops ();
  D.18185 = D.18184->scan_object;
  D.18185 (obj, queue);
  <D.18183>:
  <D.18180>:
  <D.18172>:
}


sgen_gc_descr_has_references (mword desc)
{
  long unsigned int D.18187;
  gboolean D.18190;
  long unsigned int D.18191;
  long unsigned int D.18194;

  D.18187 = desc & 4294901767;
  if (D.18187 == 1) goto <D.18188>; else goto <D.18189>;
  <D.18188>:
  D.18190 = 0;
  return D.18190;
  <D.18189>:
  D.18191 = desc & 49159;
  if (D.18191 == 4) goto <D.18192>; else goto <D.18193>;
  <D.18192>:
  D.18190 = 0;
  return D.18190;
  <D.18193>:
  D.18194 = desc & 7;
  if (D.18194 == 7) goto <D.18195>; else goto <D.18196>;
  <D.18195>:
  D.18190 = 0;
  return D.18190;
  <D.18196>:
  D.18190 = 1;
  return D.18190;
}


sgen_par_object_get_size (struct MonoVTable * vtable, struct MonoObject * o)
{
  void * D.18198;
  long unsigned int D.18199;
  guint D.18204;
  int D.18205;
  int D.18206;
  unsigned int D.18207;
  long unsigned int D.18210;
  int D.18211;
  unsigned int D.18212;
  unsigned int element_size.20;
  unsigned int D.18214;
  long unsigned int D.18215;
  long unsigned int D.18216;
  struct MonoClass * D.18219;
  unsigned char D.18220;
  long unsigned int D.18221;
  long unsigned int D.18222;
  mword descr;
  mword type;

  D.18198 = vtable->gc_descr;
  descr = (mword) D.18198;
  type = descr & 7;
  D.18199 = type + 18446744073709551615;
  if (D.18199 <= 1) goto <D.18200>; else goto <D.18201>;
  <D.18200>:
  {
    mword size;

    size = descr & 65528;
    if (size == 0) goto <D.18202>; else goto <D.18203>;
    <D.18202>:
    D.18205 = MEM[(struct MonoString *)o].length;
    D.18206 = D.18205 * 2;
    D.18207 = (unsigned int) D.18206;
    D.18204 = D.18207 + 26;
    return D.18204;
    <D.18203>:
    D.18204 = (guint) size;
    return D.18204;
  }
  <D.18201>:
  if (type == 4) goto <D.18208>; else goto <D.18209>;
  <D.18208>:
  {
    int element_size;
    struct MonoArray * array;
    size_t size;

    D.18210 = descr >> 3;
    D.18211 = (int) D.18210;
    element_size = D.18211 & 1023;
    array = o;
    D.18212 = array->max_length;
    element_size.20 = (unsigned int) element_size;
    D.18214 = D.18212 * element_size.20;
    D.18215 = (long unsigned int) D.18214;
    size = D.18215 + 32;
    D.18216 = descr & 8192;
    if (D.18216 != 0) goto <D.18217>; else goto <D.18218>;
    <D.18217>:
    size = size + 3;
    size = size & 18446744073709551612;
    D.18219 = vtable->klass;
    D.18220 = D.18219->rank;
    D.18221 = (long unsigned int) D.18220;
    D.18222 = D.18221 * 8;
    size = D.18222 + size;
    <D.18218>:
    D.18204 = (guint) size;
    return D.18204;
  }
  <D.18209>:
  D.18204 = slow_object_get_size (vtable, o);
  return D.18204;
}


slow_object_get_size (struct MonoVTable * vtable, struct MonoObject * o)
{
  struct MonoClass * D.18224;
  guint D.18227;
  int D.18228;
  int D.18229;
  unsigned int D.18230;
  unsigned char D.18231;
  int D.18234;
  unsigned int D.18235;
  unsigned int D.18236;
  unsigned int D.18237;
  long unsigned int D.18238;
  struct MonoArrayBounds * D.18239;
  _Bool D.18240;
  long int D.18241;
  long int D.18242;
  long unsigned int D.18245;
  long unsigned int D.18246;
  int D.18247;
  struct MonoClass * klass;

  klass = vtable->klass;
  D.18224 = mono_defaults.string_class;
  if (D.18224 == klass) goto <D.18225>; else goto <D.18226>;
  <D.18225>:
  D.18228 = MEM[(struct MonoString *)o].length;
  D.18229 = D.18228 * 2;
  D.18230 = (unsigned int) D.18229;
  D.18227 = D.18230 + 26;
  return D.18227;
  <D.18226>:
  D.18231 = klass->rank;
  if (D.18231 != 0) goto <D.18232>; else goto <D.18233>;
  <D.18232>:
  {
    struct MonoArray * array;
    size_t size;

    array = o;
    D.18234 = klass->sizes.element_size;
    D.18235 = (unsigned int) D.18234;
    D.18236 = array->max_length;
    D.18237 = D.18235 * D.18236;
    D.18238 = (long unsigned int) D.18237;
    size = D.18238 + 32;
    D.18239 = array->bounds;
    D.18240 = D.18239 != 0B;
    D.18241 = (long int) D.18240;
    D.18242 = __builtin_expect (D.18241, 0);
    if (D.18242 != 0) goto <D.18243>; else goto <D.18244>;
    <D.18243>:
    size = size + 3;
    size = size & 18446744073709551612;
    D.18231 = klass->rank;
    D.18245 = (long unsigned int) D.18231;
    D.18246 = D.18245 * 8;
    size = D.18246 + size;
    <D.18244>:
    D.18227 = (guint) size;
    return D.18227;
  }
  <D.18233>:
  D.18247 = klass->instance_size;
  D.18227 = (guint) D.18247;
  return D.18227;
}


sgen_card_table_prepare_card_for_scanning (guint8 * card)
{

}


sgen_ptr_in_nursery (void * p)
{
  gboolean D.18249;
  int sgen_nursery_bits.21;
  int D.18251;
  int D.18252;
  long unsigned int D.18253;
  long unsigned int p.22;
  long unsigned int D.18255;
  char * sgen_nursery_start.23;
  long unsigned int sgen_nursery_start.24;
  _Bool D.18258;

  sgen_nursery_bits.21 = sgen_nursery_bits;
  D.18251 = 1 << sgen_nursery_bits.21;
  D.18252 = -D.18251;
  D.18253 = (long unsigned int) D.18252;
  p.22 = (long unsigned int) p;
  D.18255 = D.18253 & p.22;
  sgen_nursery_start.23 = sgen_nursery_start;
  sgen_nursery_start.24 = (long unsigned int) sgen_nursery_start.23;
  D.18258 = D.18255 == sgen_nursery_start.24;
  D.18249 = (gboolean) D.18258;
  return D.18249;
}


find_next_card (guint8 * card_data, guint8 * end)
{
  unsigned char D.18260;
  guint8 * D.18263;
  long unsigned int card_data.25;
  long unsigned int D.18265;
  long unsigned int end.26;
  long unsigned int D.18270;
  int D.18273;
  sizetype D.18274;
  mword * cards;
  mword * cards_end;
  mword card;

  goto <D.17938>;
  <D.17937>:
  D.18260 = *card_data;
  if (D.18260 != 0) goto <D.18261>; else goto <D.18262>;
  <D.18261>:
  D.18263 = card_data;
  return D.18263;
  <D.18262>:
  card_data = card_data + 1;
  <D.17938>:
  card_data.25 = (long unsigned int) card_data;
  D.18265 = card_data.25 & 7;
  if (D.18265 != 0) goto <D.18266>; else goto <D.17939>;
  <D.18266>:
  if (card_data < end) goto <D.17937>; else goto <D.17939>;
  <D.17939>:
  if (card_data == end) goto <D.18267>; else goto <D.18268>;
  <D.18267>:
  D.18263 = end;
  return D.18263;
  <D.18268>:
  cards = card_data;
  end.26 = (long unsigned int) end;
  D.18270 = end.26 & 18446744073709551608;
  cards_end = (mword *) D.18270;
  goto <D.17941>;
  <D.17940>:
  card = *cards;
  if (card != 0) goto <D.18271>; else goto <D.18272>;
  <D.18271>:
  D.18273 = find_card_offset (card);
  D.18274 = (sizetype) D.18273;
  D.18263 = cards + D.18274;
  return D.18263;
  <D.18272>:
  cards = cards + 8;
  <D.17941>:
  if (cards < cards_end) goto <D.17940>; else goto <D.17942>;
  <D.17942>:
  card_data = cards_end;
  goto <D.17944>;
  <D.17943>:
  D.18260 = *card_data;
  if (D.18260 != 0) goto <D.18275>; else goto <D.18276>;
  <D.18275>:
  D.18263 = card_data;
  return D.18263;
  <D.18276>:
  card_data = card_data + 1;
  <D.17944>:
  if (card_data < end) goto <D.17943>; else goto <D.17945>;
  <D.17945>:
  D.18263 = end;
  return D.18263;
}


find_card_offset (mword card)
{
  int D.18278;
  long long int card.27;
  int D.18280;
  int D.18281;

  card.27 = (long long int) card;
  D.18280 = __builtin_ffsll (card.27);
  D.18281 = D.18280 + -1;
  D.18278 = D.18281 / 8;
  return D.18278;
}


sgen_card_table_is_range_marked (guint8 * cards, mword address, mword size)
{
  long unsigned int D.18283;
  guint8 * cards.28;
  unsigned char D.18285;
  gboolean D.18288;
  guint8 * end;

  D.18283 = cards_in_range (address, size);
  end = cards + D.18283;
  goto <D.17850>;
  <D.17849>:
  cards.28 = cards;
  cards = cards.28 + 1;
  D.18285 = *cards.28;
  if (D.18285 != 0) goto <D.18286>; else goto <D.18287>;
  <D.18286>:
  D.18288 = 1;
  return D.18288;
  <D.18287>:
  <D.17850>:
  if (cards != end) goto <D.17849>; else goto <D.17851>;
  <D.17851>:
  D.18288 = 0;
  return D.18288;
}


sgen_card_table_region_begin_scanning (mword start, mword end)
{
  int D.18290;
  gboolean D.18293;

  goto <D.17821>;
  <D.17820>:
  D.18290 = sgen_card_table_card_begin_scanning (start);
  if (D.18290 != 0) goto <D.18291>; else goto <D.18292>;
  <D.18291>:
  D.18293 = 1;
  return D.18293;
  <D.18292>:
  start = start + 512;
  <D.17821>:
  if (start <= end) goto <D.17820>; else goto <D.17822>;
  <D.17822>:
  D.18293 = 0;
  return D.18293;
}


sgen_card_table_card_begin_scanning (mword address)
{
  gboolean D.18295;
  guint8 * D.18296;
  unsigned char D.18297;
  _Bool D.18298;

  D.18296 = sgen_card_table_get_shadow_card_address (address);
  D.18297 = *D.18296;
  D.18298 = D.18297 != 0;
  D.18295 = (gboolean) D.18298;
  return D.18295;
}


sgen_card_table_init (struct SgenRemeberedSet * remset)
{
  void * sgen_cardtable.29;
  void * sgen_shadow_cardtable.30;
  struct SgenMajorCollector * D.18302;
  int need_mod_union.31;

  sgen_cardtable.29 = sgen_alloc_os_memory (8388608, 2, "card table");
  sgen_cardtable = sgen_cardtable.29;
  sgen_shadow_cardtable.30 = sgen_alloc_os_memory (8388608, 2, "shadow card table");
  sgen_shadow_cardtable = sgen_shadow_cardtable.30;
  mono_counters_register ("cardtable major scan time", 519, &major_card_scan_time);
  mono_counters_register ("cardtable los scan time", 519, &los_card_scan_time);
  remset->wbarrier_set_field = sgen_card_table_wbarrier_set_field;
  remset->wbarrier_set_arrayref = sgen_card_table_wbarrier_set_arrayref;
  remset->wbarrier_arrayref_copy = sgen_card_table_wbarrier_arrayref_copy;
  remset->wbarrier_value_copy = sgen_card_table_wbarrier_value_copy;
  remset->wbarrier_object_copy = sgen_card_table_wbarrier_object_copy;
  remset->wbarrier_generic_nostore = sgen_card_table_wbarrier_generic_nostore;
  remset->record_pointer = sgen_card_table_record_pointer;
  remset->finish_scan_remsets = sgen_card_table_finish_scan_remsets;
  remset->finish_minor_collection = sgen_card_table_finish_minor_collection;
  remset->prepare_for_major_collection = sgen_card_table_prepare_for_major_collection;
  remset->find_address = sgen_card_table_find_address;
  remset->find_address_with_cards = sgen_card_table_find_address_with_cards;
  D.18302 = sgen_get_major_collector ();
  need_mod_union.31 = D.18302->is_concurrent;
  need_mod_union = need_mod_union.31;
}


sgen_card_table_find_address_with_cards (char * cards_start, guint8 * cards, char * addr)
{
  gboolean D.18304;
  long int addr.32;
  long int cards_start.33;
  long int D.18307;
  long int D.18308;
  sizetype D.18309;
  guint8 * D.18310;
  unsigned char D.18311;

  cards_start = sgen_card_table_align_pointer (cards_start);
  addr.32 = (long int) addr;
  cards_start.33 = (long int) cards_start;
  D.18307 = addr.32 - cards_start.33;
  D.18308 = D.18307 >> 9;
  D.18309 = (sizetype) D.18308;
  D.18310 = cards + D.18309;
  D.18311 = *D.18310;
  D.18304 = (gboolean) D.18311;
  return D.18304;
}


sgen_card_table_find_address (char * addr)
{
  gboolean D.18313;
  long unsigned int addr.34;

  addr.34 = (long unsigned int) addr;
  D.18313 = sgen_card_table_address_is_marked (addr.34);
  return D.18313;
}


sgen_card_table_address_is_marked (mword address)
{
  gboolean D.18316;
  guint8 * D.18317;
  unsigned char D.18318;
  _Bool D.18319;

  D.18317 = sgen_card_table_get_card_address (address);
  D.18318 = *D.18317;
  D.18319 = D.18318 != 0;
  D.18316 = (gboolean) D.18319;
  return D.18316;
}


sgen_card_table_prepare_for_major_collection ()
{
  sgen_major_collector_iterate_live_block_ranges (clear_cards);
  sgen_los_iterate_live_block_ranges (clear_cards);
}


clear_cards (mword start, mword size)
{
  guint8 * D.18321;
  guint8 * sgen_cardtable.35;
  guint8 * D.18323;
  long int D.18326;
  long int addr.36;
  long int D.18328;
  long unsigned int D.18329;
  guint8 * addr;
  size_t bytes;

  addr = sgen_card_table_get_card_address (start);
  bytes = cards_in_range (start, size);
  D.18321 = addr + bytes;
  sgen_cardtable.35 = sgen_cardtable;
  D.18323 = sgen_cardtable.35 + 8388608;
  if (D.18321 > D.18323) goto <D.18324>; else goto <D.18325>;
  <D.18324>:
  {
    size_t first_chunk;

    sgen_cardtable.35 = sgen_cardtable;
    D.18323 = sgen_cardtable.35 + 8388608;
    D.18326 = (long int) D.18323;
    addr.36 = (long int) addr;
    D.18328 = D.18326 - addr.36;
    first_chunk = (size_t) D.18328;
    memset (addr, 0, first_chunk);
    D.18329 = bytes - first_chunk;
    sgen_cardtable.35 = sgen_cardtable;
    memset (sgen_cardtable.35, 0, D.18329);
  }
  goto <D.18330>;
  <D.18325>:
  memset (addr, 0, bytes);
  <D.18330>:
}


sgen_card_table_finish_minor_collection ()
{
  sgen_card_tables_collect_stats (0);
}


sgen_card_tables_collect_stats (gboolean begin)
{

}


sgen_card_table_finish_scan_remsets (void * start_nursery, void * end_nursery, struct SgenGrayQueue * queue)
{
  long int D.18331;
  long int D.18332;
  int D.18333;
  long long int last_major_scan_time.37;
  long long int major_card_scan_time.38;
  long long int last_major_scan_time.39;
  long long int major_card_scan_time.40;
  long int D.18338;
  long int D.18339;
  int D.18340;
  long long int last_los_scan_time.41;
  long long int los_card_scan_time.42;
  long long int last_los_scan_time.43;
  long long int los_card_scan_time.44;
  gint64 atv;
  gint64 btv;

  sgen_card_tables_collect_stats (1);
  sgen_major_collector_iterate_live_block_ranges (move_cards_to_shadow_table);
  sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table);
  sgen_card_table_prepare_for_major_collection ();
  atv = mono_100ns_ticks ();
  sgen_major_collector_scan_card_table (queue);
  btv = mono_100ns_ticks ();
  D.18331 = btv - atv;
  D.18332 = D.18331 / 10;
  D.18333 = (int) D.18332;
  last_major_scan_time.37 = (long long int) D.18333;
  last_major_scan_time = last_major_scan_time.37;
  major_card_scan_time.38 = major_card_scan_time;
  last_major_scan_time.39 = last_major_scan_time;
  major_card_scan_time.40 = major_card_scan_time.38 + last_major_scan_time.39;
  major_card_scan_time = major_card_scan_time.40;
  sgen_los_scan_card_table (0, queue);
  atv = mono_100ns_ticks ();
  D.18338 = atv - btv;
  D.18339 = D.18338 / 10;
  D.18340 = (int) D.18339;
  last_los_scan_time.41 = (long long int) D.18340;
  last_los_scan_time = last_los_scan_time.41;
  los_card_scan_time.42 = los_card_scan_time;
  last_los_scan_time.43 = last_los_scan_time;
  los_card_scan_time.44 = los_card_scan_time.42 + last_los_scan_time.43;
  los_card_scan_time = los_card_scan_time.44;
}


move_cards_to_shadow_table (mword start, mword size)
{
  guint8 * D.18345;
  guint8 * sgen_shadow_cardtable.45;
  guint8 * D.18347;
  long int D.18350;
  long int to.46;
  long int D.18352;
  long unsigned int D.18353;
  guint8 * sgen_cardtable.47;
  guint8 * from;
  guint8 * to;
  size_t bytes;

  from = sgen_card_table_get_card_address (start);
  to = sgen_card_table_get_shadow_card_address (start);
  bytes = cards_in_range (start, size);
  D.18345 = to + bytes;
  sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
  D.18347 = sgen_shadow_cardtable.45 + 8388608;
  if (D.18345 > D.18347) goto <D.18348>; else goto <D.18349>;
  <D.18348>:
  {
    size_t first_chunk;
    size_t second_chunk;

    sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
    D.18347 = sgen_shadow_cardtable.45 + 8388608;
    D.18350 = (long int) D.18347;
    to.46 = (long int) to;
    D.18352 = D.18350 - to.46;
    first_chunk = (size_t) D.18352;
    D.18353 = MIN_EXPR <bytes, 8388608>;
    second_chunk = D.18353 - first_chunk;
    memcpy (to, from, first_chunk);
    sgen_cardtable.47 = sgen_cardtable;
    sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
    memcpy (sgen_shadow_cardtable.45, sgen_cardtable.47, second_chunk);
  }
  goto <D.18355>;
  <D.18349>:
  memcpy (to, from, bytes);
  <D.18355>:
}


sgen_card_table_record_pointer (void * address)
{
  long unsigned int address.48;
  guint8 * D.18357;

  address.48 = (long unsigned int) address;
  D.18357 = sgen_card_table_get_card_address (address.48);
  *D.18357 = 1;
}


sgen_card_table_wbarrier_generic_nostore (void * ptr)
{
  long unsigned int ptr.49;

  ptr.49 = (long unsigned int) ptr;
  sgen_card_table_mark_address (ptr.49);
}


sgen_card_table_mark_address (mword address)
{
  guint8 * D.18359;

  D.18359 = sgen_card_table_get_card_address (address);
  *D.18359 = 1;
}


sgen_card_table_wbarrier_object_copy (struct MonoObject * obj, struct MonoObject * src)
{
  struct MonoVTable * D.18360;
  struct MonoClass * D.18361;
  struct SgenThreadInfo * sgen_thread_info.50;
  long unsigned int D.18363;
  long unsigned int D.18364;
  const void * D.18365;
  void * D.18366;
  long unsigned int D.18367;
  long unsigned int obj.51;
  int size;

  D.18360 = obj->vtable;
  D.18361 = D.18360->klass;
  size = D.18361->instance_size;
  sgen_thread_info.50 = sgen_thread_info;
  sgen_thread_info.50->in_critical_region = 1;
  mono_memory_barrier ();
  D.18363 = (long unsigned int) size;
  D.18364 = D.18363 + 18446744073709551600;
  D.18365 = src + 16;
  D.18366 = obj + 16;
  mono_gc_memmove_aligned (D.18366, D.18365, D.18364);
  D.18367 = (long unsigned int) size;
  obj.51 = (long unsigned int) obj;
  sgen_card_table_mark_range (obj.51, D.18367);
  sgen_thread_info.50 = sgen_thread_info;
  sgen_thread_info.50->in_critical_region = 0;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


sgen_card_table_wbarrier_value_copy (void * dest, void * src, int count, struct MonoClass * klass)
{
  int D.18369;
  long unsigned int D.18370;
  struct SgenThreadInfo * sgen_thread_info.52;
  long unsigned int dest.53;
  size_t element_size;
  size_t size;

  D.18369 = mono_class_value_size (klass, 0B);
  element_size = (size_t) D.18369;
  D.18370 = (long unsigned int) count;
  size = D.18370 * element_size;
  sgen_thread_info.52 = sgen_thread_info;
  sgen_thread_info.52->in_critical_region = 1;
  mono_memory_barrier ();
  mono_gc_memmove_atomic (dest, src, size);
  dest.53 = (long unsigned int) dest;
  sgen_card_table_mark_range (dest.53, size);
  sgen_thread_info.52 = sgen_thread_info;
  sgen_thread_info.52->in_critical_region = 0;
}


sgen_card_table_wbarrier_arrayref_copy (void * dest_ptr, void * src_ptr, int count)
{
  long unsigned int D.18376;
  long unsigned int D.18377;
  void * * D.18378;
  sizetype D.18380;
  int need_mod_union.54;
  int D.18385;
  long unsigned int dest.55;
  int D.18390;
  void * * dest;
  void * * src;

  dest = dest_ptr;
  src = src_ptr;
  if (src < dest) goto <D.18375>; else goto <D.18373>;
  <D.18375>:
  D.18376 = (long unsigned int) count;
  D.18377 = D.18376 * 8;
  D.18378 = src + D.18377;
  if (D.18378 > dest) goto <D.18379>; else goto <D.18373>;
  <D.18379>:
  {
    void * * start;

    start = dest;
    D.18376 = (long unsigned int) count;
    D.18377 = D.18376 * 8;
    D.18380 = D.18377 + 18446744073709551608;
    dest = dest + D.18380;
    D.18376 = (long unsigned int) count;
    D.18377 = D.18376 * 8;
    D.18380 = D.18377 + 18446744073709551608;
    src = src + D.18380;
    goto <D.17792>;
    <D.17791>:
    {
      void * value;

      value = *src;
      *dest = value;
      need_mod_union.54 = need_mod_union;
      if (need_mod_union.54 != 0) goto <D.18381>; else goto <D.18384>;
      <D.18384>:
      D.18385 = sgen_ptr_in_nursery (value);
      if (D.18385 != 0) goto <D.18381>; else goto <D.18382>;
      <D.18381>:
      dest.55 = (long unsigned int) dest;
      sgen_card_table_mark_address (dest.55);
      <D.18382>:
      sgen_dummy_use (value);
    }
    src = src + 18446744073709551608;
    dest = dest + 18446744073709551608;
    <D.17792>:
    if (dest >= start) goto <D.17791>; else goto <D.17793>;
    <D.17793>:
  }
  goto <D.18374>;
  <D.18373>:
  {
    void * * end;

    D.18376 = (long unsigned int) count;
    D.18377 = D.18376 * 8;
    end = dest + D.18377;
    goto <D.17797>;
    <D.17796>:
    {
      void * value;

      value = *src;
      *dest = value;
      need_mod_union.54 = need_mod_union;
      if (need_mod_union.54 != 0) goto <D.18387>; else goto <D.18389>;
      <D.18389>:
      D.18390 = sgen_ptr_in_nursery (value);
      if (D.18390 != 0) goto <D.18387>; else goto <D.18388>;
      <D.18387>:
      dest.55 = (long unsigned int) dest;
      sgen_card_table_mark_address (dest.55);
      <D.18388>:
      sgen_dummy_use (value);
    }
    src = src + 8;
    dest = dest + 8;
    <D.17797>:
    if (dest < end) goto <D.17796>; else goto <D.17798>;
    <D.17798>:
  }
  <D.18374>:
}


sgen_dummy_use (void * v)
{
  __asm__ __volatile__("" : "=r" v : "r" v);
}


sgen_card_table_wbarrier_set_arrayref (struct MonoArray * arr, void * slot_ptr, struct MonoObject * value)
{
  int need_mod_union.56;
  int D.18395;
  long unsigned int slot_ptr.57;

  MEM[(void * *)slot_ptr] = value;
  need_mod_union.56 = need_mod_union;
  if (need_mod_union.56 != 0) goto <D.18391>; else goto <D.18394>;
  <D.18394>:
  D.18395 = sgen_ptr_in_nursery (value);
  if (D.18395 != 0) goto <D.18391>; else goto <D.18392>;
  <D.18391>:
  slot_ptr.57 = (long unsigned int) slot_ptr;
  sgen_card_table_mark_address (slot_ptr.57);
  <D.18392>:
  sgen_dummy_use (value);
}


sgen_card_table_wbarrier_set_field (struct MonoObject * obj, void * field_ptr, struct MonoObject * value)
{
  int need_mod_union.58;
  int D.18401;
  long unsigned int field_ptr.59;

  MEM[(void * *)field_ptr] = value;
  need_mod_union.58 = need_mod_union;
  if (need_mod_union.58 != 0) goto <D.18397>; else goto <D.18400>;
  <D.18400>:
  D.18401 = sgen_ptr_in_nursery (value);
  if (D.18401 != 0) goto <D.18397>; else goto <D.18398>;
  <D.18397>:
  field_ptr.59 = (long unsigned int) field_ptr;
  sgen_card_table_mark_address (field_ptr.59);
  <D.18398>:
  sgen_dummy_use (value);
}


