Merge pull request #1412 from esdrubal/stackframe
[mono.git] / mono / mini / mini.c
index b642073e91ff5d3f86b0febabd82fbe90d58a08f..f876ce3ea5c5e30c9eff8506e15d0c87eca36806 100755 (executable)
@@ -64,6 +64,7 @@
 #include <mono/utils/mono-threads.h>
 
 #include "mini.h"
+#include "seq-points.h"
 #include "mini-llvm.h"
 #include "tasklets.h"
 #include <string.h>
@@ -76,6 +77,7 @@
 
 #include "mini-gc.h"
 #include "debugger-agent.h"
+#include "seq-points.h"
 
 static gpointer mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex);
 
@@ -3921,159 +3923,6 @@ mono_postprocess_patches (MonoCompile *cfg)
        }
 }
 
-static void
-collect_pred_seq_points (MonoBasicBlock *bb, MonoInst *ins, GSList **next, int depth)
-{
-       int i;
-       MonoBasicBlock *in_bb;
-       GSList *l;
-
-       for (i = 0; i < bb->in_count; ++i) {
-               in_bb = bb->in_bb [i];
-
-               if (in_bb->last_seq_point) {
-                       int src_index = in_bb->last_seq_point->backend.size;
-                       int dst_index = ins->backend.size;
-
-                       /* bb->in_bb might contain duplicates */
-                       for (l = next [src_index]; l; l = l->next)
-                               if (GPOINTER_TO_UINT (l->data) == dst_index)
-                                       break;
-                       if (!l)
-                               next [src_index] = g_slist_append (next [src_index], GUINT_TO_POINTER (dst_index));
-               } else {
-                       /* Have to look at its predecessors */
-                       if (depth < 5)
-                               collect_pred_seq_points (in_bb, ins, next, depth + 1);
-               }
-       }
-}
-
-static void
-mono_save_seq_point_info (MonoCompile *cfg)
-{
-       MonoBasicBlock *bb;
-       GSList *bb_seq_points, *l;
-       MonoInst *last;
-       MonoDomain *domain = cfg->domain;
-       int i;
-       MonoSeqPointInfo *info;
-       GSList **next;
-
-       if (!cfg->seq_points)
-               return;
-
-       info = g_malloc0 (sizeof (MonoSeqPointInfo) + (cfg->seq_points->len * sizeof (SeqPoint)));
-       info->len = cfg->seq_points->len;
-       for (i = 0; i < cfg->seq_points->len; ++i) {
-               SeqPoint *sp = &info->seq_points [i];
-               MonoInst *ins = g_ptr_array_index (cfg->seq_points, i);
-
-               sp->il_offset = ins->inst_imm;
-               sp->native_offset = ins->inst_offset;
-               if (ins->flags & MONO_INST_NONEMPTY_STACK)
-                       sp->flags |= MONO_SEQ_POINT_FLAG_NONEMPTY_STACK;
-
-               /* Used below */
-               ins->backend.size = i;
-       }
-
-       /*
-        * For each sequence point, compute the list of sequence points immediately
-        * following it, this is needed to implement 'step over' in the debugger agent.
-        */ 
-       next = g_new0 (GSList*, cfg->seq_points->len);
-       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
-               bb_seq_points = g_slist_reverse (bb->seq_points);
-               last = NULL;
-               for (l = bb_seq_points; l; l = l->next) {
-                       MonoInst *ins = l->data;
-
-                       if (ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET)
-                               /* Used to implement method entry/exit events */
-                               continue;
-                       if (ins->inst_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE)
-                               continue;
-
-                       if (last != NULL) {
-                               /* Link with the previous seq point in the same bb */
-                               next [last->backend.size] = g_slist_append (next [last->backend.size], GUINT_TO_POINTER (ins->backend.size));
-                       } else {
-                               /* Link with the last bb in the previous bblocks */
-                               collect_pred_seq_points (bb, ins, next, 0);
-                       }
-
-                       last = ins;
-               }
-
-               if (bb->last_ins && bb->last_ins->opcode == OP_ENDFINALLY && bb->seq_points) {
-                       MonoBasicBlock *bb2;
-                       MonoInst *endfinally_seq_point = NULL;
-
-                       /*
-                        * The ENDFINALLY branches are not represented in the cfg, so link it with all seq points starting bbs.
-                        */
-                       l = g_slist_last (bb->seq_points);
-                       if (l) {
-                               endfinally_seq_point = l->data;
-
-                               for (bb2 = cfg->bb_entry; bb2; bb2 = bb2->next_bb) {
-                                       GSList *l = g_slist_last (bb2->seq_points);
-
-                                       if (l) {
-                                               MonoInst *ins = l->data;
-
-                                               if (!(ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET) && ins != endfinally_seq_point)
-                                                       next [endfinally_seq_point->backend.size] = g_slist_append (next [endfinally_seq_point->backend.size], GUINT_TO_POINTER (ins->backend.size));
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (cfg->verbose_level > 2) {
-               printf ("\nSEQ POINT MAP: \n");
-       }
-
-       for (i = 0; i < cfg->seq_points->len; ++i) {
-               SeqPoint *sp = &info->seq_points [i];
-               GSList *l;
-               int j, next_index;
-
-               sp->next_len = g_slist_length (next [i]);
-               sp->next = g_new (int, sp->next_len);
-               j = 0;
-               if (cfg->verbose_level > 2 && next [i]) {
-                       printf ("\tIL0x%x ->", sp->il_offset);
-                       for (l = next [i]; l; l = l->next) {
-                               next_index = GPOINTER_TO_UINT (l->data);
-                               printf (" IL0x%x", info->seq_points [next_index].il_offset);
-                       }
-                       printf ("\n");
-               }
-               for (l = next [i]; l; l = l->next) {
-                       next_index = GPOINTER_TO_UINT (l->data);
-                       sp->next [j ++] = next_index;
-               }
-               g_slist_free (next [i]);
-       }
-       g_free (next);
-
-       cfg->seq_point_info = info;
-
-       // FIXME: dynamic methods
-       if (!cfg->compile_aot) {
-               mono_domain_lock (domain);
-               // FIXME: How can the lookup succeed ?
-               if (!g_hash_table_lookup (domain_jit_info (domain)->seq_points, cfg->method_to_register))
-                       g_hash_table_insert (domain_jit_info (domain)->seq_points, cfg->method_to_register, info);
-               mono_domain_unlock (domain);
-       }
-
-       g_ptr_array_free (cfg->seq_points, TRUE);
-       cfg->seq_points = NULL;
-}
-
 void
 mono_codegen (MonoCompile *cfg)
 {
@@ -5001,7 +4850,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        cfg->full_aot = full_aot;
        cfg->skip_visibility = method->skip_visibility;
        cfg->orig_method = method;
-       cfg->gen_seq_points = debug_options.gen_seq_points;
+       cfg->gen_seq_points = TRUE;
+       cfg->gen_seq_points_debug_data = debug_options.gen_seq_points_debug_data;
+
        cfg->explicit_null_checks = debug_options.explicit_null_checks;
        cfg->soft_breakpoints = debug_options.soft_breakpoints;
        cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv;
@@ -7064,7 +6915,7 @@ mini_parse_debug_options (void)
                else if (!strcmp (arg, "explicit-null-checks"))
                        debug_options.explicit_null_checks = TRUE;
                else if (!strcmp (arg, "gen-seq-points"))
-                       debug_options.gen_seq_points = TRUE;
+                       debug_options.gen_seq_points_debug_data = TRUE;
                else if (!strcmp (arg, "init-stacks"))
                        debug_options.init_stacks = TRUE;
                else if (!strcmp (arg, "casts"))
@@ -7142,6 +6993,7 @@ register_jit_stats (void)
        mono_counters_register ("Allocated vars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocate_var);
        mono_counters_register ("Code reallocs", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.code_reallocs);
        mono_counters_register ("Allocated code size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_code_size);
+       mono_counters_register ("Allocated seq points size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_seq_points_size);
        mono_counters_register ("Inlineable methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlineable_methods);
        mono_counters_register ("Inlined methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlined_methods);
        mono_counters_register ("Regvars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.regvars);
@@ -7156,7 +7008,6 @@ register_jit_stats (void)
 }
 
 static void runtime_invoke_info_free (gpointer value);
-static void seq_point_info_free (gpointer value);
 
 static gint
 class_method_pair_equal (gconstpointer ka, gconstpointer kb)
@@ -7227,19 +7078,6 @@ runtime_invoke_info_free (gpointer value)
        g_free (info);
 }
 
-static void seq_point_info_free (gpointer value)
-{
-       int i = 0;
-       MonoSeqPointInfo* info = (MonoSeqPointInfo*)value;
-       
-       for (i = 0; i < info->len; ++i) {
-               SeqPoint *sp = &info->seq_points [i];
-               g_free (sp->next);
-       }
-
-       g_free (info);
-}
-
 static void
 mini_free_jit_domain_info (MonoDomain *domain)
 {