mono_g_hash_table_new_type (guint (*GHashFunc) (const void *) hash_func, gboolean (*GEqualFunc) (const void *, const void *) key_equal_func, MonoGHashGCType type)
{
  void * table_hash_descr.0;
  void * table_hash_descr.1;
  struct MonoGHashTable * D.19961;
  struct MonoGHashTable * hash;

  hash = mono_g_hash_table_new (hash_func, key_equal_func);
  hash->gc_type = type;
  if (type > 3) goto <D.19953>; else goto <D.19954>;
  <D.19953>:
  monoeg_g_log (0B, 4, "wrong type for gc hashtable");
  <D.19763>:
  goto <D.19763>;
  <D.19954>:
  table_hash_descr.0 = table_hash_descr;
  if (table_hash_descr.0 == 0B) goto <D.19956>; else goto <D.19957>;
  <D.19956>:
  table_hash_descr.1 = mono_gc_make_root_descr_user (mono_g_hash_mark);
  table_hash_descr = table_hash_descr.1;
  <D.19957>:
  if (type != 0) goto <D.19959>; else goto <D.19960>;
  <D.19959>:
  table_hash_descr.0 = table_hash_descr;
  mono_gc_register_root_wbarrier (hash, 40, table_hash_descr.0);
  <D.19960>:
  D.19961 = hash;
  return D.19961;
}


mono_g_hash_mark (void * addr, void (*MonoGCMarkFunc) (void * *) mark_func)
{
  <unnamed type> D.19963;
  struct Slot * * D.19966;
  unsigned int i.2;
  unsigned int D.19968;
  struct Slot * * D.19969;
  void * D.19970;
  void * * D.19973;
  int D.19974;
  void * D.19978;
  void * * D.19981;
  struct MonoGHashTable * table;
  struct Slot * node;
  int i;

  table = addr;
  D.19963 = table->gc_type;
  if (D.19963 == 1) goto <D.19964>; else goto <D.19965>;
  <D.19964>:
  i = 0;
  goto <D.19936>;
  <D.19935>:
  D.19966 = table->table;
  i.2 = (unsigned int) i;
  D.19968 = i.2 * 4;
  D.19969 = D.19966 + D.19968;
  node = *D.19969;
  goto <D.19933>;
  <D.19932>:
  D.19970 = node->key;
  if (D.19970 != 0B) goto <D.19971>; else goto <D.19972>;
  <D.19971>:
  D.19973 = &node->key;
  mark_func (D.19973);
  <D.19972>:
  node = node->next;
  <D.19933>:
  if (node != 0B) goto <D.19932>; else goto <D.19934>;
  <D.19934>:
  i = i + 1;
  <D.19936>:
  D.19974 = table->table_size;
  if (D.19974 > i) goto <D.19935>; else goto <D.19937>;
  <D.19937>:
  goto <D.19975>;
  <D.19965>:
  D.19963 = table->gc_type;
  if (D.19963 == 2) goto <D.19976>; else goto <D.19977>;
  <D.19976>:
  i = 0;
  goto <D.19942>;
  <D.19941>:
  D.19966 = table->table;
  i.2 = (unsigned int) i;
  D.19968 = i.2 * 4;
  D.19969 = D.19966 + D.19968;
  node = *D.19969;
  goto <D.19939>;
  <D.19938>:
  D.19978 = node->value;
  if (D.19978 != 0B) goto <D.19979>; else goto <D.19980>;
  <D.19979>:
  D.19981 = &node->value;
  mark_func (D.19981);
  <D.19980>:
  node = node->next;
  <D.19939>:
  if (node != 0B) goto <D.19938>; else goto <D.19940>;
  <D.19940>:
  i = i + 1;
  <D.19942>:
  D.19974 = table->table_size;
  if (D.19974 > i) goto <D.19941>; else goto <D.19943>;
  <D.19943>:
  goto <D.19982>;
  <D.19977>:
  D.19963 = table->gc_type;
  if (D.19963 == 3) goto <D.19983>; else goto <D.19984>;
  <D.19983>:
  i = 0;
  goto <D.19948>;
  <D.19947>:
  D.19966 = table->table;
  i.2 = (unsigned int) i;
  D.19968 = i.2 * 4;
  D.19969 = D.19966 + D.19968;
  node = *D.19969;
  goto <D.19945>;
  <D.19944>:
  D.19970 = node->key;
  if (D.19970 != 0B) goto <D.19985>; else goto <D.19986>;
  <D.19985>:
  D.19973 = &node->key;
  mark_func (D.19973);
  <D.19986>:
  D.19978 = node->value;
  if (D.19978 != 0B) goto <D.19987>; else goto <D.19988>;
  <D.19987>:
  D.19981 = &node->value;
  mark_func (D.19981);
  <D.19988>:
  node = node->next;
  <D.19945>:
  if (node != 0B) goto <D.19944>; else goto <D.19946>;
  <D.19946>:
  i = i + 1;
  <D.19948>:
  D.19974 = table->table_size;
  if (D.19974 > i) goto <D.19947>; else goto <D.19949>;
  <D.19949>:
  <D.19984>:
  <D.19982>:
  <D.19975>:
}


