__attribute__((visibility ("hidden")))
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.17739>;
  <D.17738>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.17739>:
  if (i <= 2) goto <D.17738>; else goto <D.17740>;
  <D.17740>:
  goto <D.17743>;
  <D.17742>:
  {
    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.17743>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.17742>; else goto <D.17744>;
  <D.17744>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.17839;
  struct PinStatAddress * D.17840;

  if (node == 0B) goto <D.17837>; else goto <D.17838>;
  <D.17837>:
  return;
  <D.17838>:
  D.17839 = node->left;
  pin_stats_tree_free (D.17839);
  D.17840 = node->right;
  pin_stats_tree_free (D.17840);
  sgen_free_internal_dynamic (node, 32, 11);
}


__attribute__((visibility ("hidden")))
sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.17842;
  int D.17845;
  int D.17846;
  struct PinStatAddress * D.17850;
  struct PinStatAddress * D.17851;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.17753>;
  <D.17752>:
  node = *node_ptr;
  D.17842 = node->addr;
  if (D.17842 == addr) goto <D.17843>; else goto <D.17844>;
  <D.17843>:
  D.17845 = node->pin_types;
  D.17846 = D.17845 | pin_type_bit;
  node->pin_types = D.17846;
  return;
  <D.17844>:
  D.17842 = node->addr;
  if (D.17842 > addr) goto <D.17847>; else goto <D.17848>;
  <D.17847>:
  node_ptr = &node->left;
  goto <D.17849>;
  <D.17848>:
  node_ptr = &node->right;
  <D.17849>:
  <D.17753>:
  D.17850 = *node_ptr;
  if (D.17850 != 0B) goto <D.17752>; else goto <D.17754>;
  <D.17754>:
  node = sgen_alloc_internal_dynamic (32, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.17851 = node->right;
  node->left = D.17851;
  *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.17858;
  long unsigned int D.17859;
  struct MonoVTable * D.17860;
  struct MonoClass * D.17861;
  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.17856>; else goto <D.17857>;
      <D.17856>:
      D.17858 = MEM[(mword *)obj];
      D.17859 = D.17858 & 18446744073709551612;
      D.17860 = (struct MonoVTable *) D.17859;
      D.17861 = D.17860->klass;
      pin_types.4 = pin_types;
      register_class (D.17861, pin_types.4);
      <D.17857>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.17864;
  char * D.17867;
  int D.17870;
  int D.17871;
  int D.17874;
  int D.17875;
  long unsigned int D.17878;
  long unsigned int D.17879;
  int D.17880;
  struct PinStatAddress * D.17883;
  sizetype D.17884;
  char * D.17885;
  struct PinStatAddress * D.17888;

  if (node == 0B) goto <D.17862>; else goto <D.17863>;
  <D.17862>:
  return;
  <D.17863>:
  D.17864 = node->addr;
  if (D.17864 >= obj) goto <D.17865>; else goto <D.17866>;
  <D.17865>:
  D.17864 = node->addr;
  D.17867 = obj + size;
  if (D.17864 < D.17867) goto <D.17868>; else goto <D.17869>;
  <D.17868>:
  {
    int i;

    i = 0;
    goto <D.17764>;
    <D.17763>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.17870 = *pin_types;
      D.17871 = D.17870 & pin_bit;
      if (D.17871 == 0) goto <D.17872>; else goto <D.17873>;
      <D.17872>:
      D.17874 = node->pin_types;
      D.17875 = D.17874 & pin_bit;
      if (D.17875 != 0) goto <D.17876>; else goto <D.17877>;
      <D.17876>:
      D.17878 = pinned_byte_counts[i];
      D.17879 = D.17878 + size;
      pinned_byte_counts[i] = D.17879;
      D.17870 = *pin_types;
      D.17880 = D.17870 | pin_bit;
      *pin_types = D.17880;
      <D.17877>:
      <D.17873>:
    }
    i = i + 1;
    <D.17764>:
    if (i <= 2) goto <D.17763>; else goto <D.17765>;
    <D.17765>:
  }
  <D.17869>:
  <D.17866>:
  D.17864 = node->addr;
  if (D.17864 > obj) goto <D.17881>; else goto <D.17882>;
  <D.17881>:
  D.17883 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.17883, pin_types);
  <D.17882>:
  D.17884 = size + 18446744073709551615;
  D.17885 = obj + D.17884;
  D.17864 = node->addr;
  if (D.17885 > D.17864) goto <D.17886>; else goto <D.17887>;
  <D.17886>:
  D.17888 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.17888, pin_types);
  <D.17887>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.17890;
  int D.17891;
  long unsigned int D.17894;
  long unsigned int D.17895;
  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.17781>;
      <D.17780>:
      D.17890 = pin_types >> i;
      D.17891 = D.17890 & 1;
      if (D.17891 != 0) goto <D.17892>; else goto <D.17893>;
      <D.17892>:
      D.17894 = entry->num_pins[i];
      D.17895 = D.17894 + 1;
      entry->num_pins[i] = D.17895;
      <D.17893>:
      i = i + 1;
      <D.17781>:
      if (i <= 2) goto <D.17780>; else goto <D.17782>;
      <D.17782>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


