2010-03-30 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / tools / sgen / sgen-grep-binprot.c
blobf114ff8c4ddf07e697ecbc3a3cd72922814d1b11
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <glib.h>
6 #include <mono/metadata/sgen-protocol.h>
8 #define SGEN_PROTOCOL_EOF 255
10 static int
11 read_entry (FILE *in, void **data)
13 unsigned char type;
14 int size;
16 if (fread (&type, 1, 1, in) != 1)
17 return SGEN_PROTOCOL_EOF;
18 switch (type) {
19 case SGEN_PROTOCOL_COLLECTION: size = sizeof (SGenProtocolCollection); break;
20 case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break;
21 case SGEN_PROTOCOL_COPY: size = sizeof (SGenProtocolCopy); break;
22 case SGEN_PROTOCOL_PIN: size = sizeof (SGenProtocolPin); break;
23 case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
24 case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
25 case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
26 case SGEN_PROTOCOL_CLEANUP: size = sizeof (SGenProtocolCleanup); break;
27 case SGEN_PROTOCOL_EMPTY: size = sizeof (SGenProtocolEmpty); break;
28 case SGEN_PROTOCOL_THREAD_RESTART: size = sizeof (SGenProtocolThreadRestart); break;
29 case SGEN_PROTOCOL_THREAD_REGISTER: size = sizeof (SGenProtocolThreadRegister); break;
30 case SGEN_PROTOCOL_THREAD_UNREGISTER: size = sizeof (SGenProtocolThreadUnregister); break;
31 case SGEN_PROTOCOL_MISSING_REMSET: size = sizeof (SGenProtocolMissingRemset); break;
32 default: assert (0);
35 *data = malloc (size);
36 if (fread (*data, size, 1, in) != 1)
37 assert (0);
39 return (int)type;
42 static void
43 print_entry (int type, void *data)
45 switch (type) {
46 case SGEN_PROTOCOL_COLLECTION: {
47 SGenProtocolCollection *entry = data;
48 printf ("collection generation %d\n", entry->generation);
49 break;
51 case SGEN_PROTOCOL_ALLOC: {
52 SGenProtocolAlloc *entry = data;
53 printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
54 break;
56 case SGEN_PROTOCOL_COPY: {
57 SGenProtocolCopy *entry = data;
58 printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
59 break;
61 case SGEN_PROTOCOL_PIN: {
62 SGenProtocolPin *entry = data;
63 printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
64 break;
66 case SGEN_PROTOCOL_WBARRIER: {
67 SGenProtocolWBarrier *entry = data;
68 printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
69 break;
71 case SGEN_PROTOCOL_GLOBAL_REMSET: {
72 SGenProtocolGlobalRemset *entry = data;
73 printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
74 break;
76 case SGEN_PROTOCOL_PTR_UPDATE: {
77 SGenProtocolPtrUpdate *entry = data;
78 printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
79 entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
80 break;
82 case SGEN_PROTOCOL_CLEANUP: {
83 SGenProtocolCleanup *entry = data;
84 printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
85 break;
87 case SGEN_PROTOCOL_EMPTY: {
88 SGenProtocolEmpty *entry = data;
89 printf ("empty start %p size %d\n", entry->start, entry->size);
90 break;
92 case SGEN_PROTOCOL_THREAD_RESTART: {
93 SGenProtocolThreadRestart *entry = data;
94 printf ("thread_restart thread %p\n", entry->thread);
95 break;
97 case SGEN_PROTOCOL_THREAD_REGISTER: {
98 SGenProtocolThreadRegister *entry = data;
99 printf ("thread_register thread %p\n", entry->thread);
100 break;
102 case SGEN_PROTOCOL_THREAD_UNREGISTER: {
103 SGenProtocolThreadUnregister *entry = data;
104 printf ("thread_unregister thread %p\n", entry->thread);
105 break;
107 case SGEN_PROTOCOL_MISSING_REMSET: {
108 SGenProtocolMissingRemset *entry = data;
109 printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
110 entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
111 break;
113 default:
114 assert (0);
118 static gboolean
119 matches_interval (gpointer ptr, gpointer start, int size)
121 return ptr >= start && (char*)ptr < (char*)start + size;
124 static gboolean
125 is_match (gpointer ptr, int type, void *data)
127 switch (type) {
128 case SGEN_PROTOCOL_COLLECTION:
129 case SGEN_PROTOCOL_THREAD_RESTART:
130 case SGEN_PROTOCOL_THREAD_REGISTER:
131 case SGEN_PROTOCOL_THREAD_UNREGISTER:
132 return TRUE;
133 case SGEN_PROTOCOL_ALLOC: {
134 SGenProtocolAlloc *entry = data;
135 return matches_interval (ptr, entry->obj, entry->size);
137 case SGEN_PROTOCOL_COPY: {
138 SGenProtocolCopy *entry = data;
139 return matches_interval (ptr, entry->from, entry->size) || matches_interval (ptr, entry->to, entry->size);
141 case SGEN_PROTOCOL_PIN: {
142 SGenProtocolPin *entry = data;
143 return matches_interval (ptr, entry->obj, entry->size);
145 case SGEN_PROTOCOL_WBARRIER: {
146 SGenProtocolWBarrier *entry = data;
147 return ptr == entry->ptr || ptr == entry->value;
149 case SGEN_PROTOCOL_GLOBAL_REMSET: {
150 SGenProtocolGlobalRemset *entry = data;
151 return ptr == entry->ptr || ptr == entry->value;
153 case SGEN_PROTOCOL_PTR_UPDATE: {
154 SGenProtocolPtrUpdate *entry = data;
155 return ptr == entry->ptr ||
156 matches_interval (ptr, entry->old_value, entry->size) ||
157 matches_interval (ptr, entry->new_value, entry->size);
159 case SGEN_PROTOCOL_CLEANUP: {
160 SGenProtocolCleanup *entry = data;
161 return matches_interval (ptr, entry->ptr, entry->size);
163 case SGEN_PROTOCOL_EMPTY: {
164 SGenProtocolEmpty *entry = data;
165 return matches_interval (ptr, entry->start, entry->size);
167 case SGEN_PROTOCOL_MISSING_REMSET: {
168 SGenProtocolMissingRemset *entry = data;
169 return ptr == entry->obj || ptr == entry->value || ptr == (char*)entry->obj + entry->offset;
171 default:
172 assert (0);
177 main (int argc, char *argv[])
179 int type;
180 void *data;
181 int num_nums = argc - 1;
182 int i;
183 long nums [num_nums];
185 for (i = 0; i < num_nums; ++i)
186 nums [i] = strtol (argv [i + 1], NULL, 16);
188 while ((type = read_entry (stdin, &data)) != SGEN_PROTOCOL_EOF) {
189 gboolean match = FALSE;
190 for (i = 0; i < num_nums; ++i) {
191 if (is_match ((gpointer) nums [i], type, data)) {
192 match = TRUE;
193 break;
196 if (match)
197 print_entry (type, data);
198 free (data);
201 return 0;