sgen_process_togglerefs ()
{
  struct FILE * gc_debug_file.0;
  int toggleref_array_size.1;
  struct MonoGCToggleRef * toggleref_array.2;
  unsigned int i.3;
  unsigned int D.19796;
  struct MonoGCToggleRef * D.19797;
  void * D.19798;
  void * D.19802;
  MonoToggleRefStatus (*<T3891>) (struct MonoObject *) toggleref_callback.4;
  <unnamed type> D.19807;
  int D.19808;
  int D.19809;
  unsigned int w.5;
  unsigned int D.19811;
  struct MonoGCToggleRef * D.19812;
  int D.19815;
  int D.19816;
  int D.19817;
  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.19790>; else goto <D.19791>;
      <D.19790>:
      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.19791>:
      w = 0;
      i = w;
      goto <D.19756>;
      <D.19755>:
      {
        int res;
        struct MonoGCToggleRef r;
        struct MonoObject * obj;

        try
          {
            toggleref_array.2 = toggleref_array;
            i.3 = (unsigned int) i;
            D.19796 = i.3 * 8;
            D.19797 = toggleref_array.2 + D.19796;
            r = *D.19797;
            D.19798 = r.strong_ref;
            if (D.19798 != 0B) goto <D.19799>; else goto <D.19800>;
            <D.19799>:
            obj = r.strong_ref;
            goto <D.19801>;
            <D.19800>:
            D.19802 = r.weak_ref;
            if (D.19802 != 0B) goto <D.19803>; else goto <D.19804>;
            <D.19803>:
            obj = r.weak_ref;
            goto <D.19805>;
            <D.19804>:
            // predicted unlikely by continue predictor.
            goto <D.19749>;
            <D.19805>:
            <D.19801>:
            toggleref_callback.4 = toggleref_callback;
            D.19807 = toggleref_callback.4 (obj);
            res = (int) D.19807;
            D.19808 = toggle_ref_counts[res];
            D.19809 = D.19808 + 1;
            toggle_ref_counts[res] = D.19809;
            switch (res) <default: <D.19754>, case 0: <D.19750>, case 1: <D.19752>, case 2: <D.19753>>
            <D.19750>:
            goto <D.19751>;
            <D.19752>:
            toggleref_array.2 = toggleref_array;
            w.5 = (unsigned int) w;
            D.19811 = w.5 * 8;
            D.19812 = toggleref_array.2 + D.19811;
            D.19812->strong_ref = obj;
            toggleref_array.2 = toggleref_array;
            w.5 = (unsigned int) w;
            D.19811 = w.5 * 8;
            D.19812 = toggleref_array.2 + D.19811;
            D.19812->weak_ref = 0B;
            w = w + 1;
            goto <D.19751>;
            <D.19753>:
            toggleref_array.2 = toggleref_array;
            w.5 = (unsigned int) w;
            D.19811 = w.5 * 8;
            D.19812 = toggleref_array.2 + D.19811;
            D.19812->strong_ref = 0B;
            toggleref_array.2 = toggleref_array;
            w.5 = (unsigned int) w;
            D.19811 = w.5 * 8;
            D.19812 = toggleref_array.2 + D.19811;
            D.19812->weak_ref = obj;
            w = w + 1;
            goto <D.19751>;
            <D.19754>:
            monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "sgen-toggleref.c", 80);
            <D.19751>:
          }
        finally
          {
            r = {CLOBBER};
          }
      }
      <D.19749>:
      i = i + 1;
      <D.19756>:
      toggleref_array_size.1 = toggleref_array_size;
      if (i < toggleref_array_size.1) goto <D.19755>; else goto <D.19757>;
      <D.19757>:
      toggleref_array_size = w;
      if (0 != 0) goto <D.19813>; else goto <D.19814>;
      <D.19813>:
      gc_debug_file.0 = gc_debug_file;
      D.19815 = toggle_ref_counts[0];
      D.19816 = toggle_ref_counts[1];
      D.19817 = toggle_ref_counts[2];
      fprintf (gc_debug_file.0, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d\n", D.19815, D.19816, D.19817, w);
      gc_debug_file.0 = gc_debug_file;
      fflush (gc_debug_file.0);
      <D.19814>:
    }
  finally
    {
      toggle_ref_counts = {CLOBBER};
    }
}


