sgen_pin_stats_reset ()
{
  struct PinStatAddress * pin_stat_addresses.0;
  struct ObjectList * pinned_objects.1;
  int i;

  pin_stat_addresses.0 = pin_stat_addresses;
  pin_stats_tree_free (pin_stat_addresses.0);
  pin_stat_addresses = 0B;
  i = 0;
  goto <D.18125>;
  <D.18124>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.18125>:
  if (i <= 2) goto <D.18124>; else goto <D.18126>;
  <D.18126>:
  goto <D.18129>;
  <D.18128>:
  {
    struct ObjectList * next;

    pinned_objects.1 = pinned_objects;
    next = pinned_objects.1->next;
    pinned_objects.1 = pinned_objects;
    sgen_free_internal_dynamic (pinned_objects.1, 16, 11);
    pinned_objects = next;
  }
  <D.18129>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.18128>; else goto <D.18130>;
  <D.18130>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.18225;
  struct PinStatAddress * D.18226;

  if (node == 0B) goto <D.18223>; else goto <D.18224>;
  <D.18223>:
  return;
  <D.18224>:
  D.18225 = node->left;
  pin_stats_tree_free (D.18225);
  D.18226 = node->right;
  pin_stats_tree_free (D.18226);
  sgen_free_internal_dynamic (node, 32, 11);
}


sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.18228;
  int D.18231;
  int D.18232;
  struct PinStatAddress * D.18236;
  struct PinStatAddress * D.18237;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.18139>;
  <D.18138>:
  node = *node_ptr;
  D.18228 = node->addr;
  if (D.18228 == addr) goto <D.18229>; else goto <D.18230>;
  <D.18229>:
  D.18231 = node->pin_types;
  D.18232 = D.18231 | pin_type_bit;
  node->pin_types = D.18232;
  return;
  <D.18230>:
  D.18228 = node->addr;
  if (D.18228 > addr) goto <D.18233>; else goto <D.18234>;
  <D.18233>:
  node_ptr = &node->left;
  goto <D.18235>;
  <D.18234>:
  node_ptr = &node->right;
  <D.18235>:
  <D.18139>:
  D.18236 = *node_ptr;
  if (D.18236 != 0B) goto <D.18138>; else goto <D.18140>;
  <D.18140>:
  node = sgen_alloc_internal_dynamic (32, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.18237 = node->right;
  node->left = D.18237;
  *node_ptr = node;
}


