__attribute__((visibility ("hidden")))
sgen_process_togglerefs ()
{
  struct FILE * gc_debug_file.0;
  int toggleref_array_size.1;
  struct MonoGCToggleRef * toggleref_array.2;
  long unsigned int D.17737;
  long unsigned int D.17738;
  struct MonoGCToggleRef * D.17739;
  void * D.17740;
  void * D.17744;
  MonoToggleRefStatus (*<T3015>) (struct MonoObject *) toggleref_callback.3;
  <unnamed type> D.17749;
  int D.17750;
  int D.17751;
  long unsigned int D.17752;
  long unsigned int D.17753;
  struct MonoGCToggleRef * D.17754;
  int D.17757;
  int D.17758;
  int D.17759;
  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.17732>; else goto <D.17733>;
      <D.17732>:
      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.17733>:
      w = 0;
      i = w;
      goto <D.17700>;
      <D.17699>:
      {
        int res;
        struct MonoGCToggleRef r;
        struct MonoObject * obj;

        try
          {
            toggleref_array.2 = toggleref_array;
            D.17737 = (long unsigned int) i;
            D.17738 = D.17737 * 16;
            D.17739 = toggleref_array.2 + D.17738;
            r = *D.17739;
            D.17740 = r.strong_ref;
            if (D.17740 != 0B) goto <D.17741>; else goto <D.17742>;
            <D.17741>:
            obj = r.strong_ref;
            goto <D.17743>;
            <D.17742>:
            D.17744 = r.weak_ref;
            if (D.17744 != 0B) goto <D.17745>; else goto <D.17746>;
            <D.17745>:
            obj = r.weak_ref;
            goto <D.17747>;
            <D.17746>:
            // predicted unlikely by continue predictor.
            goto <D.17693>;
            <D.17747>:
            <D.17743>:
            toggleref_callback.3 = toggleref_callback;
            D.17749 = toggleref_callback.3 (obj);
            res = (int) D.17749;
            D.17750 = toggle_ref_counts[res];
            D.17751 = D.17750 + 1;
            toggle_ref_counts[res] = D.17751;
            switch (res) <default: <D.17698>, case 0: <D.17694>, case 1: <D.17696>, case 2: <D.17697>>
            <D.17694>:
            goto <D.17695>;
            <D.17696>:
            toggleref_array.2 = toggleref_array;
            D.17752 = (long unsigned int) w;
            D.17753 = D.17752 * 16;
            D.17754 = toggleref_array.2 + D.17753;
            D.17754->strong_ref = obj;
            toggleref_array.2 = toggleref_array;
            D.17752 = (long unsigned int) w;
            D.17753 = D.17752 * 16;
            D.17754 = toggleref_array.2 + D.17753;
            D.17754->weak_ref = 0B;
            w = w + 1;
            goto <D.17695>;
            <D.17697>:
            toggleref_array.2 = toggleref_array;
            D.17752 = (long unsigned int) w;
            D.17753 = D.17752 * 16;
            D.17754 = toggleref_array.2 + D.17753;
            D.17754->strong_ref = 0B;
            toggleref_array.2 = toggleref_array;
            D.17752 = (long unsigned int) w;
            D.17753 = D.17752 * 16;
            D.17754 = toggleref_array.2 + D.17753;
            D.17754->weak_ref = obj;
            w = w + 1;
            goto <D.17695>;
            <D.17698>:
            monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "sgen-toggleref.c", 80);
            <D.17695>:
          }
        finally
          {
            r = {CLOBBER};
          }
      }
      <D.17693>:
      i = i + 1;
      <D.17700>:
      toggleref_array_size.1 = toggleref_array_size;
      if (i < toggleref_array_size.1) goto <D.17699>; else goto <D.17701>;
      <D.17701>:
      toggleref_array_size = w;
      if (0 != 0) goto <D.17755>; else goto <D.17756>;
      <D.17755>:
      gc_debug_file.0 = gc_debug_file;
      D.17757 = toggle_ref_counts[0];
      D.17758 = toggle_ref_counts[1];
      D.17759 = toggle_ref_counts[2];
      fprintf (gc_debug_file.0, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d\n", D.17757, D.17758, D.17759, w);
      gc_debug_file.0 = gc_debug_file;
      fflush (gc_debug_file.0);
      <D.17756>:
    }
  finally
    {
      toggle_ref_counts = {CLOBBER};
    }
}


