sgen_mark_bridge_object (struct MonoObject * obj)
{
  int D.20089;
  _Bool D.20090;
  int D.20091;
  struct MonoObject * D.20092;
  struct SgenHashTable * hash_table;

  D.20089 = sgen_ptr_in_nursery (obj);
  D.20090 = D.20089 == 0;
  D.20091 = (int) D.20090;
  hash_table = get_finalize_entry_hash_table (D.20091);
  D.20092 = tagged_object_apply (obj, 1);
  sgen_hash_table_set_key (hash_table, obj, D.20092);
}


sgen_ptr_in_nursery (void * p)
{
  gboolean D.20093;
  int sgen_nursery_bits.0;
  int D.20095;
  int D.20096;
  unsigned int D.20097;
  unsigned int p.1;
  unsigned int D.20099;
  char * sgen_nursery_start.2;
  unsigned int sgen_nursery_start.3;
  _Bool D.20102;

  sgen_nursery_bits.0 = sgen_nursery_bits;
  D.20095 = 1 << sgen_nursery_bits.0;
  D.20096 = -D.20095;
  D.20097 = (unsigned int) D.20096;
  p.1 = (unsigned int) p;
  D.20099 = D.20097 & p.1;
  sgen_nursery_start.2 = sgen_nursery_start;
  sgen_nursery_start.3 = (unsigned int) sgen_nursery_start.2;
  D.20102 = D.20099 == sgen_nursery_start.3;
  D.20093 = (gboolean) D.20102;
  return D.20093;
}


get_finalize_entry_hash_table (int generation)
{
  struct SgenHashTable * D.20104;

  switch (generation) <default: <D.19795>, case 0: <D.19793>, case 1: <D.19794>>
  <D.19793>:
  D.20104 = &minor_finalizable_hash;
  return D.20104;
  <D.19794>:
  D.20104 = &major_finalizable_hash;
  return D.20104;
  <D.19795>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "sgen-fin-weak-hash.c", 94);
}


tagged_object_equals (struct MonoObject * a, struct MonoObject * b)
{
  gboolean D.20106;
  struct MonoObject * D.20107;
  struct MonoObject * D.20108;
  _Bool D.20109;

  D.20107 = tagged_object_get_object (a);
  D.20108 = tagged_object_get_object (b);
  D.20109 = D.20107 == D.20108;
  D.20106 = (gboolean) D.20109;
  return D.20106;
}


tagged_object_get_object (struct MonoObject * object)
{
  struct MonoObject * D.20111;
  unsigned int object.4;
  unsigned int D.20113;

  object.4 = (unsigned int) object;
  D.20113 = object.4 & 4294967294;
  D.20111 = (struct MonoObject *) D.20113;
  return D.20111;
}


tagged_object_hash (struct MonoObject * o)
{
  int D.20115;
  struct MonoObject * D.20116;

  D.20116 = tagged_object_get_object (o);
  D.20115 = mono_object_hash (D.20116);
  return D.20115;
}


tagged_object_apply (void * object, int tag_bits)
{
  struct MonoObject * D.20118;
  unsigned int object.5;
  unsigned int tag_bits.6;
  unsigned int D.20121;

  object.5 = (unsigned int) object;
  tag_bits.6 = (unsigned int) tag_bits;
  D.20121 = object.5 | tag_bits.6;
  D.20118 = (struct MonoObject *) D.20121;
  return D.20118;
}


sgen_collect_bridge_objects (int generation, struct ScanCopyContext ctx)
{
  int no_finalize.7;
  unsigned int D.20126;
  gboolean (*<T3655>) (char *) D.20129;
  int D.20130;
  int D.20133;
  int D.20136;
  char * copy.8;
  int D.20142;
  struct SgenHashTableEntry * D.20144;
  unsigned int D.20145;
  unsigned int D.20146;
  int D.20149;
  struct MonoObject * D.20150;
  struct FILE * gc_debug_file.9;
  const char * D.20154;
  const char * D.20157;
  struct MonoObject * D.20158;
  struct SgenHashTableEntry * D.20159;
  unsigned int D.20160;
  void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;
  struct GrayQueue * queue;
  struct SgenHashTable * hash_table;
  struct MonoObject * object;
  void * dummy;
  char * copy;

  try
    {
      copy_func = ctx.copy_func;
      queue = ctx.queue;
      hash_table = get_finalize_entry_hash_table (generation);
      no_finalize.7 = no_finalize;
      if (no_finalize.7 != 0) goto <D.20124>; else goto <D.20125>;
      <D.20124>:
      return;
      <D.20125>:
      {
        struct SgenHashTable * __hash_table;
        struct SgenHashTableEntry * * __table;
        guint __i;

        __hash_table = hash_table;
        __table = __hash_table->table;
        __i = 0;
        goto <D.19822>;
        <D.19821>:
        {
          struct SgenHashTableEntry * * __iter;
          struct SgenHashTableEntry * * __next;

          D.20126 = __i * 4;
          __iter = __table + D.20126;
          goto <D.19819>;
          <D.19818>:
          {
            struct SgenHashTableEntry * __entry;

            __entry = *__iter;
            __next = &__entry->next;
            object = __entry->key;
            dummy = &__entry->data;
            {
              int tag;

              tag = tagged_object_get_tag (object);
              object = tagged_object_get_object (object);
              if (tag == 1) goto <D.20127>; else goto <D.20128>;
              <D.20127>:
              // predicted unlikely by continue predictor.
              goto <D.19817>;
              <D.20128>:
              D.20129 = major_collector.is_object_live;
              D.20130 = D.20129 (object);
              if (D.20130 != 0) goto <D.20131>; else goto <D.20132>;
              <D.20131>:
              // predicted unlikely by continue predictor.
              goto <D.19817>;
              <D.20132>:
              D.20133 = sgen_gc_is_object_ready_for_finalization (object);
              if (D.20133 == 0) goto <D.20134>; else goto <D.20135>;
              <D.20134>:
              // predicted unlikely by continue predictor.
              goto <D.19817>;
              <D.20135>:
              D.20136 = sgen_is_bridge_object (object);
              if (D.20136 == 0) goto <D.20137>; else goto <D.20138>;
              <D.20137>:
              // predicted unlikely by continue predictor.
              goto <D.19817>;
              <D.20138>:
              copy = object;
              copy_func (&copy, queue);
              copy.8 = copy;
              sgen_bridge_register_finalized_object (copy.8);
              if (hash_table == &minor_finalizable_hash) goto <D.20141>; else goto <D.20140>;
              <D.20141>:
              copy.8 = copy;
              D.20142 = sgen_ptr_in_nursery (copy.8);
              if (D.20142 == 0) goto <D.20143>; else goto <D.20140>;
              <D.20143>:
              D.20144 = *__next;
              *__iter = D.20144;
              __next = __iter;
              D.20145 = __hash_table->num_entries;
              D.20146 = D.20145 + 4294967295;
              __hash_table->num_entries = D.20146;
              if (1 != 0) goto <D.20147>; else goto <D.20148>;
              <D.20147>:
              D.20149 = __hash_table->entry_mem_type;
              sgen_free_internal (__entry, D.20149);
              <D.20148>:
              copy.8 = copy;
              D.20150 = tagged_object_apply (copy.8, tag);
              sgen_hash_table_replace (&major_finalizable_hash, D.20150, 0B, 0B);
              if (0 != 0) goto <D.20151>; else goto <D.20152>;
              <D.20151>:
              gc_debug_file.9 = gc_debug_file;
              copy.8 = copy;
              copy.8 = copy;
              D.20154 = sgen_safe_name (copy.8);
              fprintf (gc_debug_file.9, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy.8, D.20154, object);
              gc_debug_file.9 = gc_debug_file;
              fflush (gc_debug_file.9);
              <D.20152>:
              // predicted unlikely by continue predictor.
              goto <D.19817>;
              <D.20140>:
              if (0 != 0) goto <D.20155>; else goto <D.20156>;
              <D.20155>:
              gc_debug_file.9 = gc_debug_file;
              copy.8 = copy;
              copy.8 = copy;
              D.20157 = sgen_safe_name (copy.8);
              fprintf (gc_debug_file.9, "Updating object for finalization: %p (%s) (was at %p)\n", copy.8, D.20157, object);
              gc_debug_file.9 = gc_debug_file;
              fflush (gc_debug_file.9);
              <D.20156>:
              copy.8 = copy;
              D.20158 = tagged_object_apply (copy.8, tag);
              __entry->key = D.20158;
            }
          }
          <D.19817>:
          __iter = __next;
          <D.19819>:
          D.20159 = *__iter;
          if (D.20159 != 0B) goto <D.19818>; else goto <D.19820>;
          <D.19820>:
        }
        __i = __i + 1;
        <D.19822>:
        D.20160 = hash_table->size;
        if (D.20160 > __i) goto <D.19821>; else goto <D.19823>;
        <D.19823>:
      }
    }
  finally
    {
      copy = {CLOBBER};
    }
}


