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.17124;
  struct MonoGHashTable * hash;

  hash = mono_g_hash_table_new (hash_func, key_equal_func);
  hash->gc_type = type;
  if (type > 3) goto <D.17116>; else goto <D.17117>;
  <D.17116>:
  monoeg_g_log (0B, 4, "wrong type for gc hashtable");
  <D.16928>:
  goto <D.16928>;
  <D.17117>:
  table_hash_descr.0 = table_hash_descr;
  if (table_hash_descr.0 == 0B) goto <D.17119>; else goto <D.17120>;
  <D.17119>:
  table_hash_descr.1 = mono_gc_make_root_descr_user (mono_g_hash_mark);
  table_hash_descr = table_hash_descr.1;
  <D.17120>:
  if (type != 0) goto <D.17122>; else goto <D.17123>;
  <D.17122>:
  table_hash_descr.0 = table_hash_descr;
  mono_gc_register_root_wbarrier (hash, 40, table_hash_descr.0);
  <D.17123>:
  D.17124 = hash;
  return D.17124;
}


mono_g_hash_mark (void * addr, void (*MonoGCMarkFunc) (void * *) mark_func)
{
  <unnamed type> D.17126;
  struct Slot * * D.17129;
  unsigned int i.2;
  unsigned int D.17131;
  struct Slot * * D.17132;
  void * D.17133;
  void * * D.17136;
  int D.17137;
  void * D.17141;
  void * * D.17144;
  struct MonoGHashTable * table;
  struct Slot * node;
  int i;

  table = addr;
  D.17126 = table->gc_type;
  if (D.17126 == 1) goto <D.17127>; else goto <D.17128>;
  <D.17127>:
  i = 0;
  goto <D.17101>;
  <D.17100>:
  D.17129 = table->table;
  i.2 = (unsigned int) i;
  D.17131 = i.2 * 4;
  D.17132 = D.17129 + D.17131;
  node = *D.17132;
  goto <D.17098>;
  <D.17097>:
  D.17133 = node->key;
  if (D.17133 != 0B) goto <D.17134>; else goto <D.17135>;
  <D.17134>:
  D.17136 = &node->key;
  mark_func (D.17136);
  <D.17135>:
  node = node->next;
  <D.17098>:
  if (node != 0B) goto <D.17097>; else goto <D.17099>;
  <D.17099>:
  i = i + 1;
  <D.17101>:
  D.17137 = table->table_size;
  if (D.17137 > i) goto <D.17100>; else goto <D.17102>;
  <D.17102>:
  goto <D.17138>;
  <D.17128>:
  D.17126 = table->gc_type;
  if (D.17126 == 2) goto <D.17139>; else goto <D.17140>;
  <D.17139>:
  i = 0;
  goto <D.17107>;
  <D.17106>:
  D.17129 = table->table;
  i.2 = (unsigned int) i;
  D.17131 = i.2 * 4;
  D.17132 = D.17129 + D.17131;
  node = *D.17132;
  goto <D.17104>;
  <D.17103>:
  D.17141 = node->value;
  if (D.17141 != 0B) goto <D.17142>; else goto <D.17143>;
  <D.17142>:
  D.17144 = &node->value;
  mark_func (D.17144);
  <D.17143>:
  node = node->next;
  <D.17104>:
  if (node != 0B) goto <D.17103>; else goto <D.17105>;
  <D.17105>:
  i = i + 1;
  <D.17107>:
  D.17137 = table->table_size;
  if (D.17137 > i) goto <D.17106>; else goto <D.17108>;
  <D.17108>:
  goto <D.17145>;
  <D.17140>:
  D.17126 = table->gc_type;
  if (D.17126 == 3) goto <D.17146>; else goto <D.17147>;
  <D.17146>:
  i = 0;
  goto <D.17113>;
  <D.17112>:
  D.17129 = table->table;
  i.2 = (unsigned int) i;
  D.17131 = i.2 * 4;
  D.17132 = D.17129 + D.17131;
  node = *D.17132;
  goto <D.17110>;
  <D.17109>:
  D.17133 = node->key;
  if (D.17133 != 0B) goto <D.17148>; else goto <D.17149>;
  <D.17148>:
  D.17136 = &node->key;
  mark_func (D.17136);
  <D.17149>:
  D.17141 = node->value;
  if (D.17141 != 0B) goto <D.17150>; else goto <D.17151>;
  <D.17150>:
  D.17144 = &node->value;
  mark_func (D.17144);
  <D.17151>:
  node = node->next;
  <D.17110>:
  if (node != 0B) goto <D.17109>; else goto <D.17111>;
  <D.17111>:
  i = i + 1;
  <D.17113>:
  D.17137 = table->table_size;
  if (D.17137 > i) goto <D.17112>; else goto <D.17114>;
  <D.17114>:
  <D.17147>:
  <D.17145>:
  <D.17138>:
}


