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.17212>;
  <D.17211>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.17212>:
  if (i <= 2) goto <D.17211>; else goto <D.17213>;
  <D.17213>:
  goto <D.17216>;
  <D.17215>:
  {
    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.17216>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.17215>; else goto <D.17217>;
  <D.17217>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.17312;
  struct PinStatAddress * D.17313;

  if (node == 0B) goto <D.17310>; else goto <D.17311>;
  <D.17310>:
  return;
  <D.17311>:
  D.17312 = node->left;
  pin_stats_tree_free (D.17312);
  D.17313 = node->right;
  pin_stats_tree_free (D.17313);
  sgen_free_internal_dynamic (node, 16, 11);
}


sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.17315;
  int D.17318;
  int D.17319;
  struct PinStatAddress * D.17323;
  struct PinStatAddress * D.17324;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.17226>;
  <D.17225>:
  node = *node_ptr;
  D.17315 = node->addr;
  if (D.17315 == addr) goto <D.17316>; else goto <D.17317>;
  <D.17316>:
  D.17318 = node->pin_types;
  D.17319 = D.17318 | pin_type_bit;
  node->pin_types = D.17319;
  return;
  <D.17317>:
  D.17315 = node->addr;
  if (D.17315 > addr) goto <D.17320>; else goto <D.17321>;
  <D.17320>:
  node_ptr = &node->left;
  goto <D.17322>;
  <D.17321>:
  node_ptr = &node->right;
  <D.17322>:
  <D.17226>:
  D.17323 = *node_ptr;
  if (D.17323 != 0B) goto <D.17225>; else goto <D.17227>;
  <D.17227>:
  node = sgen_alloc_internal_dynamic (16, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.17324 = node->right;
  node->left = D.17324;
  *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.17331;
  unsigned int D.17332;
  struct MonoVTable * D.17333;
  struct MonoClass * D.17334;
  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.17329>; else goto <D.17330>;
      <D.17329>:
      D.17331 = MEM[(mword *)obj];
      D.17332 = D.17331 & 4294967292;
      D.17333 = (struct MonoVTable *) D.17332;
      D.17334 = D.17333->klass;
      pin_types.4 = pin_types;
      register_class (D.17334, pin_types.4);
      <D.17330>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.17337;
  char * D.17340;
  int D.17343;
  int D.17344;
  int D.17347;
  int D.17348;
  unsigned int D.17351;
  unsigned int D.17352;
  int D.17353;
  struct PinStatAddress * D.17356;
  sizetype D.17357;
  char * D.17358;
  struct PinStatAddress * D.17361;

  if (node == 0B) goto <D.17335>; else goto <D.17336>;
  <D.17335>:
  return;
  <D.17336>:
  D.17337 = node->addr;
  if (D.17337 >= obj) goto <D.17338>; else goto <D.17339>;
  <D.17338>:
  D.17337 = node->addr;
  D.17340 = obj + size;
  if (D.17337 < D.17340) goto <D.17341>; else goto <D.17342>;
  <D.17341>:
  {
    int i;

    i = 0;
    goto <D.17237>;
    <D.17236>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.17343 = *pin_types;
      D.17344 = D.17343 & pin_bit;
      if (D.17344 == 0) goto <D.17345>; else goto <D.17346>;
      <D.17345>:
      D.17347 = node->pin_types;
      D.17348 = D.17347 & pin_bit;
      if (D.17348 != 0) goto <D.17349>; else goto <D.17350>;
      <D.17349>:
      D.17351 = pinned_byte_counts[i];
      D.17352 = D.17351 + size;
      pinned_byte_counts[i] = D.17352;
      D.17343 = *pin_types;
      D.17353 = D.17343 | pin_bit;
      *pin_types = D.17353;
      <D.17350>:
      <D.17346>:
    }
    i = i + 1;
    <D.17237>:
    if (i <= 2) goto <D.17236>; else goto <D.17238>;
    <D.17238>:
  }
  <D.17342>:
  <D.17339>:
  D.17337 = node->addr;
  if (D.17337 > obj) goto <D.17354>; else goto <D.17355>;
  <D.17354>:
  D.17356 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.17356, pin_types);
  <D.17355>:
  D.17357 = size + 4294967295;
  D.17358 = obj + D.17357;
  D.17337 = node->addr;
  if (D.17358 > D.17337) goto <D.17359>; else goto <D.17360>;
  <D.17359>:
  D.17361 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.17361, pin_types);
  <D.17360>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.17363;
  int D.17364;
  long unsigned int D.17367;
  long unsigned int D.17368;
  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.17254>;
      <D.17253>:
      D.17363 = pin_types >> i;
      D.17364 = D.17363 & 1;
      if (D.17364 != 0) goto <D.17365>; else goto <D.17366>;
      <D.17365>:
      D.17367 = entry->num_pins[i];
      D.17368 = D.17367 + 1;
      entry->num_pins[i] = D.17368;
      <D.17366>:
      i = i + 1;
      <D.17254>:
      if (i <= 2) goto <D.17253>; else goto <D.17255>;
      <D.17255>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.17371;
  int D.17376;
  void * D.17378;
  unsigned int D.17379;

  D.17371 = __builtin_constant_p (__len);
  if (D.17371 != 0) goto <D.17372>; else goto <D.17373>;
  <D.17372>:
  if (__len == 0) goto <D.17374>; else goto <D.17375>;
  <D.17374>:
  D.17376 = __builtin_constant_p (__ch);
  if (D.17376 == 0) goto <D.17369>; else goto <D.17377>;
  <D.17377>:
  if (__ch != 0) goto <D.17369>; else goto <D.17370>;
  <D.17369>:
  __warn_memset_zero_len ();
  D.17378 = __dest;
  return D.17378;
  <D.17370>:
  <D.17375>:
  <D.17373>:
  D.17379 = __builtin_object_size (__dest, 0);
  D.17378 = __builtin___memset_chk (__dest, __ch, __len, D.17379);
  return D.17378;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.17381;
  const char * D.17382;
  void * D.17386;
  char * name;
  void * entry;

  D.17381 = class->name_space;
  D.17382 = class->name;
  name = monoeg_g_strdup_printf ("%s.%s", D.17381, D.17382);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.17383>; else goto <D.17384>;
  <D.17383>:
  monoeg_g_free (name);
  goto <D.17385>;
  <D.17384>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.17385>:
  D.17386 = entry;
  return D.17386;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  unsigned int D.17388;
  unsigned int D.17389;
  struct MonoVTable * D.17390;
  struct MonoClass * D.17391;
  long unsigned int D.17392;
  long unsigned int D.17393;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 4);
      D.17388 = MEM[(mword *)obj];
      D.17389 = D.17388 & 4294967292;
      D.17390 = (struct MonoVTable *) D.17389;
      D.17391 = D.17390->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.17391, &empty_entry);
      D.17392 = entry->num_remsets;
      D.17393 = D.17392 + 1;
      entry->num_remsets = D.17393;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  unsigned int D.17394;
  long unsigned int D.17395;
  struct SgenHashTableEntry * D.17396;
  unsigned int D.17397;
  unsigned int D.17398;
  long unsigned int D.17399;
  struct SgenHashTableEntry * D.17400;
  unsigned int D.17401;
  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.17287>;
    <D.17286>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17394 = __i * 4;
      __iter = __table + D.17394;
      goto <D.17284>;
      <D.17283>:
      {
        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.17281>;
          <D.17280>:
          D.17395 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.17395);
          i = i + 1;
          <D.17281>:
          if (i <= 2) goto <D.17280>; else goto <D.17282>;
          <D.17282>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.17284>:
      D.17396 = *__iter;
      if (D.17396 != 0B) goto <D.17283>; else goto <D.17285>;
      <D.17285>:
    }
    __i = __i + 1;
    <D.17287>:
    D.17397 = pinned_class_hash_table.size;
    if (D.17397 > __i) goto <D.17286>; else goto <D.17288>;
    <D.17288>:
  }
  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.17299>;
    <D.17298>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17398 = __i * 4;
      __iter = __table + D.17398;
      goto <D.17296>;
      <D.17295>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.17399 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.17399);
      }
      __iter = __next;
      <D.17296>:
      D.17400 = *__iter;
      if (D.17400 != 0B) goto <D.17295>; else goto <D.17297>;
      <D.17297>:
    }
    __i = __i + 1;
    <D.17299>:
    D.17401 = global_remset_class_hash_table.size;
    if (D.17401 > __i) goto <D.17298>; else goto <D.17300>;
    <D.17300>:
  }
}


sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.17402;

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


sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.17404;

  D.17404 = pinned_objects;
  return D.17404;
}