tagged_object_get_tag (struct MonoObject * object)
{
  int D.20164;
  int object.10;

  object.10 = (int) object;
  D.20164 = object.10 & 1;
  return D.20164;
}


sgen_finalize_in_range (int generation, struct ScanCopyContext ctx)
{
  int no_finalize.11;
  unsigned int D.20170;
  gboolean (*<T3655>) (char *) D.20171;
  int D.20172;
  struct SgenHashTableEntry * D.20177;
  unsigned int D.20178;
  unsigned int D.20179;
  int D.20182;
  int num_ready_finalizers.12;
  int num_ready_finalizers.13;
  struct MonoObject * copy.14;
  struct FILE * gc_debug_file.15;
  const char * D.20189;
  unsigned int D.20190;
  int D.20193;
  struct MonoObject * D.20197;
  const char * D.20200;
  const char * D.20203;
  struct MonoObject * D.20204;
  struct SgenHashTableEntry * D.20205;
  unsigned int D.20206;
  void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;
  struct GrayQueue * queue;
  struct SgenHashTable * hash_table;
  struct MonoObject * object;
  void * dummy;

  copy_func = ctx.copy_func;
  queue = ctx.queue;
  hash_table = get_finalize_entry_hash_table (generation);
  no_finalize.11 = no_finalize;
  if (no_finalize.11 != 0) goto <D.20168>; else goto <D.20169>;
  <D.20168>:
  return;
  <D.20169>:
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash_table;
    __table = __hash_table->table;
    __i = 0;
    goto <D.19847>;
    <D.19846>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20170 = __i * 4;
      __iter = __table + D.20170;
      goto <D.19844>;
      <D.19843>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        object = __entry->key;
        dummy = &__entry->data;
        {
          int tag;

          tag = tagged_object_get_tag (object);
          object = tagged_object_get_object (object);
          D.20171 = major_collector.is_object_live;
          D.20172 = D.20171 (object);
          if (D.20172 == 0) goto <D.20173>; else goto <D.20174>;
          <D.20173>:
          {
            gboolean is_fin_ready;
            struct MonoObject * copy;

            try
              {
                is_fin_ready = sgen_gc_is_object_ready_for_finalization (object);
                copy = object;
                copy_func (&copy, queue);
                if (is_fin_ready != 0) goto <D.20175>; else goto <D.20176>;
                <D.20175>:
                D.20177 = *__next;
                *__iter = D.20177;
                __next = __iter;
                D.20178 = __hash_table->num_entries;
                D.20179 = D.20178 + 4294967295;
                __hash_table->num_entries = D.20179;
                if (1 != 0) goto <D.20180>; else goto <D.20181>;
                <D.20180>:
                D.20182 = __hash_table->entry_mem_type;
                sgen_free_internal (__entry, D.20182);
                <D.20181>:
                num_ready_finalizers.12 = num_ready_finalizers;
                num_ready_finalizers.13 = num_ready_finalizers.12 + 1;
                num_ready_finalizers = num_ready_finalizers.13;
                copy.14 = copy;
                sgen_queue_finalization_entry (copy.14);
                if (0 != 0) goto <D.20186>; else goto <D.20187>;
                <D.20186>:
                gc_debug_file.15 = gc_debug_file;
                copy.14 = copy;
                copy.14 = copy;
                D.20189 = sgen_safe_name (copy.14);
                num_ready_finalizers.12 = num_ready_finalizers;
                D.20190 = hash_table->num_entries;
                fprintf (gc_debug_file.15, "Queueing object for finalization: %p (%s) (was at %p) (%d/%d)\n", copy.14, D.20189, object, num_ready_finalizers.12, D.20190);
                gc_debug_file.15 = gc_debug_file;
                fflush (gc_debug_file.15);
                <D.20187>:
                // predicted unlikely by continue predictor.
                goto <D.19842>;
                <D.20176>:
                if (hash_table == &minor_finalizable_hash) goto <D.20192>; else goto <D.20191>;
                <D.20192>:
                copy.14 = copy;
                D.20193 = sgen_ptr_in_nursery (copy.14);
                if (D.20193 == 0) goto <D.20194>; else goto <D.20191>;
                <D.20194>:
                D.20177 = *__next;
                *__iter = D.20177;
                __next = __iter;
                D.20178 = __hash_table->num_entries;
                D.20179 = D.20178 + 4294967295;
                __hash_table->num_entries = D.20179;
                if (1 != 0) goto <D.20195>; else goto <D.20196>;
                <D.20195>:
                D.20182 = __hash_table->entry_mem_type;
                sgen_free_internal (__entry, D.20182);
                <D.20196>:
                copy.14 = copy;
                D.20197 = tagged_object_apply (copy.14, tag);
                sgen_hash_table_replace (&major_finalizable_hash, D.20197, 0B, 0B);
                if (0 != 0) goto <D.20198>; else goto <D.20199>;
                <D.20198>:
                gc_debug_file.15 = gc_debug_file;
                copy.14 = copy;
                copy.14 = copy;
                D.20200 = sgen_safe_name (copy.14);
                fprintf (gc_debug_file.15, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy.14, D.20200, object);
                gc_debug_file.15 = gc_debug_file;
                fflush (gc_debug_file.15);
                <D.20199>:
                // predicted unlikely by continue predictor.
                goto <D.19842>;
                <D.20191>:
                if (0 != 0) goto <D.20201>; else goto <D.20202>;
                <D.20201>:
                gc_debug_file.15 = gc_debug_file;
                copy.14 = copy;
                copy.14 = copy;
                D.20203 = sgen_safe_name (copy.14);
                fprintf (gc_debug_file.15, "Updating object for finalization: %p (%s) (was at %p)\n", copy.14, D.20203, object);
                gc_debug_file.15 = gc_debug_file;
                fflush (gc_debug_file.15);
                <D.20202>:
                copy.14 = copy;
                D.20204 = tagged_object_apply (copy.14, tag);
                __entry->key = D.20204;
              }
            finally
              {
                copy = {CLOBBER};
              }
          }
          <D.20174>:
        }
      }
      <D.19842>:
      __iter = __next;
      <D.19844>:
      D.20205 = *__iter;
      if (D.20205 != 0B) goto <D.19843>; else goto <D.19845>;
      <D.19845>:
    }
    __i = __i + 1;
    <D.19847>:
    D.20206 = hash_table->size;
    if (D.20206 > __i) goto <D.19846>; else goto <D.19848>;
    <D.19848>:
  }
}