mono_g_hash_table_new (guint (*GHashFunc) (const void *) hash_func, gboolean (*GEqualFunc) (const void *, const void *) key_equal_func)
{
  unsigned int D.17156;
  int D.17157;
  int D.17158;
  unsigned int D.17159;
  unsigned int D.17160;
  void * D.17161;
  struct MonoGHashTable * D.17162;
  struct MonoGHashTable * hash;

  if (hash_func == 0B) goto <D.17152>; else goto <D.17153>;
  <D.17152>:
  hash_func = monoeg_g_direct_hash;
  <D.17153>:
  if (key_equal_func == 0B) goto <D.17154>; else goto <D.17155>;
  <D.17154>:
  key_equal_func = monoeg_g_direct_equal;
  <D.17155>:
  hash = monoeg_malloc0 (40);
  hash->hash_func = hash_func;
  hash->key_equal_func = key_equal_func;
  D.17156 = monoeg_g_spaced_primes_closest (1);
  D.17157 = (int) D.17156;
  hash->table_size = D.17157;
  D.17158 = hash->table_size;
  D.17159 = (unsigned int) D.17158;
  D.17160 = D.17159 * 4;
  D.17161 = monoeg_malloc0 (D.17160);
  hash->table = D.17161;
  D.17158 = hash->table_size;
  hash->last_rehash = D.17158;
  D.17162 = hash;
  return D.17162;
}


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.17166;
  struct MonoGHashTable * hash;

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


mono_g_hash_table_size (struct MonoGHashTable * hash)
{
  guint D.17170;
  int D.17171;

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


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

  try
    {
      D.17173 = mono_g_hash_table_lookup_extended (hash, key, &orig_key, &value);
      if (D.17173 != 0) goto <D.17174>; else goto <D.17175>;
      <D.17174>:
      D.17176 = value;
      return D.17176;
      <D.17175>:
      D.17176 = 0B;
      return D.17176;
    }
  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.17181;
  guint (*<Tdb9>) (const void *) D.17182;
  unsigned int D.17183;
  int D.17184;
  unsigned int D.17185;
  struct Slot * * D.17186;
  unsigned int D.17187;
  struct Slot * * D.17188;
  void * D.17189;
  int D.17190;
  void * D.17193;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  guint hashcode;

  if (hash == 0B) goto <D.17179>; else goto <D.17180>;
  <D.17179>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 273, "hash != NULL");
  D.17181 = 0;
  return D.17181;
  <D.17180>:
  equal = hash->key_equal_func;
  D.17182 = hash->hash_func;
  D.17183 = D.17182 (key);
  D.17184 = hash->table_size;
  D.17185 = (unsigned int) D.17184;
  hashcode = D.17183 % D.17185;
  D.17186 = hash->table;
  D.17187 = hashcode * 4;
  D.17188 = D.17186 + D.17187;
  s = *D.17188;
  goto <D.16988>;
  <D.16987>:
  D.17189 = s->key;
  D.17190 = equal (D.17189, key);
  if (D.17190 != 0) goto <D.17191>; else goto <D.17192>;
  <D.17191>:
  D.17189 = s->key;
  *orig_key = D.17189;
  D.17193 = s->value;
  *value = D.17193;
  D.17181 = 1;
  return D.17181;
  <D.17192>:
  s = s->next;
  <D.16988>:
  if (s != 0B) goto <D.16987>; else goto <D.16989>;
  <D.16989>:
  D.17181 = 0;
  return D.17181;
}


