sgen_process_togglerefs ()
{
  struct FILE * gc_debug_file.0;
  int toggleref_array_size.1;
  struct MonoGCToggleRef * toggleref_array.2;
  long unsigned int D.18123;
  long unsigned int D.18124;
  struct MonoGCToggleRef * D.18125;
  void * D.18126;
  void * D.18130;
  MonoToggleRefStatus (*<T2f5e>) (struct MonoObject *) toggleref_callback.3;
  <unnamed type> D.18135;
  int D.18136;
  int D.18137;
  long unsigned int D.18138;
  long unsigned int D.18139;
  struct MonoGCToggleRef * D.18140;
  int D.18143;
  int D.18144;
  int D.18145;
  int i;
  int w;
  int toggle_ref_counts[3];

  try
    {
      toggle_ref_counts[0] = 0;
      toggle_ref_counts[1] = 0;
      toggle_ref_counts[2] = 0;
      if (0 != 0) goto <D.18118>; else goto <D.18119>;
      <D.18118>:
      gc_debug_file.0 = gc_debug_file;
      toggleref_array_size.1 = toggleref_array_size;
      fprintf (gc_debug_file.0, "Proccessing ToggleRefs %d\n", toggleref_array_size.1);
      gc_debug_file.0 = gc_debug_file;
      fflush (gc_debug_file.0);
      <D.18119>:
      w = 0;
      i = w;
      goto <D.18086>;
      <D.18085>:
      {
        int res;
        struct MonoGCToggleRef r;
        struct MonoObject * obj;

        try
          {
            toggleref_array.2 = toggleref_array;
            D.18123 = (long unsigned int) i;
            D.18124 = D.18123 * 16;
            D.18125 = toggleref_array.2 + D.18124;
            r = *D.18125;
            D.18126 = r.strong_ref;
            if (D.18126 != 0B) goto <D.18127>; else goto <D.18128>;
            <D.18127>:
            obj = r.strong_ref;
            goto <D.18129>;
            <D.18128>:
            D.18130 = r.weak_ref;
            if (D.18130 != 0B) goto <D.18131>; else goto <D.18132>;
            <D.18131>:
            obj = r.weak_ref;
            goto <D.18133>;
            <D.18132>:
            // predicted unlikely by continue predictor.
            goto <D.18079>;
            <D.18133>:
            <D.18129>:
            toggleref_callback.3 = toggleref_callback;
            D.18135 = toggleref_callback.3 (obj);
            res = (int) D.18135;
            D.18136 = toggle_ref_counts[res];
            D.18137 = D.18136 + 1;
            toggle_ref_counts[res] = D.18137;
            switch (res) <default: <D.18084>, case 0: <D.18080>, case 1: <D.18082>, case 2: <D.18083>>
            <D.18080>:
            goto <D.18081>;
            <D.18082>:
            toggleref_array.2 = toggleref_array;
            D.18138 = (long unsigned int) w;
            D.18139 = D.18138 * 16;
            D.18140 = toggleref_array.2 + D.18139;
            D.18140->strong_ref = obj;
            toggleref_array.2 = toggleref_array;
            D.18138 = (long unsigned int) w;
            D.18139 = D.18138 * 16;
            D.18140 = toggleref_array.2 + D.18139;
            D.18140->weak_ref = 0B;
            w = w + 1;
            goto <D.18081>;
            <D.18083>:
            toggleref_array.2 = toggleref_array;
            D.18138 = (long unsigned int) w;
            D.18139 = D.18138 * 16;
            D.18140 = toggleref_array.2 + D.18139;
            D.18140->strong_ref = 0B;
            toggleref_array.2 = toggleref_array;
            D.18138 = (long unsigned int) w;
            D.18139 = D.18138 * 16;
            D.18140 = toggleref_array.2 + D.18139;
            D.18140->weak_ref = obj;
            w = w + 1;
            goto <D.18081>;
            <D.18084>:
            monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "sgen-toggleref.c", 80);
            <D.18081>:
          }
        finally
          {
            r = {CLOBBER};
          }
      }
      <D.18079>:
      i = i + 1;
      <D.18086>:
      toggleref_array_size.1 = toggleref_array_size;
      if (i < toggleref_array_size.1) goto <D.18085>; else goto <D.18087>;
      <D.18087>:
      toggleref_array_size = w;
      if (0 != 0) goto <D.18141>; else goto <D.18142>;
      <D.18141>:
      gc_debug_file.0 = gc_debug_file;
      D.18143 = toggle_ref_counts[0];
      D.18144 = toggle_ref_counts[1];
      D.18145 = toggle_ref_counts[2];
      fprintf (gc_debug_file.0, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d\n", D.18143, D.18144, D.18145, w);
      gc_debug_file.0 = gc_debug_file;
      fflush (gc_debug_file.0);
      <D.18142>:
    }
  finally
    {
      toggle_ref_counts = {CLOBBER};
    }
}


