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.19795>;
  <D.19794>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.19795>:
  if (i <= 2) goto <D.19794>; else goto <D.19796>;
  <D.19796>:
  goto <D.19799>;
  <D.19798>:
  {
    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, 8, 11);
    pinned_objects = next;
  }
  <D.19799>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.19798>; else goto <D.19800>;
  <D.19800>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.19897;
  struct PinStatAddress * D.19898;

  if (node == 0B) goto <D.19895>; else goto <D.19896>;
  <D.19895>:
  return;
  <D.19896>:
  D.19897 = node->left;
  pin_stats_tree_free (D.19897);
  D.19898 = node->right;
  pin_stats_tree_free (D.19898);
  sgen_free_internal_dynamic (node, 16, 11);
}


sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.19900;
  int D.19903;
  int D.19904;
  struct PinStatAddress * D.19908;
  struct PinStatAddress * D.19909;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.19809>;
  <D.19808>:
  node = *node_ptr;
  D.19900 = node->addr;
  if (D.19900 == addr) goto <D.19901>; else goto <D.19902>;
  <D.19901>:
  D.19903 = node->pin_types;
  D.19904 = D.19903 | pin_type_bit;
  node->pin_types = D.19904;
  return;
  <D.19902>:
  D.19900 = node->addr;
  if (D.19900 > addr) goto <D.19905>; else goto <D.19906>;
  <D.19905>:
  node_ptr = &node->left;
  goto <D.19907>;
  <D.19906>:
  node_ptr = &node->right;
  <D.19907>:
  <D.19809>:
  D.19908 = *node_ptr;
  if (D.19908 != 0B) goto <D.19808>; else goto <D.19810>;
  <D.19810>:
  node = sgen_alloc_internal_dynamic (16, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.19909 = node->right;
  node->left = D.19909;
  *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;
  unsigned int D.19916;
  unsigned int D.19917;
  struct MonoVTable * D.19918;
  struct MonoClass * D.19919;
  int pin_types;
  struct ObjectList * list;

  try
    {
      pin_types = 0;
      list = sgen_alloc_internal_dynamic (8, 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.19914>; else goto <D.19915>;
      <D.19914>:
      D.19916 = MEM[(mword *)obj];
      D.19917 = D.19916 & 4294967292;
      D.19918 = (struct MonoVTable *) D.19917;
      D.19919 = D.19918->klass;
      pin_types.4 = pin_types;
      register_class (D.19919, pin_types.4);
      <D.19915>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.19922;
  char * D.19925;
  int D.19928;
  int D.19929;
  int D.19932;
  int D.19933;
  unsigned int D.19936;
  unsigned int D.19937;
  int D.19938;
  struct PinStatAddress * D.19941;
  sizetype D.19942;
  char * D.19943;
  struct PinStatAddress * D.19946;

  if (node == 0B) goto <D.19920>; else goto <D.19921>;
  <D.19920>:
  return;
  <D.19921>:
  D.19922 = node->addr;
  if (D.19922 >= obj) goto <D.19923>; else goto <D.19924>;
  <D.19923>:
  D.19922 = node->addr;
  D.19925 = obj + size;
  if (D.19922 < D.19925) goto <D.19926>; else goto <D.19927>;
  <D.19926>:
  {
    int i;

    i = 0;
    goto <D.19820>;
    <D.19819>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.19928 = *pin_types;
      D.19929 = D.19928 & pin_bit;
      if (D.19929 == 0) goto <D.19930>; else goto <D.19931>;
      <D.19930>:
      D.19932 = node->pin_types;
      D.19933 = D.19932 & pin_bit;
      if (D.19933 != 0) goto <D.19934>; else goto <D.19935>;
      <D.19934>:
      D.19936 = pinned_byte_counts[i];
      D.19937 = D.19936 + size;
      pinned_byte_counts[i] = D.19937;
      D.19928 = *pin_types;
      D.19938 = D.19928 | pin_bit;
      *pin_types = D.19938;
      <D.19935>:
      <D.19931>:
    }
    i = i + 1;
    <D.19820>:
    if (i <= 2) goto <D.19819>; else goto <D.19821>;
    <D.19821>:
  }
  <D.19927>:
  <D.19924>:
  D.19922 = node->addr;
  if (D.19922 > obj) goto <D.19939>; else goto <D.19940>;
  <D.19939>:
  D.19941 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.19941, pin_types);
  <D.19940>:
  D.19942 = size + 4294967295;
  D.19943 = obj + D.19942;
  D.19922 = node->addr;
  if (D.19943 > D.19922) goto <D.19944>; else goto <D.19945>;
  <D.19944>:
  D.19946 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.19946, pin_types);
  <D.19945>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.19948;
  int D.19949;
  long unsigned int D.19952;
  long unsigned int D.19953;
  struct PinnedClassEntry empty_entry;
  struct PinnedClassEntry * entry;
  int i;

  try
    {
      memset (&empty_entry, 0, 12);
      entry = lookup_class_entry (&pinned_class_hash_table, class, &empty_entry);
      i = 0;
      goto <D.19837>;
      <D.19836>:
      D.19948 = pin_types >> i;
      D.19949 = D.19948 & 1;
      if (D.19949 != 0) goto <D.19950>; else goto <D.19951>;
      <D.19950>:
      D.19952 = entry->num_pins[i];
      D.19953 = D.19952 + 1;
      entry->num_pins[i] = D.19953;
      <D.19951>:
      i = i + 1;
      <D.19837>:
      if (i <= 2) goto <D.19836>; else goto <D.19838>;
      <D.19838>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.19956;
  int D.19961;
  void * D.19963;
  unsigned int D.19964;

  D.19956 = __builtin_constant_p (__len);
  if (D.19956 != 0) goto <D.19957>; else goto <D.19958>;
  <D.19957>:
  if (__len == 0) goto <D.19959>; else goto <D.19960>;
  <D.19959>:
  D.19961 = __builtin_constant_p (__ch);
  if (D.19961 == 0) goto <D.19954>; else goto <D.19962>;
  <D.19962>:
  if (__ch != 0) goto <D.19954>; else goto <D.19955>;
  <D.19954>:
  __warn_memset_zero_len ();
  D.19963 = __dest;
  return D.19963;
  <D.19955>:
  <D.19960>:
  <D.19958>:
  D.19964 = __builtin_object_size (__dest, 0);
  D.19963 = __builtin___memset_chk (__dest, __ch, __len, D.19964);
  return D.19963;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.19966;
  const char * D.19967;
  void * D.19971;
  char * name;
  void * entry;

  D.19966 = class->name_space;
  D.19967 = class->name;
  name = monoeg_g_strdup_printf ("%s.%s", D.19966, D.19967);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.19968>; else goto <D.19969>;
  <D.19968>:
  monoeg_g_free (name);
  goto <D.19970>;
  <D.19969>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.19970>:
  D.19971 = entry;
  return D.19971;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  unsigned int D.19973;
  unsigned int D.19974;
  struct MonoVTable * D.19975;
  struct MonoClass * D.19976;
  long unsigned int D.19977;
  long unsigned int D.19978;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 4);
      D.19973 = MEM[(mword *)obj];
      D.19974 = D.19973 & 4294967292;
      D.19975 = (struct MonoVTable *) D.19974;
      D.19976 = D.19975->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.19976, &empty_entry);
      D.19977 = entry->num_remsets;
      D.19978 = D.19977 + 1;
      entry->num_remsets = D.19978;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  unsigned int D.19979;
  long unsigned int D.19980;
  struct SgenHashTableEntry * D.19981;
  unsigned int D.19982;
  unsigned int D.19983;
  long unsigned int D.19984;
  struct SgenHashTableEntry * D.19985;
  unsigned int D.19986;
  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.19870>;
    <D.19869>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.19979 = __i * 4;
      __iter = __table + D.19979;
      goto <D.19867>;
      <D.19866>:
      {
        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.19864>;
          <D.19863>:
          D.19980 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.19980);
          i = i + 1;
          <D.19864>:
          if (i <= 2) goto <D.19863>; else goto <D.19865>;
          <D.19865>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.19867>:
      D.19981 = *__iter;
      if (D.19981 != 0B) goto <D.19866>; else goto <D.19868>;
      <D.19868>:
    }
    __i = __i + 1;
    <D.19870>:
    D.19982 = pinned_class_hash_table.size;
    if (D.19982 > __i) goto <D.19869>; else goto <D.19871>;
    <D.19871>:
  }
  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.19882>;
    <D.19881>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.19983 = __i * 4;
      __iter = __table + D.19983;
      goto <D.19879>;
      <D.19878>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.19984 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.19984);
      }
      __iter = __next;
      <D.19879>:
      D.19985 = *__iter;
      if (D.19985 != 0B) goto <D.19878>; else goto <D.19880>;
      <D.19880>:
    }
    __i = __i + 1;
    <D.19882>:
    D.19986 = global_remset_class_hash_table.size;
    if (D.19986 > __i) goto <D.19881>; else goto <D.19883>;
    <D.19883>:
  }
}


sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.19987;

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


sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.19989;

  D.19989 = pinned_objects;
  return D.19989;
}