mono_g_hash_table_foreach (struct MonoGHashTable * hash, void (*GHFunc) (void *, void *, void *) func, void * user_data)
{
  struct Slot * * D.17199;
  unsigned int i.3;
  unsigned int D.17201;
  struct Slot * * D.17202;
  void * D.17203;
  void * D.17204;
  int D.17205;
  int i;

  if (hash == 0B) goto <D.17195>; else goto <D.17196>;
  <D.17195>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 293, "hash != NULL");
  return;
  <D.17196>:
  if (func == 0B) goto <D.17197>; else goto <D.17198>;
  <D.17197>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 294, "func != NULL");
  return;
  <D.17198>:
  i = 0;
  goto <D.17001>;
  <D.17000>:
  {
    struct Slot * s;

    D.17199 = hash->table;
    i.3 = (unsigned int) i;
    D.17201 = i.3 * 4;
    D.17202 = D.17199 + D.17201;
    s = *D.17202;
    goto <D.16998>;
    <D.16997>:
    D.17203 = s->key;
    D.17204 = s->value;
    func (D.17203, D.17204, user_data);
    s = s->next;
    <D.16998>:
    if (s != 0B) goto <D.16997>; else goto <D.16999>;
    <D.16999>:
  }
  i = i + 1;
  <D.17001>:
  D.17205 = hash->table_size;
  if (D.17205 > i) goto <D.17000>; else goto <D.17002>;
  <D.17002>:
}


mono_g_hash_table_find (struct MonoGHashTable * hash, gboolean (*GHRFunc) (void *, void *, void *) predicate, void * user_data)
{
  void * D.17209;
  struct Slot * * D.17212;
  unsigned int i.4;
  unsigned int D.17214;
  struct Slot * * D.17215;
  void * D.17216;
  void * D.17217;
  int D.17218;
  int D.17221;
  int i;

  if (hash == 0B) goto <D.17207>; else goto <D.17208>;
  <D.17207>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 309, "hash != NULL");
  D.17209 = 0B;
  return D.17209;
  <D.17208>:
  if (predicate == 0B) goto <D.17210>; else goto <D.17211>;
  <D.17210>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 310, "predicate != NULL");
  D.17209 = 0B;
  return D.17209;
  <D.17211>:
  i = 0;
  goto <D.17014>;
  <D.17013>:
  {
    struct Slot * s;

    D.17212 = hash->table;
    i.4 = (unsigned int) i;
    D.17214 = i.4 * 4;
    D.17215 = D.17212 + D.17214;
    s = *D.17215;
    goto <D.17011>;
    <D.17010>:
    D.17216 = s->key;
    D.17217 = s->value;
    D.17218 = predicate (D.17216, D.17217, user_data);
    if (D.17218 != 0) goto <D.17219>; else goto <D.17220>;
    <D.17219>:
    D.17209 = s->value;
    return D.17209;
    <D.17220>:
    s = s->next;
    <D.17011>:
    if (s != 0B) goto <D.17010>; else goto <D.17012>;
    <D.17012>:
  }
  i = i + 1;
  <D.17014>:
  D.17221 = hash->table_size;
  if (D.17221 > i) goto <D.17013>; else goto <D.17015>;
  <D.17015>:
  D.17209 = 0B;
  return D.17209;
}