__attribute__((__artificial__, __gnu_inline__, __always_inline__, __nothrow__, __leaf__))
memset (void * __dest, int __ch, size_t __len)
{
  void * D.17896;
  long unsigned int D.17897;

  D.17897 = __builtin_object_size (__dest, 0);
  D.17896 = __builtin___memset_chk (__dest, __ch, __len, D.17897);
  return D.17896;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.17899;
  const char * D.17900;
  void * D.17904;
  char * name;
  void * entry;

  D.17899 = class->name_space;
  D.17900 = class->name;
  name = monoeg_g_strdup_printf ("%s.%s", D.17899, D.17900);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.17901>; else goto <D.17902>;
  <D.17901>:
  monoeg_g_free (name);
  goto <D.17903>;
  <D.17902>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.17903>:
  D.17904 = entry;
  return D.17904;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  long unsigned int D.17906;
  long unsigned int D.17907;
  struct MonoVTable * D.17908;
  struct MonoClass * D.17909;
  long unsigned int D.17910;
  long unsigned int D.17911;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 8);
      D.17906 = MEM[(mword *)obj];
      D.17907 = D.17906 & 18446744073709551612;
      D.17908 = (struct MonoVTable *) D.17907;
      D.17909 = D.17908->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.17909, &empty_entry);
      D.17910 = entry->num_remsets;
      D.17911 = D.17910 + 1;
      entry->num_remsets = D.17911;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  long unsigned int D.17912;
  long unsigned int D.17913;
  long unsigned int D.17914;
  struct SgenHashTableEntry * D.17915;
  unsigned int D.17916;
  long unsigned int D.17917;
  long unsigned int D.17918;
  long unsigned int D.17919;
  struct SgenHashTableEntry * D.17920;
  unsigned int D.17921;
  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.17814>;
    <D.17813>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17912 = (long unsigned int) __i;
      D.17913 = D.17912 * 8;
      __iter = __table + D.17913;
      goto <D.17811>;
      <D.17810>:
      {
        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.17808>;
          <D.17807>:
          D.17914 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.17914);
          i = i + 1;
          <D.17808>:
          if (i <= 2) goto <D.17807>; else goto <D.17809>;
          <D.17809>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.17811>:
      D.17915 = *__iter;
      if (D.17915 != 0B) goto <D.17810>; else goto <D.17812>;
      <D.17812>:
    }
    __i = __i + 1;
    <D.17814>:
    D.17916 = pinned_class_hash_table.size;
    if (D.17916 > __i) goto <D.17813>; else goto <D.17815>;
    <D.17815>:
  }
  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.17826>;
    <D.17825>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17917 = (long unsigned int) __i;
      D.17918 = D.17917 * 8;
      __iter = __table + D.17918;
      goto <D.17823>;
      <D.17822>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.17919 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.17919);
      }
      __iter = __next;
      <D.17823>:
      D.17920 = *__iter;
      if (D.17920 != 0B) goto <D.17822>; else goto <D.17824>;
      <D.17824>:
    }
    __i = __i + 1;
    <D.17826>:
    D.17921 = global_remset_class_hash_table.size;
    if (D.17921 > __i) goto <D.17825>; else goto <D.17827>;
    <D.17827>:
  }
}


__attribute__((visibility ("hidden")))
sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.17922;

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


__attribute__((visibility ("hidden")))
sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.17924;

  D.17924 = pinned_objects;
  return D.17924;
}