sgen_process_fin_stage_entries ()
{
  lock_stage_for_processing (&next_fin_stage_entry);
  process_stage_entries (1024, &next_fin_stage_entry, &fin_stage_entries, process_fin_stage_entry);
}


process_fin_stage_entry (struct MonoObject * obj, void * user_data, int index)
{
  int D.20210;

  D.20210 = sgen_ptr_in_nursery (obj);
  if (D.20210 != 0) goto <D.20211>; else goto <D.20212>;
  <D.20211>:
  register_for_finalization (obj, user_data, 0);
  goto <D.20213>;
  <D.20212>:
  register_for_finalization (obj, user_data, 1);
  <D.20213>:
}


register_for_finalization (struct MonoObject * obj, void * user_data, int generation)
{
  int no_finalize.16;
  int iftmp.17;
  _Bool D.20222;
  long int D.20223;
  long int D.20224;
  int D.20229;
  struct FILE * gc_debug_file.18;
  struct MonoVTable * D.20235;
  struct MonoClass * D.20236;
  const char * D.20237;
  unsigned int D.20238;
  const char * D.20239;
  int D.20241;
  struct SgenHashTable * hash_table;

  hash_table = get_finalize_entry_hash_table (generation);
  no_finalize.16 = no_finalize;
  if (no_finalize.16 != 0) goto <D.20215>; else goto <D.20216>;
  <D.20215>:
  return;
  <D.20216>:
  if (user_data != 0B) goto <D.20220>; else goto <D.20218>;
  <D.20220>:
  if (user_data != mono_gc_run_finalize) goto <D.20221>; else goto <D.20218>;
  <D.20221>:
  iftmp.17 = 1;
  goto <D.20219>;
  <D.20218>:
  iftmp.17 = 0;
  <D.20219>:
  D.20222 = iftmp.17 != 0;
  D.20223 = (long int) D.20222;
  D.20224 = __builtin_expect (D.20223, 0);
  if (D.20224 != 0) goto <D.20225>; else goto <D.20226>;
  <D.20225>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-fin-weak-hash.c", 223, "user_data == NULL || user_data == mono_gc_run_finalize");
  <D.20226>:
  if (user_data != 0B) goto <D.20227>; else goto <D.20228>;
  <D.20227>:
  D.20229 = sgen_hash_table_replace (hash_table, obj, 0B, 0B);
  if (D.20229 != 0) goto <D.20230>; else goto <D.20231>;
  <D.20230>:
  if (0 != 0) goto <D.20232>; else goto <D.20233>;
  <D.20232>:
  gc_debug_file.18 = gc_debug_file;
  D.20235 = obj->vtable;
  D.20236 = D.20235->klass;
  D.20237 = D.20236->name;
  D.20238 = hash_table->num_entries;
  D.20239 = sgen_generation_name (generation);
  fprintf (gc_debug_file.18, "Added finalizer for object: %p (%s) (%d) to %s table\n", obj, D.20237, D.20238, D.20239);
  gc_debug_file.18 = gc_debug_file;
  fflush (gc_debug_file.18);
  <D.20233>:
  <D.20231>:
  goto <D.20240>;
  <D.20228>:
  D.20241 = sgen_hash_table_remove (hash_table, obj, 0B);
  if (D.20241 != 0) goto <D.20242>; else goto <D.20243>;
  <D.20242>:
  if (0 != 0) goto <D.20244>; else goto <D.20245>;
  <D.20244>:
  gc_debug_file.18 = gc_debug_file;
  D.20235 = obj->vtable;
  D.20236 = D.20235->klass;
  D.20237 = D.20236->name;
  D.20238 = hash_table->num_entries;
  fprintf (gc_debug_file.18, "Removed finalizer for object: %p (%s) (%d)\n", obj, D.20237, D.20238);
  gc_debug_file.18 = gc_debug_file;
  fflush (gc_debug_file.18);
  <D.20245>:
  <D.20243>:
  <D.20240>:
}


lock_stage_for_processing (volatile gint32 * next_entry)
{
  *next_entry = -1;
}


process_stage_entries (int num_entries, volatile gint32 * next_entry, struct StageEntry * entries, void (*<T3902>) (struct MonoObject *, void *, int) process_func)
{
  int D.20247;
  unsigned int i.19;
  unsigned int D.20251;
  struct StageEntry * D.20252;
  volatile gint32 * D.20253;
  int D.20254;
  struct MonoObject * D.20258;
  void * D.20259;
  int i;
  void retry = <<< error >>>;

  D.20247 = *next_entry;
  if (D.20247 != -1) goto <D.20248>; else goto <D.20249>;
  <D.20248>:
  return;
  <D.20249>:
  i = 0;
  goto <D.19891>;
  <D.19890>:
  {
    gint32 state;

    retry:
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    state = D.20252->state;
    switch (state) <default: <D.19888>, case 0: <D.19882>, case 1: <D.19885>, case 2: <D.19886>, case 3: <D.19883>>
    <D.19882>:
    <D.19883>:
    // predicted unlikely by continue predictor.
    goto <D.19884>;
    <D.19885>:
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20253 = &D.20252->state;
    D.20254 = InterlockedCompareExchange (D.20253, 3, 1);
    if (D.20254 != 1) goto retry; else goto <D.20255>;
    <D.20255>:
    // predicted unlikely by continue predictor.
    goto <D.19884>;
    <D.19886>:
    goto <D.19887>;
    <D.19888>:
    if (1 != 0) goto <D.20256>; else goto <D.20257>;
    <D.20256>:
    monoeg_g_log (0B, 4, "Invalid stage entry state");
    <D.19889>:
    goto <D.19889>;
    <D.20257>:
    goto <D.19887>;
    <D.19887>:
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20258 = D.20252->obj;
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20259 = D.20252->user_data;
    process_func (D.20258, D.20259, i);
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20252->obj = 0B;
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20252->user_data = 0B;
    mono_memory_write_barrier ();
    i.19 = (unsigned int) i;
    D.20251 = i.19 * 12;
    D.20252 = entries + D.20251;
    D.20252->state = 0;
  }
  <D.19884>:
  i = i + 1;
  <D.19891>:
  if (i < num_entries) goto <D.19890>; else goto <D.19892>;
  <D.19892>:
  mono_memory_write_barrier ();
  *next_entry = 0;
}