mono_g_hash_table_remove (struct MonoGHashTable * hash, const void * key)
{
  gboolean D.17225;
  guint (*<Tdb9>) (const void *) D.17226;
  unsigned int D.17227;
  int D.17228;
  unsigned int D.17229;
  struct Slot * * D.17230;
  unsigned int D.17231;
  struct Slot * * D.17232;
  void * D.17233;
  int D.17234;
  void (*<Td0d>) (void *) D.17237;
  void (*<Td0d>) (void *) D.17240;
  void * D.17243;
  struct Slot * D.17246;
  int D.17248;
  int D.17249;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  struct Slot * last;
  guint hashcode;

  if (hash == 0B) goto <D.17223>; else goto <D.17224>;
  <D.17223>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 329, "hash != NULL");
  D.17225 = 0;
  return D.17225;
  <D.17224>:
  equal = hash->key_equal_func;
  D.17226 = hash->hash_func;
  D.17227 = D.17226 (key);
  D.17228 = hash->table_size;
  D.17229 = (unsigned int) D.17228;
  hashcode = D.17227 % D.17229;
  last = 0B;
  D.17230 = hash->table;
  D.17231 = hashcode * 4;
  D.17232 = D.17230 + D.17231;
  s = *D.17232;
  goto <D.17025>;
  <D.17024>:
  D.17233 = s->key;
  D.17234 = equal (D.17233, key);
  if (D.17234 != 0) goto <D.17235>; else goto <D.17236>;
  <D.17235>:
  D.17237 = hash->key_destroy_func;
  if (D.17237 != 0B) goto <D.17238>; else goto <D.17239>;
  <D.17238>:
  D.17237 = hash->key_destroy_func;
  D.17233 = s->key;
  D.17237 (D.17233);
  <D.17239>:
  D.17240 = hash->value_destroy_func;
  if (D.17240 != 0B) goto <D.17241>; else goto <D.17242>;
  <D.17241>:
  D.17240 = hash->value_destroy_func;
  D.17243 = s->value;
  D.17240 (D.17243);
  <D.17242>:
  if (last == 0B) goto <D.17244>; else goto <D.17245>;
  <D.17244>:
  D.17230 = hash->table;
  D.17231 = hashcode * 4;
  D.17232 = D.17230 + D.17231;
  D.17246 = s->next;
  *D.17232 = D.17246;
  goto <D.17247>;
  <D.17245>:
  D.17246 = s->next;
  last->next = D.17246;
  <D.17247>:
  free_slot (hash, s);
  D.17248 = hash->in_use;
  D.17249 = D.17248 + -1;
  hash->in_use = D.17249;
  D.17225 = 1;
  return D.17225;
  <D.17236>:
  last = s;
  s = s->next;
  <D.17025>:
  if (s != 0B) goto <D.17024>; else goto <D.17026>;
  <D.17026>:
  D.17225 = 0;
  return D.17225;
}


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

  D.17251 = hash->gc_type;
  if (D.17251 == 0) goto <D.17252>; else goto <D.17253>;
  <D.17252>:
  mono_gc_free_fixed (slot);
  goto <D.17254>;
  <D.17253>:
  monoeg_g_free (slot);
  <D.17254>:
}