mono_g_hash_table_new (guint (*GHashFunc) (const void *) hash_func, gboolean (*GEqualFunc) (const void *, const void *) key_equal_func)
{
  unsigned int D.19993;
  int D.19994;
  int D.19995;
  unsigned int D.19996;
  unsigned int D.19997;
  void * D.19998;
  struct MonoGHashTable * D.19999;
  struct MonoGHashTable * hash;

  if (hash_func == 0B) goto <D.19989>; else goto <D.19990>;
  <D.19989>:
  hash_func = monoeg_g_direct_hash;
  <D.19990>:
  if (key_equal_func == 0B) goto <D.19991>; else goto <D.19992>;
  <D.19991>:
  key_equal_func = monoeg_g_direct_equal;
  <D.19992>:
  hash = monoeg_malloc0 (40);
  hash->hash_func = hash_func;
  hash->key_equal_func = key_equal_func;
  D.19993 = monoeg_g_spaced_primes_closest (1);
  D.19994 = (int) D.19993;
  hash->table_size = D.19994;
  D.19995 = hash->table_size;
  D.19996 = (unsigned int) D.19995;
  D.19997 = D.19996 * 4;
  D.19998 = monoeg_malloc0 (D.19997);
  hash->table = D.19998;
  D.19995 = hash->table_size;
  hash->last_rehash = D.19995;
  D.19999 = hash;
  return D.19999;
}


mono_g_hash_table_new_full (guint (*GHashFunc) (const void *) hash_func, gboolean (*GEqualFunc) (const void *, const void *) key_equal_func, void (*GDestroyNotify) (void *) key_destroy_func, void (*GDestroyNotify) (void *) value_destroy_func)
{
  struct MonoGHashTable * D.20003;
  struct MonoGHashTable * hash;

  hash = mono_g_hash_table_new (hash_func, key_equal_func);
  if (hash == 0B) goto <D.20001>; else goto <D.20002>;
  <D.20001>:
  D.20003 = 0B;
  return D.20003;
  <D.20002>:
  hash->key_destroy_func = key_destroy_func;
  hash->value_destroy_func = value_destroy_func;
  D.20003 = hash;
  return D.20003;
}


mono_g_hash_table_size (struct MonoGHashTable * hash)
{
  guint D.20007;
  int D.20008;

  if (hash == 0B) goto <D.20005>; else goto <D.20006>;
  <D.20005>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 250, "hash != NULL");
  D.20007 = 0;
  return D.20007;
  <D.20006>:
  D.20008 = hash->in_use;
  D.20007 = (guint) D.20008;
  return D.20007;
}


