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.17232>;
  <D.17231>:
  pinned_byte_counts[i] = 0;
  i = i + 1;
  <D.17232>:
  if (i <= 2) goto <D.17231>; else goto <D.17233>;
  <D.17233>:
  goto <D.17236>;
  <D.17235>:
  {
    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.17236>:
  pinned_objects.1 = pinned_objects;
  if (pinned_objects.1 != 0B) goto <D.17235>; else goto <D.17237>;
  <D.17237>:
}


pin_stats_tree_free (struct PinStatAddress * node)
{
  struct PinStatAddress * D.17332;
  struct PinStatAddress * D.17333;

  if (node == 0B) goto <D.17330>; else goto <D.17331>;
  <D.17330>:
  return;
  <D.17331>:
  D.17332 = node->left;
  pin_stats_tree_free (D.17332);
  D.17333 = node->right;
  pin_stats_tree_free (D.17333);
  sgen_free_internal_dynamic (node, 16, 11);
}


sgen_pin_stats_register_address (char * addr, int pin_type)
{
  char * D.17335;
  int D.17338;
  int D.17339;
  struct PinStatAddress * D.17343;
  struct PinStatAddress * D.17344;
  struct PinStatAddress * * node_ptr;
  struct PinStatAddress * node;
  int pin_type_bit;

  node_ptr = &pin_stat_addresses;
  pin_type_bit = 1 << pin_type;
  goto <D.17246>;
  <D.17245>:
  node = *node_ptr;
  D.17335 = node->addr;
  if (D.17335 == addr) goto <D.17336>; else goto <D.17337>;
  <D.17336>:
  D.17338 = node->pin_types;
  D.17339 = D.17338 | pin_type_bit;
  node->pin_types = D.17339;
  return;
  <D.17337>:
  D.17335 = node->addr;
  if (D.17335 > addr) goto <D.17340>; else goto <D.17341>;
  <D.17340>:
  node_ptr = &node->left;
  goto <D.17342>;
  <D.17341>:
  node_ptr = &node->right;
  <D.17342>:
  <D.17246>:
  D.17343 = *node_ptr;
  if (D.17343 != 0B) goto <D.17245>; else goto <D.17247>;
  <D.17247>:
  node = sgen_alloc_internal_dynamic (16, 11, 1);
  node->addr = addr;
  node->pin_types = pin_type_bit;
  node->right = 0B;
  D.17344 = node->right;
  node->left = D.17344;
  *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.17351;
  unsigned int D.17352;
  struct MonoVTable * D.17353;
  struct MonoClass * D.17354;
  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.17349>; else goto <D.17350>;
      <D.17349>:
      pin_types.4 = pin_types;
      D.17351 = MEM[(mword *)obj];
      D.17352 = D.17351 & 4294967292;
      D.17353 = (struct MonoVTable *) D.17352;
      D.17354 = D.17353->klass;
      register_class (D.17354, pin_types.4);
      <D.17350>:
    }
  finally
    {
      pin_types = {CLOBBER};
    }
}


pin_stats_count_object_from_tree (char * obj, size_t size, struct PinStatAddress * node, int * pin_types)
{
  char * D.17357;
  char * D.17360;
  int D.17363;
  int D.17364;
  int D.17367;
  int D.17368;
  unsigned int D.17371;
  unsigned int D.17372;
  int D.17373;
  struct PinStatAddress * D.17376;
  sizetype D.17377;
  char * D.17378;
  struct PinStatAddress * D.17381;

  if (node == 0B) goto <D.17355>; else goto <D.17356>;
  <D.17355>:
  return;
  <D.17356>:
  D.17357 = node->addr;
  if (D.17357 >= obj) goto <D.17358>; else goto <D.17359>;
  <D.17358>:
  D.17357 = node->addr;
  D.17360 = obj + size;
  if (D.17357 < D.17360) goto <D.17361>; else goto <D.17362>;
  <D.17361>:
  {
    int i;

    i = 0;
    goto <D.17257>;
    <D.17256>:
    {
      int pin_bit;

      pin_bit = 1 << i;
      D.17363 = *pin_types;
      D.17364 = D.17363 & pin_bit;
      if (D.17364 == 0) goto <D.17365>; else goto <D.17366>;
      <D.17365>:
      D.17367 = node->pin_types;
      D.17368 = D.17367 & pin_bit;
      if (D.17368 != 0) goto <D.17369>; else goto <D.17370>;
      <D.17369>:
      D.17371 = pinned_byte_counts[i];
      D.17372 = D.17371 + size;
      pinned_byte_counts[i] = D.17372;
      D.17363 = *pin_types;
      D.17373 = D.17363 | pin_bit;
      *pin_types = D.17373;
      <D.17370>:
      <D.17366>:
    }
    i = i + 1;
    <D.17257>:
    if (i <= 2) goto <D.17256>; else goto <D.17258>;
    <D.17258>:
  }
  <D.17362>:
  <D.17359>:
  D.17357 = node->addr;
  if (D.17357 > obj) goto <D.17374>; else goto <D.17375>;
  <D.17374>:
  D.17376 = node->left;
  pin_stats_count_object_from_tree (obj, size, D.17376, pin_types);
  <D.17375>:
  D.17377 = size + 4294967295;
  D.17378 = obj + D.17377;
  D.17357 = node->addr;
  if (D.17378 > D.17357) goto <D.17379>; else goto <D.17380>;
  <D.17379>:
  D.17381 = node->right;
  pin_stats_count_object_from_tree (obj, size, D.17381, pin_types);
  <D.17380>:
}