InterlockedCompareExchange (volatile gint32 * dest, gint32 exch, gint32 comp)
{
  gint32 D.20263;
  unsigned int comp.20;
  unsigned int exch.21;
  unsigned int D.20266;

  comp.20 = (unsigned int) comp;
  exch.21 = (unsigned int) exch;
  D.20266 = __sync_val_compare_and_swap_4 (dest, comp.20, exch.21);
  D.20263 = (gint32) D.20266;
  return D.20263;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_gc_register_for_finalization (struct MonoObject * obj, void * user_data)
{
  int D.20268;
  int D.20271;

  goto <D.19927>;
  <D.19926>:
  D.20268 = try_lock_stage_for_processing (1024, &next_fin_stage_entry);
  if (D.20268 != 0) goto <D.20269>; else goto <D.20270>;
  <D.20269>:
  pthread_mutex_lock (&gc_mutex);
  process_stage_entries (1024, &next_fin_stage_entry, &fin_stage_entries, process_fin_stage_entry);
  sgen_gc_unlock ();
  <D.20270>:
  <D.19927>:
  D.20271 = add_stage_entry (1024, &next_fin_stage_entry, &fin_stage_entries, obj, user_data);
  if (D.20271 == -1) goto <D.19926>; else goto <D.19928>;
  <D.19928>:
}


try_lock_stage_for_processing (int num_entries, volatile gint32 * next_entry)
{
  gboolean D.20274;
  int D.20275;
  _Bool D.20276;
  gint32 old;

  old = *next_entry;
  if (old < num_entries) goto <D.20272>; else goto <D.20273>;
  <D.20272>:
  D.20274 = 0;
  return D.20274;
  <D.20273>:
  D.20275 = InterlockedCompareExchange (next_entry, -1, old);
  D.20276 = D.20275 == old;
  D.20274 = (gboolean) D.20276;
  return D.20274;
}


add_stage_entry (int num_entries, volatile gint32 * next_entry, struct StageEntry * entries, struct MonoObject * obj, void * user_data)
{
  int D.20280;
  unsigned int index.22;
  unsigned int D.20286;
  struct StageEntry * D.20287;
  int D.20288;
  volatile gint32 * D.20290;
  int D.20291;
  int D.20292;
  int D.20295;
  _Bool D.20298;
  _Bool D.20299;
  _Bool D.20300;
  int D.20301;
  _Bool D.20302;
  long int D.20303;
  long int D.20304;
  volatile gint32 * D.20307;
  _Bool D.20310;
  _Bool D.20311;
  _Bool D.20312;
  int D.20313;
  _Bool D.20314;
  long int D.20315;
  long int D.20316;
  _Bool D.20319;
  long int D.20320;
  long int D.20321;
  gint32 index;
  gint32 new_next_entry;
  gint32 old_next_entry;
  gint32 previous_state;
  void retry = <<< error >>>;

  retry:
  <D.19910>:
  index = *next_entry;
  if (index >= num_entries) goto <D.20278>; else goto <D.20279>;
  <D.20278>:
  D.20280 = -1;
  return D.20280;
  <D.20279>:
  if (index < 0) goto <D.20281>; else goto <D.20282>;
  <D.20281>:
  goto <D.19906>;
  <D.19905>:
  monoeg_g_usleep (200);
  <D.19906>:
  index = *next_entry;
  if (index < 0) goto <D.19905>; else goto <D.19907>;
  <D.19907>:
  // predicted unlikely by continue predictor.
  goto <D.19908>;
  <D.20282>:
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20288 = D.20287->state;
  if (D.20288 != 0) goto <D.20283>; else goto <D.20289>;
  <D.20289>:
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20290 = &D.20287->state;
  D.20291 = InterlockedCompareExchange (D.20290, 1, 0);
  if (D.20291 != 0) goto <D.20283>; else goto <D.20284>;
  <D.20283>:
  D.20292 = *next_entry;
  if (D.20292 == index) goto <D.20293>; else goto <D.20294>;
  <D.20293>:
  D.20295 = index + 1;
  InterlockedCompareExchange (next_entry, D.20295, index);
  <D.20294>:
  // predicted unlikely by continue predictor.
  goto <D.19908>;
  <D.20284>:
  mono_memory_write_barrier ();
  D.20295 = index + 1;
  old_next_entry = InterlockedCompareExchange (next_entry, D.20295, index);
  if (old_next_entry < index) goto <D.20296>; else goto <D.20297>;
  <D.20296>:
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->state = 0;
  // predicted unlikely by continue predictor.
  goto <D.19908>;
  <D.20297>:
  goto <D.19909>;
  <D.19908>:
  goto <D.19910>;
  <D.19909>:
  D.20298 = index < 0;
  D.20299 = index >= num_entries;
  D.20300 = D.20298 | D.20299;
  D.20301 = (int) D.20300;
  D.20302 = D.20301 != 0;
  D.20303 = (long int) D.20302;
  D.20304 = __builtin_expect (D.20303, 0);
  if (D.20304 != 0) goto <D.20305>; else goto <D.20306>;
  <D.20305>:
  monoeg_g_log (0B, 4, "Invalid index");
  <D.19911>:
  goto <D.19911>;
  <D.20306>:
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->obj = obj;
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->user_data = user_data;
  mono_memory_write_barrier ();
  new_next_entry = *next_entry;
  mono_memory_read_barrier ();
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20307 = &D.20287->state;
  previous_state = InterlockedCompareExchange (D.20307, 2, 1);
  if (previous_state == 1) goto <D.20308>; else goto <D.20309>;
  <D.20308>:
  D.20310 = new_next_entry < index;
  D.20311 = new_next_entry >= 0;
  D.20312 = D.20310 & D.20311;
  D.20313 = (int) D.20312;
  D.20314 = D.20313 != 0;
  D.20315 = (long int) D.20314;
  D.20316 = __builtin_expect (D.20315, 0);
  if (D.20316 != 0) goto <D.20317>; else goto <D.20318>;
  <D.20317>:
  monoeg_g_log (0B, 4, "Invalid next entry index - as long as we\'re busy, other thread can only increment or invalidate it");
  <D.19912>:
  goto <D.19912>;
  <D.20318>:
  D.20280 = index;
  return D.20280;
  <D.20309>:
  D.20319 = previous_state != 3;
  D.20320 = (long int) D.20319;
  D.20321 = __builtin_expect (D.20320, 0);
  if (D.20321 != 0) goto <D.20322>; else goto <D.20323>;
  <D.20322>:
  monoeg_g_log (0B, 4, "Invalid state transition - other thread can only make busy state invalid");
  <D.19913>:
  goto <D.19913>;
  <D.20323>:
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->obj = 0B;
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->user_data = 0B;
  mono_memory_write_barrier ();
  index.22 = (unsigned int) index;
  D.20286 = index.22 * 12;
  D.20287 = entries + D.20286;
  D.20287->state = 0;
  goto retry;
}


mono_memory_read_barrier ()
{
  mono_memory_barrier ();
}


mono_gc_finalizers_for_domain (struct MonoDomain * domain, struct MonoObject * * out_array, int out_size)
{
  unsigned int result.23;
  unsigned int D.20328;
  struct MonoObject * * D.20329;
  int D.20330;
  int D.20331;
  int D.20332;
  int result;

  pthread_mutex_lock (&gc_mutex);
  sgen_process_fin_stage_entries ();
  result = finalizers_for_domain (domain, out_array, out_size, &minor_finalizable_hash);
  if (result < out_size) goto <D.20325>; else goto <D.20326>;
  <D.20325>:
  result.23 = (unsigned int) result;
  D.20328 = result.23 * 4;
  D.20329 = out_array + D.20328;
  D.20330 = out_size - result;
  D.20331 = finalizers_for_domain (domain, D.20329, D.20330, &major_finalizable_hash);
  result = D.20331 + result;
  <D.20326>:
  sgen_gc_unlock ();
  D.20332 = result;
  return D.20332;
}


finalizers_for_domain (struct MonoDomain * domain, struct MonoObject * * out_array, int out_size, struct SgenHashTable * hash_table)
{
  int no_finalize.24;
  _Bool D.20338;
  _Bool D.20339;
  _Bool D.20340;
  int D.20341;
  unsigned int D.20342;
  struct MonoVTable * D.20343;
  struct MonoDomain * D.20344;
  struct SgenHashTableEntry * D.20347;
  unsigned int D.20348;
  unsigned int D.20349;
  int D.20352;
  int count.25;
  unsigned int count.26;
  unsigned int D.20355;
  struct MonoObject * * D.20356;
  struct FILE * gc_debug_file.27;
  const char * D.20360;
  int num_ready_finalizers.28;
  unsigned int D.20362;
  struct SgenHashTableEntry * D.20365;
  unsigned int D.20366;
  struct MonoObject * object;
  void * dummy;
  int count;

  no_finalize.24 = no_finalize;
  if (no_finalize.24 != 0) goto <D.20334>; else goto <D.20337>;
  <D.20337>:
  D.20338 = out_size == 0;
  D.20339 = out_array == 0B;
  D.20340 = D.20338 | D.20339;
  if (D.20340 != 0) goto <D.20334>; else goto <D.20335>;
  <D.20334>:
  D.20341 = 0;
  return D.20341;
  <D.20335>:
  count = 0;
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash_table;
    __table = __hash_table->table;
    __i = 0;
    goto <D.19949>;
    <D.19948>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20342 = __i * 4;
      __iter = __table + D.20342;
      goto <D.19946>;
      <D.19945>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        object = __entry->key;
        dummy = &__entry->data;
        object = tagged_object_get_object (object);
        D.20343 = object->vtable;
        D.20344 = D.20343->domain;
        if (D.20344 == domain) goto <D.20345>; else goto <D.20346>;
        <D.20345>:
        D.20347 = *__next;
        *__iter = D.20347;
        __next = __iter;
        D.20348 = __hash_table->num_entries;
        D.20349 = D.20348 + 4294967295;
        __hash_table->num_entries = D.20349;
        if (1 != 0) goto <D.20350>; else goto <D.20351>;
        <D.20350>:
        D.20352 = __hash_table->entry_mem_type;
        sgen_free_internal (__entry, D.20352);
        <D.20351>:
        count.25 = count;
        count = count.25 + 1;
        count.26 = (unsigned int) count.25;
        D.20355 = count.26 * 4;
        D.20356 = out_array + D.20355;
        *D.20356 = object;
        if (0 != 0) goto <D.20357>; else goto <D.20358>;
        <D.20357>:
        gc_debug_file.27 = gc_debug_file;
        D.20360 = sgen_safe_name (object);
        num_ready_finalizers.28 = num_ready_finalizers;
        D.20362 = hash_table->num_entries;
        fprintf (gc_debug_file.27, "Collecting object for finalization: %p (%s) (%d/%d)\n", object, D.20360, num_ready_finalizers.28, D.20362);
        gc_debug_file.27 = gc_debug_file;
        fflush (gc_debug_file.27);
        <D.20358>:
        if (count == out_size) goto <D.20363>; else goto <D.20364>;
        <D.20363>:
        D.20341 = count;
        return D.20341;
        <D.20364>:
        // predicted unlikely by continue predictor.
        goto <D.19944>;
        <D.20346>:
      }
      <D.19944>:
      __iter = __next;
      <D.19946>:
      D.20365 = *__iter;
      if (D.20365 != 0B) goto <D.19945>; else goto <D.19947>;
      <D.19947>:
    }
    __i = __i + 1;
    <D.19949>:
    D.20366 = hash_table->size;
    if (D.20366 > __i) goto <D.19948>; else goto <D.19950>;
    <D.19950>:
  }
  D.20341 = count;
  return D.20341;
}