mono_g_hash_table_lookup (struct MonoGHashTable * hash, const void * key)
{
  int D.20010;
  void * D.20013;
  void * orig_key;
  void * value;

  try
    {
      D.20010 = mono_g_hash_table_lookup_extended (hash, key, &orig_key, &value);
      if (D.20010 != 0) goto <D.20011>; else goto <D.20012>;
      <D.20011>:
      D.20013 = value;
      return D.20013;
      <D.20012>:
      D.20013 = 0B;
      return D.20013;
    }
  finally
    {
      orig_key = {CLOBBER};
      value = {CLOBBER};
    }
}


mono_g_hash_table_lookup_extended (struct MonoGHashTable * hash, const void * key, void * * orig_key, void * * value)
{
  gboolean D.20018;
  guint (*<T18ba>) (const void *) D.20019;
  unsigned int D.20020;
  int D.20021;
  unsigned int D.20022;
  struct Slot * * D.20023;
  unsigned int D.20024;
  struct Slot * * D.20025;
  void * D.20026;
  int D.20027;
  void * D.20030;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  guint hashcode;

  if (hash == 0B) goto <D.20016>; else goto <D.20017>;
  <D.20016>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 273, "hash != NULL");
  D.20018 = 0;
  return D.20018;
  <D.20017>:
  equal = hash->key_equal_func;
  D.20019 = hash->hash_func;
  D.20020 = D.20019 (key);
  D.20021 = hash->table_size;
  D.20022 = (unsigned int) D.20021;
  hashcode = D.20020 % D.20022;
  D.20023 = hash->table;
  D.20024 = hashcode * 4;
  D.20025 = D.20023 + D.20024;
  s = *D.20025;
  goto <D.19823>;
  <D.19822>:
  D.20026 = s->key;
  D.20027 = equal (D.20026, key);
  if (D.20027 != 0) goto <D.20028>; else goto <D.20029>;
  <D.20028>:
  D.20026 = s->key;
  *orig_key = D.20026;
  D.20030 = s->value;
  *value = D.20030;
  D.20018 = 1;
  return D.20018;
  <D.20029>:
  s = s->next;
  <D.19823>:
  if (s != 0B) goto <D.19822>; else goto <D.19824>;
  <D.19824>:
  D.20018 = 0;
  return D.20018;
}


mono_g_hash_table_foreach (struct MonoGHashTable * hash, void (*GHFunc) (void *, void *, void *) func, void * user_data)
{
  struct Slot * * D.20036;
  unsigned int i.3;
  unsigned int D.20038;
  struct Slot * * D.20039;
  void * D.20040;
  void * D.20041;
  int D.20042;
  int i;

  if (hash == 0B) goto <D.20032>; else goto <D.20033>;
  <D.20032>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 293, "hash != NULL");
  return;
  <D.20033>:
  if (func == 0B) goto <D.20034>; else goto <D.20035>;
  <D.20034>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 294, "func != NULL");
  return;
  <D.20035>:
  i = 0;
  goto <D.19836>;
  <D.19835>:
  {
    struct Slot * s;

    D.20036 = hash->table;
    i.3 = (unsigned int) i;
    D.20038 = i.3 * 4;
    D.20039 = D.20036 + D.20038;
    s = *D.20039;
    goto <D.19833>;
    <D.19832>:
    D.20040 = s->key;
    D.20041 = s->value;
    func (D.20040, D.20041, user_data);
    s = s->next;
    <D.19833>:
    if (s != 0B) goto <D.19832>; else goto <D.19834>;
    <D.19834>:
  }
  i = i + 1;
  <D.19836>:
  D.20042 = hash->table_size;
  if (D.20042 > i) goto <D.19835>; else goto <D.19837>;
  <D.19837>:
}