sgen_scan_togglerefs (char * start, char * end, struct ScanCopyContext ctx)
{
  struct FILE * gc_debug_file.6;
  int toggleref_array_size.7;
  struct MonoGCToggleRef * toggleref_array.8;
  unsigned int i.9;
  unsigned int D.19827;
  struct MonoGCToggleRef * D.19828;
  void * D.19829;
  _Bool D.19832;
  _Bool D.19833;
  _Bool D.19834;
  void * * D.19839;
  void * D.19841;
  _Bool D.19844;
  _Bool D.19845;
  _Bool D.19846;
  int D.19849;
  void * * D.19857;
  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.19821>; else goto <D.19822>;
  <D.19821>:
  gc_debug_file.6 = gc_debug_file;
  toggleref_array_size.7 = toggleref_array_size;
  fprintf (gc_debug_file.6, "Scanning ToggleRefs %d\n", toggleref_array_size.7);
  gc_debug_file.6 = gc_debug_file;
  fflush (gc_debug_file.6);
  <D.19822>:
  i = 0;
  goto <D.19769>;
  <D.19768>:
  toggleref_array.8 = toggleref_array;
  i.9 = (unsigned int) i;
  D.19827 = i.9 * 8;
  D.19828 = toggleref_array.8 + D.19827;
  D.19829 = D.19828->strong_ref;
  if (D.19829 != 0B) goto <D.19830>; else goto <D.19831>;
  <D.19830>:
  {
    char * object;

    toggleref_array.8 = toggleref_array;
    i.9 = (unsigned int) i;
    D.19827 = i.9 * 8;
    D.19828 = toggleref_array.8 + D.19827;
    object = D.19828->strong_ref;
    D.19832 = object >= start;
    D.19833 = object < end;
    D.19834 = D.19832 & D.19833;
    if (D.19834 != 0) goto <D.19835>; else goto <D.19836>;
    <D.19835>:
    if (0 != 0) goto <D.19837>; else goto <D.19838>;
    <D.19837>:
    gc_debug_file.6 = gc_debug_file;
    fprintf (gc_debug_file.6, "\tcopying strong slot %d\n", i);
    gc_debug_file.6 = gc_debug_file;
    fflush (gc_debug_file.6);
    <D.19838>:
    toggleref_array.8 = toggleref_array;
    i.9 = (unsigned int) i;
    D.19827 = i.9 * 8;
    D.19828 = toggleref_array.8 + D.19827;
    D.19839 = &D.19828->strong_ref;
    copy_func (D.19839, queue);
    <D.19836>:
  }
  goto <D.19840>;
  <D.19831>:
  toggleref_array.8 = toggleref_array;
  i.9 = (unsigned int) i;
  D.19827 = i.9 * 8;
  D.19828 = toggleref_array.8 + D.19827;
  D.19841 = D.19828->weak_ref;
  if (D.19841 != 0B) goto <D.19842>; else goto <D.19843>;
  <D.19842>:
  {
    char * object;

    toggleref_array.8 = toggleref_array;
    i.9 = (unsigned int) i;
    D.19827 = i.9 * 8;
    D.19828 = toggleref_array.8 + D.19827;
    object = D.19828->weak_ref;
    D.19844 = object >= start;
    D.19845 = object < end;
    D.19846 = D.19844 & D.19845;
    if (D.19846 != 0) goto <D.19847>; else goto <D.19848>;
    <D.19847>:
    D.19849 = sgen_gc_is_object_ready_for_finalization (object);
    if (D.19849 != 0) goto <D.19850>; else goto <D.19851>;
    <D.19850>:
    if (0 != 0) goto <D.19852>; else goto <D.19853>;
    <D.19852>:
    gc_debug_file.6 = gc_debug_file;
    fprintf (gc_debug_file.6, "\tcleaning weak slot %d\n", i);
    gc_debug_file.6 = gc_debug_file;
    fflush (gc_debug_file.6);
    <D.19853>:
    toggleref_array.8 = toggleref_array;
    i.9 = (unsigned int) i;
    D.19827 = i.9 * 8;
    D.19828 = toggleref_array.8 + D.19827;
    D.19828->weak_ref = 0B;
    goto <D.19854>;
    <D.19851>:
    if (0 != 0) goto <D.19855>; else goto <D.19856>;
    <D.19855>:
    gc_debug_file.6 = gc_debug_file;
    fprintf (gc_debug_file.6, "\tkeeping weak slot %d\n", i);
    gc_debug_file.6 = gc_debug_file;
    fflush (gc_debug_file.6);
    <D.19856>:
    toggleref_array.8 = toggleref_array;
    i.9 = (unsigned int) i;
    D.19827 = i.9 * 8;
    D.19828 = toggleref_array.8 + D.19827;
    D.19857 = &D.19828->weak_ref;
    copy_func (D.19857, queue);
    <D.19854>:
    <D.19848>:
  }
  <D.19843>:
  <D.19840>:
  i = i + 1;
  <D.19769>:
  toggleref_array_size.7 = toggleref_array_size;
  if (i < toggleref_array_size.7) goto <D.19768>; else goto <D.19770>;
  <D.19770>:
}