mono_g_hash_table_foreach_remove (struct MonoGHashTable * hash, gboolean (*GHRFunc) (void *, void *, void *) func, void * user_data)
{
  guint D.17257;
  struct Slot * * D.17260;
  unsigned int i.5;
  unsigned int D.17262;
  struct Slot * * D.17263;
  void * D.17264;
  void * D.17265;
  int D.17266;
  void (*<Td0d>) (void *) D.17269;
  void (*<Td0d>) (void *) D.17272;
  struct Slot * D.17277;
  int D.17279;
  int D.17280;
  int D.17282;
  int i;
  int count;

  count = 0;
  if (hash == 0B) goto <D.17255>; else goto <D.17256>;
  <D.17255>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 359, "hash != NULL");
  D.17257 = 0;
  return D.17257;
  <D.17256>:
  if (func == 0B) goto <D.17258>; else goto <D.17259>;
  <D.17258>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 360, "func != NULL");
  D.17257 = 0;
  return D.17257;
  <D.17259>:
  i = 0;
  goto <D.17041>;
  <D.17040>:
  {
    struct Slot * s;
    struct Slot * last;

    last = 0B;
    D.17260 = hash->table;
    i.5 = (unsigned int) i;
    D.17262 = i.5 * 4;
    D.17263 = D.17260 + D.17262;
    s = *D.17263;
    goto <D.17038>;
    <D.17037>:
    D.17264 = s->key;
    D.17265 = s->value;
    D.17266 = func (D.17264, D.17265, user_data);
    if (D.17266 != 0) goto <D.17267>; else goto <D.17268>;
    <D.17267>:
    {
      struct Slot * n;

      D.17269 = hash->key_destroy_func;
      if (D.17269 != 0B) goto <D.17270>; else goto <D.17271>;
      <D.17270>:
      D.17269 = hash->key_destroy_func;
      D.17264 = s->key;
      D.17269 (D.17264);
      <D.17271>:
      D.17272 = hash->value_destroy_func;
      if (D.17272 != 0B) goto <D.17273>; else goto <D.17274>;
      <D.17273>:
      D.17272 = hash->value_destroy_func;
      D.17265 = s->value;
      D.17272 (D.17265);
      <D.17274>:
      if (last == 0B) goto <D.17275>; else goto <D.17276>;
      <D.17275>:
      D.17260 = hash->table;
      i.5 = (unsigned int) i;
      D.17262 = i.5 * 4;
      D.17263 = D.17260 + D.17262;
      D.17277 = s->next;
      *D.17263 = D.17277;
      n = s->next;
      goto <D.17278>;
      <D.17276>:
      D.17277 = s->next;
      last->next = D.17277;
      n = last->next;
      <D.17278>:
      free_slot (hash, s);
      D.17279 = hash->in_use;
      D.17280 = D.17279 + -1;
      hash->in_use = D.17280;
      count = count + 1;
      s = n;
    }
    goto <D.17281>;
    <D.17268>:
    last = s;
    s = s->next;
    <D.17281>:
    <D.17038>:
    if (s != 0B) goto <D.17037>; else goto <D.17039>;
    <D.17039>:
  }
  i = i + 1;
  <D.17041>:
  D.17282 = hash->table_size;
  if (D.17282 > i) goto <D.17040>; else goto <D.17042>;
  <D.17042>:
  if (count > 0) goto <D.17283>; else goto <D.17284>;
  <D.17283>:
  rehash (hash);
  <D.17284>:
  D.17257 = (guint) count;
  return D.17257;
}