mono_g_hash_table_find (struct MonoGHashTable * hash, gboolean (*GHRFunc) (void *, void *, void *) predicate, void * user_data)
{
  void * D.20046;
  struct Slot * * D.20049;
  unsigned int i.4;
  unsigned int D.20051;
  struct Slot * * D.20052;
  void * D.20053;
  void * D.20054;
  int D.20055;
  int D.20058;
  int i;

  if (hash == 0B) goto <D.20044>; else goto <D.20045>;
  <D.20044>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 309, "hash != NULL");
  D.20046 = 0B;
  return D.20046;
  <D.20045>:
  if (predicate == 0B) goto <D.20047>; else goto <D.20048>;
  <D.20047>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 310, "predicate != NULL");
  D.20046 = 0B;
  return D.20046;
  <D.20048>:
  i = 0;
  goto <D.19849>;
  <D.19848>:
  {
    struct Slot * s;

    D.20049 = hash->table;
    i.4 = (unsigned int) i;
    D.20051 = i.4 * 4;
    D.20052 = D.20049 + D.20051;
    s = *D.20052;
    goto <D.19846>;
    <D.19845>:
    D.20053 = s->key;
    D.20054 = s->value;
    D.20055 = predicate (D.20053, D.20054, user_data);
    if (D.20055 != 0) goto <D.20056>; else goto <D.20057>;
    <D.20056>:
    D.20046 = s->value;
    return D.20046;
    <D.20057>:
    s = s->next;
    <D.19846>:
    if (s != 0B) goto <D.19845>; else goto <D.19847>;
    <D.19847>:
  }
  i = i + 1;
  <D.19849>:
  D.20058 = hash->table_size;
  if (D.20058 > i) goto <D.19848>; else goto <D.19850>;
  <D.19850>:
  D.20046 = 0B;
  return D.20046;
}


mono_g_hash_table_remove (struct MonoGHashTable * hash, const void * key)
{
  gboolean D.20062;
  guint (*<T18ba>) (const void *) D.20063;
  unsigned int D.20064;
  int D.20065;
  unsigned int D.20066;
  struct Slot * * D.20067;
  unsigned int D.20068;
  struct Slot * * D.20069;
  void * D.20070;
  int D.20071;
  void (*<T180e>) (void *) D.20074;
  void (*<T180e>) (void *) D.20077;
  void * D.20080;
  struct Slot * D.20083;
  int D.20085;
  int D.20086;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  struct Slot * last;
  guint hashcode;

  if (hash == 0B) goto <D.20060>; else goto <D.20061>;
  <D.20060>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 329, "hash != NULL");
  D.20062 = 0;
  return D.20062;
  <D.20061>:
  equal = hash->key_equal_func;
  D.20063 = hash->hash_func;
  D.20064 = D.20063 (key);
  D.20065 = hash->table_size;
  D.20066 = (unsigned int) D.20065;
  hashcode = D.20064 % D.20066;
  last = 0B;
  D.20067 = hash->table;
  D.20068 = hashcode * 4;
  D.20069 = D.20067 + D.20068;
  s = *D.20069;
  goto <D.19860>;
  <D.19859>:
  D.20070 = s->key;
  D.20071 = equal (D.20070, key);
  if (D.20071 != 0) goto <D.20072>; else goto <D.20073>;
  <D.20072>:
  D.20074 = hash->key_destroy_func;
  if (D.20074 != 0B) goto <D.20075>; else goto <D.20076>;
  <D.20075>:
  D.20074 = hash->key_destroy_func;
  D.20070 = s->key;
  D.20074 (D.20070);
  <D.20076>:
  D.20077 = hash->value_destroy_func;
  if (D.20077 != 0B) goto <D.20078>; else goto <D.20079>;
  <D.20078>:
  D.20077 = hash->value_destroy_func;
  D.20080 = s->value;
  D.20077 (D.20080);
  <D.20079>:
  if (last == 0B) goto <D.20081>; else goto <D.20082>;
  <D.20081>:
  D.20067 = hash->table;
  D.20068 = hashcode * 4;
  D.20069 = D.20067 + D.20068;
  D.20083 = s->next;
  *D.20069 = D.20083;
  goto <D.20084>;
  <D.20082>:
  D.20083 = s->next;
  last->next = D.20083;
  <D.20084>:
  free_slot (hash, s);
  D.20085 = hash->in_use;
  D.20086 = D.20085 + -1;
  hash->in_use = D.20086;
  D.20062 = 1;
  return D.20062;
  <D.20073>:
  last = s;
  s = s->next;
  <D.19860>:
  if (s != 0B) goto <D.19859>; else goto <D.19861>;
  <D.19861>:
  D.20062 = 0;
  return D.20062;
}