sgen_scan_togglerefs (char * start, char * end, struct ScanCopyContext ctx)
{
  struct FILE * gc_debug_file.4;
  int toggleref_array_size.5;
  struct MonoGCToggleRef * toggleref_array.6;
  long unsigned int D.18154;
  long unsigned int D.18155;
  struct MonoGCToggleRef * D.18156;
  void * D.18157;
  void * * D.18166;
  void * D.18168;
  int D.18175;
  void * * D.18183;
  void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;
  struct SgenGrayQueue * queue;
  int i;

  copy_func = ctx.copy_func;
  queue = ctx.queue;
  if (0 != 0) goto <D.18149>; else goto <D.18150>;
  <D.18149>:
  gc_debug_file.4 = gc_debug_file;
  toggleref_array_size.5 = toggleref_array_size;
  fprintf (gc_debug_file.4, "Scanning ToggleRefs %d\n", toggleref_array_size.5);
  gc_debug_file.4 = gc_debug_file;
  fflush (gc_debug_file.4);
  <D.18150>:
  i = 0;
  goto <D.18099>;
  <D.18098>:
  toggleref_array.6 = toggleref_array;
  D.18154 = (long unsigned int) i;
  D.18155 = D.18154 * 16;
  D.18156 = toggleref_array.6 + D.18155;
  D.18157 = D.18156->strong_ref;
  if (D.18157 != 0B) goto <D.18158>; else goto <D.18159>;
  <D.18158>:
  {
    char * object;

    toggleref_array.6 = toggleref_array;
    D.18154 = (long unsigned int) i;
    D.18155 = D.18154 * 16;
    D.18156 = toggleref_array.6 + D.18155;
    object = D.18156->strong_ref;
    if (object >= start) goto <D.18160>; else goto <D.18161>;
    <D.18160>:
    if (object < end) goto <D.18162>; else goto <D.18163>;
    <D.18162>:
    if (0 != 0) goto <D.18164>; else goto <D.18165>;
    <D.18164>:
    gc_debug_file.4 = gc_debug_file;
    fprintf (gc_debug_file.4, "\tcopying strong slot %d\n", i);
    gc_debug_file.4 = gc_debug_file;
    fflush (gc_debug_file.4);
    <D.18165>:
    toggleref_array.6 = toggleref_array;
    D.18154 = (long unsigned int) i;
    D.18155 = D.18154 * 16;
    D.18156 = toggleref_array.6 + D.18155;
    D.18166 = &D.18156->strong_ref;
    copy_func (D.18166, queue);
    <D.18163>:
    <D.18161>:
  }
  goto <D.18167>;
  <D.18159>:
  toggleref_array.6 = toggleref_array;
  D.18154 = (long unsigned int) i;
  D.18155 = D.18154 * 16;
  D.18156 = toggleref_array.6 + D.18155;
  D.18168 = D.18156->weak_ref;
  if (D.18168 != 0B) goto <D.18169>; else goto <D.18170>;
  <D.18169>:
  {
    char * object;

    toggleref_array.6 = toggleref_array;
    D.18154 = (long unsigned int) i;
    D.18155 = D.18154 * 16;
    D.18156 = toggleref_array.6 + D.18155;
    object = D.18156->weak_ref;
    if (object >= start) goto <D.18171>; else goto <D.18172>;
    <D.18171>:
    if (object < end) goto <D.18173>; else goto <D.18174>;
    <D.18173>:
    D.18175 = sgen_gc_is_object_ready_for_finalization (object);
    if (D.18175 != 0) goto <D.18176>; else goto <D.18177>;
    <D.18176>:
    if (0 != 0) goto <D.18178>; else goto <D.18179>;
    <D.18178>:
    gc_debug_file.4 = gc_debug_file;
    fprintf (gc_debug_file.4, "\tcleaning weak slot %d\n", i);
    gc_debug_file.4 = gc_debug_file;
    fflush (gc_debug_file.4);
    <D.18179>:
    toggleref_array.6 = toggleref_array;
    D.18154 = (long unsigned int) i;
    D.18155 = D.18154 * 16;
    D.18156 = toggleref_array.6 + D.18155;
    D.18156->weak_ref = 0B;
    goto <D.18180>;
    <D.18177>:
    if (0 != 0) goto <D.18181>; else goto <D.18182>;
    <D.18181>:
    gc_debug_file.4 = gc_debug_file;
    fprintf (gc_debug_file.4, "\tkeeping weak slot %d\n", i);
    gc_debug_file.4 = gc_debug_file;
    fflush (gc_debug_file.4);
    <D.18182>:
    toggleref_array.6 = toggleref_array;
    D.18154 = (long unsigned int) i;
    D.18155 = D.18154 * 16;
    D.18156 = toggleref_array.6 + D.18155;
    D.18183 = &D.18156->weak_ref;
    copy_func (D.18183, queue);
    <D.18180>:
    <D.18174>:
    <D.18172>:
  }
  <D.18170>:
  <D.18167>:
  i = i + 1;
  <D.18099>:
  toggleref_array_size.5 = toggleref_array_size;
  if (i < toggleref_array_size.5) goto <D.18098>; else goto <D.18100>;
  <D.18100>:
}


