X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmonograph%2Fmonograph.c;h=27f1a5f3cf9cf801d857e750382395fcb80cccff;hb=1e726ce7a38a92860acab28f4427813d2ba14c13;hp=6c30820b8f9d0c3e1dd1f2bf19c8e88aee90c16a;hpb=b5cfba1835f2ba823796f825410e0062b7e4c9a3;p=mono.git diff --git a/mono/monograph/monograph.c b/mono/monograph/monograph.c index 6c30820b8f9..27f1a5f3cf9 100644 --- a/mono/monograph/monograph.c +++ b/mono/monograph/monograph.c @@ -1,6 +1,7 @@ #include #include #include +#include "mono/metadata/metadata-internals.h" #include "mono/metadata/class-internals.h" #include "mono/metadata/assembly.h" #include "mono/metadata/tokentype.h" @@ -17,6 +18,11 @@ static int max_depth = 6; static int verbose = 0; static const char *graph_properties = "\tnode [fontsize=8.0]\n\tedge [len=2,color=red]\n"; +#if defined(__native_client__) || defined(__native_client_codegen__) +volatile int __nacl_thread_suspension_needed = 0; +void __nacl_suspend_thread_if_needed() {} +#endif + static void output_type_edge (MonoClass *first, MonoClass *second) { if (include_namespace) @@ -179,7 +185,7 @@ method_stats (MonoMethod *method) { MonoMethodHeader *header; MonoMethodSignature *sig; const unsigned char *ip, *il_code_end; - int i, n; + guint32 i, n; int local_branch = 0, local_condbranch = 0, local_throw = 0, local_calls = 0; gint64 l; @@ -504,6 +510,39 @@ stats (MonoImage *image, const char *name) { } } +static void +type_size_stats (MonoClass *klass) +{ + int code_size = 0; + MonoMethod *method; + MonoMethodHeader *header; + gpointer iter; + + iter = NULL; + while ((method = mono_class_get_methods (klass, &iter))) { + guint32 size, maxs; + header = mono_method_get_header (method); + if (!header) + continue; + mono_method_header_get_code (header, &size, &maxs); + code_size += size; + } + g_print ("%s.%s: code: %d\n", klass->name_space, klass->name, code_size); +} + +static void +size_stats (MonoImage *image, const char *name) { + int i, num_types; + MonoClass *klass; + + num_types = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF); + for (i = 0; i < num_types; ++i) { + klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | (i + 1)); + type_size_stats (klass); + } +} + + static char * get_signature (MonoMethod *method) { GString *res; @@ -517,9 +556,9 @@ get_signature (MonoMethod *method) { res = g_string_new (""); if (include_namespace && *(method->klass->name_space)) - g_string_sprintfa (res, "%s.", method->klass->name_space); + g_string_append_printf (res, "%s.", method->klass->name_space); result = mono_signature_get_desc (mono_method_signature (method), include_namespace); - g_string_sprintfa (res, "%s:%s(%s)", method->klass->name, method->name, result); + g_string_append_printf (res, "%s:%s(%s)", method->klass->name, method->name, result); g_free (result); g_hash_table_insert (hash, method, res->str); @@ -553,7 +592,7 @@ print_method (MonoMethod *method, int depth) { GHashTable *hash; static GHashTable *visited = NULL; const unsigned char *ip, *il_code_end; - int i; + guint32 i; if (depth++ > max_depth) return; @@ -712,7 +751,7 @@ mono_method_find_bblocks (MonoMethodHeader *header) { const unsigned char *ip, *end, *start; const MonoOpcode *opcode; - int i, block_end = 0; + guint32 i, block_end = 0; GPtrArray *result = g_ptr_array_new (); GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal); MonoBasicBlock *entry_bb, *end_bb, *bb, *target; @@ -837,7 +876,7 @@ mono_method_find_bblocks (MonoMethodHeader *header) ip += 4; if (!(target = g_hash_table_lookup (table, itarget))) { target = g_new0 (MonoBasicBlock, 1); - target->cil_code = itarget; + target->cil_code = (const guchar*)itarget; g_ptr_array_add (result, target); g_hash_table_insert (table, (gpointer) itarget, target); } @@ -901,9 +940,9 @@ df_visit (MonoBasicBlock *bb, int *dfn, const unsigned char* code) next = tmp->data; if (!next->dfn) { if (!bb->cil_code) - fprintf (output, "\t\"DF entry\" -> \"IL_%04x (%d)\"\n", next->cil_code - code, *dfn + 1); + fprintf (output, "\t\"DF entry\" -> \"IL_%04x (%d)\"\n", (unsigned int)(next->cil_code - code), *dfn + 1); else - fprintf (output, "\t\"IL_%04x (%d)\" -> \"IL_%04x (%d)\"\n", bb->cil_code - code, bb->dfn, next->cil_code - code, *dfn + 1); + fprintf (output, "\t\"IL_%04x (%d)\" -> \"IL_%04x (%d)\"\n", (unsigned int)(bb->cil_code - code), bb->dfn, (unsigned int)(next->cil_code - code), *dfn + 1); df_visit (next, dfn, code); } } @@ -930,7 +969,7 @@ print_method_cfg (MonoMethod *method) { fprintf (output, "\tB%p [shape=record,label=\"end\"]\n", bb); else { code = mono_disasm_code (&graph_dh, method, bb->cil_code, bb->cil_code + bb->cil_length); - fprintf (output, "\tB%p [shape=record,label=\"IL_%04x\\n%s\"]\n", bb, bb->cil_code - il_code, code); + fprintf (output, "\tB%p [shape=record,label=\"IL_%04x\\n%s\"]\n", bb, (unsigned int)(bb->cil_code - il_code), code); g_free (code); } } @@ -1000,6 +1039,7 @@ usage (void) { printf ("\t-c|--call output call graph instead of type hierarchy\n"); printf ("\t-C|--control-flow output control flow of methodname\n"); printf ("\t--stats output some statistics about the assembly\n"); + printf ("\t--size output some size statistics about the assembly\n"); printf ("\t-d|--depth num max depth recursion (default: 6)\n"); printf ("\t-o|--output filename write graph to file filename (default: stdout)\n"); printf ("\t-f|--fullname include namespace in type and method names\n"); @@ -1025,6 +1065,7 @@ enum { GRAPH_CALL, GRAPH_INTERFACE, GRAPH_CONTROL_FLOW, + GRAPH_SIZE_STATS, GRAPH_STATS }; @@ -1066,6 +1107,8 @@ main (int argc, char *argv[]) { graphtype = GRAPH_INTERFACE; } else if (strcmp (argv [i], "--stats") == 0) { graphtype = GRAPH_STATS; + } else if (strcmp (argv [i], "--size") == 0) { + graphtype = GRAPH_SIZE_STATS; } else if (strcmp (argv [i], "--fullname") == 0 || strcmp (argv [i], "-f") == 0) { include_namespace = 1; } else if (strcmp (argv [i], "--neato") == 0 || strcmp (argv [i], "-n") == 0) { @@ -1110,10 +1153,10 @@ main (int argc, char *argv[]) { if (outputfile) { type = strrchr (outputfile, '.'); - g_string_sprintfa (command, " -o %s", outputfile); + g_string_append_printf (command, " -o %s", outputfile); } if (type) - g_string_sprintfa (command, " -T%s", type + 1); + g_string_append_printf (command, " -T%s", type + 1); output = popen (command->str, "w"); if (!output) { g_print ("Cannot run neato: you may need to install the graphviz package.\n"); @@ -1147,6 +1190,9 @@ main (int argc, char *argv[]) { case GRAPH_STATS: stats (image, cname); break; + case GRAPH_SIZE_STATS: + size_stats (image, cname); + break; default: g_error ("wrong graph type"); } @@ -1159,5 +1205,3 @@ main (int argc, char *argv[]) { fclose (output); return 0; } - -