Merge pull request #1412 from esdrubal/stackframe
authorZoltan Varga <vargaz@gmail.com>
Sun, 30 Nov 2014 14:11:03 +0000 (15:11 +0100)
committerZoltan Varga <vargaz@gmail.com>
Sun, 30 Nov 2014 14:11:03 +0000 (15:11 +0100)
Release sequence points and Symbolicate tool

14 files changed:
1  2 
mono/metadata/object-internals.h
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/cpu-ppc64.md
mono/mini/debugger-agent.c
mono/mini/ir-emit.h
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-arm.c
mono/mini/mini-mips.c
mono/mini/mini-ppc.c
mono/mini/mini-x86.c
mono/mini/mini.c
mono/mini/mini.h

index 0e24c963d0c84b0bf5110eb3c89bf04b0db10299,47e36e2d494aa12776453c530a1c4fd3c681d0b5..11bb021a36f609702de4cd6d494c7017b22ed56d
@@@ -380,6 -380,7 +380,7 @@@ typedef struct 
        MonoObject obj;
        gint32 il_offset;
        gint32 native_offset;
+       gint64 method_address;
        MonoReflectionMethod *method;
        MonoString *filename;
        gint32 line;
@@@ -1415,7 -1416,7 +1416,7 @@@ void        mono_reflection_create_unma
  void        mono_reflection_register_with_runtime (MonoReflectionType *type) MONO_INTERNAL;
  
  void        mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error) MONO_INTERNAL;
 -MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token) MONO_INTERNAL;
 +MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error) MONO_INTERNAL;
  
  MonoArray* mono_param_get_objects_internal  (MonoDomain *domain, MonoMethod *method, MonoClass *refclass) MONO_INTERNAL;
  
diff --combined mono/mini/aot-compiler.c
index bc9c01f401fc9f688c25190250d77ad4a934f8cd,938f8fc9a682984e438ba276abc878efb73bb9c7..283489f8d26dfafe23fa4ea3e3ba2906b7d57486
@@@ -52,6 -52,7 +52,7 @@@
  #include <mono/utils/mono-mmap.h>
  
  #include "mini.h"
+ #include "seq-points.h"
  #include "image-writer.h"
  #include "dwarfwriter.h"
  #include "mini-gc.h"
  #define TV_GETTIME(tv) tv = mono_100ns_ticks ()
  #define TV_ELAPSED(start,end) (((end) - (start)) / 10)
  
 -#ifdef TARGET_WIN32
 -#define SHARED_EXT ".dll"
 -#elif defined(__ppc__) && defined(TARGET_MACH)
 -#define SHARED_EXT ".dylib"
 -#elif defined(TARGET_MACH) && defined(TARGET_X86) && !defined(__native_client_codegen__)
 -#define SHARED_EXT ".dylib"
 -#elif defined(TARGET_MACH) && defined(TARGET_AMD64) && !defined(__native_client_codegen__)
 -#define SHARED_EXT ".dylib"
 -#else
 -#define SHARED_EXT ".so"
 -#endif
 -
  #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
  #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
  #define ROUND_DOWN(VALUE,SIZE)        ((VALUE) & ~((SIZE) - 1))
@@@ -1922,14 -1935,14 +1923,14 @@@ arch_emit_imt_thunk (MonoAotCompile *ac
        code = buf;
  
        /* Load the mscorlib got address */
 -      ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r30);
 +      ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r30);
        /* Load the parameter from the GOT */
        ppc_load (code, ppc_r0, offset * sizeof (gpointer));
 -      ppc_ldptr_indexed (code, ppc_r11, ppc_r11, ppc_r0);
 +      ppc_ldptr_indexed (code, ppc_r12, ppc_r12, ppc_r0);
  
        /* Load and check key */
        labels [1] = code;
 -      ppc_ldptr (code, ppc_r0, 0, ppc_r11);
 +      ppc_ldptr (code, ppc_r0, 0, ppc_r12);
        ppc_cmp (code, 0, sizeof (gpointer) == 8 ? 1 : 0, ppc_r0, MONO_ARCH_IMT_REG);
        labels [2] = code;
        ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0);
        ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0);
  
        /* Loop footer */
 -      ppc_addi (code, ppc_r11, ppc_r11, 2 * sizeof (gpointer));
 +      ppc_addi (code, ppc_r12, ppc_r12, 2 * sizeof (gpointer));
        labels [4] = code;
        ppc_b (code, 0);
        mono_ppc_patch (labels [4], labels [1]);
  
        /* Match */
        mono_ppc_patch (labels [2], code);
 -      ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r11);
 -      /* r11 now contains the value of the vtable slot */
 +      ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r12);
 +      /* r12 now contains the value of the vtable slot */
        /* this is not a function descriptor on ppc64 */
 -      ppc_ldptr (code, ppc_r11, 0, ppc_r11);
 -      ppc_mtctr (code, ppc_r11);
 +      ppc_ldptr (code, ppc_r12, 0, ppc_r12);
 +      ppc_mtctr (code, ppc_r12);
        ppc_bcctr (code, PPC_BR_ALWAYS, 0);
  
        /* Fail */