mono_gc_toggleref_add (struct MonoObject * object, mono_bool strong_ref)
{
  MonoToggleRefStatus (*<T2f5e>) (struct MonoObject *) toggleref_callback.7;
  struct FILE * gc_debug_file.8;
  struct MonoGCToggleRef * toggleref_array.9;
  int toggleref_array_size.10;
  long unsigned int D.18192;
  long unsigned int D.18193;
  struct MonoGCToggleRef * D.18194;
  void * iftmp.11;
  void * iftmp.12;
  int toggleref_array_size.13;

  toggleref_callback.7 = toggleref_callback;
  if (toggleref_callback.7 == 0B) goto <D.18185>; else goto <D.18186>;
  <D.18185>:
  return;
  <D.18186>:
  if (0 != 0) goto <D.18187>; else goto <D.18188>;
  <D.18187>:
  gc_debug_file.8 = gc_debug_file;
  fprintf (gc_debug_file.8, "Adding toggleref %p %d\n", object, strong_ref);
  gc_debug_file.8 = gc_debug_file;
  fflush (gc_debug_file.8);
  <D.18188>:
  sgen_gc_lock ();
  ensure_toggleref_capacity (1);
  toggleref_array.9 = toggleref_array;
  toggleref_array_size.10 = toggleref_array_size;
  D.18192 = (long unsigned int) toggleref_array_size.10;
  D.18193 = D.18192 * 16;
  D.18194 = toggleref_array.9 + D.18193;
  if (strong_ref != 0) goto <D.18196>; else goto <D.18197>;
  <D.18196>:
  iftmp.11 = object;
  goto <D.18198>;
  <D.18197>:
  iftmp.11 = 0B;
  <D.18198>:
  D.18194->strong_ref = iftmp.11;
  toggleref_array.9 = toggleref_array;
  toggleref_array_size.10 = toggleref_array_size;
  D.18192 = (long unsigned int) toggleref_array_size.10;
  D.18193 = D.18192 * 16;
  D.18194 = toggleref_array.9 + D.18193;
  if (strong_ref == 0) goto <D.18200>; else goto <D.18201>;
  <D.18200>:
  iftmp.12 = object;
  goto <D.18202>;
  <D.18201>:
  iftmp.12 = 0B;
  <D.18202>:
  D.18194->weak_ref = iftmp.12;
  toggleref_array_size.10 = toggleref_array_size;
  toggleref_array_size.13 = toggleref_array_size.10 + 1;
  toggleref_array_size = toggleref_array_size.13;
  sgen_gc_unlock ();
}


