2010-03-12 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / sgen-pinning-stats.c
blob4f1998513da86288ea78ee386f4c6e61233038e2
1 enum {
2 PIN_TYPE_STACK,
3 PIN_TYPE_STATIC_DATA,
4 PIN_TYPE_OTHER,
5 PIN_TYPE_MAX
6 };
8 typedef struct _PinStatAddress PinStatAddress;
9 struct _PinStatAddress {
10 char *addr;
11 int pin_types;
12 PinStatAddress *left;
13 PinStatAddress *right;
16 static PinStatAddress *pin_stat_addresses = NULL;
17 static size_t pinned_byte_counts [PIN_TYPE_MAX];
19 static void
20 pin_stats_tree_free (PinStatAddress *node)
22 if (!node)
23 return;
24 pin_stats_tree_free (node->left);
25 pin_stats_tree_free (node->right);
26 free_internal_mem (node, INTERNAL_MEM_STATISTICS);
29 static void
30 pin_stats_reset (void)
32 int i;
33 pin_stats_tree_free (pin_stat_addresses);
34 pin_stat_addresses = NULL;
35 for (i = 0; i < PIN_TYPE_MAX; ++i)
36 pinned_byte_counts [i] = 0;
39 static void
40 pin_stats_register_address (char *addr, int pin_type)
42 PinStatAddress **node_ptr = &pin_stat_addresses;
43 PinStatAddress *node;
44 int pin_type_bit = 1 << pin_type;
46 while (*node_ptr) {
47 node = *node_ptr;
48 if (addr == node->addr) {
49 node->pin_types |= pin_type_bit;
50 return;
52 if (addr < node->addr)
53 node_ptr = &node->left;
54 else
55 node_ptr = &node->right;
58 node = get_internal_mem (sizeof (PinStatAddress), INTERNAL_MEM_STATISTICS);
59 node->addr = addr;
60 node->pin_types = pin_type_bit;
61 node->left = node->right = NULL;
63 *node_ptr = node;
66 static void
67 pin_stats_count_object_from_tree (char *obj, size_t size, PinStatAddress *node, int *pin_types)
69 if (!node)
70 return;
71 if (node->addr >= obj && node->addr < obj + size) {
72 int i;
73 for (i = 0; i < PIN_TYPE_MAX; ++i) {
74 int pin_bit = 1 << i;
75 if (!(*pin_types & pin_bit) && (node->pin_types & pin_bit)) {
76 pinned_byte_counts [i] += size;
77 *pin_types |= pin_bit;
81 if (obj < node->addr)
82 pin_stats_count_object_from_tree (obj, size, node->left, pin_types);
83 if (obj + size - 1 > node->addr)
84 pin_stats_count_object_from_tree (obj, size, node->right, pin_types);
87 static void
88 pin_stats_register_object (char *obj, size_t size)
90 int pin_types = 0;
91 pin_stats_count_object_from_tree (obj, size, pin_stat_addresses, &pin_types);