mono_gc_toggleref_add (struct MonoObject * object, mono_bool strong_ref)
{
  MonoToggleRefStatus (*<T3891>) (struct MonoObject *) toggleref_callback.10;
  struct FILE * gc_debug_file.11;
  struct MonoGCToggleRef * toggleref_array.12;
  int toggleref_array_size.13;
  unsigned int toggleref_array_size.14;
  unsigned int D.19867;
  struct MonoGCToggleRef * D.19868;
  void * iftmp.15;
  void * iftmp.16;
  int toggleref_array_size.17;

  toggleref_callback.10 = toggleref_callback;
  if (toggleref_callback.10 == 0B) goto <D.19859>; else goto <D.19860>;
  <D.19859>:
  return;
  <D.19860>:
  if (0 != 0) goto <D.19861>; else goto <D.19862>;
  <D.19861>:
  gc_debug_file.11 = gc_debug_file;
  fprintf (gc_debug_file.11, "Adding toggleref %p %d\n", object, strong_ref);
  gc_debug_file.11 = gc_debug_file;
  fflush (gc_debug_file.11);
  <D.19862>:
  sgen_gc_lock ();
  ensure_toggleref_capacity (1);
  toggleref_array.12 = toggleref_array;
  toggleref_array_size.13 = toggleref_array_size;
  toggleref_array_size.14 = (unsigned int) toggleref_array_size.13;
  D.19867 = toggleref_array_size.14 * 8;
  D.19868 = toggleref_array.12 + D.19867;
  if (strong_ref != 0) goto <D.19870>; else goto <D.19871>;
  <D.19870>:
  iftmp.15 = object;
  goto <D.19872>;
  <D.19871>:
  iftmp.15 = 0B;
  <D.19872>:
  D.19868->strong_ref = iftmp.15;
  toggleref_array.12 = toggleref_array;
  toggleref_array_size.13 = toggleref_array_size;
  toggleref_array_size.14 = (unsigned int) toggleref_array_size.13;
  D.19867 = toggleref_array_size.14 * 8;
  D.19868 = toggleref_array.12 + D.19867;
  if (strong_ref == 0) goto <D.19874>; else goto <D.19875>;
  <D.19874>:
  iftmp.16 = object;
  goto <D.19876>;
  <D.19875>:
  iftmp.16 = 0B;
  <D.19876>:
  D.19868->weak_ref = iftmp.16;
  toggleref_array_size.13 = toggleref_array_size;
  toggleref_array_size.17 = toggleref_array_size.13 + 1;
  toggleref_array_size = toggleref_array_size.17;
  sgen_gc_unlock ();
}


ensure_toggleref_capacity (int capacity)
{
  struct MonoGCToggleRef * toggleref_array.18;
  int toggleref_array_capacity.19;
  unsigned int toggleref_array_capacity.20;
  unsigned int D.19884;
  void * toggleref_array.21;
  int toggleref_array_size.22;
  int D.19887;
  int toggleref_array_capacity.23;
  unsigned int toggleref_array_size.24;
  unsigned int D.19892;
  unsigned int old_capacity.25;
  unsigned int D.19894;

  toggleref_array.18 = toggleref_array;
  if (toggleref_array.18 == 0B) goto <D.19880>; else goto <D.19881>;
  <D.19880>:
  toggleref_array_capacity = 32;
  toggleref_array_capacity.19 = toggleref_array_capacity;
  toggleref_array_capacity.20 = (unsigned int) toggleref_array_capacity.19;
  D.19884 = toggleref_array_capacity.20 * 8;
  toggleref_array.21 = sgen_alloc_internal_dynamic (D.19884, 27, 1);
  toggleref_array = toggleref_array.21;
  <D.19881>:
  toggleref_array_size.22 = toggleref_array_size;
  D.19887 = toggleref_array_size.22 + capacity;
  toggleref_array_capacity.19 = toggleref_array_capacity;
  if (D.19887 >= toggleref_array_capacity.19) goto <D.19888>; else goto <D.19889>;
  <D.19888>:
  {
    struct MonoGCToggleRef * tmp;
    int old_capacity;

    old_capacity = toggleref_array_capacity;
    goto <D.19777>;
    <D.19776>:
    toggleref_array_capacity.19 = toggleref_array_capacity;
    toggleref_array_capacity.23 = toggleref_array_capacity.19 * 2;
    toggleref_array_capacity = toggleref_array_capacity.23;
    <D.19777>:
    toggleref_array_size.22 = toggleref_array_size;
    D.19887 = toggleref_array_size.22 + capacity;
    toggleref_array_capacity.19 = toggleref_array_capacity;
    if (D.19887 > toggleref_array_capacity.19) goto <D.19776>; else goto <D.19778>;
    <D.19778>:
    toggleref_array_capacity.19 = toggleref_array_capacity;
    toggleref_array_capacity.20 = (unsigned int) toggleref_array_capacity.19;
    D.19884 = toggleref_array_capacity.20 * 8;
    tmp = sgen_alloc_internal_dynamic (D.19884, 27, 1);
    toggleref_array.18 = toggleref_array;
    toggleref_array_size.22 = toggleref_array_size;
    toggleref_array_size.24 = (unsigned int) toggleref_array_size.22;
    D.19892 = toggleref_array_size.24 * 8;
    memcpy (tmp, toggleref_array.18, D.19892);
    toggleref_array.18 = toggleref_array;
    old_capacity.25 = (unsigned int) old_capacity;
    D.19894 = old_capacity.25 * 8;
    sgen_free_internal_dynamic (toggleref_array.18, D.19894, 27);
    toggleref_array = tmp;
  }
  <D.19889>:
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.19895;
  unsigned int D.19896;

  D.19896 = __builtin_object_size (__dest, 0);
  D.19895 = __builtin___memcpy_chk (__dest, __src, __len, D.19896);
  return D.19895;
}


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