__attribute__((visibility ("hidden")))
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.17768;
  long unsigned int D.17769;
  struct MonoGCToggleRef * D.17770;
  void * D.17771;
  void * * D.17780;
  void * D.17782;
  int D.17789;
  void * * D.17797;
  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.17763>; else goto <D.17764>;
  <D.17763>:
  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.17764>:
  i = 0;
  goto <D.17713>;
  <D.17712>:
  toggleref_array.6 = toggleref_array;
  D.17768 = (long unsigned int) i;
  D.17769 = D.17768 * 16;
  D.17770 = toggleref_array.6 + D.17769;
  D.17771 = D.17770->strong_ref;
  if (D.17771 != 0B) goto <D.17772>; else goto <D.17773>;
  <D.17772>:
  {
    char * object;

    toggleref_array.6 = toggleref_array;
    D.17768 = (long unsigned int) i;
    D.17769 = D.17768 * 16;
    D.17770 = toggleref_array.6 + D.17769;
    object = D.17770->strong_ref;
    if (object >= start) goto <D.17774>; else goto <D.17775>;
    <D.17774>:
    if (object < end) goto <D.17776>; else goto <D.17777>;
    <D.17776>:
    if (0 != 0) goto <D.17778>; else goto <D.17779>;
    <D.17778>:
    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.17779>:
    toggleref_array.6 = toggleref_array;
    D.17768 = (long unsigned int) i;
    D.17769 = D.17768 * 16;
    D.17770 = toggleref_array.6 + D.17769;
    D.17780 = &D.17770->strong_ref;
    copy_func (D.17780, queue);
    <D.17777>:
    <D.17775>:
  }
  goto <D.17781>;
  <D.17773>:
  toggleref_array.6 = toggleref_array;
  D.17768 = (long unsigned int) i;
  D.17769 = D.17768 * 16;
  D.17770 = toggleref_array.6 + D.17769;
  D.17782 = D.17770->weak_ref;
  if (D.17782 != 0B) goto <D.17783>; else goto <D.17784>;
  <D.17783>:
  {
    char * object;

    toggleref_array.6 = toggleref_array;
    D.17768 = (long unsigned int) i;
    D.17769 = D.17768 * 16;
    D.17770 = toggleref_array.6 + D.17769;
    object = D.17770->weak_ref;
    if (object >= start) goto <D.17785>; else goto <D.17786>;
    <D.17785>:
    if (object < end) goto <D.17787>; else goto <D.17788>;
    <D.17787>:
    D.17789 = sgen_gc_is_object_ready_for_finalization (object);
    if (D.17789 != 0) goto <D.17790>; else goto <D.17791>;
    <D.17790>:
    if (0 != 0) goto <D.17792>; else goto <D.17793>;
    <D.17792>:
    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.17793>:
    toggleref_array.6 = toggleref_array;
    D.17768 = (long unsigned int) i;
    D.17769 = D.17768 * 16;
    D.17770 = toggleref_array.6 + D.17769;
    D.17770->weak_ref = 0B;
    goto <D.17794>;
    <D.17791>:
    if (0 != 0) goto <D.17795>; else goto <D.17796>;
    <D.17795>:
    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.17796>:
    toggleref_array.6 = toggleref_array;
    D.17768 = (long unsigned int) i;
    D.17769 = D.17768 * 16;
    D.17770 = toggleref_array.6 + D.17769;
    D.17797 = &D.17770->weak_ref;
    copy_func (D.17797, queue);
    <D.17794>:
    <D.17788>:
    <D.17786>:
  }
  <D.17784>:
  <D.17781>:
  i = i + 1;
  <D.17713>:
  toggleref_array_size.5 = toggleref_array_size;
  if (i < toggleref_array_size.5) goto <D.17712>; else goto <D.17714>;
  <D.17714>:
}


