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.17595>;
  <D.17594>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.17595>:
  if (i <= 2) goto <D.17594>; else goto <D.17596>;
  <D.17596>:
  goto <D.17599>;
  <D.17598>:
  {
    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.17599>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.17598>; else goto <D.17600>;
  <D.17600>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.17695;
  struct PinStatAddress * D.17696;

  if (node == 0B) goto <D.17693>; else goto <D.17694>;
  <D.17693>:
  return;
  <D.17694>:
  D.17695 = node->left;
  pin_stats_tree_free (D.17695);
  D.17696 = node->right;
  pin_stats_tree_free (D.17696);
  sgen_free_internal_dynamic (node, 32, 11);
}


sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.17698;
  int D.17701;
  int D.17702;
  struct PinStatAddress * D.17706;
  struct PinStatAddress * D.17707;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.17609>;
  <D.17608>:
  node = *node_ptr;
  D.17698 = node->addr;
  if (D.17698 == addr) goto <D.17699>; else goto <D.17700>;
  <D.17699>:
  D.17701 = node->pin_types;
  D.17702 = D.17701 | pin_type_bit;
  node->pin_types = D.17702;
  return;
  <D.17700>:
  D.17698 = node->addr;
  if (D.17698 > addr) goto <D.17703>; else goto <D.17704>;
  <D.17703>:
  node_ptr = &node->left;
  goto <D.17705>;
  <D.17704>:
  node_ptr = &node->right;
  <D.17705>:
  <D.17609>:
  D.17706 = *node_ptr;
  if (D.17706 != 0B) goto <D.17608>; else goto <D.17610>;
  <D.17610>:
  node = sgen_alloc_internal_dynamic (32, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.17707 = node->right;
  node->left = D.17707;
  *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.17714;
  long unsigned int D.17715;
  struct MonoVTable * D.17716;
  struct MonoClass * D.17717;
  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.17712>; else goto <D.17713>;
      <D.17712>:
      pin_types.4 = pin_types;
      D.17714 = MEM[(mword *)obj];
      D.17715 = D.17714 & 18446744073709551612;
      D.17716 = (struct MonoVTable *) D.17715;
      D.17717 = D.17716->klass;
      register_class (D.17717, pin_types.4);
      <D.17713>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.17720;
  char * D.17723;
  int D.17726;
  int D.17727;
  int D.17730;
  int D.17731;
  long unsigned int D.17734;
  long unsigned int D.17735;
  int D.17736;
  struct PinStatAddress * D.17739;
  sizetype D.17740;
  char * D.17741;
  struct PinStatAddress * D.17744;

  if (node == 0B) goto <D.17718>; else goto <D.17719>;
  <D.17718>:
  return;
  <D.17719>:
  D.17720 = node->addr;
  if (D.17720 >= obj) goto <D.17721>; else goto <D.17722>;
  <D.17721>:
  D.17720 = node->addr;
  D.17723 = obj + size;
  if (D.17720 < D.17723) goto <D.17724>; else goto <D.17725>;
  <D.17724>:
  {
    int i;

    i = 0;
    goto <D.17620>;
    <D.17619>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.17726 = *pin_types;
      D.17727 = D.17726 & pin_bit;
      if (D.17727 == 0) goto <D.17728>; else goto <D.17729>;
      <D.17728>:
      D.17730 = node->pin_types;
      D.17731 = D.17730 & pin_bit;
      if (D.17731 != 0) goto <D.17732>; else goto <D.17733>;
      <D.17732>:
      D.17734 = pinned_byte_counts[i];
      D.17735 = D.17734 + size;
      pinned_byte_counts[i] = D.17735;
      D.17726 = *pin_types;
      D.17736 = D.17726 | pin_bit;
      *pin_types = D.17736;
      <D.17733>:
      <D.17729>:
    }
    i = i + 1;
    <D.17620>:
    if (i <= 2) goto <D.17619>; else goto <D.17621>;
    <D.17621>:
  }
  <D.17725>:
  <D.17722>:
  D.17720 = node->addr;
  if (D.17720 > obj) goto <D.17737>; else goto <D.17738>;
  <D.17737>:
  D.17739 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.17739, pin_types);
  <D.17738>:
  D.17740 = size + 18446744073709551615;
  D.17741 = obj + D.17740;
  D.17720 = node->addr;
  if (D.17741 > D.17720) goto <D.17742>; else goto <D.17743>;
  <D.17742>:
  D.17744 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.17744, pin_types);
  <D.17743>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.17746;
  int D.17747;
  long unsigned int D.17750;
  long unsigned int D.17751;
  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.17637>;
      <D.17636>:
      D.17746 = pin_types >> i;
      D.17747 = D.17746 & 1;
      if (D.17747 != 0) goto <D.17748>; else goto <D.17749>;
      <D.17748>:
      D.17750 = entry->num_pins[i];
      D.17751 = D.17750 + 1;
      entry->num_pins[i] = D.17751;
      <D.17749>:
      i = i + 1;
      <D.17637>:
      if (i <= 2) goto <D.17636>; else goto <D.17638>;
      <D.17638>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.17754;
  int D.17759;
  void * D.17761;
  long unsigned int D.17762;

  D.17754 = __builtin_constant_p (__len);
  if (D.17754 != 0) goto <D.17755>; else goto <D.17756>;
  <D.17755>:
  if (__len == 0) goto <D.17757>; else goto <D.17758>;
  <D.17757>:
  D.17759 = __builtin_constant_p (__ch);
  if (D.17759 == 0) goto <D.17752>; else goto <D.17760>;
  <D.17760>:
  if (__ch != 0) goto <D.17752>; else goto <D.17753>;
  <D.17752>:
  __warn_memset_zero_len ();
  D.17761 = __dest;
  return D.17761;
  <D.17753>:
  <D.17758>:
  <D.17756>:
  D.17762 = __builtin_object_size (__dest, 0);
  D.17761 = __builtin___memset_chk (__dest, __ch, __len, D.17762);
  return D.17761;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.17764;
  const char * D.17765;
  void * D.17769;
  char * name;
  void * entry;

  D.17764 = class->name;
  D.17765 = class->name_space;
  name = monoeg_g_strdup_printf ("%s.%s", D.17765, D.17764);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.17766>; else goto <D.17767>;
  <D.17766>:
  monoeg_g_free (name);
  goto <D.17768>;
  <D.17767>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.17768>:
  D.17769 = entry;
  return D.17769;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  long unsigned int D.17771;
  long unsigned int D.17772;
  struct MonoVTable * D.17773;
  struct MonoClass * D.17774;
  long unsigned int D.17775;
  long unsigned int D.17776;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 8);
      D.17771 = MEM[(mword *)obj];
      D.17772 = D.17771 & 18446744073709551612;
      D.17773 = (struct MonoVTable *) D.17772;
      D.17774 = D.17773->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.17774, &empty_entry);
      D.17775 = entry->num_remsets;
      D.17776 = D.17775 + 1;
      entry->num_remsets = D.17776;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  long unsigned int D.17777;
  long unsigned int D.17778;
  long unsigned int D.17779;
  struct SgenHashTableEntry * D.17780;
  unsigned int D.17781;
  long unsigned int D.17782;
  long unsigned int D.17783;
  long unsigned int D.17784;
  struct SgenHashTableEntry * D.17785;
  unsigned int D.17786;
  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.17670>;
    <D.17669>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17777 = (long unsigned int) __i;
      D.17778 = D.17777 * 8;
      __iter = __table + D.17778;
      goto <D.17667>;
      <D.17666>:
      {
        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.17664>;
          <D.17663>:
          D.17779 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.17779);
          i = i + 1;
          <D.17664>:
          if (i <= 2) goto <D.17663>; else goto <D.17665>;
          <D.17665>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.17667>:
      D.17780 = *__iter;
      if (D.17780 != 0B) goto <D.17666>; else goto <D.17668>;
      <D.17668>:
    }
    __i = __i + 1;
    <D.17670>:
    D.17781 = pinned_class_hash_table.size;
    if (D.17781 > __i) goto <D.17669>; else goto <D.17671>;
    <D.17671>:
  }
  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.17682>;
    <D.17681>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17782 = (long unsigned int) __i;
      D.17783 = D.17782 * 8;
      __iter = __table + D.17783;
      goto <D.17679>;
      <D.17678>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.17784 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.17784);
      }
      __iter = __next;
      <D.17679>:
      D.17785 = *__iter;
      if (D.17785 != 0B) goto <D.17678>; else goto <D.17680>;
      <D.17680>:
    }
    __i = __i + 1;
    <D.17682>:
    D.17786 = global_remset_class_hash_table.size;
    if (D.17786 > __i) goto <D.17681>; else goto <D.17683>;
    <D.17683>:
  }
}


sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.17787;

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


sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.17789;

  D.17789 = pinned_objects;
  return D.17789;
}