sgen_null_link_in_range (int generation, gboolean before_finalization, struct ScanCopyContext ctx)
{
  unsigned int D.20368;
  void * D.20369;
  struct FILE * gc_debug_file.29;
  long unsigned int D.20375;
  long unsigned int D.20376;
  _Bool D.20377;
  long unsigned int D.20380;
  long unsigned int D.20381;
  gboolean (*<T3655>) (char *) D.20386;
  int D.20387;
  int D.20390;
  struct SgenHashTableEntry * D.20395;
  unsigned int D.20396;
  unsigned int D.20397;
  int D.20400;
  char * copy.30;
  int D.20404;
  _Bool D.20408;
  long int D.20409;
  long int D.20410;
  long unsigned int iftmp.31;
  long unsigned int copy.32;
  long unsigned int D.20418;
  long unsigned int D.20419;
  void * D.20420;
  long unsigned int iftmp.33;
  long unsigned int D.20427;
  long unsigned int D.20428;
  void * D.20429;
  void * D.20432;
  struct SgenHashTableEntry * D.20433;
  unsigned int D.20434;
  void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;
  struct GrayQueue * queue;
  void * * link;
  void * dummy;
  struct SgenHashTable * hash;

  copy_func = ctx.copy_func;
  queue = ctx.queue;
  hash = get_dislink_hash_table (generation);
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash;
    __table = __hash_table->table;
    __i = 0;
    goto <D.19995>;
    <D.19994>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20368 = __i * 4;
      __iter = __table + D.20368;
      goto <D.19992>;
      <D.19991>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        link = __entry->key;
        dummy = &__entry->data;
        {
          char * object;
          gboolean track;

          D.20369 = *link;
          if (D.20369 == 0B) goto <D.20370>; else goto <D.20371>;
          <D.20370>:
          if (0 != 0) goto <D.20372>; else goto <D.20373>;
          <D.20372>:
          gc_debug_file.29 = gc_debug_file;
          fprintf (gc_debug_file.29, "Dislink %p was externally nullified\n", link);
          gc_debug_file.29 = gc_debug_file;
          fflush (gc_debug_file.29);
          <D.20373>:
          // predicted unlikely by continue predictor.
          goto <D.19989>;
          <D.20371>:
          D.20369 = *link;
          D.20375 = (long unsigned int) D.20369;
          D.20376 = D.20375 & 1;
          D.20377 = D.20376 == 0;
          track = (gboolean) D.20377;
          if (track != before_finalization) goto <D.20378>; else goto <D.20379>;
          <D.20378>:
          D.20369 = *link;
          D.20375 = (long unsigned int) D.20369;
          D.20380 = ~D.20375;
          D.20381 = D.20380 & 4294967292;
          object = (char *) D.20381;
          if (object == 0B) goto <D.20382>; else goto <D.20383>;
          <D.20382>:
          if (0 != 0) goto <D.20384>; else goto <D.20385>;
          <D.20384>:
          gc_debug_file.29 = gc_debug_file;
          fprintf (gc_debug_file.29, "Dislink %p with a hidden null object\n", link);
          gc_debug_file.29 = gc_debug_file;
          fflush (gc_debug_file.29);
          <D.20385>:
          // predicted unlikely by continue predictor.
          goto <D.19989>;
          <D.20383>:
          D.20386 = major_collector.is_object_live;
          D.20387 = D.20386 (object);
          if (D.20387 == 0) goto <D.20388>; else goto <D.20389>;
          <D.20388>:
          D.20390 = sgen_gc_is_object_ready_for_finalization (object);
          if (D.20390 != 0) goto <D.20391>; else goto <D.20392>;
          <D.20391>:
          *link = 0B;
          if (0 != 0) goto <D.20393>; else goto <D.20394>;
          <D.20393>:
          gc_debug_file.29 = gc_debug_file;
          fprintf (gc_debug_file.29, "Dislink nullified at %p to GCed object %p\n", link, object);
          gc_debug_file.29 = gc_debug_file;
          fflush (gc_debug_file.29);
          <D.20394>:
          D.20395 = *__next;
          *__iter = D.20395;
          __next = __iter;
          D.20396 = __hash_table->num_entries;
          D.20397 = D.20396 + 4294967295;
          __hash_table->num_entries = D.20397;
          if (1 != 0) goto <D.20398>; else goto <D.20399>;
          <D.20398>:
          D.20400 = __hash_table->entry_mem_type;
          sgen_free_internal (__entry, D.20400);
          <D.20399>:
          // predicted unlikely by continue predictor.
          goto <D.19989>;
          <D.20392>:
          {
            char * copy;

            try
              {
                copy = object;
                copy_func (&copy, queue);
                if (hash == &minor_disappearing_link_hash) goto <D.20402>; else goto <D.20401>;
                <D.20402>:
                copy.30 = copy;
                D.20404 = sgen_ptr_in_nursery (copy.30);
                if (D.20404 == 0) goto <D.20405>; else goto <D.20401>;
                <D.20405>:
                D.20395 = *__next;
                *__iter = D.20395;
                __next = __iter;
                D.20396 = __hash_table->num_entries;
                D.20397 = D.20396 + 4294967295;
                __hash_table->num_entries = D.20397;
                if (1 != 0) goto <D.20406>; else goto <D.20407>;
                <D.20406>:
                D.20400 = __hash_table->entry_mem_type;
                sgen_free_internal (__entry, D.20400);
                <D.20407>:
                copy.30 = copy;
                D.20408 = copy.30 == 0B;
                D.20409 = (long int) D.20408;
                D.20410 = __builtin_expect (D.20409, 0);
                if (D.20410 != 0) goto <D.20411>; else goto <D.20412>;
                <D.20411>:
                monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "sgen-fin-weak-hash.c", 700, "copy");
                <D.20412>:
                if (track != 0) goto <D.20414>; else goto <D.20415>;
                <D.20414>:
                iftmp.31 = 1;
                goto <D.20416>;
                <D.20415>:
                iftmp.31 = 0;
                <D.20416>:
                copy.30 = copy;
                copy.32 = (long unsigned int) copy.30;
                D.20418 = iftmp.31 | copy.32;
                D.20419 = ~D.20418;
                D.20420 = (void *) D.20419;
                *link = D.20420;
                copy.30 = copy;
                add_or_remove_disappearing_link (copy.30, link, 1);
                if (0 != 0) goto <D.20421>; else goto <D.20422>;
                <D.20421>:
                gc_debug_file.29 = gc_debug_file;
                copy.30 = copy;
                fprintf (gc_debug_file.29, "Upgraded dislink at %p to major because object %p moved to %p\n", link, object, copy.30);
                gc_debug_file.29 = gc_debug_file;
                fflush (gc_debug_file.29);
                <D.20422>:
                // predicted unlikely by continue predictor.
                goto <D.19989>;
                <D.20401>:
                if (track != 0) goto <D.20424>; else goto <D.20425>;
                <D.20424>:
                iftmp.33 = 1;
                goto <D.20426>;
                <D.20425>:
                iftmp.33 = 0;
                <D.20426>:
                copy.30 = copy;
                copy.32 = (long unsigned int) copy.30;
                D.20427 = iftmp.33 | copy.32;
                D.20428 = ~D.20427;
                D.20429 = (void *) D.20428;
                *link = D.20429;
                if (0 != 0) goto <D.20430>; else goto <D.20431>;
                <D.20430>:
                gc_debug_file.29 = gc_debug_file;
                D.20369 = *link;
                D.20375 = (long unsigned int) D.20369;
                D.20380 = ~D.20375;
                D.20381 = D.20380 & 4294967292;
                D.20432 = (void *) D.20381;
                fprintf (gc_debug_file.29, "Updated dislink at %p to %p\n", link, D.20432);
                gc_debug_file.29 = gc_debug_file;
                fflush (gc_debug_file.29);
                <D.20431>:
              }
            finally
              {
                copy = {CLOBBER};
              }
          }
          <D.20389>:
          <D.20379>:
        }
      }
      <D.19989>:
      __iter = __next;
      <D.19992>:
      D.20433 = *__iter;
      if (D.20433 != 0B) goto <D.19991>; else goto <D.19993>;
      <D.19993>:
    }
    __i = __i + 1;
    <D.19995>:
    D.20434 = hash->size;
    if (D.20434 > __i) goto <D.19994>; else goto <D.19996>;
    <D.19996>:
  }
}