mono_gc_toggleref_add (struct MonoObject * object, mono_bool strong_ref)
{
  MonoToggleRefStatus (*<T3015>) (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.17806;
  long unsigned int D.17807;
  struct MonoGCToggleRef * D.17808;
  void * iftmp.11;
  void * iftmp.12;
  int D.17817;

  toggleref_callback.7 = toggleref_callback;
  if (toggleref_callback.7 == 0B) goto <D.17799>; else goto <D.17800>;
  <D.17799>:
  return;
  <D.17800>:
  if (0 != 0) goto <D.17801>; else goto <D.17802>;
  <D.17801>:
  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.17802>:
  sgen_gc_lock ();
  ensure_toggleref_capacity (1);
  toggleref_array.9 = toggleref_array;
  toggleref_array_size.10 = toggleref_array_size;
  D.17806 = (long unsigned int) toggleref_array_size.10;
  D.17807 = D.17806 * 16;
  D.17808 = toggleref_array.9 + D.17807;
  if (strong_ref != 0) goto <D.17810>; else goto <D.17811>;
  <D.17810>:
  iftmp.11 = object;
  goto <D.17812>;
  <D.17811>:
  iftmp.11 = 0B;
  <D.17812>:
  D.17808->strong_ref = iftmp.11;
  toggleref_array.9 = toggleref_array;
  toggleref_array_size.10 = toggleref_array_size;
  D.17806 = (long unsigned int) toggleref_array_size.10;
  D.17807 = D.17806 * 16;
  D.17808 = toggleref_array.9 + D.17807;
  if (strong_ref == 0) goto <D.17814>; else goto <D.17815>;
  <D.17814>:
  iftmp.12 = object;
  goto <D.17816>;
  <D.17815>:
  iftmp.12 = 0B;
  <D.17816>:
  D.17808->weak_ref = iftmp.12;
  toggleref_array_size.10 = toggleref_array_size;
  D.17817 = toggleref_array_size.10 + 1;
  toggleref_array_size = D.17817;
  sgen_gc_unlock ();
}


ensure_toggleref_capacity (int capacity)
{
  struct MonoGCToggleRef * toggleref_array.13;
  int toggleref_array_capacity.14;
  long unsigned int D.17823;
  long unsigned int D.17824;
  void * D.17825;
  int toggleref_array_size.15;
  int D.17827;
  int D.17830;
  long unsigned int D.17831;
  long unsigned int D.17832;
  long unsigned int D.17833;
  long unsigned int D.17834;

  toggleref_array.13 = toggleref_array;
  if (toggleref_array.13 == 0B) goto <D.17820>; else goto <D.17821>;
  <D.17820>:
  toggleref_array_capacity = 32;
  toggleref_array_capacity.14 = toggleref_array_capacity;
  D.17823 = (long unsigned int) toggleref_array_capacity.14;
  D.17824 = D.17823 * 16;
  D.17825 = sgen_alloc_internal_dynamic (D.17824, 27, 1);
  toggleref_array = D.17825;
  <D.17821>:
  toggleref_array_size.15 = toggleref_array_size;
  D.17827 = toggleref_array_size.15 + capacity;
  toggleref_array_capacity.14 = toggleref_array_capacity;
  if (D.17827 >= toggleref_array_capacity.14) goto <D.17828>; else goto <D.17829>;
  <D.17828>:
  {
    struct MonoGCToggleRef * tmp;
    int old_capacity;

    old_capacity = toggleref_array_capacity;
    goto <D.17721>;
    <D.17720>:
    toggleref_array_capacity.14 = toggleref_array_capacity;
    D.17830 = toggleref_array_capacity.14 * 2;
    toggleref_array_capacity = D.17830;
    <D.17721>:
    toggleref_array_size.15 = toggleref_array_size;
    D.17827 = toggleref_array_size.15 + capacity;
    toggleref_array_capacity.14 = toggleref_array_capacity;
    if (D.17827 > toggleref_array_capacity.14) goto <D.17720>; else goto <D.17722>;
    <D.17722>:
    toggleref_array_capacity.14 = toggleref_array_capacity;
    D.17823 = (long unsigned int) toggleref_array_capacity.14;
    D.17824 = D.17823 * 16;
    tmp = sgen_alloc_internal_dynamic (D.17824, 27, 1);
    toggleref_array.13 = toggleref_array;
    toggleref_array_size.15 = toggleref_array_size;
    D.17831 = (long unsigned int) toggleref_array_size.15;
    D.17832 = D.17831 * 16;
    memcpy (tmp, toggleref_array.13, D.17832);
    toggleref_array.13 = toggleref_array;
    D.17833 = (long unsigned int) old_capacity;
    D.17834 = D.17833 * 16;
    sgen_free_internal_dynamic (toggleref_array.13, D.17834, 27);
    toggleref_array = tmp;
  }
  <D.17829>:
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.17835;
  long unsigned int D.17836;

  D.17836 = __builtin_object_size (__dest, 0);
  D.17835 = __builtin___memcpy_chk (__dest, __src, __len, D.17836);
  return D.17835;
}


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