@@@ -5322,7 -5335,7 +5323,7 @@@ emit_exception_debug_info (MonoAotCompi
  {
        MonoMethod *method;
        int i, k, buf_size, method_index;
-       guint32 debug_info_size;
+       guint32 debug_info_size, seq_points_size;
        guint8 *code;
        MonoMethodHeader *header;
        guint8 *p, *buf, *debug_info;
  
        seq_points = cfg->seq_point_info;
  
-       buf_size = header->num_clauses * 256 + debug_info_size + 2048 + (seq_points ? (seq_points->len * 128) : 0) + cfg->gc_map_size;
+       seq_points_size = seq_point_info_get_write_size (seq_points);
+       buf_size = header->num_clauses * 256 + debug_info_size + 2048 + seq_points_size + cfg->gc_map_size;
        p = buf = g_malloc (buf_size);
  
        use_unwind_ops = cfg->unwind_ops != NULL;
                encode_value (table->num_holes, p, &p);
        }
  
 +      if (jinfo->has_arch_eh_info) {
 +              /*
 +               * In AOT mode, the code length is calculated from the address of the previous method,
 +               * which could include alignment padding, so calculating the start of the epilog as
 +               * code_len - epilog_size is correct any more. Save the real code len as a workaround.
 +               */
 +              encode_value (jinfo->code_size, p, &p);
 +      }
 +
        /* Exception table */
        if (cfg->compile_llvm) {
                /*
                }
        }
  
-       if (seq_points) {
-               int il_offset, native_offset, last_il_offset, last_native_offset, j;
-               encode_value (seq_points->len, p, &p);
-               last_il_offset = last_native_offset = 0;
-               for (i = 0; i < seq_points->len; ++i) {
-                       SeqPoint *sp = &seq_points->seq_points [i];
-                       il_offset = sp->il_offset;
-                       native_offset = sp->native_offset;
-                       encode_value (il_offset - last_il_offset, p, &p);
-                       encode_value (native_offset - last_native_offset, p, &p);
-                       last_il_offset = il_offset;
-                       last_native_offset = native_offset;
+       if (seq_points)
+               p += seq_point_info_write (seq_points, p);
  
-                       encode_value (sp->flags, p, &p);
-                       encode_value (sp->next_len, p, &p);
-                       for (j = 0; j < sp->next_len; ++j)
-                               encode_value (sp->next [j], p, &p);
-               }
-       }
-               
        g_assert (debug_info_size < buf_size);
  
        encode_value (debug_info_size, p, &p);
@@@ -8638,7 -8626,7 +8623,7 @@@ compile_asm (MonoAotCompile *acfg
        if (acfg->aot_opts.outfile)
                outfile_name = g_strdup_printf ("%s", acfg->aot_opts.outfile);
        else
 -              outfile_name = g_strdup_printf ("%s%s", acfg->image->name, SHARED_EXT);
 +              outfile_name = g_strdup_printf ("%s%s", acfg->image->name, MONO_SOLIB_EXT);
  
        tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
  
  
        g_free (command);
  
 -      /*com = g_strdup_printf ("strip --strip-unneeded %s%s", acfg->image->name, SHARED_EXT);
 +      /*com = g_strdup_printf ("strip --strip-unneeded %s%s", acfg->image->name, MONO_SOLIB_EXT);
        printf ("Stripping the binary: %s\n", com);
        system (com);
        g_free (com);*/
@@@ -8855,7 -8843,7 +8840,7 @@@ mono_compile_assembly (MonoAssembly *as
                MonoDebugOptions *opt = mini_get_debug_options ();
  
                opt->mdb_optimizations = TRUE;
-               opt->gen_seq_points = TRUE;
+               opt->gen_seq_points_debug_data = TRUE;
  
                if (!mono_debug_enabled ()) {
                        aot_printerrf (acfg, "The soft-debug AOT option requires the --debug option.\n");
                if (acfg->aot_opts.outfile)
                        outfile_name = g_strdup_printf ("%s", acfg->aot_opts.outfile);
                else
 -                      outfile_name = g_strdup_printf ("%s%s", acfg->image->name, SHARED_EXT);
 +                      outfile_name = g_strdup_printf ("%s%s", acfg->image->name, MONO_SOLIB_EXT);
  
                /* 
                 * Can't use g_file_open_tmp () as it will be deleted at exit, and
diff --combined mono/mini/aot-runtime.c
index 757b730e655ab0cc3c9f95dfa3d87eda897f3d77,856819c3936db84740a6f3d0deb9f152621a0ed1..7158952a2ec6ca57bf03dc33978d6a317ef18b30
@@@ -58,6 -58,7 +58,7 @@@
  #include <mono/utils/mono-digest.h>
  
  #include "mini.h"
+ #include "seq-points.h"
  #include "version.h"
  
  #ifndef DISABLE_AOT
  #define ENABLE_AOT_CACHE
  #endif
  
 -#ifdef TARGET_WIN32
 -#define SHARED_EXT ".dll"
 -#elif ((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) || defined(__MACH__)) && !defined(__linux__)
 -#define SHARED_EXT ".dylib"
 -#elif defined(__APPLE__) && defined(TARGET_X86) && !defined(__native_client_codegen__)
 -#define SHARED_EXT ".dylib"
 -#else
 -#define SHARED_EXT ".so"
 -#endif
 -
  #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
  #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
  #define ROUND_DOWN(VALUE,SIZE)        ((VALUE) & ~((SIZE) - 1))
@@@ -1434,7 -1445,7 +1435,7 @@@ aot_cache_load_module (MonoAssembly *as
         */
        hash = get_aot_config_hash (assembly);
  
 -      tmp2 = g_strdup_printf ("%s-%s%s", assembly->image->assembly_name, hash, SHARED_EXT);
 +      tmp2 = g_strdup_printf ("%s-%s%s", assembly->image->assembly_name, hash, MONO_SOLIB_EXT);
        fname = g_build_filename (cache_dir, tmp2, NULL);
        *aot_name = fname;
        g_free (tmp2);
@@@ -1762,21 -1773,13 +1763,21 @@@ load_aot_module (MonoAssembly *assembly
                        sofile = aot_cache_load_module (assembly, &aot_name);
                if (!sofile) {
                        char *err;
 -                      aot_name = g_strdup_printf ("%s%s", assembly->image->name, SHARED_EXT);
 +                      aot_name = g_strdup_printf ("%s%s", assembly->image->name, MONO_SOLIB_EXT);
  
                        sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
  
                        if (!sofile) {
                                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
                                g_free (err);
 +
 +                              aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), ARCHITECTURE, g_path_get_basename (assembly->image->name), MONO_SOLIB_EXT);
 +                              sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
 +                              if (!sofile) {
 +                                      mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
 +                                      g_free (err);
 +                              }
 +
                        }
                }
        }
@@@ -2583,22 -2586,18 +2584,22 @@@ decode_exception_debug_info (MonoAotMod
        } else {
                num_holes = try_holes_info_size = 0;
        }
 -      /* Exception table */
 -      if (has_clauses)
 -              num_clauses = decode_value (p, &p);
 -      else
 -              num_clauses = 0;
 +
        if (has_arch_eh_jit_info) {
                flags |= JIT_INFO_HAS_ARCH_EH_INFO;
                arch_eh_jit_info_size = sizeof (MonoArchEHJitInfo);
 +              /* Overwrite the original code_len which includes alignment padding */
 +              code_len = decode_value (p, &p);
        } else {
                arch_eh_jit_info_size = 0;
        }
  
 +      /* Exception table */
 +      if (has_clauses)
 +              num_clauses = decode_value (p, &p);
 +      else
 +              num_clauses = 0;
 +
        if (from_llvm) {
                MonoJitExceptionInfo *clauses;
                GSList **nesting;
  
        if (method && has_seq_points) {
                MonoSeqPointInfo *seq_points;
-               int il_offset, native_offset, last_il_offset, last_native_offset, j;
  
-               int len = decode_value (p, &p);
-               seq_points = g_malloc0 (sizeof (MonoSeqPointInfo) + (len - MONO_ZERO_LEN_ARRAY) * sizeof (SeqPoint));
-               seq_points->len = len;
-               last_il_offset = last_native_offset = 0;
-               for (i = 0; i < len; ++i) {
-                       SeqPoint *sp = &seq_points->seq_points [i];
-                       il_offset = last_il_offset + decode_value (p, &p);
-                       native_offset = last_native_offset + decode_value (p, &p);
-                       sp->il_offset = il_offset;
-                       sp->native_offset = native_offset;
-                       
-                       sp->flags = decode_value (p, &p);
-                       sp->next_len = decode_value (p, &p);
-                       sp->next = g_new (int, sp->next_len);
-                       for (j = 0; j < sp->next_len; ++j)
-                               sp->next [j] = decode_value (p, &p);
-                       last_il_offset = il_offset;
-                       last_native_offset = native_offset;
-               }
+               p += seq_point_info_read (&seq_points, p, FALSE);
  
                mono_domain_lock (domain);
                g_hash_table_insert (domain_jit_info (domain)->seq_points, method, seq_points);
diff --combined mono/mini/cpu-ppc64.md
index c47c6e25b7b969d0dea0b177efa20c711a780e8a,1f5234a7670e5df800a24c6f4daa8e32c121aa36..dc6ac728ab435698dd1566cfae5513e96c9f5a36
@@@ -50,6 -50,7 +50,7 @@@ nop: len:
  relaxed_nop: len:4
  break: len:40
  seq_point: len:48
+ il_seq_point: len:0
  jmp: len:96
  call: dest:a clob:c len:36
  br: len:4
@@@ -380,7 -381,7 +381,7 @@@ vcall2_membase: src1:b len:16 clob:
  
  jump_table: dest:i len:20
  
 -atomic_add_i4: src1:b src2:i dest:i len:20
 -atomic_add_i8: src1:b src2:i dest:i len:20
 +atomic_add_i4: src1:b src2:i dest:i len:28
 +atomic_add_i8: src1:b src2:i dest:i len:28
  atomic_cas_i4: src1:b src2:i src3:i dest:i len:38
  atomic_cas_i8: src1:b src2:i src3:i dest:i len:38
index e2467da18f04e8e16a433d2134aca0c926838597,e5ca36c2692032ce17622883e734f6c053003c11..240f8419a4532cb81c55751c5b4f9965a4f7ac98
@@@ -84,6 -84,7 +84,7 @@@ int WSAAPI getnameinfo(const struct soc
  #include <mono/utils/mono-threads.h>
  #include "debugger-agent.h"
  #include "mini.h"
+ #include "seq-points.h"
  
  /*
  On iOS we can't use System.Environment.Exit () as it will do the wrong
@@@ -289,7 -290,7 +290,7 @@@ typedef struct 
  #define HEADER_LENGTH 11
  
  #define MAJOR_VERSION 2
 -#define MINOR_VERSION 37
 +#define MINOR_VERSION 38
  
  typedef enum {
        CMD_SET_VM = 1,
@@@ -514,8 -515,7 +515,8 @@@ typedef enum 
  typedef enum {
        CMD_STACK_FRAME_GET_VALUES = 1,
        CMD_STACK_FRAME_GET_THIS = 2,
 -      CMD_STACK_FRAME_SET_VALUES = 3
 +      CMD_STACK_FRAME_SET_VALUES = 3,
 +      CMD_STACK_FRAME_GET_DOMAIN = 4,
  } CmdStackFrame;
  
  typedef enum {
@@@ -816,12 -816,6 +817,12 @@@ static voi
  register_socket_transport (void);
  #endif
  
 +static inline gboolean
 +is_debugger_thread (void)
 +{
 +      return GetCurrentThreadId () == debugger_thread_id;
 +}
 +
  static int
  parse_address (char *address, char **host, int *port)
  {
@@@ -995,9 -989,6 +996,9 @@@ mono_debugger_agent_init (void
  
        mono_native_tls_alloc (&debugger_tls_id, NULL);
  
 +      /* Needed by the hash_table_new_type () call below */
 +      mono_gc_base_init ();
 +
        thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
        MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls);
  
        breakpoints_init ();
        suspend_init ();
  
-       mini_get_debug_options ()->gen_seq_points = TRUE;
+       mini_get_debug_options ()->gen_seq_points_debug_data = TRUE;
        /* 
         * This is needed because currently we don't handle liveness info.
         */
@@@ -3145,24 -3136,6 +3146,6 @@@ is_suspended (void
        return count_threads_to_wait_for () == 0;
  }
  
- static MonoSeqPointInfo*
- get_seq_points (MonoDomain *domain, MonoMethod *method)
- {
-       MonoSeqPointInfo *seq_points;
-       mono_domain_lock (domain);
-       seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, method);
-       if (!seq_points && method->is_inflated) {
-               /* generic sharing + aot */
-               seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, mono_method_get_declaring_generic_method (method));
-               if (!seq_points)
-                       seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, mini_get_shared_method (method));
-       }
-       mono_domain_unlock (domain);
-       return seq_points;
- }
  static void
  no_seq_points_found (MonoMethod *method)
  {
        printf ("Unable to find seq points for method '%s'.\n", mono_method_full_name (method, TRUE));
  }
  
- /*
-  * find_next_seq_point_for_native_offset:
-  *
-  *   Find the first sequence point after NATIVE_OFFSET.
-  */
- static SeqPoint*
- find_next_seq_point_for_native_offset (MonoDomain *domain, MonoMethod *method, gint32 native_offset, MonoSeqPointInfo **info)
- {
-       MonoSeqPointInfo *seq_points;
-       int i;
-       seq_points = get_seq_points (domain, method);
-       if (!seq_points) {
-               if (info)
-                       *info = NULL;
-               return NULL;
-       }
-       g_assert (seq_points);
-       if (info)
-               *info = seq_points;
-       for (i = 0; i < seq_points->len; ++i) {
-               if (seq_points->seq_points [i].native_offset >= native_offset)
-                       return &seq_points->seq_points [i];
-       }
-       return NULL;
- }
- /*
-  * find_prev_seq_point_for_native_offset:
-  *
-  *   Find the first sequence point before NATIVE_OFFSET.
-  */
- static SeqPoint*
- find_prev_seq_point_for_native_offset (MonoDomain *domain, MonoMethod *method, gint32 native_offset, MonoSeqPointInfo **info)
- {
-       MonoSeqPointInfo *seq_points;
-       int i;
-       seq_points = get_seq_points (domain, method);
-       if (info)
-               *info = seq_points;
-       if (!seq_points)
-               return NULL;
-       for (i = seq_points->len - 1; i >= 0; --i) {
-               if (seq_points->seq_points [i].native_offset <= native_offset)
-                       return &seq_points->seq_points [i];
-       }
-       return NULL;
- }
- /*
-  * find_seq_point:
-  *
-  *   Find the sequence point corresponding to the IL offset IL_OFFSET, which
-  * should be the location of a sequence point.
-  */
- static G_GNUC_UNUSED SeqPoint*
- find_seq_point (MonoDomain *domain, MonoMethod *method, gint32 il_offset, MonoSeqPointInfo **info)
- {
-       MonoSeqPointInfo *seq_points;
-       int i;
-       *info = NULL;
-       seq_points = get_seq_points (domain, method);
-       if (!seq_points)
-               return NULL;
-       *info = seq_points;
-       for (i = 0; i < seq_points->len; ++i) {
-               if (seq_points->seq_points [i].il_offset == il_offset)
-                       return &seq_points->seq_points [i];
-       }
-       return NULL;
- }
  typedef struct {
        DebuggerTlsData *tls;
        GSList *frames;
@@@ -3264,7 -3156,7 +3166,7 @@@ process_frame (StackFrameInfo *info, Mo
        ComputeFramesUserData *ud = user_data;
        StackFrame *frame;
        MonoMethod *method, *actual_method, *api_method;
-       SeqPoint *sp;
+       SeqPoint sp;
        int flags = 0;
  
        if (info->type != FRAME_TYPE_MANAGED) {
        if (info->il_offset == -1) {
                /* mono_debug_il_offset_from_address () doesn't seem to be precise enough (#2092) */
                if (ud->frames == NULL) {
-                       sp = find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL);
-                       if (sp)
-                               info->il_offset = sp->il_offset;
+                       if (find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL, &sp))
+                               info->il_offset = sp.il_offset;
                }
                if (info->il_offset == -1)
                        info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset);
@@@ -4080,10 -3971,6 +3981,10 @@@ appdomain_start_unload (MonoProfiler *p
  {
        DebuggerTlsData *tls;
  
 +      /* This might be called during shutdown on the debugger thread from the CMD_VM_EXIT code */
 +      if (is_debugger_thread ())
 +              return;
 +
        /*
         * Remember the currently unloading appdomain as it is needed to generate
         * proper ids for unloading assemblies.
@@@ -4098,9 -3985,6 +3999,9 @@@ appdomain_unload (MonoProfiler *prof, M
  {
        DebuggerTlsData *tls;
  
 +      if (is_debugger_thread ())
 +              return;
 +
        tls = mono_native_tls_get_value (debugger_tls_id);
        g_assert (tls);
        tls->domain_unloading = NULL;
@@@ -4286,7 -4170,6 +4187,6 @@@ typedef struct 
        guint8 *ip;
        MonoJitInfo *ji;
        MonoDomain *domain;
-       SeqPoint *sp;
  } BreakpointInstance;
  
  /*
@@@ -4331,38 -4214,44 +4231,44 @@@ breakpoints_init (void
  static void
  insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo *ji, MonoBreakpoint *bp, MonoError *error)
  {
-       int i, count;
+       int count;
        BreakpointInstance *inst;
-       SeqPoint *sp = NULL;
+       SeqPointIterator it;
+       gboolean it_has_sp = FALSE;
  
        if (error)
                mono_error_init (error);
  
-       for (i = 0; i < seq_points->len; ++i) {
-               sp = &seq_points->seq_points [i];
-               if (sp->il_offset == bp->il_offset)
+       seq_point_iterator_init (&it, seq_points);
+       while (seq_point_iterator_next (&it)) {
+               if (it.seq_point.il_offset == bp->il_offset) {
+                       it_has_sp = TRUE;
                        break;
+               }
        }
  
-       if (i == seq_points->len) {
+       if (!it_has_sp) {
                /*
                 * The set of IL offsets with seq points doesn't completely match the
                 * info returned by CMD_METHOD_GET_DEBUG_INFO (#407).
                 */
-               for (i = 0; i < seq_points->len; ++i) {
-                       sp = &seq_points->seq_points [i];
-                       if (sp->il_offset != METHOD_ENTRY_IL_OFFSET && sp->il_offset != METHOD_EXIT_IL_OFFSET && sp->il_offset + 1 == bp->il_offset)
+               seq_point_iterator_init (&it, seq_points);
+               while (seq_point_iterator_next (&it)) {
+                       if (it.seq_point.il_offset != METHOD_ENTRY_IL_OFFSET &&
+                               it.seq_point.il_offset != METHOD_EXIT_IL_OFFSET &&
+                               it.seq_point.il_offset + 1 == bp->il_offset) {
+                               it_has_sp = TRUE;
                                break;
+                       }
                }
        }
  
-       if (i == seq_points->len) {
-               char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%d, seq_points=%d\n", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset, seq_points->len);
+       if (!it_has_sp) {
+               char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%d", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset);
  
-               for (i = 0; i < seq_points->len; ++i)
-                       DEBUG (1, fprintf (log_file, "%d\n", seq_points->seq_points [i].il_offset));
+               seq_point_iterator_init (&it, seq_points);
+               while (seq_point_iterator_next (&it))
+                       DEBUG (1, fprintf (log_file, "%d\n", it.seq_point.il_offset));
  
                if (error) {
                        mono_error_set_error (error, MONO_ERROR_GENERIC, "%s", s);
        }
  
        inst = g_new0 (BreakpointInstance, 1);
-       inst->sp = sp;
-       inst->native_offset = sp->native_offset;
-       inst->ip = (guint8*)ji->code_start + sp->native_offset;
+       inst->il_offset = it.seq_point.il_offset;
+       inst->native_offset = it.seq_point.native_offset;
+       inst->ip = (guint8*)ji->code_start + it.seq_point.native_offset;
        inst->ji = ji;
        inst->domain = domain;
  
        g_hash_table_insert (bp_locs, inst->ip, GINT_TO_POINTER (count + 1));
        dbg_unlock ();
  
-       if (sp->native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
+       if (it.seq_point.native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
                DEBUG (1, fprintf (log_file, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset));
        } else if (count == 0) {
  #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
  #endif
        }
  
-       DEBUG(1, fprintf (log_file, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)sp->il_offset, inst->ip, count));
+       DEBUG(1, fprintf (log_file, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, inst->ip, count));
  }
  
  static void
@@@ -4776,7 -4665,8 +4682,8 @@@ process_breakpoint_inner (DebuggerTlsDa
        MonoContext *ctx = &tls->restore_ctx;
        MonoMethod *method;
        MonoSeqPointInfo *info;
-       SeqPoint *sp;
+       SeqPoint sp;
+       gboolean found_sp;
  
        // FIXME: Speed this up
  
         * The ip points to the instruction causing the breakpoint event, which is after
         * the offset recorded in the seq point map, so find the prev seq point before ip.
         */
-       sp = find_prev_seq_point_for_native_offset (mono_domain_get (), method, native_offset, &info);
-       if (!sp)
+       found_sp = find_prev_seq_point_for_native_offset (mono_domain_get (), method, native_offset, &info, &sp);
+       if (!found_sp)
                no_seq_points_found (method);
-       g_assert (sp);
  
-       DEBUG(1, fprintf (log_file, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp ? sp->il_offset : -1));
+       g_assert (found_sp);
+       DEBUG(1, fprintf (log_file, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp.il_offset));
  
        bp = NULL;
        for (i = 0; i < breakpoints->len; ++i) {
  
                for (j = 0; j < bp->children->len; ++j) {
                        inst = g_ptr_array_index (bp->children, j);
-                       if (inst->ji == ji && inst->sp == sp) {
+                       if (inst->ji == ji && inst->il_offset == sp.il_offset && inst->native_offset == sp.native_offset) {
                                if (bp->req->event_kind == EVENT_KIND_STEP) {
                                        g_ptr_array_add (ss_reqs_orig, bp->req);
                                } else {
        }
        if (bp_reqs->len == 0 && ss_reqs_orig->len == 0) {
                /* Maybe a method entry/exit event */
-               if (sp->il_offset == METHOD_ENTRY_IL_OFFSET)
+               if (sp.il_offset == METHOD_ENTRY_IL_OFFSET)
                        kind = EVENT_KIND_METHOD_ENTRY;
-               else if (sp->il_offset == METHOD_EXIT_IL_OFFSET)
+               else if (sp.il_offset == METHOD_EXIT_IL_OFFSET)
                        kind = EVENT_KIND_METHOD_EXIT;
        }
  
                if (mono_thread_internal_current () != ss_req->thread)
                        continue;
  
-               hit = ss_update (ss_req, ji, sp, tls, ctx);
+               hit = ss_update (ss_req, ji, &sp, tls, ctx);
                if (hit)
                        g_ptr_array_add (ss_reqs, req);
  
                /* Start single stepping again from the current sequence point */
-               ss_start (ss_req, method, sp, info, ctx, tls, FALSE);
+               ss_start (ss_req, method, &sp, info, ctx, tls, FALSE);
        }
        
        if (ss_reqs->len > 0)
@@@ -5014,7 -4906,7 +4923,7 @@@ process_single_step_inner (DebuggerTlsD
        GSList *events;
        MonoContext *ctx = &tls->restore_ctx;
        MonoMethod *method;
-       SeqPoint *sp;
+       SeqPoint sp;
        MonoSeqPointInfo *info;
  
        ip = MONO_CONTEXT_GET_IP (ctx);
         * The ip points to the instruction causing the single step event, which is before
         * the offset recorded in the seq point map, so find the next seq point after ip.
         */
-       sp = find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info);
-       if (!sp)
+       if (!find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp))
                return;
-       il_offset = sp->il_offset;
  
-       if (!ss_update (ss_req, ji, sp, tls, ctx))
+       il_offset = sp.il_offset;
+       if (!ss_update (ss_req, ji, &sp, tls, ctx))
                return;
  
        /* Start single stepping again from the current sequence point */
-       ss_start (ss_req, method, sp, info, ctx, tls, FALSE);
+       ss_start (ss_req, method, &sp, info, ctx, tls, FALSE);
  
        if ((ss_req->filter & STEP_FILTER_STATIC_CTOR) &&
                (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
@@@ -5243,10 -5135,12 +5152,12 @@@ ss_stop (SingleStepReq *ss_req
   * belong to the same thread as CTX.
   */
  static void
- ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint *sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch)
+ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPointsp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch)
  {
        int i, j, frame_index;
        SeqPoint *next_sp;
+       SeqPoint local_sp;
+       gboolean found_sp;
        MonoBreakpoint *bp;
        gboolean enable_global = FALSE;
  
                                StackFrame *frame = tls->frames [frame_index];
  
                                method = frame->method;
-                               sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info);
+                               found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                               sp = (found_sp)? &local_sp : NULL;
                                frame_index ++;
                                if (sp && sp->next_len != 0)
                                        break;
                                        StackFrame *frame = tls->frames [frame_index];
  
                                        method = frame->method;
-                                       sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info);
+                                       found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                                       sp = (found_sp)? &local_sp : NULL;
                                        if (sp && sp->next_len != 0)
                                                break;
                                        sp = NULL;
                }
  
                if (sp && sp->next_len > 0) {
-                       for (i = 0; i < sp->next_len; ++i) {
-                               next_sp = &info->seq_points [sp->next [i]];
+                       SeqPoint* next = g_new(SeqPoint, sp->next_len);
+                       seq_point_init_next (info, *sp, next);
+                       for (i = 0; i < sp->next_len; i++) {
+                               next_sp = &next[i];
  
                                bp = set_breakpoint (method, next_sp->il_offset, ss_req->req, NULL);
                                ss_req->bps = g_slist_append (ss_req->bps, bp);
                        }
+                       g_free (next);
                }
  
                if (ss_req->depth == STEP_DEPTH_OVER) {
                                        for (j = 0; j < jinfo->num_clauses; ++j) {
                                                MonoJitExceptionInfo *ei = &jinfo->clauses [j];
  
-                                               sp = find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL);
+                                               found_sp = find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
+                                               sp = (found_sp)? &local_sp : NULL;
                                                if (sp) {
                                                        bp = set_breakpoint (frame->method, sp->il_offset, ss_req->req, NULL);
                                                        ss_req->bps = g_slist_append (ss_req->bps, bp);
@@@ -5369,6 -5270,8 +5287,8 @@@ ss_create (MonoInternalThread *thread, 
        DebuggerTlsData *tls;
        MonoSeqPointInfo *info = NULL;
        SeqPoint *sp = NULL;
+       SeqPoint local_sp;
+       gboolean found_sp;
        MonoMethod *method = NULL;
        MonoDebugMethodInfo *minfo;
        gboolean step_to_catch = FALSE;
                 * Find the seq point corresponding to the landing site ip, which is the first seq
                 * point after ip.
                 */
-               sp = find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info);
+               found_sp = find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info, &local_sp);
+               sp = (found_sp)? &local_sp : NULL;
                if (!sp)
                        no_seq_points_found (frame.method);
                g_assert (sp);
  
                        if (!method && frame->il_offset != -1) {
                                /* FIXME: Sort the table and use a binary search */
-                               sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info);
+                               found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
+                               sp = (found_sp)? &local_sp : NULL;
                                if (!sp)
                                        no_seq_points_found (frame->method);
                                g_assert (sp);
@@@ -8856,9 -8761,9 +8778,9 @@@ thread_commands (int command, guint8 *p
                MonoMethod *method;
                MonoDomain *domain;
                MonoSeqPointInfo *seq_points;
-               SeqPoint *sp = NULL;
+               SeqPoint sp;
+               gboolean found_sp;
                gint64 il_offset;
-               int i;
  
                method = decode_methodid (p, &p, end, &domain, &err);
                if (err)
                if (tls->frame_count == 0 || tls->frames [0]->actual_method != method)
                        return ERR_INVALID_ARGUMENT;
  
-               seq_points = get_seq_points (domain, method);
-               g_assert (seq_points);
+               found_sp = find_seq_point (domain, method, il_offset, &seq_points, &sp);
  
-               for (i = 0; i < seq_points->len; ++i) {
-                       sp = &seq_points->seq_points [i];
+               g_assert (seq_points);
  
-                       if (sp->il_offset == il_offset)
-                               break;
-               }
-               if (i == seq_points->len)
+               if (!found_sp)
                        return ERR_INVALID_ARGUMENT;
  
                // FIXME: Check that the ip change is safe
  
-               DEBUG (1, fprintf (log_file, "[dbg] Setting IP to %s:0x%0x(0x%0x)\n", tls->frames [0]->actual_method->name, (int)sp->il_offset, (int)sp->native_offset));
-               MONO_CONTEXT_SET_IP (&tls->restore_ctx, (guint8*)tls->frames [0]->ji->code_start + sp->native_offset);
+               DEBUG (1, fprintf (log_file, "[dbg] Setting IP to %s:0x%0x(0x%0x)\n", tls->frames [0]->actual_method->name, (int)sp.il_offset, (int)sp.native_offset));
+               MONO_CONTEXT_SET_IP (&tls->restore_ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset);
                break;
        }
        default:
@@@ -9054,11 -8954,6 +8971,11 @@@ frame_commands (int command, guint8 *p
                mono_metadata_free_mh (header);
                break;
        }
 +      case CMD_STACK_FRAME_GET_DOMAIN: {
 +              if (CHECK_PROTOCOL_VERSION (2, 38))
 +                      buffer_add_domainid (buf, frame->domain);
 +              break;
 +      }
        default:
                return ERR_NOT_IMPLEMENTED;
        }
@@@ -9427,8 -9322,7 +9344,8 @@@ static const char* type_cmds_str[] = 
  static const char* stack_frame_cmds_str[] = {
        "GET_VALUES",
        "GET_THIS",
 -      "SET_VALUES"
 +      "SET_VALUES",
 +      "GET_DOMAIN",
  };
  
  static const char* array_cmds_str[] = {
@@@ -9807,4 -9701,3 +9724,3 @@@ mono_debugger_agent_unhandled_exceptio
  }
  
  #endif
diff --combined mono/mini/ir-emit.h
index 2bfd1ac51725410d5d3f9b3ce83fe19560bf3483,937ba3bd4625a16c92caba5d6c14e073681e96fc..aac45186598af0c3295e282aca2433512024e1e9
@@@ -302,6 -302,8 +302,6 @@@ alloc_dreg (MonoCompile *cfg, MonoStack
  
  #define NEW_JIT_ICALL_ADDRCONST(cfg,dest,name) NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_JIT_ICALL_ADDR, (name))
  
 -#define GET_VARINFO_INST(cfg,num) ((cfg)->varinfo [(num)]->inst)
 -
  #define NEW_VARLOAD(cfg,dest,var,vartype) do { \
          MONO_INST_NEW ((cfg), (dest), OP_MOVE); \
                (dest)->opcode = mono_type_to_regmove ((cfg), (vartype));  \
@@@ -405,7 -407,7 +405,7 @@@ handle_gsharedvt_ldaddr (MonoCompile *c
        } while (0)
  
  #define NEW_SEQ_POINT(cfg,dest,il_offset,intr_loc) do {        \
-       MONO_INST_NEW ((cfg), (dest), OP_SEQ_POINT); \
+       MONO_INST_NEW ((cfg), (dest), cfg->gen_seq_points_debug_data ? OP_SEQ_POINT : OP_IL_SEQ_POINT); \
        (dest)->inst_imm = (il_offset); \
        (dest)->flags = intr_loc ? MONO_INST_SINGLE_STEP_LOC : 0; \
        } while (0)
diff --combined mono/mini/method-to-ir.c
index 5504b8c5cd80d97cbd49b1412717e3a1cbbb1c1b,a7e2e8785907e3b4891cf227b595cc5660cce314..3e1a3554c836e6ce99c720541fbf0abed7fcc2c5
@@@ -68,6 -68,7 +68,7 @@@
  #include "jit-icalls.h"
  #include "jit.h"
  #include "debugger-agent.h"
+ #include "seq-points.h"
  
  #define BRANCH_COST 10
  #define INLINE_LENGTH_LIMIT 20
                LOAD_ERROR;                                     \
        } while (0)
  
 +#define CHECK_CFG_ERROR do {\
 +              if (!mono_error_ok (&cfg->error)) { \
 +                      mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);        \
 +                      goto mono_error_exit; \
 +              } \
 +      } while (0)
 +
  /* Determine whenever 'ins' represents a load of the 'this' argument */
  #define MONO_CHECK_THIS(ins) (mono_method_signature (cfg->method)->hasthis && ((ins)->opcode == OP_MOVE) && ((ins)->sreg1 == cfg->args [0]->dreg))
  
@@@ -6620,7 -6614,6 +6621,7 @@@ initialize_array_data (MonoMethod *meth
         * call void class [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
         */
        if (ip [0] == CEE_DUP && ip [1] == CEE_LDTOKEN && ip [5] == 0x4 && ip [6] == CEE_CALL) {
 +              MonoError error;
                guint32 token = read32 (ip + 7);
                guint32 field_token = read32 (ip + 2);
                guint32 field_index = field_token & 0xffffff;
                int size = 0;
                MonoMethod *cmethod;
                MonoClass *dummy_class;
 -              MonoClassField *field = mono_field_from_token (method->klass->image, field_token, &dummy_class, NULL);
 +              MonoClassField *field = mono_field_from_token_checked (method->klass->image, field_token, &dummy_class, NULL, &error);
                int dummy_align;
  
 -              if (!field)
 +              if (!field) {
 +                      mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        return NULL;
 +              }
  
                *out_field_token = field_token;
  
@@@ -7135,7 -7126,7 +7136,7 @@@ mono_method_to_ir (MonoCompile *cfg, Mo
                seq_points = FALSE;
        }
  
-       if (cfg->gen_seq_points && cfg->method == method) {
+       if (cfg->gen_seq_points_debug_data && cfg->method == method) {
                minfo = mono_debug_lookup_method (method);
                if (minfo) {
                        int i, n_il_offsets;
  
        skip_dead_blocks = !dont_verify;
        if (skip_dead_blocks) {
 -              original_bb = bb = mono_basic_block_split (method, &error);
 -              if (!mono_error_ok (&error)) {
 -                      mono_error_cleanup (&error);
 -                      UNVERIFIED;
 -              }
 +              original_bb = bb = mono_basic_block_split (method, &cfg->error);
 +              CHECK_CFG_ERROR;
                g_assert (bb);
        }
  
                                        } else if (constrained_call) {
                                                fsig = mono_method_signature (cmethod);
                                        } else {
 -                                              fsig = mono_method_get_signature_full (cmethod, image, token, generic_context);
 +                                              fsig = mono_method_get_signature_checked (cmethod, image, token, generic_context, &cfg->error);
 +                                              CHECK_CFG_ERROR;
                                        }
                                }
  
                        cmethod = mini_get_method (cfg, method, token, NULL, generic_context);
                        if (!cmethod || mono_loader_get_last_error ())
                                LOAD_ERROR;
 -                      fsig = mono_method_get_signature (cmethod, image, token);
 -                      if (!fsig)
 -                              LOAD_ERROR;
 +                      fsig = mono_method_get_signature_checked (cmethod, image, token, NULL, &cfg->error);
 +                      CHECK_CFG_ERROR;
  
                        mono_save_token_info (cfg, image, token, cmethod);
  
                                klass = field->parent;
                        }
                        else {
 -                              field = mono_field_from_token (image, token, &klass, generic_context);
 +                              field = mono_field_from_token_checked (image, token, &klass, generic_context, &cfg->error);
 +                              CHECK_CFG_ERROR;
                        }
 -                      if (!field)
 -                              LOAD_ERROR;
                        if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_field (method, field))
                                FIELD_ACCESS_FAILURE (method, field);
                        mono_class_init (klass);
                        MONO_INST_NEW (cfg, ins, *ip);
                        --sp;
                        CHECK_OPSIZE (5);
 -                      klass = mono_class_get_and_inflate_typespec_checked (image, read32 (ip + 1), generic_context, &error);
 -                      mono_error_cleanup (&error); /* FIXME don't swallow the error */
 +                      klass = mini_get_class (method, read32 (ip + 1), generic_context);
                        CHECK_TYPELOAD (klass);
 -                      mono_class_init (klass);
  
                        context_used = mini_class_check_context_used (cfg, klass);
  
                        MONO_INST_NEW (cfg, ins, *ip);
                        --sp;
                        CHECK_OPSIZE (5);
 -                      klass = mono_class_get_and_inflate_typespec_checked (image, read32 (ip + 1), generic_context, &error);
 -                      mono_error_cleanup (&error); /* FIXME don't swallow the error */
 +                      klass = mini_get_class (method, read32 (ip + 1), generic_context);
                        CHECK_TYPELOAD (klass);
 -                      mono_class_init (klass);
  
                        context_used = mini_class_check_context_used (cfg, klass);
  
                                CHECK_OPSIZE (6);
                                token = read32 (ip + 2);
                                if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC && !image_is_dynamic (method->klass->image) && !generic_context) {
 -                                      MonoType *type = mono_type_create_from_typespec_checked (image, token, &error);
 -                                      mono_error_cleanup (&error); /* FIXME don't swallow the error */
 -                                      if (!type)
 -                                              UNVERIFIED;
 +                                      MonoType *type = mono_type_create_from_typespec_checked (image, token, &cfg->error);
 +                                      CHECK_CFG_ERROR;
  
                                        val = mono_type_size (type, &ialign);
                                } else {
 -                                      MonoClass *klass = mono_class_get_and_inflate_typespec_checked (image, token, generic_context, &error);
 -                                      mono_error_cleanup (&error); /* FIXME don't swallow the error */
 +                                      MonoClass *klass = mini_get_class (method, token, generic_context);
                                        CHECK_TYPELOAD (klass);
 -                                      mono_class_init (klass);
 +
                                        val = mono_type_size (&klass->byval_arg, &ialign);
  
                                        if (mini_is_gsharedvt_klass (cfg, klass))
                mono_print_code (cfg, "AFTER METHOD-TO-IR");
  
        goto cleanup;
 +
 +mono_error_exit:
 +      g_assert (!mono_error_ok (&cfg->error));
 +      goto cleanup;
   
   exception_exit:
        g_assert (cfg->exception_type != MONO_EXCEPTION_NONE);
diff --combined mono/mini/mini-amd64.c
index 23e70e0dcdf6a4b31afbfa5758b5a1be67964dbf,248a1bebb822be56766ed313c97be51a7ff7bfca..58e6ebecb8d28c6694e0e061a1e88d4e259e5153
@@@ -4109,6 -4109,9 +4109,9 @@@ mono_arch_output_basic_block (MonoCompi
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        int i;
  
@@@ -7690,11 -7693,14 +7693,11 @@@ get_delegate_invoke_impl (gboolean has_
                g_assert ((code - start) < 64);
        }
  
 -      nacl_global_codeman_validate(&start, 64, &code);
 -
 -      mono_debug_add_delegate_trampoline (start, code - start);
 +      nacl_global_codeman_validate (&start, 64, &code);
  
        if (code_len)
                *code_len = code - start;
  
 -
        if (mono_jit_map_is_enabled ()) {
                char *buff;
                if (has_target)
diff --combined mono/mini/mini-arm.c
index 50aa640e8b48225e5c2bd6cab6ea6bdf7f1d689d,456a8b34250cc5fa765e628179d71c12a4a94442..343cb49b8dc00e45f9b9df396c6d3c2259a37ddd
@@@ -177,7 -177,30 +177,7 @@@ int mono_exc_esp_offset = 0
  #define LDR_PC_VAL ((ARMCOND_AL << ARMCOND_SHIFT) | (1 << 26) | (0 << 22) | (1 << 20) | (15 << 12))
  #define IS_LDR_PC(val) (((val) & LDR_MASK) == LDR_PC_VAL)
  
 -#define ADD_LR_PC_4 ((ARMCOND_AL << ARMCOND_SHIFT) | (1 << 25) | (1 << 23) | (ARMREG_PC << 16) | (ARMREG_LR << 12) | 4)
 -#define MOV_LR_PC ((ARMCOND_AL << ARMCOND_SHIFT) | (1 << 24) | (0xa << 20) |  (ARMREG_LR << 12) | ARMREG_PC)
  //#define DEBUG_IMT 0
 - 
 -/* A variant of ARM_LDR_IMM which can handle large offsets */
 -#define ARM_LDR_IMM_GENERAL(code, dreg, basereg, offset, scratch_reg) do { \
 -      if (arm_is_imm12 ((offset))) { \
 -              ARM_LDR_IMM (code, (dreg), (basereg), (offset));        \
 -      } else {                                                                                                \
 -              g_assert ((scratch_reg) != (basereg));                                     \
 -              code = mono_arm_emit_load_imm (code, (scratch_reg), (offset));  \
 -              ARM_LDR_REG_REG (code, (dreg), (basereg), (scratch_reg));               \
 -      }                                                                                                                                       \
 -      } while (0)
 -
 -#define ARM_STR_IMM_GENERAL(code, dreg, basereg, offset, scratch_reg) do {    \
 -      if (arm_is_imm12 ((offset))) { \
 -              ARM_STR_IMM (code, (dreg), (basereg), (offset));        \
 -      } else {                                                                                                \
 -              g_assert ((scratch_reg) != (basereg));                                     \
 -              code = mono_arm_emit_load_imm (code, (scratch_reg), (offset));  \
 -              ARM_STR_REG_REG (code, (dreg), (basereg), (scratch_reg));               \
 -      }                                                                                                                                       \
 -      } while (0)
  
  #ifndef DISABLE_JIT
  static void mono_arch_compute_omit_fp (MonoCompile *cfg);
@@@ -1093,6 -1116,8 +1093,6 @@@ mono_arch_get_allocatable_int_vars (Mon
        return vars;
  }
  
 -#define USE_EXTRA_TEMPS 0
 -
  GList *
  mono_arch_get_global_int_regs (MonoCompile *cfg)
  {
@@@ -4377,6 -4402,9 +4377,9 @@@ mono_arch_output_basic_block (MonoCompi
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        int i;
                        MonoInst *info_var = cfg->arch.seq_point_info_var;
diff --combined mono/mini/mini-mips.c
index 1eb61e9b20413c8771133920eb2971bf604f7051,336f245f53c9625dcb659f642a6569046f59ec46..277b4744a073964abae19a7f050016d450df3531
@@@ -3305,8 -3305,8 +3305,8 @@@ emit_reserve_param_area (MonoCompile *c
        if (ppc_is_imm16 (-size)) {
                ppc_stwu (code, ppc_r0, -size, ppc_sp);
        } else {
 -              ppc_load (code, ppc_r11, -size);
 -              ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
 +              ppc_load (code, ppc_r12, -size);
 +              ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
        }
  #endif
        return code;
@@@ -3327,8 -3327,8 +3327,8 @@@ emit_unreserve_param_area (MonoCompile 
        if (ppc_is_imm16 (size)) {
                ppc_stwu (code, ppc_r0, size, ppc_sp);
        } else {
 -              ppc_load (code, ppc_r11, size);
 -              ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
 +              ppc_load (code, ppc_r12, size);
 +              ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
        }
  #endif
        return code;
@@@ -3394,6 -3394,9 +3394,9 @@@ mono_arch_output_basic_block (MonoCompi
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
                                guint32 addr = (guint32)ss_trigger_page;
                case OP_DIV_IMM:
                        g_assert_not_reached ();
  #if 0
 -                      ppc_load (code, ppc_r11, ins->inst_imm);
 -                      ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r11);
 +                      ppc_load (code, ppc_r12, ins->inst_imm);
 +                      ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r12);
                        ppc_mfspr (code, ppc_r0, ppc_xer);
                        ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
                        /* FIXME: use OverflowException for 0x80000000/-1 */
diff --combined mono/mini/mini-ppc.c
index 594a72e06b10430a1967798a5203bdecf951dbfe,7117bb1cefa605e44cfe3ca7e4cbcd3cbf1eda55..907fe766c9c1219742d862bc1844896111d358b8
@@@ -104,11 -104,11 +104,11 @@@ offsets_from_pthread_key (guint32 key, 
  /* FIXME: ensure the sc call preserves all but r3 */
  #define emit_darwing4_tls(code,dreg,key) do {\
                int off1 = 0x48 + key * sizeof (gpointer);      \
 -              if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r11, ppc_r3); \
 +              if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r12, ppc_r3); \
                ppc_li ((code), ppc_r0, 0x7FF2);        \
                ppc_sc ((code));        \
                ppc_lwz ((code), (dreg), off1, ppc_r3); \
 -              if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r3, ppc_r11); \
 +              if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r3, ppc_r12); \
        } while (0);
  
  #ifdef PPC_THREAD_PTR_REG
                        ppc_ldptr ((code), (dreg), off1, PPC_THREAD_PTR_REG);   \
                } else { \
                        int off3 = (off2 + 1) > 1; \
 -                      ppc_addis ((code), ppc_r11, PPC_THREAD_PTR_REG, off3); \
 -                      ppc_ldptr ((code), (dreg), off1, ppc_r11);      \
 +                      ppc_addis ((code), ppc_r12, PPC_THREAD_PTR_REG, off3); \
 +                      ppc_ldptr ((code), (dreg), off1, ppc_r12);      \
                } \
        } while (0);
  #else
@@@ -191,29 -191,29 +191,29 @@@ emit_memcpy (guint8 *code, int size, in
  
                ppc_load (code, ppc_r0, shifted);
                ppc_mtctr (code, ppc_r0);
 -              //g_assert (sreg == ppc_r11);
 -              ppc_addi (code, ppc_r12, dreg, (doffset - sizeof (gpointer)));
 -              ppc_addi (code, ppc_r11, sreg, (soffset - sizeof (gpointer)));
 +              //g_assert (sreg == ppc_r12);
 +              ppc_addi (code, ppc_r11, dreg, (doffset - sizeof (gpointer)));
 +              ppc_addi (code, ppc_r12, sreg, (soffset - sizeof (gpointer)));
                copy_loop_start = code;
 -              ppc_ldptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r11);
 -              ppc_stptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r12);
 +              ppc_ldptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r12);
 +              ppc_stptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r11);
                copy_loop_jump = code;
                ppc_bc (code, PPC_BR_DEC_CTR_NONZERO, 0, 0);
                ppc_patch (copy_loop_jump, copy_loop_start);
                size -= shifted * sizeof (gpointer);
                doffset = soffset = 0;
 -              dreg = ppc_r12;
 +              dreg = ppc_r11;
        }
  #ifdef __mono_ppc64__
        /* the hardware has multiple load/store units and the move is long
           enough to use more then one regiester, then use load/load/store/store
           to execute 2 instructions per cycle. */
 -      if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r12) && (sreg != ppc_r12)) { 
 +      if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r11) && (sreg != ppc_r11)) { 
                while (size >= 16) {
                        ppc_ldptr (code, ppc_r0, soffset, sreg);
 -                      ppc_ldptr (code, ppc_r12, soffset+8, sreg);
 +                      ppc_ldptr (code, ppc_r11, soffset+8, sreg);
                        ppc_stptr (code, ppc_r0, doffset, dreg);
 -                      ppc_stptr (code, ppc_r12, doffset+8, dreg);
 +                      ppc_stptr (code, ppc_r11, doffset+8, dreg);
                        size -= 16;
                        soffset += 16;
                        doffset += 16; 
                doffset += 8;
        }
  #else
 -      if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r12) && (sreg != ppc_r12)) { 
 +      if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r11) && (sreg != ppc_r11)) { 
                while (size >= 8) {
                        ppc_lwz (code, ppc_r0, soffset, sreg);
 -                      ppc_lwz (code, ppc_r12, soffset+4, sreg);
 +                      ppc_lwz (code, ppc_r11, soffset+4, sreg);
                        ppc_stw (code, ppc_r0, doffset, dreg);
 -                      ppc_stw (code, ppc_r12, doffset+4, dreg);
 +                      ppc_stw (code, ppc_r11, doffset+4, dreg);
                        size -= 8;
                        soffset += 8;
                        doffset += 8; 
@@@ -744,7 -744,7 +744,7 @@@ mono_arch_get_global_int_regs (MonoComp
        for (i = 14; i < top; ++i) {
                /*
                 * Reserve r29 for holding the vtable address for virtual calls in AOT mode,
 -               * since the trampolines can clobber r11.
 +               * since the trampolines can clobber r12.
                 */
                if (!(cfg->compile_aot && i == 29))
                        regs = g_list_prepend (regs, GUINT_TO_POINTER (i));
@@@ -1789,8 -1789,8 +1789,8 @@@ mono_arch_instrument_prolog (MonoCompil
  
        ppc_load_ptr (code, ppc_r3, cfg->method);
        ppc_li (code, ppc_r4, 0); /* NULL ebp for now */
 -      ppc_load_func (code, ppc_r0, func);
 -      ppc_mtlr (code, ppc_r0);
 +      ppc_load_func (code, PPC_CALL_REG, func);
 +      ppc_mtlr (code, PPC_CALL_REG);
        ppc_blrl (code);
        return code;
  }
@@@ -1887,8 -1887,8 +1887,8 @@@ mono_arch_instrument_epilog_full (MonoC
        }
  
        ppc_load_ptr (code, ppc_r3, cfg->method);
 -      ppc_load_func (code, ppc_r0, func);
 -      ppc_mtlr (code, ppc_r0);
 +      ppc_load_func (code, PPC_CALL_REG, func);
 +      ppc_mtlr (code, PPC_CALL_REG);
        ppc_blrl (code);
  
        switch (save_mode) {
@@@ -2822,14 -2822,14 +2822,14 @@@ handle_thunk (int absolute, guchar *cod
  static void
  patch_ins (guint8 *code, guint32 ins)
  {
 -      *(guint32*)code = GUINT32_TO_BE (ins);
 +      *(guint32*)code = ins;
        mono_arch_flush_icache (code, 4);
  }
  
  void
  ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
  {
 -      guint32 ins = GUINT32_FROM_BE (*(guint32*)code);
 +      guint32 ins = *(guint32*)code;
        guint32 prim = ins >> 26;
        guint32 ovf;
  
                        else
                                code -= 24;
                } else {
 -                      if (ppc_is_load_op (seq [5]) || ppc_opcode (seq [5]) == 31) /* ld || lwz || mr */
 +                      if (ppc_is_load_op (seq [5])
 +#ifdef PPC_USES_FUNCTION_DESCRIPTOR
 +                          /* With function descs we need to do more careful
 +                             matches.  */
 +                          || ppc_opcode (seq [5]) == 31 /* ld || lwz || mr */
 +#endif
 +                         )
                                branch_ins = seq + 8;
                        else
                                branch_ins = seq + 6;
  
                        if (!is_fd) {
                                guint8 *buf = (guint8*)&seq [5];
 -                              ppc_mr (buf, ppc_r0, ppc_r11);
 +                              ppc_mr (buf, PPC_CALL_REG, ppc_r12);
                                ppc_nop (buf);
                        }
                } else {
                }
  
                /* FIXME: make this thread safe */
 -              /* FIXME: we're assuming we're using r11 here */
 -              ppc_load_ptr_sequence (code, ppc_r11, target);
 +#ifdef PPC_USES_FUNCTION_DESCRIPTOR
 +              /* FIXME: we're assuming we're using r12 here */
 +              ppc_load_ptr_sequence (code, ppc_r12, target);
 +#else
 +              ppc_load_ptr_sequence (code, PPC_CALL_REG, target);
 +#endif
                mono_arch_flush_icache ((guint8*)seq, 28);
  #else
                guint32 *seq;
                g_assert ((seq [2] >> 26) == 31);
                g_assert (seq [3] == 0x4e800021 || seq [3] == 0x4e800020 || seq [3] == 0x4e800420);
                /* FIXME: make this thread safe */
 -              ppc_lis (code, ppc_r0, (guint32)(target) >> 16);
 -              ppc_ori (code, ppc_r0, ppc_r0, (guint32)(target) & 0xffff);
 +              ppc_lis (code, PPC_CALL_REG, (guint32)(target) >> 16);
 +              ppc_ori (code, PPC_CALL_REG, PPC_CALL_REG, (guint32)(target) & 0xffff);
                mono_arch_flush_icache (code - 8, 8);
  #endif
        } else {
@@@ -3020,8 -3010,8 +3020,8 @@@ emit_reserve_param_area (MonoCompile *c
        if (ppc_is_imm16 (-size)) {
                ppc_stptr_update (code, ppc_r0, -size, ppc_sp);
        } else {
 -              ppc_load (code, ppc_r11, -size);
 -              ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
 +              ppc_load (code, ppc_r12, -size);
 +              ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
        }
  
        return code;
@@@ -3042,8 -3032,8 +3042,8 @@@ emit_unreserve_param_area (MonoCompile 
        if (ppc_is_imm16 (size)) {
                ppc_stptr_update (code, ppc_r0, size, ppc_sp);
        } else {
 -              ppc_load (code, ppc_r11, size);
 -              ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
 +              ppc_load (code, ppc_r12, size);
 +              ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
        }
  
        return code;
@@@ -3104,6 -3094,9 +3104,9 @@@ mono_arch_output_basic_block (MonoCompi
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        int i;
  
                         * a breakpoint is hit will step to the next IL offset.
                         */
                        if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
 -                              ppc_load (code, ppc_r11, (gsize)ss_trigger_page);
 -                              ppc_ldptr (code, ppc_r11, 0, ppc_r11);
 +                              ppc_load (code, ppc_r12, (gsize)ss_trigger_page);
 +                              ppc_ldptr (code, ppc_r12, 0, ppc_r12);
                        }
  
                        mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
                                ppc_stb (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_stb (code, ins->sreg1, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_stb (code, ins->sreg1, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_stbx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
                                ppc_sth (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_sth (code, ins->sreg1, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_sth (code, ins->sreg1, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_sthx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
                                ppc_stptr (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_stptr (code, ins->sreg1, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_stptr (code, ins->sreg1, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_stptr_indexed (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
                                             (gpointer)"mono_break");
                        if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtlr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtlr (code, PPC_CALL_REG);
                                ppc_blrl (code);
                        } else {
                                ppc_bl (code, 0);
                         */
                        g_assert (!cfg->method->save_lmf);
                        /*
 -                       * Note: we can use ppc_r11 here because it is dead anyway:
 +                       * Note: we can use ppc_r12 here because it is dead anyway:
                         * we're leaving the method.
                         */
                        if (1 || cfg->flags & MONO_CFG_HAS_CALLS) {
                                if (ppc_is_imm16 (ret_offset)) {
                                        ppc_ldptr (code, ppc_r0, ret_offset, cfg->frame_reg);
                                } else {
 -                                      ppc_load (code, ppc_r11, ret_offset);
 -                                      ppc_ldptr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r11);
 +                                      ppc_load (code, ppc_r12, ret_offset);
 +                                      ppc_ldptr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r12);
                                }
                                ppc_mtlr (code, ppc_r0);
                        }
  
                        if (ppc_is_imm16 (cfg->stack_usage)) {
 -                              ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage);
 +                              ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage);
                        } else {
                                /* cfg->stack_usage is an int, so we can use
                                 * an addis/addi sequence here even in 64-bit.  */
 -                              ppc_addis (code, ppc_r11, cfg->frame_reg, ppc_ha(cfg->stack_usage));
 -                              ppc_addi (code, ppc_r11, ppc_r11, cfg->stack_usage);
 +                              ppc_addis (code, ppc_r12, cfg->frame_reg, ppc_ha(cfg->stack_usage));
 +                              ppc_addi (code, ppc_r12, ppc_r12, cfg->stack_usage);
                        }
                        if (!cfg->method->save_lmf) {
                                pos = 0;
                                for (i = 31; i >= 13; --i) {
                                        if (cfg->used_int_regs & (1 << i)) {
                                                pos += sizeof (gpointer);
 -                                              ppc_ldptr (code, i, -pos, ppc_r11);
 +                                              ppc_ldptr (code, i, -pos, ppc_r12);
                                        }
                                }
                        } else {
  
                        /* Copy arguments on the stack to our argument area */
                        if (call->stack_usage) {
 -                              code = emit_memcpy (code, call->stack_usage, ppc_r11, PPC_STACK_PARAM_OFFSET, ppc_sp, PPC_STACK_PARAM_OFFSET);
 -                              /* r11 was clobbered */
 +                              code = emit_memcpy (code, call->stack_usage, ppc_r12, PPC_STACK_PARAM_OFFSET, ppc_sp, PPC_STACK_PARAM_OFFSET);
 +                              /* r12 was clobbered */
                                g_assert (cfg->frame_reg == ppc_sp);
                                if (ppc_is_imm16 (cfg->stack_usage)) {
 -                                      ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage);
 +                                      ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage);
                                } else {
                                        /* cfg->stack_usage is an int, so we can use
                                         * an addis/addi sequence here even in 64-bit.  */
 -                                      ppc_addis (code, ppc_r11, cfg->frame_reg, ppc_ha(cfg->stack_usage));
 -                                      ppc_addi (code, ppc_r11, ppc_r11, cfg->stack_usage);
 +                                      ppc_addis (code, ppc_r12, cfg->frame_reg, ppc_ha(cfg->stack_usage));
 +                                      ppc_addi (code, ppc_r12, ppc_r12, cfg->stack_usage);
                                }
                        }
  
 -                      ppc_mr (code, ppc_sp, ppc_r11);
 +                      ppc_mr (code, ppc_sp, ppc_r12);
                        mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method);
                        if (cfg->compile_aot) {
                                /* arch_emit_got_access () patches this */
                                ppc_load32 (code, ppc_r0, 0);
  #ifdef PPC_USES_FUNCTION_DESCRIPTOR
 -                              ppc_ldptr_indexed (code, ppc_r11, ppc_r30, ppc_r0);
 -                              ppc_ldptr (code, ppc_r0, 0, ppc_r11);
 +                              ppc_ldptr_indexed (code, ppc_r12, ppc_r30, ppc_r0);
 +                              ppc_ldptr (code, ppc_r0, 0, ppc_r12);
  #else
                                ppc_ldptr_indexed (code, ppc_r0, ppc_r30, ppc_r0);
  #endif
                        else
                                mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, call->fptr);
                        if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtlr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtlr (code, PPC_CALL_REG);
                                ppc_blrl (code);
                        } else {
                                ppc_bl (code, 0);
                case OP_VCALL2_MEMBASE:
                case OP_VOIDCALL_MEMBASE:
                case OP_CALL_MEMBASE:
 -                      if (cfg->compile_aot && ins->sreg1 == ppc_r11) {
 +                      if (cfg->compile_aot && ins->sreg1 == ppc_r12) {
                                /* The trampolines clobber this */
                                ppc_mr (code, ppc_r29, ins->sreg1);
                                ppc_ldptr (code, ppc_r0, ins->inst_offset, ppc_r29);
                        int alloca_waste = PPC_STACK_PARAM_OFFSET + cfg->param_area + 31;
                        int area_offset = alloca_waste;
                        area_offset &= ~31;
 -                      ppc_addi (code, ppc_r11, ins->sreg1, alloca_waste + 31);
 +                      ppc_addi (code, ppc_r12, ins->sreg1, alloca_waste + 31);
                        /* FIXME: should be calculated from MONO_ARCH_FRAME_ALIGNMENT */
 -                      ppc_clear_right_imm (code, ppc_r11, ppc_r11, 4);
 +                      ppc_clear_right_imm (code, ppc_r12, ppc_r12, 4);
                        /* use ctr to store the number of words to 0 if needed */
                        if (ins->flags & MONO_INST_INIT) {
                                /* we zero 4 bytes at a time:
                                ppc_mtctr (code, ppc_r0);
                        }
                        ppc_ldptr (code, ppc_r0, 0, ppc_sp);
 -                      ppc_neg (code, ppc_r11, ppc_r11);
 -                      ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
 +                      ppc_neg (code, ppc_r12, ppc_r12);
 +                      ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
  
                        /* FIXME: make this loop work in 8 byte
                           increments on PPC64 */
                                 * run at least once
                                 */
                                ppc_addi (code, ins->dreg, ppc_sp, (area_offset - 8));
 -                              ppc_li (code, ppc_r11, 0);
 +                              ppc_li (code, ppc_r12, 0);
                                zero_loop_start = code;
 -                              ppc_stwu (code, ppc_r11, 4, ins->dreg);
 +                              ppc_stwu (code, ppc_r12, 4, ins->dreg);
                                zero_loop_jump = code;
                                ppc_bc (code, PPC_BR_DEC_CTR_NONZERO, 0, 0);
                                ppc_patch (zero_loop_jump, zero_loop_start);
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
                                             (gpointer)"mono_arch_throw_exception");
                        if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtlr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtlr (code, PPC_CALL_REG);
                                ppc_blrl (code);
                        } else {
                                ppc_bl (code, 0);
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
                                             (gpointer)"mono_arch_rethrow_exception");
                        if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtlr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtlr (code, PPC_CALL_REG);
                                ppc_blrl (code);
                        } else {
                                ppc_bl (code, 0);
                        if (ppc_is_imm16 (spvar->inst_offset)) {
                                ppc_stptr (code, ppc_r0, spvar->inst_offset, spvar->inst_basereg);
                        } else {
 -                              ppc_load (code, ppc_r11, spvar->inst_offset);
 -                              ppc_stptr_indexed (code, ppc_r0, ppc_r11, spvar->inst_basereg);
 +                              ppc_load (code, ppc_r12, spvar->inst_offset);
 +                              ppc_stptr_indexed (code, ppc_r0, ppc_r12, spvar->inst_basereg);
                        }
                        break;
                }
                        if (ppc_is_imm16 (spvar->inst_offset)) {
                                ppc_ldptr (code, ppc_r0, spvar->inst_offset, spvar->inst_basereg);
                        } else {
 -                              ppc_load (code, ppc_r11, spvar->inst_offset);
 -                              ppc_ldptr_indexed (code, ppc_r0, spvar->inst_basereg, ppc_r11);
 +                              ppc_load (code, ppc_r12, spvar->inst_offset);
 +                              ppc_ldptr_indexed (code, ppc_r0, spvar->inst_basereg, ppc_r12);
                        }
                        ppc_mtlr (code, ppc_r0);
                        ppc_blr (code);
  
                        /* FIXME: Optimize this */
                        ppc_bl (code, 1);
 -                      ppc_mflr (code, ppc_r11);
 +                      ppc_mflr (code, ppc_r12);
                        ppc_b (code, 3);
                        *(double*)code = *(double*)ins->inst_p0;
                        code += 8;
 -                      ppc_lfd (code, ins->dreg, 8, ppc_r11);
 +                      ppc_lfd (code, ins->dreg, 8, ppc_r12);
                        break;
                case OP_R4CONST:
                        g_assert_not_reached ();
                                ppc_stfd (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_stfd (code, ins->sreg1, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_stfd (code, ins->sreg1, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_stfdx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
                                ppc_lfd (code, ins->dreg, ins->inst_offset, ins->inst_basereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_lfd (code, ins->dreg, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_lfd (code, ins->dreg, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_lfdx (code, ins->dreg, ins->inst_destbasereg, ppc_r0);
                                ppc_stfs (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_stfs (code, ins->sreg1, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_stfs (code, ins->sreg1, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_stfsx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
                                ppc_lfs (code, ins->dreg, ins->inst_offset, ins->inst_basereg);
                        } else {
                                if (ppc_is_imm32 (ins->inst_offset)) {
 -                                      ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 -                                      ppc_lfs (code, ins->dreg, ins->inst_offset, ppc_r12);
 +                                      ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
 +                                      ppc_lfs (code, ins->dreg, ins->inst_offset, ppc_r11);
                                } else {
                                        ppc_load (code, ppc_r0, ins->inst_offset);
                                        ppc_lfsx (code, ins->dreg, ins->inst_destbasereg, ppc_r0);
@@@ -4519,16 -4512,6 +4522,16 @@@ mono_arch_register_lowlevel_calls (void
  }
  
  #ifdef __mono_ppc64__
 +#ifdef _LITTLE_ENDIAN
 +#define patch_load_sequence(ip,val) do {\
 +              guint16 *__load = (guint16*)(ip);       \
 +              g_assert (sizeof (val) == sizeof (gsize)); \
 +              __load [0] = (((guint64)(gsize)(val)) >> 48) & 0xffff;  \
 +              __load [2] = (((guint64)(gsize)(val)) >> 32) & 0xffff;  \
 +              __load [6] = (((guint64)(gsize)(val)) >> 16) & 0xffff;  \
 +              __load [8] =  ((guint64)(gsize)(val))        & 0xffff;  \
 +      } while (0)
 +#elif defined _BIG_ENDIAN
  #define patch_load_sequence(ip,val) do {\
                guint16 *__load = (guint16*)(ip);       \
                g_assert (sizeof (val) == sizeof (gsize)); \
                __load [9] =  ((guint64)(gsize)(val))        & 0xffff;  \
        } while (0)
  #else
 +#error huh?  No endianess defined by compiler
 +#endif
 +#else
  #define patch_load_sequence(ip,val) do {\
                guint16 *__lis_ori = (guint16*)(ip);    \
                __lis_ori [1] = (((gulong)(val)) >> 16) & 0xffff;       \
@@@ -4751,12 -4731,12 +4754,12 @@@ mono_arch_emit_prolog (MonoCompile *cfg
                        code = save_registers (cfg, code, alloc_size - pos, ppc_sp, method->save_lmf, cfg->used_int_regs, cfa_offset);
                } else {
                        if (pos)
 -                              ppc_addi (code, ppc_r11, ppc_sp, -pos);
 +                              ppc_addi (code, ppc_r12, ppc_sp, -pos);
                        ppc_load (code, ppc_r0, -alloc_size);
                        ppc_str_update_indexed (code, ppc_sp, ppc_sp, ppc_r0);
                        cfa_offset = alloc_size;
                        mono_emit_unwind_op_def_cfa_offset (cfg, code, alloc_size);
 -                      code = save_registers (cfg, code, 0, ppc_r11, method->save_lmf, cfg->used_int_regs, cfa_offset);
 +                      code = save_registers (cfg, code, 0, ppc_r12, method->save_lmf, cfg->used_int_regs, cfa_offset);
                }
        }
        if (cfg->frame_reg != ppc_sp) {
                if (ppc_is_imm16 (inst->inst_offset)) {
                        ppc_stptr (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                } else {
 -                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                      ppc_stptr_indexed (code, ainfo->reg, ppc_r11, inst->inst_basereg);
 +                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                      ppc_stptr_indexed (code, ainfo->reg, ppc_r12, inst->inst_basereg);
                }
        }
  
                        else if (ainfo->regtype == RegTypeFP)
                                ppc_fmr (code, inst->dreg, ainfo->reg);
                        else if (ainfo->regtype == RegTypeBase) {
 -                              ppc_ldr (code, ppc_r11, 0, ppc_sp);
 -                              ppc_ldptr (code, inst->dreg, ainfo->offset, ppc_r11);
 +                              ppc_ldr (code, ppc_r12, 0, ppc_sp);
 +                              ppc_ldptr (code, inst->dreg, ainfo->offset, ppc_r12);
                        } else
                                g_assert_not_reached ();
  
                                                ppc_stb (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stb (code, ainfo->reg, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stb (code, ainfo->reg, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stbx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stbx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                                ppc_sth (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_sth (code, ainfo->reg, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_sth (code, ainfo->reg, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_sthx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_sthx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                                ppc_stw (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stw (code, ainfo->reg, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stw (code, ainfo->reg, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stwx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stwx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                        if (ppc_is_imm16 (inst->inst_offset)) {
                                                ppc_str (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                        } else {
 -                                              ppc_load (code, ppc_r11, inst->inst_offset);
 -                                              ppc_str_indexed (code, ainfo->reg, ppc_r11, inst->inst_basereg);
 +                                              ppc_load (code, ppc_r12, inst->inst_offset);
 +                                              ppc_str_indexed (code, ainfo->reg, ppc_r12, inst->inst_basereg);
                                        }
                                        break;
  #else
                                                ppc_stw (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                                ppc_stw (code, ainfo->reg + 1, inst->inst_offset + 4, inst->inst_basereg);
                                        } else {
 -                                              ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                              ppc_addi (code, ppc_r11, ppc_r11, inst->inst_offset);
 -                                              ppc_stw (code, ainfo->reg, 0, ppc_r11);
 -                                              ppc_stw (code, ainfo->reg + 1, 4, ppc_r11);
 +                                              ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                              ppc_addi (code, ppc_r12, ppc_r12, inst->inst_offset);
 +                                              ppc_stw (code, ainfo->reg, 0, ppc_r12);
 +                                              ppc_stw (code, ainfo->reg + 1, 4, ppc_r12);
                                        }
                                        break;
  #endif
                                                ppc_stptr (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stptr (code, ainfo->reg, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stptr (code, ainfo->reg, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stptr_indexed (code, ainfo->reg, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stptr_indexed (code, ainfo->reg, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                }
                        } else if (ainfo->regtype == RegTypeBase) {
                                g_assert (ppc_is_imm16 (ainfo->offset));
 -                              /* load the previous stack pointer in r11 */
 -                              ppc_ldr (code, ppc_r11, 0, ppc_sp);
 -                              ppc_ldptr (code, ppc_r0, ainfo->offset, ppc_r11);
 +                              /* load the previous stack pointer in r12 */
 +                              ppc_ldr (code, ppc_r12, 0, ppc_sp);
 +                              ppc_ldptr (code, ppc_r0, ainfo->offset, ppc_r12);
                                switch (ainfo->size) {
                                case 1:
                                        if (ppc_is_imm16 (inst->inst_offset)) {
                                                ppc_stb (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stb (code, ppc_r0, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stb (code, ppc_r0, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stbx (code, ppc_r0, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stbx (code, ppc_r0, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                                ppc_sth (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_sth (code, ppc_r0, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_sth (code, ppc_r0, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_sthx (code, ppc_r0, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_sthx (code, ppc_r0, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                                ppc_stw (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stw (code, ppc_r0, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stw (code, ppc_r0, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stwx (code, ppc_r0, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stwx (code, ppc_r0, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                        if (ppc_is_imm16 (inst->inst_offset)) {
                                                ppc_str (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
                                        } else {
 -                                              ppc_load (code, ppc_r11, inst->inst_offset);
 -                                              ppc_str_indexed (code, ppc_r0, ppc_r11, inst->inst_basereg);
 +                                              ppc_load (code, ppc_r12, inst->inst_offset);
 +                                              ppc_str_indexed (code, ppc_r0, ppc_r12, inst->inst_basereg);
                                        }
                                        break;
  #else
                                        g_assert (ppc_is_imm16 (ainfo->offset + 4));
                                        if (ppc_is_imm16 (inst->inst_offset + 4)) {
                                                ppc_stw (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
 -                                              ppc_lwz (code, ppc_r0, ainfo->offset + 4, ppc_r11);
 +                                              ppc_lwz (code, ppc_r0, ainfo->offset + 4, ppc_r12);
                                                ppc_stw (code, ppc_r0, inst->inst_offset + 4, inst->inst_basereg);
                                        } else {
 -                                              /* use r12 to load the 2nd half of the long before we clobber r11.  */
 -                                              ppc_lwz (code, ppc_r12, ainfo->offset + 4, ppc_r11);
 -                                              ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                              ppc_addi (code, ppc_r11, ppc_r11, inst->inst_offset);
 -                                              ppc_stw (code, ppc_r0, 0, ppc_r11);
 -                                              ppc_stw (code, ppc_r12, 4, ppc_r11);
 +                                              /* use r11 to load the 2nd half of the long before we clobber r12.  */
 +                                              ppc_lwz (code, ppc_r11, ainfo->offset + 4, ppc_r12);
 +                                              ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                              ppc_addi (code, ppc_r12, ppc_r12, inst->inst_offset);
 +                                              ppc_stw (code, ppc_r0, 0, ppc_r12);
 +                                              ppc_stw (code, ppc_r11, 4, ppc_r12);
                                        }
                                        break;
  #endif
                                                ppc_stptr (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
                                        } else {
                                                if (ppc_is_imm32 (inst->inst_offset)) {
 -                                                      ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
 -                                                      ppc_stptr (code, ppc_r0, inst->inst_offset, ppc_r11);
 +                                                      ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
 +                                                      ppc_stptr (code, ppc_r0, inst->inst_offset, ppc_r12);
                                                } else {
 -                                                      ppc_load (code, ppc_r11, inst->inst_offset);
 -                                                      ppc_stptr_indexed (code, ppc_r0, inst->inst_basereg, ppc_r11);
 +                                                      ppc_load (code, ppc_r12, inst->inst_offset);
 +                                                      ppc_stptr_indexed (code, ppc_r0, inst->inst_basereg, ppc_r12);
                                                }
                                        }
                                        break;
                                        /* FIXME: we need to do the shifting here, too */
                                        if (ainfo->bytes)
                                                NOT_IMPLEMENTED;
 -                                      /* load the previous stack pointer in r11 (r0 gets overwritten by the memcpy) */
 -                                      ppc_ldr (code, ppc_r11, 0, ppc_sp);
 +                                      /* load the previous stack pointer in r12 (r0 gets overwritten by the memcpy) */
 +                                      ppc_ldr (code, ppc_r12, 0, ppc_sp);
                                        if ((size & MONO_PPC_32_64_CASE (3, 7)) != 0) {
                                                code = emit_memcpy (code, size - soffset,
                                                        inst->inst_basereg, doffset,
 -                                                      ppc_r11, ainfo->offset + soffset);
 +                                                      ppc_r12, ainfo->offset + soffset);
                                        } else {
                                                code = emit_memcpy (code, ainfo->vtsize * sizeof (gpointer),
                                                        inst->inst_basereg, doffset,
 -                                                      ppc_r11, ainfo->offset + soffset);
 +                                                      ppc_r12, ainfo->offset + soffset);
                                        }
                                }
                        } else if (ainfo->regtype == RegTypeStructByAddr) {
                                /* if it was originally a RegTypeBase */
                                if (ainfo->offset) {
 -                                      /* load the previous stack pointer in r11 */
 -                                      ppc_ldr (code, ppc_r11, 0, ppc_sp);
 -                                      ppc_ldptr (code, ppc_r11, ainfo->offset, ppc_r11);
 +                                      /* load the previous stack pointer in r12 */
 +                                      ppc_ldr (code, ppc_r12, 0, ppc_sp);
 +                                      ppc_ldptr (code, ppc_r12, ainfo->offset, ppc_r12);
                                } else {
 -                                      ppc_mr (code, ppc_r11, ainfo->reg);
 +                                      ppc_mr (code, ppc_r12, ainfo->reg);
                                }
  
                                if (cfg->tailcall_valuetype_addrs) {
                                        MonoInst *addr = cfg->tailcall_valuetype_addrs [tailcall_struct_index];
  
                                        g_assert (ppc_is_imm16 (addr->inst_offset));
 -                                      ppc_stptr (code, ppc_r11, addr->inst_offset, addr->inst_basereg);
 +                                      ppc_stptr (code, ppc_r12, addr->inst_offset, addr->inst_basereg);
  
                                        tailcall_struct_index++;
                                }
  
                                g_assert (ppc_is_imm16 (inst->inst_offset));
 -                              code = emit_memcpy (code, ainfo->vtsize, inst->inst_basereg, inst->inst_offset, ppc_r11, 0);
 +                              code = emit_memcpy (code, ainfo->vtsize, inst->inst_basereg, inst->inst_offset, ppc_r12, 0);
                                /*g_print ("copy in %s: %d bytes from %d to offset: %d\n", method->name, ainfo->vtsize, ainfo->reg, inst->inst_offset);*/
                        } else
                                g_assert_not_reached ();
                        mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, 
                                     (gpointer)"mono_get_lmf_addr");
                        if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtlr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtlr (code, PPC_CALL_REG);
                                ppc_blrl (code);
                        } else {
                                ppc_bl (code, 0);
                /* lmf_offset is the offset from the previous stack pointer,
                 * alloc_size is the total stack space allocated, so the offset
                 * of MonoLMF from the current stack ptr is alloc_size - lmf_offset.
 -               * The pointer to the struct is put in ppc_r11 (new_lmf).
 +               * The pointer to the struct is put in ppc_r12 (new_lmf).
                 * The callee-saved registers are already in the MonoLMF structure
                 */
 -              ppc_addi (code, ppc_r11, ppc_sp, alloc_size - lmf_offset);
 +              ppc_addi (code, ppc_r12, ppc_sp, alloc_size - lmf_offset);
                /* ppc_r3 is the result from mono_get_lmf_addr () */
 -              ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
 +              ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
                /* new_lmf->previous_lmf = *lmf_addr */
                ppc_ldptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
 -              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
 -              /* *(lmf_addr) = r11 */
 -              ppc_stptr (code, ppc_r11, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
 +              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
 +              /* *(lmf_addr) = r12 */
 +              ppc_stptr (code, ppc_r12, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
                /* save method info */
                if (cfg->compile_aot)
                        // FIXME:
                        ppc_load (code, ppc_r0, 0);
                else
                        ppc_load_ptr (code, ppc_r0, method);
 -              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
 -              ppc_stptr (code, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r11);
 +              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r12);
 +              ppc_stptr (code, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r12);
                /* save the current IP */
                if (cfg->compile_aot) {
                        ppc_bl (code, 1);
                        ppc_load_sequence (code, ppc_r0, (gulong)0x01010101L);
  #endif
                }
 -              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r11);
 +              ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r12);
        }
  
        if (tracing)
@@@ -5192,21 -5172,21 +5195,21 @@@ mono_arch_emit_epilog (MonoCompile *cfg
                lmf_offset = pos;
                /* save the frame reg in r8 */
                ppc_mr (code, ppc_r8, cfg->frame_reg);
 -              ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage - lmf_offset);
 +              ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage - lmf_offset);
                /* r5 = previous_lmf */
 -              ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
 +              ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
                /* r6 = lmf_addr */
 -              ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
 +              ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
                /* *(lmf_addr) = previous_lmf */
                ppc_stptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r6);
                /* FIXME: speedup: there is no actual need to restore the registers if
                 * we didn't actually change them (idea from Zoltan).
                 */
                /* restore iregs */
 -              ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r11);
 +              ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r12);
                /* restore fregs */
                /*for (i = 14; i < 32; i++) {
 -                      ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r11);
 +                      ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r12);
                }*/
                g_assert (ppc_is_imm16 (cfg->stack_usage + PPC_RET_ADDR_OFFSET));
                /* use the saved copy of the frame reg in r8 */
                        if (ppc_is_imm16 (return_offset)) {
                                ppc_ldr (code, ppc_r0, return_offset, cfg->frame_reg);
                        } else {
 -                              ppc_load (code, ppc_r11, return_offset);
 -                              ppc_ldr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r11);
 +                              ppc_load (code, ppc_r12, return_offset);
 +                              ppc_ldr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r12);
                        }
                        ppc_mtlr (code, ppc_r0);
                }
                                        offset -= sizeof (mgreg_t);
                        }
                        if (cfg->frame_reg != ppc_sp)
 -                              ppc_mr (code, ppc_r11, cfg->frame_reg);
 +                              ppc_mr (code, ppc_r12, cfg->frame_reg);
                        /* note r31 (possibly the frame register) is restored last */
                        for (i = 13; i <= 31; i++) {
                                if (cfg->used_int_regs & (1 << i)) {
                                }
                        }
                        if (cfg->frame_reg != ppc_sp)
 -                              ppc_addi (code, ppc_sp, ppc_r11, cfg->stack_usage);
 +                              ppc_addi (code, ppc_sp, ppc_r12, cfg->stack_usage);
                        else
                                ppc_addi (code, ppc_sp, ppc_sp, cfg->stack_usage);
                } else {
 -                      ppc_load32 (code, ppc_r11, cfg->stack_usage);
 +                      ppc_load32 (code, ppc_r12, cfg->stack_usage);
                        if (cfg->used_int_regs) {
 -                              ppc_add (code, ppc_r11, cfg->frame_reg, ppc_r11);
 +                              ppc_add (code, ppc_r12, cfg->frame_reg, ppc_r12);
                                for (i = 31; i >= 13; --i) {
                                        if (cfg->used_int_regs & (1 << i)) {
                                                pos += sizeof (mgreg_t);
 -                                              ppc_ldr (code, i, -pos, ppc_r11);
 +                                              ppc_ldr (code, i, -pos, ppc_r12);
                                        }
                                }
 -                              ppc_mr (code, ppc_sp, ppc_r11);
 +                              ppc_mr (code, ppc_sp, ppc_r12);
                        } else {
 -                              ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
 +                              ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r12);
                        }
                }
  
@@@ -5408,8 -5388,8 +5411,8 @@@ mono_arch_emit_exceptions (MonoCompile 
                        patch_info->data.name = "mono_arch_throw_corlib_exception";
                        patch_info->ip.i = code - cfg->native_code;
                        if (FORCE_INDIR_CALL || cfg->method->dynamic) {
 -                              ppc_load_func (code, ppc_r0, 0);
 -                              ppc_mtctr (code, ppc_r0);
 +                              ppc_load_func (code, PPC_CALL_REG, 0);
 +                              ppc_mtctr (code, PPC_CALL_REG);
                                ppc_bcctr (code, PPC_BR_ALWAYS, 0);
                        } else {
                                ppc_bl (code, 0);
@@@ -5644,15 -5624,15 +5647,15 @@@ mono_arch_build_imt_thunk (MonoVTable *
        start = code;
  
        /*
 -       * We need to save and restore r11 because it might be
 +       * We need to save and restore r12 because it might be
         * used by the caller as the vtable register, so
         * clobbering it will trip up the magic trampoline.
         *
 -       * FIXME: Get rid of this by making sure that r11 is
 +       * FIXME: Get rid of this by making sure that r12 is
         * not used as the vtable register in interface calls.
         */
 -      ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
 -      ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0])));
 +      ppc_stptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
 +      ppc_load (code, ppc_r12, (gsize)(& (vtable->vtable [0])));
  
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                                if (item->has_target_code) {
                                        ppc_load_ptr (code, ppc_r0, item->value.target_code);
                                } else {
 -                                      ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r11);
 -                                      ppc_ldptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
 +                                      ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r12);
 +                                      ppc_ldptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
                                }
                                ppc_mtctr (code, ppc_r0);
                                ppc_bcctr (code, PPC_BR_ALWAYS, 0);
                                        item->jmp_code = code;
                                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
  #endif
 -                                      ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r11);
 -                                      ppc_ldptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
 +                                      ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r12);
 +                                      ppc_ldptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
                                        ppc_mtctr (code, ppc_r0);
                                        ppc_bcctr (code, PPC_BR_ALWAYS, 0);
  #if ENABLE_WRONG_METHOD_CHECK
@@@ -5827,17 -5807,17 +5830,17 @@@ mono_arch_emit_load_got_addr (guint8 *s
   *   Emit code to load the contents of the GOT slot identified by TRAMP_TYPE and
   * TARGET from the mscorlib GOT in full-aot code.
   * On PPC, the GOT address is assumed to be in r30, and the result is placed into 
 - * r11.
 + * r12.
   */
  guint8*
  mono_arch_emit_load_aotconst (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target)
  {
        /* Load the mscorlib got address */
 -      ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r30);
 +      ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r30);
        *ji = mono_patch_info_list_prepend (*ji, code - start, tramp_type, target);
        /* arch_emit_got_access () patches this */
        ppc_load32 (code, ppc_r0, 0);
 -      ppc_ldptr_indexed (code, ppc_r11, ppc_r11, ppc_r0);
 +      ppc_ldptr_indexed (code, ppc_r12, ppc_r12, ppc_r0);
  
        return code;
  }
@@@ -5860,8 -5840,8 +5863,8 @@@ mono_arch_set_breakpoint (MonoJitInfo *
        guint8 *code = ip;
        guint8 *orig_code = code;
  
 -      ppc_load_sequence (code, ppc_r11, (gsize)bp_trigger_page);
 -      ppc_ldptr (code, ppc_r11, 0, ppc_r11);
 +      ppc_load_sequence (code, ppc_r12, (gsize)bp_trigger_page);
 +      ppc_ldptr (code, ppc_r12, 0, ppc_r12);
  
        g_assert (code - orig_code == BREAKPOINT_SIZE);
  
diff --combined mono/mini/mini-x86.c
index 35f56d0f984fd50aba7cf01c9471fb046e95bf2a,5e5d1f9df512383c6a32d2c6a3970fd8bfa084c5..e4415df43fafc31b378379671f8ff6abd6672305
@@@ -2761,6 -2761,9 +2761,9 @@@ mono_arch_output_basic_block (MonoCompi
                case OP_NOT_REACHED:
                case OP_NOT_NULL:
                        break;
+               case OP_IL_SEQ_POINT:
+                       mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+                       break;
                case OP_SEQ_POINT: {
                        int i;
  
@@@ -6101,7 -6104,8 +6104,7 @@@ get_delegate_invoke_impl (gboolean has_
                g_assert ((code - start) < code_reserve);
        }
  
 -      nacl_global_codeman_validate(&start, code_reserve, &code);
 -      mono_debug_add_delegate_trampoline (start, code - start);
 +      nacl_global_codeman_validate (&start, code_reserve, &code);
  
        if (code_len)
                *code_len = code - start;
diff --combined mono/mini/mini.c
index b642073e91ff5d3f86b0febabd82fbe90d58a08f,604a4142aa8257a8d982c0848274a522fb6a21a1..f876ce3ea5c5e30c9eff8506e15d0c87eca36806
@@@ -53,7 -53,6 +53,7 @@@
  #include <mono/utils/mono-math.h>
  #include <mono/utils/mono-compiler.h>
  #include <mono/utils/mono-counters.h>
 +#include <mono/utils/mono-error-internals.h>
  #include <mono/utils/mono-logger-internal.h>
  #include <mono/utils/mono-mmap.h>
  #include <mono/utils/mono-path.h>
@@@ -64,6 -63,7 +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 -76,7 +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);
  
@@@ -711,11 -712,10 +713,11 @@@ G_GNUC_UNUSED gboolea
  mono_debug_count (void)
  {
        static int count = 0;
 -      count ++;
        static gboolean inited;
        static const char *value;
  
 +      count ++;
 +
        if (!inited) {
                value = g_getenv ("COUNT");
                inited = TRUE;
@@@ -3921,159 -3921,6 +3923,6 @@@ mono_postprocess_patches (MonoCompile *
        }
  }
  
- 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)
  {
  
        cfg->code_len = code - cfg->native_code;
        cfg->prolog_end = cfg->code_len;
 +      cfg->cfa_reg = cfg->cur_cfa_reg;
 +      cfg->cfa_offset = cfg->cur_cfa_offset;
  
        mono_debug_open_method (cfg);
  
                if (bb == cfg->bb_exit) {
                        cfg->epilog_begin = cfg->code_len;
                        mono_arch_emit_epilog (cfg);
 +                      cfg->epilog_end = cfg->code_len;
                }
        }
  
@@@ -4650,7 -4494,7 +4499,7 @@@ create_jit_info (MonoCompile *cfg, Mono
  
                        info = mono_jit_info_get_arch_eh_info (jinfo);
                        g_assert (info);
 -                      info->epilog_size = cfg->code_size - cfg->epilog_begin;
 +                      info->epilog_size = cfg->code_len - cfg->epilog_begin;
                }
                jinfo->unwind_info = unwind_desc;
                g_free (unwind_info);
@@@ -5001,7 -4845,9 +4850,9 @@@ mini_method_compile (MonoMethod *method
        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;
  
        if (cfg->gen_seq_points)
                cfg->seq_points = g_ptr_array_new ();
 +      mono_error_init (&cfg->error);
  
        if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) {
                cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED;
        */
  
  //#define DEBUGSSA "logic_run"
 -#define DEBUGSSA_CLASS "Tests"
 +//#define DEBUGSSA_CLASS "Tests"
  #ifdef DEBUGSSA
  
        if (!cfg->disable_ssa) {
@@@ -6103,10 -5948,6 +5954,10 @@@ mono_jit_compile_method_inner (MonoMeth
        case MONO_EXCEPTION_OUT_OF_MEMORY:
                ex = mono_domain_get ()->out_of_memory_ex;
                break;
 +      case MONO_EXCEPTION_MONO_ERROR:
 +              g_assert (!mono_error_ok (&cfg->error));
 +              ex = mono_error_convert_to_exception (&cfg->error);
 +              break;
        default:
                g_assert_not_reached ();
        }
@@@ -7064,7 -6905,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"))
@@@ -7094,9 -6935,10 +6945,9 @@@ mini_get_debug_options (void
  static gpointer
  mini_create_ftnptr (MonoDomain *domain, gpointer addr)
  {
 -#if !defined(__ia64__) && !defined(__ppc64__) && !defined(__powerpc64__)
 +#if !defined(__ia64__) && (!defined(__ppc64__) && !defined(__powerpc64__) || _CALL_ELF == 2)
        return addr;
  #else
 -
        gpointer* desc = NULL;
  
        if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr)))
  static gpointer
  mini_get_addr_from_ftnptr (gpointer descr)
  {
 -#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
 +#if defined(__ia64__) || ((defined(__ppc64__) || defined(__powerpc64__)) && _CALL_ELF != 2)
        return *(gpointer*)descr;
  #else
        return descr;
@@@ -7142,6 -6984,7 +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);
  }
  
  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 -7069,6 +7078,6 @@@ runtime_invoke_info_free (gpointer valu
        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)
  {
diff --combined mono/mini/mini.h
index cfd1053320746dbe7dc71be133f232f62413a561,18d9425211079705913656a72d5e16d871661bf0..2169a79423f1b5440e27fd30fd9736a56b807dc8
  #endif
  
  /* Version number of the AOT file format */
 -#define MONO_AOT_FILE_VERSION 103
 +#define MONO_AOT_FILE_VERSION 104
  
  //TODO: This is x86/amd64 specific.
  #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
  #define printf g_print
  #endif
  
 -#if !defined(HAVE_KW_THREAD) || !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR)
 -#define MONO_JIT_TLS_DATA_HAS_LMF
 -#endif
 -
  #define MONO_TYPE_IS_PRIMITIVE(t) ((!(t)->byref && ((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_R8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
  
  /* Constants used to encode different types of methods in AOT */
@@@ -329,28 -333,19 +329,13 @@@ typedef struct 
   */
  typedef MonoStackFrameInfo StackFrameInfo;
  
- #define MONO_SEQ_POINT_FLAG_NONEMPTY_STACK 1
- typedef struct {
-       int il_offset, native_offset, flags;
-       /* Indexes of successor sequence points */
-       int *next;
-       /* Number of entries in next */
-       int next_len;
- } SeqPoint;
- typedef struct {
-       int len;
-       SeqPoint seq_points [MONO_ZERO_LEN_ARRAY];
- } MonoSeqPointInfo;
  #if 0
  #define mono_bitset_foreach_bit(set,b,n) \
        for (b = 0; b < n; b++)\
                if (mono_bitset_test_fast(set,b))
 -#define mono_bitset_foreach_bit_rev(set,b,n) \
 -      for (b = n - 1; b >= 0; b--)\
 -              if (mono_bitset_test_fast(set,b))
  #else
  #define mono_bitset_foreach_bit(set,b,n) \
        for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
 -#define mono_bitset_foreach_bit_rev(set,b,n) \
 -      for (b = mono_bitset_find_last (set, n - 1); b >= 0; b = b ? mono_bitset_find_last (set, b) : -1)
 - 
  #endif
  
  /*
@@@ -387,6 -382,11 +372,6 @@@ enum 
          (dest)->inst.cil_code = (cfg)->ip;  \
        } while (0)
  
 -#define MONO_INST_NEW_CALL_ARG(cfg,dest,op) do {      \
 -              (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallArgParm));        \
 -              (dest)->ins.opcode = (op);      \
 -      } while (0)
 -
  #define MONO_ADD_INS(b,inst) do {     \
                if ((b)->last_ins) {    \
                        (b)->last_ins->next = (inst);   \
@@@ -1431,7 -1431,6 +1416,7 @@@ typedef struct 
        guint            code_len;
        guint            prolog_end;
        guint            epilog_begin;
 +      guint            epilog_end;
        regmask_t        used_int_regs;
        guint32          opt;
        guint32          prof_options;
        guint            uses_simd_intrinsics : 1;
        guint            keep_cil_nops : 1;
        guint            gen_seq_points : 1;
+       guint            gen_seq_points_debug_data : 1;
        guint            explicit_null_checks : 1;
        guint            compute_gc_maps : 1;
        guint            soft_breakpoints : 1;
        GPtrArray *seq_points;
  
        /* The encoded sequence point info */
-       MonoSeqPointInfo *seq_point_info;
+       struct MonoSeqPointInfo *seq_point_info;
  
        /* Method headers which need to be freed after compilation */
        GSList *headers_to_free;
        /* The offsets of the locals area relative to the frame pointer */
        gint locals_min_stack_offset, locals_max_stack_offset;
  
 +      /* The current CFA rule */
 +      int cur_cfa_reg, cur_cfa_offset;
 +
        /* The final CFA rule at the end of the prolog */
        int cfa_reg, cfa_offset;
  
        guint8 *gc_map;
        guint32 gc_map_size;
  
 +      /* Error handling */
 +      MonoError error;
 +
        /* Stats */
        int stat_allocate_var;
        int stat_locals_stack_size;
@@@ -1666,6 -1660,7 +1652,7 @@@ typedef struct 
        gint32 max_code_size_ratio;
        gint32 biggest_method_size;
        gint32 allocated_code_size;
+       gint32 allocated_seq_points_size;
        gint32 inlineable_methods;
        gint32 inlined_methods;
        gint32 basic_blocks;
@@@ -1844,7 -1839,11 +1831,11 @@@ typedef struct 
        gboolean suspend_on_unhandled;
        gboolean dyn_runtime_invoke;
        gboolean gdb;
-       gboolean gen_seq_points;
+       /*
+        * Whenever data such as next sequence points and flags is required.
+        * Next sequence points and flags are required by the debugger agent.
+        */
+       gboolean gen_seq_points_debug_data;
        gboolean explicit_null_checks;
        /*
         * Fill stack frames with 0x2a in method prologs. This helps with the
@@@ -2746,6 -2745,8 +2737,6 @@@ enum 
        SIMD_VERSION_INDEX_END = 6 
  };
  
 -#define MASK(x) (1 << x)
 -
  enum {
        SIMD_COMP_EQ,
        SIMD_COMP_LT,