get_dislink_hash_table (int generation)
{
  struct SgenHashTable * D.20437;

  switch (generation) <default: <D.19964>, case 0: <D.19962>, case 1: <D.19963>>
  <D.19962>:
  D.20437 = &minor_disappearing_link_hash;
  return D.20437;
  <D.19963>:
  D.20437 = &major_disappearing_link_hash;
  return D.20437;
  <D.19964>:
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "sgen-fin-weak-hash.c", 608);
}


add_or_remove_disappearing_link (struct MonoObject * obj, void * * link, int generation)
{
  int D.20441;
  struct FILE * gc_debug_file.34;
  unsigned int D.20447;
  const char * D.20448;
  struct MonoVTable * D.20451;
  struct MonoClass * D.20452;
  const char * D.20453;
  const char * D.20454;
  struct SgenHashTable * hash_table;

  hash_table = get_dislink_hash_table (generation);
  if (obj == 0B) goto <D.20439>; else goto <D.20440>;
  <D.20439>:
  D.20441 = sgen_hash_table_remove (hash_table, link, 0B);
  if (D.20441 != 0) goto <D.20442>; else goto <D.20443>;
  <D.20442>:
  if (0 != 0) goto <D.20444>; else goto <D.20445>;
  <D.20444>:
  gc_debug_file.34 = gc_debug_file;
  D.20447 = hash_table->num_entries;
  D.20448 = sgen_generation_name (generation);
  fprintf (gc_debug_file.34, "Removed dislink %p (%d) from %s table\n", link, D.20447, D.20448);
  gc_debug_file.34 = gc_debug_file;
  fflush (gc_debug_file.34);
  <D.20445>:
  <D.20443>:
  return;
  <D.20440>:
  sgen_hash_table_replace (hash_table, link, 0B, 0B);
  if (0 != 0) goto <D.20449>; else goto <D.20450>;
  <D.20449>:
  gc_debug_file.34 = gc_debug_file;
  D.20451 = obj->vtable;
  D.20452 = D.20451->klass;
  D.20453 = D.20452->name;
  D.20454 = sgen_generation_name (generation);
  fprintf (gc_debug_file.34, "Added dislink for object: %p (%s) at %p to %s table\n", obj, D.20453, link, D.20454);
  gc_debug_file.34 = gc_debug_file;
  fflush (gc_debug_file.34);
  <D.20450>:
}