sgen_pin_stats_register_object (char * obj, size_t size)
{
  struct PinStatAddress * pin_stat_addresses.2;
  struct ObjectList * pinned_objects.3;
  int pin_types.4;
  long unsigned int D.18244;
  long unsigned int D.18245;
  struct MonoVTable * D.18246;
  struct MonoClass * D.18247;
  int pin_types;
  struct ObjectList * list;

  try
    {
      pin_types = 0;
      list = sgen_alloc_internal_dynamic (16, 11, 1);
      pin_stat_addresses.2 = pin_stat_addresses;
      pin_stats_count_object_from_tree (obj, size, pin_stat_addresses.2, &pin_types);
      list->obj = obj;
      pinned_objects.3 = pinned_objects;
      list->next = pinned_objects.3;
      pinned_objects = list;
      pin_types.4 = pin_types;
      if (pin_types.4 != 0) goto <D.18242>; else goto <D.18243>;
      <D.18242>:
      D.18244 = MEM[(mword *)obj];
      D.18245 = D.18244 & 18446744073709551612;
      D.18246 = (struct MonoVTable *) D.18245;
      D.18247 = D.18246->klass;
      pin_types.4 = pin_types;
      register_class (D.18247, pin_types.4);
      <D.18243>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.18250;
  char * D.18253;
  int D.18256;
  int D.18257;
  int D.18260;
  int D.18261;
  long unsigned int D.18264;
  long unsigned int D.18265;
  int D.18266;
  struct PinStatAddress * D.18269;
  sizetype D.18270;
  char * D.18271;
  struct PinStatAddress * D.18274;

  if (node == 0B) goto <D.18248>; else goto <D.18249>;
  <D.18248>:
  return;
  <D.18249>:
  D.18250 = node->addr;
  if (D.18250 >= obj) goto <D.18251>; else goto <D.18252>;
  <D.18251>:
  D.18250 = node->addr;
  D.18253 = obj + size;
  if (D.18250 < D.18253) goto <D.18254>; else goto <D.18255>;
  <D.18254>:
  {
    int i;

    i = 0;
    goto <D.18150>;
    <D.18149>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.18256 = *pin_types;
      D.18257 = D.18256 & pin_bit;
      if (D.18257 == 0) goto <D.18258>; else goto <D.18259>;
      <D.18258>:
      D.18260 = node->pin_types;
      D.18261 = D.18260 & pin_bit;
      if (D.18261 != 0) goto <D.18262>; else goto <D.18263>;
      <D.18262>:
      D.18264 = pinned_byte_counts[i];
      D.18265 = D.18264 + size;
      pinned_byte_counts[i] = D.18265;
      D.18256 = *pin_types;
      D.18266 = D.18256 | pin_bit;
      *pin_types = D.18266;
      <D.18263>:
      <D.18259>:
    }
    i = i + 1;
    <D.18150>:
    if (i <= 2) goto <D.18149>; else goto <D.18151>;
    <D.18151>:
  }
  <D.18255>:
  <D.18252>:
  D.18250 = node->addr;
  if (D.18250 > obj) goto <D.18267>; else goto <D.18268>;
  <D.18267>:
  D.18269 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.18269, pin_types);
  <D.18268>:
  D.18270 = size + 18446744073709551615;
  D.18271 = obj + D.18270;
  D.18250 = node->addr;
  if (D.18271 > D.18250) goto <D.18272>; else goto <D.18273>;
  <D.18272>:
  D.18274 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.18274, pin_types);
  <D.18273>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.18276;
  int D.18277;
  long unsigned int D.18280;
  long unsigned int D.18281;
  struct PinnedClassEntry empty_entry;
  struct PinnedClassEntry * entry;
  int i;

  try
    {
      memset (&empty_entry, 0, 24);
      entry = lookup_class_entry (&pinned_class_hash_table, class, &empty_entry);
      i = 0;
      goto <D.18167>;
      <D.18166>:
      D.18276 = pin_types >> i;
      D.18277 = D.18276 & 1;
      if (D.18277 != 0) goto <D.18278>; else goto <D.18279>;
      <D.18278>:
      D.18280 = entry->num_pins[i];
      D.18281 = D.18280 + 1;
      entry->num_pins[i] = D.18281;
      <D.18279>:
      i = i + 1;
      <D.18167>:
      if (i <= 2) goto <D.18166>; else goto <D.18168>;
      <D.18168>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.18284;
  int D.18289;
  void * D.18291;
  long unsigned int D.18292;

  D.18284 = __builtin_constant_p (__len);
  if (D.18284 != 0) goto <D.18285>; else goto <D.18286>;
  <D.18285>:
  if (__len == 0) goto <D.18287>; else goto <D.18288>;
  <D.18287>:
  D.18289 = __builtin_constant_p (__ch);
  if (D.18289 == 0) goto <D.18282>; else goto <D.18290>;
  <D.18290>:
  if (__ch != 0) goto <D.18282>; else goto <D.18283>;
  <D.18282>:
  __warn_memset_zero_len ();
  D.18291 = __dest;
  return D.18291;
  <D.18283>:
  <D.18288>:
  <D.18286>:
  D.18292 = __builtin_object_size (__dest, 0);
  D.18291 = __builtin___memset_chk (__dest, __ch, __len, D.18292);
  return D.18291;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.18294;
  const char * D.18295;
  void * D.18299;
  char * name;
  void * entry;

  D.18294 = class->name_space;
  D.18295 = class->name;
  name = monoeg_g_strdup_printf ("%s.%s", D.18294, D.18295);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.18296>; else goto <D.18297>;
  <D.18296>:
  monoeg_g_free (name);
  goto <D.18298>;
  <D.18297>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.18298>:
  D.18299 = entry;
  return D.18299;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  long unsigned int D.18301;
  long unsigned int D.18302;
  struct MonoVTable * D.18303;
  struct MonoClass * D.18304;
  long unsigned int D.18305;
  long unsigned int D.18306;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 8);
      D.18301 = MEM[(mword *)obj];
      D.18302 = D.18301 & 18446744073709551612;
      D.18303 = (struct MonoVTable *) D.18302;
      D.18304 = D.18303->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.18304, &empty_entry);
      D.18305 = entry->num_remsets;
      D.18306 = D.18305 + 1;
      entry->num_remsets = D.18306;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  long unsigned int D.18307;
  long unsigned int D.18308;
  long unsigned int D.18309;
  struct SgenHashTableEntry * D.18310;
  unsigned int D.18311;
  long unsigned int D.18312;
  long unsigned int D.18313;
  long unsigned int D.18314;
  struct SgenHashTableEntry * D.18315;
  unsigned int D.18316;
  char * name;
  struct PinnedClassEntry * pinned_entry;
  struct GlobalRemsetClassEntry * remset_entry;

  monoeg_g_print ("\n%-50s  %10s  %10s  %10s\n", "Class", "Stack", "Static", "Other");
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = &pinned_class_hash_table;
    __table = __hash_table->table;
    __i = 0;
    goto <D.18200>;
    <D.18199>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.18307 = (long unsigned int) __i;
      D.18308 = D.18307 * 8;
      __iter = __table + D.18308;
      goto <D.18197>;
      <D.18196>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        pinned_entry = &__entry->data;
        {
          int i;

          monoeg_g_print ("%-50s", name);
          i = 0;
          goto <D.18194>;
          <D.18193>:
          D.18309 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.18309);
          i = i + 1;
          <D.18194>:
          if (i <= 2) goto <D.18193>; else goto <D.18195>;
          <D.18195>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.18197>:
      D.18310 = *__iter;
      if (D.18310 != 0B) goto <D.18196>; else goto <D.18198>;
      <D.18198>:
    }
    __i = __i + 1;
    <D.18200>:
    D.18311 = pinned_class_hash_table.size;
    if (D.18311 > __i) goto <D.18199>; else goto <D.18201>;
    <D.18201>:
  }
  monoeg_g_print ("\n%-50s  %10s\n", "Class", "#Remsets");
  {
    struct SgenHashTable * __hash_table;
    struct SgenHashTableEntry * * __table;
    guint __i;

    __hash_table = &global_remset_class_hash_table;
    __table = __hash_table->table;
    __i = 0;
    goto <D.18212>;
    <D.18211>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.18312 = (long unsigned int) __i;
      D.18313 = D.18312 * 8;
      __iter = __table + D.18313;
      goto <D.18209>;
      <D.18208>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.18314 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.18314);
      }
      __iter = __next;
      <D.18209>:
      D.18315 = *__iter;
      if (D.18315 != 0B) goto <D.18208>; else goto <D.18210>;
      <D.18210>:
    }
    __i = __i + 1;
    <D.18212>:
    D.18316 = global_remset_class_hash_table.size;
    if (D.18316 > __i) goto <D.18211>; else goto <D.18213>;
    <D.18213>:
  }
}


sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.18317;

  D.18317 = pinned_byte_counts[pin_type];
  return D.18317;
}


sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.18319;

  D.18319 = pinned_objects;
  return D.18319;
}