register_class (struct MonoClass * class, int pin_types)
{
  int D.17383;
  int D.17384;
  long unsigned int D.17387;
  long unsigned int D.17388;
  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.17274>;
      <D.17273>:
      D.17383 = pin_types >> i;
      D.17384 = D.17383 & 1;
      if (D.17384 != 0) goto <D.17385>; else goto <D.17386>;
      <D.17385>:
      D.17387 = entry->num_pins[i];
      D.17388 = D.17387 + 1;
      entry->num_pins[i] = D.17388;
      <D.17386>:
      i = i + 1;
      <D.17274>:
      if (i <= 2) goto <D.17273>; else goto <D.17275>;
      <D.17275>:
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.17391;
  int D.17396;
  void * D.17398;
  unsigned int D.17399;

  D.17391 = __builtin_constant_p (__len);
  if (D.17391 != 0) goto <D.17392>; else goto <D.17393>;
  <D.17392>:
  if (__len == 0) goto <D.17394>; else goto <D.17395>;
  <D.17394>:
  D.17396 = __builtin_constant_p (__ch);
  if (D.17396 == 0) goto <D.17389>; else goto <D.17397>;
  <D.17397>:
  if (__ch != 0) goto <D.17389>; else goto <D.17390>;
  <D.17389>:
  __warn_memset_zero_len ();
  D.17398 = __dest;
  return D.17398;
  <D.17390>:
  <D.17395>:
  <D.17393>:
  D.17399 = __builtin_object_size (__dest, 0);
  D.17398 = __builtin___memset_chk (__dest, __ch, __len, D.17399);
  return D.17398;
}


lookup_class_entry (struct SgenHashTable * hash_table, struct MonoClass * class, void * empty_entry)
{
  const char * D.17401;
  const char * D.17402;
  void * D.17406;
  char * name;
  void * entry;

  D.17401 = class->name;
  D.17402 = class->name_space;
  name = monoeg_g_strdup_printf ("%s.%s", D.17402, D.17401);
  entry = sgen_hash_table_lookup (hash_table, name);
  if (entry != 0B) goto <D.17403>; else goto <D.17404>;
  <D.17403>:
  monoeg_g_free (name);
  goto <D.17405>;
  <D.17404>:
  sgen_hash_table_replace (hash_table, name, empty_entry, 0B);
  entry = sgen_hash_table_lookup (hash_table, name);
  <D.17405>:
  D.17406 = entry;
  return D.17406;
}


sgen_pin_stats_register_global_remset (char * obj)
{
  unsigned int D.17408;
  unsigned int D.17409;
  struct MonoVTable * D.17410;
  struct MonoClass * D.17411;
  long unsigned int D.17412;
  long unsigned int D.17413;
  struct GlobalRemsetClassEntry empty_entry;
  struct GlobalRemsetClassEntry * entry;

  try
    {
      memset (&empty_entry, 0, 4);
      D.17408 = MEM[(mword *)obj];
      D.17409 = D.17408 & 4294967292;
      D.17410 = (struct MonoVTable *) D.17409;
      D.17411 = D.17410->klass;
      entry = lookup_class_entry (&global_remset_class_hash_table, D.17411, &empty_entry);
      D.17412 = entry->num_remsets;
      D.17413 = D.17412 + 1;
      entry->num_remsets = D.17413;
    }
  finally
    {
      empty_entry = {CLOBBER};
    }
}


sgen_pin_stats_print_class_stats ()
{
  unsigned int D.17414;
  long unsigned int D.17415;
  struct SgenHashTableEntry * D.17416;
  unsigned int D.17417;
  unsigned int D.17418;
  long unsigned int D.17419;
  struct SgenHashTableEntry * D.17420;
  unsigned int D.17421;
  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.17307>;
    <D.17306>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17414 = __i * 4;
      __iter = __table + D.17414;
      goto <D.17304>;
      <D.17303>:
      {
        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.17301>;
          <D.17300>:
          D.17415 = pinned_entry->num_pins[i];
          monoeg_g_print ("  %10ld", D.17415);
          i = i + 1;
          <D.17301>:
          if (i <= 2) goto <D.17300>; else goto <D.17302>;
          <D.17302>:
          monoeg_g_print ("\n");
        }
      }
      __iter = __next;
      <D.17304>:
      D.17416 = *__iter;
      if (D.17416 != 0B) goto <D.17303>; else goto <D.17305>;
      <D.17305>:
    }
    __i = __i + 1;
    <D.17307>:
    D.17417 = pinned_class_hash_table.size;
    if (D.17417 > __i) goto <D.17306>; else goto <D.17308>;
    <D.17308>:
  }
  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.17319>;
    <D.17318>:
    {
      struct SgenHashTableEntry * * __iter;
      struct SgenHashTableEntry * * __next;

      D.17418 = __i * 4;
      __iter = __table + D.17418;
      goto <D.17316>;
      <D.17315>:
      {
        struct SgenHashTableEntry * __entry;

        __entry = *__iter;
        __next = &__entry->next;
        name = __entry->key;
        remset_entry = &__entry->data;
        D.17419 = remset_entry->num_remsets;
        monoeg_g_print ("%-50s  %10ld\n", name, D.17419);
      }
      __iter = __next;
      <D.17316>:
      D.17420 = *__iter;
      if (D.17420 != 0B) goto <D.17315>; else goto <D.17317>;
      <D.17317>:
    }
    __i = __i + 1;
    <D.17319>:
    D.17421 = global_remset_class_hash_table.size;
    if (D.17421 > __i) goto <D.17318>; else goto <D.17320>;
    <D.17320>:
  }
}


sgen_pin_stats_get_pinned_byte_count (int pin_type)
{
  size_t D.17422;

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


sgen_pin_stats_get_object_list ()
{
  struct ObjectList * D.17424;

  D.17424 = pinned_objects;
  return D.17424;
}