sgen_null_links_for_domain (struct MonoDomain * domain, int generation)
{
  unsigned int D.20456;
  void * D.20457;
  long unsigned int D.20458;
  long unsigned int D.20459;
  long unsigned int D.20460;
  struct MonoVTable * D.20465;
  struct FILE * gc_debug_file.35;
  struct SgenHashTableEntry * D.20473;
  unsigned int D.20474;
  unsigned int D.20475;
  int D.20478;
  struct SgenHashTableEntry * D.20479;
  unsigned int D.20480;
  void * * link;
  void * dummy;
  struct SgenHashTable * hash;

  hash = get_dislink_hash_table (generation);
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash;
    __table = __hash_table->table;
    __i = 0;
    goto <D.20017>;
    <D.20016>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20456 = __i * 4;
      __iter = __table + D.20456;
      goto <D.20014>;
      <D.20013>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        link = __entry->key;
        dummy = &__entry->data;
        {
          char * object;

          D.20457 = *link;
          D.20458 = (long unsigned int) D.20457;
          D.20459 = ~D.20458;
          D.20460 = D.20459 & 4294967292;
          object = (char *) D.20460;
          D.20457 = *link;
          if (D.20457 != 0B) goto <D.20461>; else goto <D.20462>;
          <D.20461>:
          if (object != 0B) goto <D.20463>; else goto <D.20464>;
          <D.20463>:
          D.20465 = MEM[(struct MonoObject *)object].vtable;
          if (D.20465 == 0B) goto <D.20466>; else goto <D.20467>;
          <D.20466>:
          {
            gboolean free;

            free = 1;
            D.20457 = *link;
            if (D.20457 != 0B) goto <D.20468>; else goto <D.20469>;
            <D.20468>:
            *link = 0B;
            free = 0;
            if (0 != 0) goto <D.20470>; else goto <D.20471>;
            <D.20470>:
            gc_debug_file.35 = gc_debug_file;
            fprintf (gc_debug_file.35, "Disappearing link %p not freed\n", link);
            gc_debug_file.35 = gc_debug_file;
            fflush (gc_debug_file.35);
            <D.20471>:
            <D.20469>:
            D.20473 = *__next;
            *__iter = D.20473;
            __next = __iter;
            D.20474 = __hash_table->num_entries;
            D.20475 = D.20474 + 4294967295;
            __hash_table->num_entries = D.20475;
            if (free != 0) goto <D.20476>; else goto <D.20477>;
            <D.20476>:
            D.20478 = __hash_table->entry_mem_type;
            sgen_free_internal (__entry, D.20478);
            <D.20477>:
            // predicted unlikely by continue predictor.
            goto <D.20012>;
          }
          <D.20467>:
          <D.20464>:
          <D.20462>:
        }
      }
      <D.20012>:
      __iter = __next;
      <D.20014>:
      D.20479 = *__iter;
      if (D.20479 != 0B) goto <D.20013>; else goto <D.20015>;
      <D.20015>:
    }
    __i = __i + 1;
    <D.20017>:
    D.20480 = hash->size;
    if (D.20480 > __i) goto <D.20016>; else goto <D.20018>;
    <D.20018>:
  }
}


sgen_null_links_with_predicate (int generation, mono_bool (*WeakLinkAlivePredicateFunc) (struct MonoObject *, void *) predicate, void * data)
{
  unsigned int D.20481;
  void * D.20482;
  long unsigned int D.20483;
  long unsigned int D.20484;
  long unsigned int D.20485;
  struct FILE * gc_debug_file.36;
  struct SgenHashTableEntry * D.20493;
  unsigned int D.20494;
  unsigned int D.20495;
  int D.20498;
  struct SgenHashTableEntry * D.20499;
  unsigned int D.20500;
  void * * link;
  void * dummy;
  struct SgenHashTable * hash;

  hash = get_dislink_hash_table (generation);
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash;
    __table = __hash_table->table;
    __i = 0;
    goto <D.20040>;
    <D.20039>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20481 = __i * 4;
      __iter = __table + D.20481;
      goto <D.20037>;
      <D.20036>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        link = __entry->key;
        dummy = &__entry->data;
        {
          char * object;
          mono_bool is_alive;

          D.20482 = *link;
          D.20483 = (long unsigned int) D.20482;
          D.20484 = ~D.20483;
          D.20485 = D.20484 & 4294967292;
          object = (char *) D.20485;
          D.20482 = *link;
          if (D.20482 == 0B) goto <D.20486>; else goto <D.20487>;
          <D.20486>:
          // predicted unlikely by continue predictor.
          goto <D.20035>;
          <D.20487>:
          is_alive = predicate (object, data);
          if (is_alive == 0) goto <D.20488>; else goto <D.20489>;
          <D.20488>:
          *link = 0B;
          if (0 != 0) goto <D.20490>; else goto <D.20491>;
          <D.20490>:
          gc_debug_file.36 = gc_debug_file;
          fprintf (gc_debug_file.36, "Dislink nullified by predicate at %p to GCed object %p\n", link, object);
          gc_debug_file.36 = gc_debug_file;
          fflush (gc_debug_file.36);
          <D.20491>:
          D.20493 = *__next;
          *__iter = D.20493;
          __next = __iter;
          D.20494 = __hash_table->num_entries;
          D.20495 = D.20494 + 4294967295;
          __hash_table->num_entries = D.20495;
          if (1 != 0) goto <D.20496>; else goto <D.20497>;
          <D.20496>:
          D.20498 = __hash_table->entry_mem_type;
          sgen_free_internal (__entry, D.20498);
          <D.20497>:
          // predicted unlikely by continue predictor.
          goto <D.20035>;
          <D.20489>:
        }
      }
      <D.20035>:
      __iter = __next;
      <D.20037>:
      D.20499 = *__iter;
      if (D.20499 != 0B) goto <D.20036>; else goto <D.20038>;
      <D.20038>:
    }
    __i = __i + 1;
    <D.20040>:
    D.20500 = hash->size;
    if (D.20500 > __i) goto <D.20039>; else goto <D.20041>;
    <D.20041>:
  }
}