free_slot (struct MonoGHashTable * hash, struct Slot * slot)
{
  <unnamed type> D.20088;

  D.20088 = hash->gc_type;
  if (D.20088 == 0) goto <D.20089>; else goto <D.20090>;
  <D.20089>:
  mono_gc_free_fixed (slot);
  goto <D.20091>;
  <D.20090>:
  monoeg_g_free (slot);
  <D.20091>:
}


mono_g_hash_table_foreach_remove (struct MonoGHashTable * hash, gboolean (*GHRFunc) (void *, void *, void *) func, void * user_data)
{
  guint D.20094;
  struct Slot * * D.20097;
  unsigned int i.5;
  unsigned int D.20099;
  struct Slot * * D.20100;
  void * D.20101;
  void * D.20102;
  int D.20103;
  void (*<T180e>) (void *) D.20106;
  void (*<T180e>) (void *) D.20109;
  struct Slot * D.20114;
  int D.20116;
  int D.20117;
  int D.20119;
  int i;
  int count;

  count = 0;
  if (hash == 0B) goto <D.20092>; else goto <D.20093>;
  <D.20092>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 359, "hash != NULL");
  D.20094 = 0;
  return D.20094;
  <D.20093>:
  if (func == 0B) goto <D.20095>; else goto <D.20096>;
  <D.20095>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 360, "func != NULL");
  D.20094 = 0;
  return D.20094;
  <D.20096>:
  i = 0;
  goto <D.19876>;
  <D.19875>:
  {
    struct Slot * s;
    struct Slot * last;

    last = 0B;
    D.20097 = hash->table;
    i.5 = (unsigned int) i;
    D.20099 = i.5 * 4;
    D.20100 = D.20097 + D.20099;
    s = *D.20100;
    goto <D.19873>;
    <D.19872>:
    D.20101 = s->key;
    D.20102 = s->value;
    D.20103 = func (D.20101, D.20102, user_data);
    if (D.20103 != 0) goto <D.20104>; else goto <D.20105>;
    <D.20104>:
    {
      struct Slot * n;

      D.20106 = hash->key_destroy_func;
      if (D.20106 != 0B) goto <D.20107>; else goto <D.20108>;
      <D.20107>:
      D.20106 = hash->key_destroy_func;
      D.20101 = s->key;
      D.20106 (D.20101);
      <D.20108>:
      D.20109 = hash->value_destroy_func;
      if (D.20109 != 0B) goto <D.20110>; else goto <D.20111>;
      <D.20110>:
      D.20109 = hash->value_destroy_func;
      D.20102 = s->value;
      D.20109 (D.20102);
      <D.20111>:
      if (last == 0B) goto <D.20112>; else goto <D.20113>;
      <D.20112>:
      D.20097 = hash->table;
      i.5 = (unsigned int) i;
      D.20099 = i.5 * 4;
      D.20100 = D.20097 + D.20099;
      D.20114 = s->next;
      *D.20100 = D.20114;
      n = s->next;
      goto <D.20115>;
      <D.20113>:
      D.20114 = s->next;
      last->next = D.20114;
      n = last->next;
      <D.20115>:
      free_slot (hash, s);
      D.20116 = hash->in_use;
      D.20117 = D.20116 + -1;
      hash->in_use = D.20117;
      count = count + 1;
      s = n;
    }
    goto <D.20118>;
    <D.20105>:
    last = s;
    s = s->next;
    <D.20118>:
    <D.19873>:
    if (s != 0B) goto <D.19872>; else goto <D.19874>;
    <D.19874>:
  }
  i = i + 1;
  <D.19876>:
  D.20119 = hash->table_size;
  if (D.20119 > i) goto <D.19875>; else goto <D.19877>;
  <D.19877>:
  if (count > 0) goto <D.20120>; else goto <D.20121>;
  <D.20120>:
  rehash (hash);
  <D.20121>:
  D.20094 = (guint) count;
  return D.20094;
}