ensure_toggleref_capacity (int capacity)
{
  struct MonoGCToggleRef * toggleref_array.14;
  int toggleref_array_capacity.15;
  long unsigned int D.18209;
  long unsigned int D.18210;
  void * toggleref_array.16;
  int toggleref_array_size.17;
  int D.18213;
  int toggleref_array_capacity.18;
  long unsigned int D.18217;
  long unsigned int D.18218;
  long unsigned int D.18219;
  long unsigned int D.18220;

  toggleref_array.14 = toggleref_array;
  if (toggleref_array.14 == 0B) goto <D.18206>; else goto <D.18207>;
  <D.18206>:
  toggleref_array_capacity = 32;
  toggleref_array_capacity.15 = toggleref_array_capacity;
  D.18209 = (long unsigned int) toggleref_array_capacity.15;
  D.18210 = D.18209 * 16;
  toggleref_array.16 = sgen_alloc_internal_dynamic (D.18210, 27, 1);
  toggleref_array = toggleref_array.16;
  <D.18207>:
  toggleref_array_size.17 = toggleref_array_size;
  D.18213 = toggleref_array_size.17 + capacity;
  toggleref_array_capacity.15 = toggleref_array_capacity;
  if (D.18213 >= toggleref_array_capacity.15) goto <D.18214>; else goto <D.18215>;
  <D.18214>:
  {
    struct MonoGCToggleRef * tmp;
    int old_capacity;

    old_capacity = toggleref_array_capacity;
    goto <D.18107>;
    <D.18106>:
    toggleref_array_capacity.15 = toggleref_array_capacity;
    toggleref_array_capacity.18 = toggleref_array_capacity.15 * 2;
    toggleref_array_capacity = toggleref_array_capacity.18;
    <D.18107>:
    toggleref_array_size.17 = toggleref_array_size;
    D.18213 = toggleref_array_size.17 + capacity;
    toggleref_array_capacity.15 = toggleref_array_capacity;
    if (D.18213 > toggleref_array_capacity.15) goto <D.18106>; else goto <D.18108>;
    <D.18108>:
    toggleref_array_capacity.15 = toggleref_array_capacity;
    D.18209 = (long unsigned int) toggleref_array_capacity.15;
    D.18210 = D.18209 * 16;
    tmp = sgen_alloc_internal_dynamic (D.18210, 27, 1);
    toggleref_array.14 = toggleref_array;
    toggleref_array_size.17 = toggleref_array_size;
    D.18217 = (long unsigned int) toggleref_array_size.17;
    D.18218 = D.18217 * 16;
    memcpy (tmp, toggleref_array.14, D.18218);
    toggleref_array.14 = toggleref_array;
    D.18219 = (long unsigned int) old_capacity;
    D.18220 = D.18219 * 16;
    sgen_free_internal_dynamic (toggleref_array.14, D.18220, 27);
    toggleref_array = tmp;
  }
  <D.18215>:
}


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

  D.18222 = __builtin_object_size (__dest, 0);
  D.18221 = __builtin___memcpy_chk (__dest, __src, __len, D.18222);
  return D.18221;
}


mono_gc_toggleref_register_callback (MonoToggleRefStatus (*<T2f5e>) (struct MonoObject *) proccess_toggleref)
{
  toggleref_callback = proccess_toggleref;
}