rehash (struct MonoGHashTable * hash)
{
  int D.17286;
  int D.17287;
  int D.17288;
  double D.17289;
  double D.17290;
  int D.17291;
  int D.17292;
  double D.17293;
  _Bool D.17294;
  _Bool D.17295;
  unsigned int D.17298;
  unsigned int D.17299;
  int D.17300;
  int D.17301;
  unsigned int D.17302;
  unsigned int D.17303;
  void * D.17304;
  int diff;
  struct RehashData data;
  void * old_table;

  try
    {
      D.17286 = hash->last_rehash;
      D.17287 = hash->in_use;
      D.17288 = D.17286 - D.17287;
      diff = ABS_EXPR <D.17288>;
      D.17289 = (double) diff;
      D.17290 = D.17289 * 7.5e-1;
      D.17291 = hash->table_size;
      D.17292 = D.17291 * 2;
      D.17293 = (double) D.17292;
      D.17294 = D.17290 > D.17293;
      D.17295 = ~D.17294;
      if (D.17295 != 0) goto <D.17296>; else goto <D.17297>;
      <D.17296>:
      return;
      <D.17297>:
      data.hash = hash;
      D.17287 = hash->in_use;
      D.17298 = (unsigned int) D.17287;
      D.17299 = monoeg_g_spaced_primes_closest (D.17298);
      D.17300 = (int) D.17299;
      data.new_size = D.17300;
      D.17301 = data.new_size;
      D.17302 = (unsigned int) D.17301;
      D.17303 = D.17302 * 4;
      D.17304 = monoeg_malloc0 (D.17303);
      data.table = D.17304;
      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.17308;
  int D.17309;
  struct Slot * * D.17310;
  unsigned int i.6;
  unsigned int D.17312;
  struct Slot * * D.17313;
  guint (*<Tdb9>) (const void *) D.17314;
  void * D.17315;
  unsigned int D.17316;
  unsigned int D.17317;
  struct Slot * * D.17318;
  unsigned int D.17319;
  struct Slot * * D.17320;
  struct Slot * D.17321;
  void * D.17322;
  struct RehashData * data;
  struct MonoGHashTable * hash;
  int current_size;
  int i;
  struct Slot * * table;

  data = _data;
  hash = data->hash;
  D.17308 = hash->table_size;
  hash->last_rehash = D.17308;
  current_size = hash->table_size;
  D.17309 = data->new_size;
  hash->table_size = D.17309;
  table = hash->table;
  D.17310 = data->table;
  hash->table = D.17310;
  i = 0;
  goto <D.16961>;
  <D.16960>:
  {
    struct Slot * s;
    struct Slot * next;

    i.6 = (unsigned int) i;
    D.17312 = i.6 * 4;
    D.17313 = table + D.17312;
    s = *D.17313;
    goto <D.16958>;
    <D.16957>:
    {
      guint hashcode;

      D.17314 = hash->hash_func;
      D.17315 = s->key;
      D.17316 = D.17314 (D.17315);
      D.17308 = hash->table_size;
      D.17317 = (unsigned int) D.17308;
      hashcode = D.17316 % D.17317;
      next = s->next;
      D.17318 = hash->table;
      D.17319 = hashcode * 4;
      D.17320 = D.17318 + D.17319;
      D.17321 = *D.17320;
      s->next = D.17321;
      D.17318 = hash->table;
      D.17319 = hashcode * 4;
      D.17320 = D.17318 + D.17319;
      *D.17320 = s;
    }
    s = next;
    <D.16958>:
    if (s != 0B) goto <D.16957>; else goto <D.16959>;
    <D.16959>:
  }
  i = i + 1;
  <D.16961>:
  if (i < current_size) goto <D.16960>; else goto <D.16962>;
  <D.16962>:
  D.17322 = table;
  return D.17322;
}


mono_g_hash_table_destroy (struct MonoGHashTable * hash)
{
  struct Slot * * D.17326;
  unsigned int i.7;
  unsigned int D.17328;
  struct Slot * * D.17329;
  void (*<Td0d>) (void *) D.17330;
  void * D.17333;
  void (*<Td0d>) (void *) D.17334;
  void * D.17337;
  int D.17338;
  int i;

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

    D.17326 = hash->table;
    i.7 = (unsigned int) i;
    D.17328 = i.7 * 4;
    D.17329 = D.17326 + D.17328;
    s = *D.17329;
    goto <D.17050>;
    <D.17049>:
    next = s->next;
    D.17330 = hash->key_destroy_func;
    if (D.17330 != 0B) goto <D.17331>; else goto <D.17332>;
    <D.17331>:
    D.17330 = hash->key_destroy_func;
    D.17333 = s->key;
    D.17330 (D.17333);
    <D.17332>:
    D.17334 = hash->value_destroy_func;
    if (D.17334 != 0B) goto <D.17335>; else goto <D.17336>;
    <D.17335>:
    D.17334 = hash->value_destroy_func;
    D.17337 = s->value;
    D.17334 (D.17337);
    <D.17336>:
    free_slot (hash, s);
    s = next;
    <D.17050>:
    if (s != 0B) goto <D.17049>; else goto <D.17051>;
    <D.17051>:
  }
  i = i + 1;
  <D.17053>:
  D.17338 = hash->table_size;
  if (D.17338 > i) goto <D.17052>; else goto <D.17054>;
  <D.17054>:
  D.17326 = hash->table;
  monoeg_g_free (D.17326);
  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.17342;
  int D.17343;
  guint (*<Tdb9>) (const void *) D.17346;
  unsigned int D.17347;
  int D.17348;
  unsigned int D.17349;
  struct Slot * * D.17350;
  unsigned int D.17351;
  struct Slot * * D.17352;
  void * D.17353;
  int D.17354;
  void (*<Td0d>) (void *) D.17359;
  void (*<Td0d>) (void *) D.17362;
  void * D.17365;
  struct Slot * D.17366;
  int D.17367;
  guint hashcode;
  struct Slot * s;
  gboolean (*GEqualFunc) (const void *, const void *) equal;

  if (hash == 0B) goto <D.17340>; else goto <D.17341>;
  <D.17340>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-hash.c", 431, "hash != NULL");
  return;
  <D.17341>:
  equal = hash->key_equal_func;
  D.17342 = hash->in_use;
  D.17343 = hash->threshold;
  if (D.17342 >= D.17343) goto <D.17344>; else goto <D.17345>;
  <D.17344>:
  rehash (hash);
  <D.17345>:
  D.17346 = hash->hash_func;
  D.17347 = D.17346 (key);
  D.17348 = hash->table_size;
  D.17349 = (unsigned int) D.17348;
  hashcode = D.17347 % D.17349;
  D.17350 = hash->table;
  D.17351 = hashcode * 4;
  D.17352 = D.17350 + D.17351;
  s = *D.17352;
  goto <D.17065>;
  <D.17064>:
  D.17353 = s->key;
  D.17354 = equal (D.17353, key);
  if (D.17354 != 0) goto <D.17355>; else goto <D.17356>;
  <D.17355>:
  if (replace != 0) goto <D.17357>; else goto <D.17358>;
  <D.17357>:
  D.17359 = hash->key_destroy_func;
  if (D.17359 != 0B) goto <D.17360>; else goto <D.17361>;
  <D.17360>:
  D.17359 = hash->key_destroy_func;
  D.17353 = s->key;
  D.17359 (D.17353);
  <D.17361>:
  s->key = key;
  <D.17358>:
  D.17362 = hash->value_destroy_func;
  if (D.17362 != 0B) goto <D.17363>; else goto <D.17364>;
  <D.17363>:
  D.17362 = hash->value_destroy_func;
  D.17365 = s->value;
  D.17362 (D.17365);
  <D.17364>:
  s->value = value;
  return;
  <D.17356>:
  s = s->next;
  <D.17065>:
  if (s != 0B) goto <D.17064>; else goto <D.17066>;
  <D.17066>:
  s = new_slot (hash);
  s->key = key;
  s->value = value;
  D.17350 = hash->table;
  D.17351 = hashcode * 4;
  D.17352 = D.17350 + D.17351;
  D.17366 = *D.17352;
  s->next = D.17366;
  D.17350 = hash->table;
  D.17351 = hashcode * 4;
  D.17352 = D.17350 + D.17351;
  *D.17352 = s;
  D.17342 = hash->in_use;
  D.17367 = D.17342 + 1;
  hash->in_use = D.17367;
}


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

  D.17369 = hash->gc_type;
  if (D.17369 == 0) goto <D.17370>; else goto <D.17371>;
  <D.17370>:
  D.17372 = mono_gc_alloc_fixed (12, 0B);
  return D.17372;
  <D.17371>:
  D.17372 = monoeg_malloc (12);
  return D.17372;
}


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.17374;
  unsigned int i.8;
  unsigned int D.17376;
  struct Slot * * D.17377;
  int D.17378;
  int D.17379;
  int i;
  int chain_size;
  int max_chain_size;
  struct Slot * node;

  max_chain_size = 0;
  i = 0;
  goto <D.17088>;
  <D.17087>:
  chain_size = 0;
  D.17374 = table->table;
  i.8 = (unsigned int) i;
  D.17376 = i.8 * 4;
  D.17377 = D.17374 + D.17376;
  node = *D.17377;
  goto <D.17085>;
  <D.17084>:
  chain_size = chain_size + 1;
  node = node->next;
  <D.17085>:
  if (node != 0B) goto <D.17084>; else goto <D.17086>;
  <D.17086>:
  max_chain_size = MAX_EXPR <chain_size, max_chain_size>;
  i = i + 1;
  <D.17088>:
  D.17378 = table->table_size;
  if (D.17378 > i) goto <D.17087>; else goto <D.17089>;
  <D.17089>:
  D.17379 = table->in_use;
  D.17378 = table->table_size;
  printf ("Size: %d Table Size: %d Max Chain Length: %d\n", D.17379, D.17378, max_chain_size);
}


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

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