rehash (struct MonoGHashTable * hash)
{
  int D.20123;
  int D.20124;
  int D.20125;
  double D.20126;
  double D.20127;
  int D.20128;
  int D.20129;
  double D.20130;
  _Bool D.20131;
  _Bool D.20132;
  unsigned int D.20135;
  unsigned int D.20136;
  int D.20137;
  int D.20138;
  unsigned int D.20139;
  unsigned int D.20140;
  void * D.20141;
  int diff;
  struct RehashData data;
  void * old_table;

  try
    {
      D.20123 = hash->last_rehash;
      D.20124 = hash->in_use;
      D.20125 = D.20123 - D.20124;
      diff = ABS_EXPR <D.20125>;
      D.20126 = (double) diff;
      D.20127 = D.20126 * 7.5e-1;
      D.20128 = hash->table_size;
      D.20129 = D.20128 * 2;
      D.20130 = (double) D.20129;
      D.20131 = D.20127 > D.20130;
      D.20132 = ~D.20131;
      if (D.20132 != 0) goto <D.20133>; else goto <D.20134>;
      <D.20133>:
      return;
      <D.20134>:
      data.hash = hash;
      D.20124 = hash->in_use;
      D.20135 = (unsigned int) D.20124;
      D.20136 = monoeg_g_spaced_primes_closest (D.20135);
      D.20137 = (int) D.20136;
      data.new_size = D.20137;
      D.20138 = data.new_size;
      D.20139 = (unsigned int) D.20138;
      D.20140 = D.20139 * 4;
      D.20141 = monoeg_malloc0 (D.20140);
      data.table = D.20141;
      old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
      monoeg_g_free (old_table);
    }
  finally
    {
      data = {CLOBBER};
    }
}


do_rehash (void * _data)
{
  int D.20145;
  int D.20146;
  struct Slot * * D.20147;
  unsigned int i.6;
  unsigned int D.20149;
  struct Slot * * D.20150;
  guint (*<T18ba>) (const void *) D.20151;
  void * D.20152;
  unsigned int D.20153;
  unsigned int D.20154;
  struct Slot * * D.20155;
  unsigned int D.20156;
  struct Slot * * D.20157;
  struct Slot * D.20158;
  void * D.20159;
  struct RehashData * data;
  struct MonoGHashTable * hash;
  int current_size;
  int i;
  struct Slot * * table;

  data = _data;
  hash = data->hash;
  D.20145 = hash->table_size;
  hash->last_rehash = D.20145;
  current_size = hash->table_size;
  D.20146 = data->new_size;
  hash->table_size = D.20146;
  table = hash->table;
  D.20147 = data->table;
  hash->table = D.20147;
  i = 0;
  goto <D.19796>;
  <D.19795>:
  {
    struct Slot * s;
    struct Slot * next;

    i.6 = (unsigned int) i;
    D.20149 = i.6 * 4;
    D.20150 = table + D.20149;
    s = *D.20150;
    goto <D.19793>;
    <D.19792>:
    {
      guint hashcode;

      D.20151 = hash->hash_func;
      D.20152 = s->key;
      D.20153 = D.20151 (D.20152);
      D.20145 = hash->table_size;
      D.20154 = (unsigned int) D.20145;
      hashcode = D.20153 % D.20154;
      next = s->next;
      D.20155 = hash->table;
      D.20156 = hashcode * 4;
      D.20157 = D.20155 + D.20156;
      D.20158 = *D.20157;
      s->next = D.20158;
      D.20155 = hash->table;
      D.20156 = hashcode * 4;
      D.20157 = D.20155 + D.20156;
      *D.20157 = s;
    }
    s = next;
    <D.19793>:
    if (s != 0B) goto <D.19792>; else goto <D.19794>;
    <D.19794>:
  }
  i = i + 1;
  <D.19796>:
  if (i < current_size) goto <D.19795>; else goto <D.19797>;
  <D.19797>:
  D.20159 = table;
  return D.20159;
}