sgen_remove_finalizers_for_domain (struct MonoDomain * domain, int generation)
{
  unsigned int D.20501;
  struct MonoVTable * D.20502;
  struct MonoDomain * D.20503;
  struct FILE * gc_debug_file.37;
  const char * D.20509;
  struct SgenHashTableEntry * D.20510;
  unsigned int D.20511;
  unsigned int D.20512;
  int D.20515;
  struct SgenHashTableEntry * D.20516;
  unsigned int D.20517;
  struct SgenHashTable * hash_table;
  struct MonoObject * object;
  void * dummy;

  hash_table = get_finalize_entry_hash_table (generation);
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = hash_table;
    __table = __hash_table->table;
    __i = 0;
    goto <D.20060>;
    <D.20059>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.20501 = __i * 4;
      __iter = __table + D.20501;
      goto <D.20057>;
      <D.20056>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        object = __entry->key;
        dummy = &__entry->data;
        object = tagged_object_get_object (object);
        D.20502 = object->vtable;
        D.20503 = D.20502->domain;
        if (D.20503 == domain) goto <D.20504>; else goto <D.20505>;
        <D.20504>:
        if (0 != 0) goto <D.20506>; else goto <D.20507>;
        <D.20506>:
        gc_debug_file.37 = gc_debug_file;
        D.20509 = sgen_safe_name (object);
        fprintf (gc_debug_file.37, "Unregistering finalizer for object: %p (%s)\n", object, D.20509);
        gc_debug_file.37 = gc_debug_file;
        fflush (gc_debug_file.37);
        <D.20507>:
        D.20510 = *__next;
        *__iter = D.20510;
        __next = __iter;
        D.20511 = __hash_table->num_entries;
        D.20512 = D.20511 + 4294967295;
        __hash_table->num_entries = D.20512;
        if (1 != 0) goto <D.20513>; else goto <D.20514>;
        <D.20513>:
        D.20515 = __hash_table->entry_mem_type;
        sgen_free_internal (__entry, D.20515);
        <D.20514>:
        // predicted unlikely by continue predictor.
        goto <D.20055>;
        <D.20505>:
      }
      <D.20055>:
      __iter = __next;
      <D.20057>:
      D.20516 = *__iter;
      if (D.20516 != 0B) goto <D.20056>; else goto <D.20058>;
      <D.20058>:
    }
    __i = __i + 1;
    <D.20060>:
    D.20517 = hash_table->size;
    if (D.20517 > __i) goto <D.20059>; else goto <D.20061>;
    <D.20061>:
  }
}


sgen_process_dislink_stage_entries ()
{
  lock_stage_for_processing (&next_dislink_stage_entry);
  process_stage_entries (1024, &next_dislink_stage_entry, &dislink_stage_entries, process_dislink_stage_entry);
}


process_dislink_stage_entry (struct MonoObject * obj, void * _link, int index)
{
  int D.20522;
  void * * link;

  link = _link;
  if (index >= 0) goto <D.20518>; else goto <D.20519>;
  <D.20518>:
  <D.20519>:
  add_or_remove_disappearing_link (0B, link, 0);
  add_or_remove_disappearing_link (0B, link, 1);
  if (obj != 0B) goto <D.20520>; else goto <D.20521>;
  <D.20520>:
  D.20522 = sgen_ptr_in_nursery (obj);
  if (D.20522 != 0) goto <D.20523>; else goto <D.20524>;
  <D.20523>:
  add_or_remove_disappearing_link (obj, link, 0);
  goto <D.20525>;
  <D.20524>:
  add_or_remove_disappearing_link (obj, link, 1);
  <D.20525>:
  <D.20521>:
}


sgen_register_disappearing_link (struct MonoObject * obj, void * * link, gboolean track, gboolean in_gc)
{
  long unsigned int iftmp.38;
  long unsigned int obj.39;
  long unsigned int D.20533;
  long unsigned int D.20534;
  void * D.20535;
  int D.20540;

  if (obj != 0B) goto <D.20526>; else goto <D.20527>;
  <D.20526>:
  if (track != 0) goto <D.20529>; else goto <D.20530>;
  <D.20529>:
  iftmp.38 = 1;
  goto <D.20531>;
  <D.20530>:
  iftmp.38 = 0;
  <D.20531>:
  obj.39 = (long unsigned int) obj;
  D.20533 = iftmp.38 | obj.39;
  D.20534 = ~D.20533;
  D.20535 = (void *) D.20534;
  *link = D.20535;
  goto <D.20536>;
  <D.20527>:
  *link = 0B;
  <D.20536>:
  if (in_gc != 0) goto <D.20537>; else goto <D.20538>;
  <D.20537>:
  process_dislink_stage_entry (obj, link, -1);
  goto <D.20539>;
  <D.20538>:
  {
    int index;

    goto <D.20081>;
    <D.20080>:
    D.20540 = try_lock_stage_for_processing (1024, &next_dislink_stage_entry);
    if (D.20540 != 0) goto <D.20541>; else goto <D.20542>;
    <D.20541>:
    pthread_mutex_lock (&gc_mutex);
    process_stage_entries (1024, &next_dislink_stage_entry, &dislink_stage_entries, process_dislink_stage_entry);
    sgen_gc_unlock ();
    <D.20542>:
    <D.20081>:
    index = add_stage_entry (1024, &next_dislink_stage_entry, &dislink_stage_entries, obj, link);
    if (index == -1) goto <D.20080>; else goto <D.20082>;
    <D.20082>:
  }
  <D.20539>:
}


sgen_init_fin_weak_hash ()
{

}