mono_g_hash_table_destroy (struct MonoGHashTable * hash)
{
  struct Slot * * D.20163;
  unsigned int i.7;
  unsigned int D.20165;
  struct Slot * * D.20166;
  void (*<T180e>) (void *) D.20167;
  void * D.20170;
  void (*<T180e>) (void *) D.20171;
  void * D.20174;
  int D.20175;
  int i;

  if (hash == 0B) goto <D.20161>; else goto <D.20162>;
  <D.20161>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 401, "hash != NULL");
  return;
  <D.20162>:
  mono_gc_deregister_root (hash);
  i = 0;
  goto <D.19888>;
  <D.19887>:
  {
    struct Slot * s;
    struct Slot * next;

    D.20163 = hash->table;
    i.7 = (unsigned int) i;
    D.20165 = i.7 * 4;
    D.20166 = D.20163 + D.20165;
    s = *D.20166;
    goto <D.19885>;
    <D.19884>:
    next = s->next;
    D.20167 = hash->key_destroy_func;
    if (D.20167 != 0B) goto <D.20168>; else goto <D.20169>;
    <D.20168>:
    D.20167 = hash->key_destroy_func;
    D.20170 = s->key;
    D.20167 (D.20170);
    <D.20169>:
    D.20171 = hash->value_destroy_func;
    if (D.20171 != 0B) goto <D.20172>; else goto <D.20173>;
    <D.20172>:
    D.20171 = hash->value_destroy_func;
    D.20174 = s->value;
    D.20171 (D.20174);
    <D.20173>:
    free_slot (hash, s);
    s = next;
    <D.19885>:
    if (s != 0B) goto <D.19884>; else goto <D.19886>;
    <D.19886>:
  }
  i = i + 1;
  <D.19888>:
  D.20175 = hash->table_size;
  if (D.20175 > i) goto <D.19887>; else goto <D.19889>;
  <D.19889>:
  D.20163 = hash->table;
  monoeg_g_free (D.20163);
  monoeg_g_free (hash);
}


mono_g_hash_table_insert (struct MonoGHashTable * h, void * k, void * v)
{
  mono_g_hash_table_insert_replace (h, k, v, 0);
}


mono_g_hash_table_insert_replace (struct MonoGHashTable * hash, void * key, void * value, gboolean replace)
{
  int D.20179;
  int D.20180;
  guint (*<T18ba>) (const void *) D.20183;
  unsigned int D.20184;
  int D.20185;
  unsigned int D.20186;
  struct Slot * * D.20187;
  unsigned int D.20188;
  struct Slot * * D.20189;
  void * D.20190;
  int D.20191;
  void (*<T180e>) (void *) D.20196;
  void (*<T180e>) (void *) D.20199;
  void * D.20202;
  struct Slot * D.20203;
  int D.20204;
  guint hashcode;
  struct Slot * s;
  gboolean (*GEqualFunc) (const void *, const void *) equal;

  if (hash == 0B) goto <D.20177>; else goto <D.20178>;
  <D.20177>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 431, "hash != NULL");
  return;
  <D.20178>:
  equal = hash->key_equal_func;
  D.20179 = hash->in_use;
  D.20180 = hash->threshold;
  if (D.20179 >= D.20180) goto <D.20181>; else goto <D.20182>;
  <D.20181>:
  rehash (hash);
  <D.20182>:
  D.20183 = hash->hash_func;
  D.20184 = D.20183 (key);
  D.20185 = hash->table_size;
  D.20186 = (unsigned int) D.20185;
  hashcode = D.20184 % D.20186;
  D.20187 = hash->table;
  D.20188 = hashcode * 4;
  D.20189 = D.20187 + D.20188;
  s = *D.20189;
  goto <D.19900>;
  <D.19899>:
  D.20190 = s->key;
  D.20191 = equal (D.20190, key);
  if (D.20191 != 0) goto <D.20192>; else goto <D.20193>;
  <D.20192>:
  if (replace != 0) goto <D.20194>; else goto <D.20195>;
  <D.20194>:
  D.20196 = hash->key_destroy_func;
  if (D.20196 != 0B) goto <D.20197>; else goto <D.20198>;
  <D.20197>:
  D.20196 = hash->key_destroy_func;
  D.20190 = s->key;
  D.20196 (D.20190);
  <D.20198>:
  s->key = key;
  <D.20195>:
  D.20199 = hash->value_destroy_func;
  if (D.20199 != 0B) goto <D.20200>; else goto <D.20201>;
  <D.20200>:
  D.20199 = hash->value_destroy_func;
  D.20202 = s->value;
  D.20199 (D.20202);
  <D.20201>:
  s->value = value;
  return;
  <D.20193>:
  s = s->next;
  <D.19900>:
  if (s != 0B) goto <D.19899>; else goto <D.19901>;
  <D.19901>:
  s = new_slot (hash);
  s->key = key;
  s->value = value;
  D.20187 = hash->table;
  D.20188 = hashcode * 4;
  D.20189 = D.20187 + D.20188;
  D.20203 = *D.20189;
  s->next = D.20203;
  D.20187 = hash->table;
  D.20188 = hashcode * 4;
  D.20189 = D.20187 + D.20188;
  *D.20189 = s;
  D.20179 = hash->in_use;
  D.20204 = D.20179 + 1;
  hash->in_use = D.20204;
}


new_slot (struct MonoGHashTable * hash)
{
  <unnamed type> D.20206;
  struct Slot * D.20209;

  D.20206 = hash->gc_type;
  if (D.20206 == 0) goto <D.20207>; else goto <D.20208>;
  <D.20207>:
  D.20209 = mono_gc_alloc_fixed (12, 0B);
  return D.20209;
  <D.20208>:
  D.20209 = monoeg_malloc (12);
  return D.20209;
}


mono_g_hash_table_replace (struct MonoGHashTable * h, void * k, void * v)
{
  mono_g_hash_table_insert_replace (h, k, v, 1);
}


mono_g_hash_table_print_stats (struct MonoGHashTable * table)
{
  struct Slot * * D.20211;
  unsigned int i.8;
  unsigned int D.20213;
  struct Slot * * D.20214;
  int D.20215;
  int D.20216;
  int i;
  int chain_size;
  int max_chain_size;
  struct Slot * node;

  max_chain_size = 0;
  i = 0;
  goto <D.19923>;
  <D.19922>:
  chain_size = 0;
  D.20211 = table->table;
  i.8 = (unsigned int) i;
  D.20213 = i.8 * 4;
  D.20214 = D.20211 + D.20213;
  node = *D.20214;
  goto <D.19920>;
  <D.19919>:
  chain_size = chain_size + 1;
  node = node->next;
  <D.19920>:
  if (node != 0B) goto <D.19919>; else goto <D.19921>;
  <D.19921>:
  max_chain_size = MAX_EXPR <chain_size, max_chain_size>;
  i = i + 1;
  <D.19923>:
  D.20215 = table->table_size;
  if (D.20215 > i) goto <D.19922>; else goto <D.19924>;
  <D.19924>:
  D.20216 = table->in_use;
  D.20215 = table->table_size;
  printf ("Size: %d Table Size: %d Max Chain Length: %d\n", D.20216, D.20215, max_chain_size);
}


printf (const char * restrict __fmt)
{
  int D.20217;

  D.20217 = __printf_chk (1, __fmt, __builtin_va_arg_pack ());
  return D.20217;
}


