+2002-05-27 Dietmar Maurer <dietmar@ximian.com>
+
+ * helpers.c (map_arg_type): move some generic helper function into
+ this file.
+
+ * mono.c (usage): new option --breakonex
+
+ * exception.c (arch_exc_is_caught): only return FALSE if really
+ unhandled.
+
+ * jit.c (mono_thread_abort): free jit_tls
+
2002-05-24 Dietmar Maurer <dietmar@ximian.com>
+ * x86.brg (stmt): use memmove to cope with overlapping
+ blocks. This is not required by the specs, so we can remove it
+ later if it turns out to be too slow (and use memcpy).
+
* jit.c (mono_analyze_stack): moved const. folding from x86.brg
* x86.brg: CPBLK impl.
exception.c \
invoke.c \
message.c \
- linear-scan.c
+ linear-scan.c \
+ helpers.h \
+ helpers.c
mono_SOURCES = mono.c
#include <mono/metadata/profiler-private.h>
#include "jit.h"
+#include "helpers.h"
#include "codegen.h"
#include "debug.h"
ip = (gpointer)(*((int *)bp + 1) - 5);
bp = (gpointer)(*((int *)bp));
- if (bp >= end_of_stack)
- return FALSE;
+ if (bp >= end_of_stack) {
+ if (!jit_tls->env)
+ return FALSE;
+ return TRUE;
+ }
} else {
- if (!lmf)
+ if (!lmf)
return FALSE;
bp = (gpointer)lmf->ebp;
lmf = lmf->previous_lmf;
- if (bp >= end_of_stack)
- return FALSE;
+ if (bp >= end_of_stack) {
+ if (!jit_tls->env)
+ return FALSE;
+ return TRUE;
+ }
}
}
cleanup = jit_tls->abort_func;
if (!arch_exc_is_caught (domain, jit_tls, ip, (gpointer *)ctx->SC_EBP, obj)) {
- if (mono_debug_format != MONO_DEBUG_FORMAT_NONE) {
- mono_debug_make_symbols ();
+ if (mono_break_on_exc) {
+ if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
+ mono_debug_make_symbols ();
+ G_BREAKPOINT ();
}
mono_unhandled_exception (obj);
}
--- /dev/null
+/*
+ * helpers.c: architecture independent helper functions
+ *
+ * Author:
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+
+#include <config.h>
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
+#include <glib.h>
+
+#include "codegen.h"
+#include "helpers.h"
+
+int
+map_store_svt_type (int svt)
+{
+ switch (svt) {
+ case VAL_I32:
+ return MB_TERM_STIND_I4;
+ case VAL_POINTER:
+ return MB_TERM_STIND_REF;
+ case VAL_I64:
+ return MB_TERM_STIND_I8;
+ case VAL_DOUBLE:
+ return MB_TERM_STIND_R8;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return 0;
+}
+
+void
+mono_get_val_sizes (MonoValueType type, int *size, int *align)
+{
+ switch (type) {
+ case VAL_I32:
+ *size = *align = sizeof (gint32);
+ break;
+ case VAL_I64:
+ *size = *align = sizeof (gint64);
+ break;
+ case VAL_POINTER:
+ *size = *align = sizeof (gpointer);
+ break;
+ case VAL_DOUBLE:
+ *size = *align = sizeof (double);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+/**
+ * map_stind_type:
+ * @type: the type to map
+ *
+ * Translates the MonoType @type into the corresponding store opcode
+ * for the code generator.
+ */
+int
+map_stind_type (MonoType *type)
+{
+ if (type->byref)
+ return MB_TERM_STIND_REF;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+
+ return MB_TERM_STIND_I1;
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ return MB_TERM_STIND_I2;
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ return MB_TERM_STIND_I4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_STIND_REF;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_STIND_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_STIND_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_STIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype)
+ return map_stind_type (type->data.klass->enum_basetype);
+ else
+ return MB_TERM_STIND_OBJ;
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+/**
+ * map_remote_stind_type:
+ * @type: the type to map
+ *
+ * Translates the MonoType @type into the corresponding remote store opcode
+ * for the code generator.
+ */
+int
+map_remote_stind_type (MonoType *type)
+{
+ if (type->byref) {
+ return MB_TERM_REMOTE_STIND_REF;
+ }
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ return MB_TERM_REMOTE_STIND_I1;
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ return MB_TERM_REMOTE_STIND_I2;
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ return MB_TERM_REMOTE_STIND_I4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_REMOTE_STIND_REF;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_REMOTE_STIND_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_REMOTE_STIND_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_REMOTE_STIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype)
+ return map_remote_stind_type (type->data.klass->enum_basetype);
+ else
+ return MB_TERM_REMOTE_STIND_OBJ;
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+int
+map_starg_type (MonoType *type)
+{
+ if (type->byref)
+ return MB_TERM_STIND_REF;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ return MB_TERM_STIND_I4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_STIND_REF;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_STIND_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_STIND_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_STIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype)
+ return map_starg_type (type->data.klass->enum_basetype);
+ else
+ return MB_TERM_STIND_OBJ;
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+int
+map_arg_type (MonoType *type)
+{
+ if (type->byref)
+ return MB_TERM_ARG_I4;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_ARG_I4;
+ case MONO_TYPE_STRING:
+ return MB_TERM_ARG_I4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_ARG_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_ARG_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_ARG_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype)
+ return map_arg_type (type->data.klass->enum_basetype);
+ else
+ return MB_TERM_ARG_OBJ;
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+/**
+ * map_ldind_type:
+ * @type: the type to map
+ *
+ * Translates the MonoType @type into the corresponding load opcode
+ * for the code generator.
+ */
+int
+map_ldind_type (MonoType *type, MonoValueType *svt)
+{
+ if (type->byref) {
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_REF;
+ }
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_I1;
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U1;
+ case MONO_TYPE_I2:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_I2;
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U2;
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_I4;
+ case MONO_TYPE_U4:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_REF;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ *svt = VAL_I64;
+ return MB_TERM_LDIND_I8;
+ case MONO_TYPE_R4:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R4;
+ case MONO_TYPE_R8:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype) {
+ return map_ldind_type (type->data.klass->enum_basetype, svt);
+ } else {
+ *svt = VAL_UNKNOWN;
+ return MB_TERM_LDIND_OBJ;
+ }
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+int
+map_ldarg_type (MonoType *type, MonoValueType *svt)
+{
+ if (type->byref) {
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_REF;
+ }
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_U4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ *svt = VAL_I64;
+ return MB_TERM_LDIND_I8;
+ case MONO_TYPE_R4:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R4;
+ case MONO_TYPE_R8:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype) {
+ return map_ldarg_type (type->data.klass->enum_basetype, svt);
+ } else {
+ *svt = VAL_UNKNOWN;
+ return MB_TERM_LDIND_OBJ;
+ }
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+/**
+ * map_call_type:
+ * @type: the type to map
+ *
+ * Translates the MonoType @type into the corresponding call opcode
+ * for the code generator.
+ */
+int
+map_call_type (MonoType *type, MonoValueType *svt)
+{
+ if (type->byref)
+ return MB_TERM_CALL_I4;
+
+ switch (type->type) {
+ case MONO_TYPE_VOID:
+ *svt = VAL_UNKNOWN;
+ return MB_TERM_CALL_VOID;
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ *svt = VAL_I32;
+ return MB_TERM_CALL_I4;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype) {
+ return map_call_type (type->data.klass->enum_basetype, svt);
+ } else {
+ *svt = VAL_I32;
+ return MB_TERM_CALL_VOID;
+ }
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ *svt = VAL_POINTER;
+ return MB_TERM_CALL_I4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ *svt = VAL_I64;
+ return MB_TERM_CALL_I8;
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_CALL_R8;
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+MBTree *
+mono_ctree_new (MonoMemPool *mp, int op, MBTree *left, MBTree *right)
+{
+ MBTree *t = mono_mempool_alloc0 (mp, sizeof (MBTree));
+
+ t->op = op;
+ t->left = left;
+ t->right = right;
+ t->reg1 = -1;
+ t->reg2 = -1;
+ t->reg3 = -1;
+ t->svt = VAL_UNKNOWN;
+ t->cli_addr = -1;
+ return t;
+}
+
+MBTree *
+mono_ctree_new_leaf (MonoMemPool *mp, int op)
+{
+ return mono_ctree_new (mp, op, NULL, NULL);
+}
+
+MBTree *
+mono_ctree_new_icon4 (MonoMemPool *mp, gint32 data)
+{
+ MBTree *t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ t1->data.i = data;
+ return t1;
+}
+
+/*
+ * prints the tree to stdout
+ */
+void
+mono_print_ctree (MonoFlowGraph *cfg, MBTree *tree)
+{
+ int arity;
+
+ if (!tree)
+ return;
+
+ arity = (tree->left != NULL) + (tree->right != NULL);
+
+ if (arity)
+ printf (" (%s", mono_burg_term_string [tree->op]);
+ else
+ printf (" %s", mono_burg_term_string [tree->op]);
+
+ switch (tree->op) {
+ case MB_TERM_CONST_I4:
+ printf ("[%d]", tree->data.i);
+ break;
+ case MB_TERM_ADDR_L:
+ if (VARINFO (cfg, tree->data.i).reg >= 0)
+ printf ("[R%d]", tree->data.i);
+ else
+ printf ("[%d]", tree->data.i);
+ break;
+ }
+
+ g_assert (!(tree->right && !tree->left));
+
+ mono_print_ctree (cfg, tree->left);
+ mono_print_ctree (cfg, tree->right);
+
+ if (arity)
+ printf (")");
+}
+
+/*
+ * prints the whole forest to stdout
+ */
+void
+mono_print_forest (MonoFlowGraph *cfg, GPtrArray *forest)
+{
+ const int top = forest->len;
+ int i;
+
+ for (i = 0; i < top; i++) {
+ MBTree *t = (MBTree *) g_ptr_array_index (forest, i);
+ printf (" ");
+ mono_print_ctree (cfg, t);
+ printf ("\n");
+ }
+
+}
+
+/**
+ * mono_disassemble_code:
+ * @code: a pointer to the code
+ * @size: the code size in bytes
+ *
+ * Disassemble to code to stdout.
+ */
+void
+mono_disassemble_code (guint8 *code, int size, char *id)
+{
+ int i;
+ FILE *ofd;
+
+ if (!(ofd = fopen ("/tmp/test.s", "w")))
+ g_assert_not_reached ();
+
+ fprintf (ofd, "%s:\n", id);
+
+ for (i = 0; i < size; ++i)
+ fprintf (ofd, ".byte %d\n", (unsigned int) code [i]);
+
+ fclose (ofd);
+
+ system ("as /tmp/test.s -o /tmp/test.o;objdump -d /tmp/test.o");
+}
+
--- /dev/null
+/*
+ * Author:
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+
+#ifndef _MONO_JIT_HELPERS_H_
+#define _MONO_JIT_HELPERS_H_
+
+#include <config.h>
+
+#include "jit.h"
+
+int
+map_store_svt_type (int svt);
+
+void
+mono_get_val_sizes (MonoValueType type, int *size, int *align);
+
+int
+map_stind_type (MonoType *type);
+
+int
+map_remote_stind_type (MonoType *type);
+
+int
+map_starg_type (MonoType *type);
+
+int
+map_arg_type (MonoType *type);
+
+int
+map_ldind_type (MonoType *type, MonoValueType *svt);
+
+int
+map_ldarg_type (MonoType *type, MonoValueType *svt);
+
+int
+map_call_type (MonoType *type, MonoValueType *svt);
+
+MBTree *
+mono_ctree_new (MonoMemPool *mp, int op, MBTree *left,
+ MBTree *right);
+MBTree *
+mono_ctree_new_leaf (MonoMemPool *mp, int op);
+
+MBTree *
+mono_ctree_new_icon4 (MonoMemPool *mp, gint32 data);
+
+void
+mono_print_ctree (MonoFlowGraph *cfg, MBTree *tree);
+
+void
+mono_print_forest (MonoFlowGraph *cfg, GPtrArray *forest);
+
+void
+mono_disassemble_code (guint8 *code, int size, char *id);
+
+
+#endif
#include <mono/metadata/profiler-private.h>
#include "jit.h"
+#include "helpers.h"
#include "regset.h"
#include "codegen.h"
#include "debug.h"
* semantics, so i disable it until we have a real solution */
/* #define OPT_BOOL */
-/* this is x86 specific */
-#define MB_TERM_LDIND_REF MB_TERM_LDIND_I4
-#define MB_TERM_LDIND_U4 MB_TERM_LDIND_I4
-#define MB_TERM_STIND_REF MB_TERM_STIND_I4
-#define MB_TERM_REMOTE_STIND_REF MB_TERM_REMOTE_STIND_I4
-
#define MAKE_CJUMP(name) \
case CEE_##name: \
case CEE_##name##_S: { \
break; \
}
-#if 0
+#ifndef ARCH_X86
#define MAKE_SPILLED_BI_ALU1(name, s1, s2) { \
t1 = mono_ctree_new (mp, MB_TERM_##name, s1, s2); \
PUSH_TREE (t1, s1->svt); }
/* TLS id to store jit data */
guint32 mono_jit_tls_id;
+/* issue a breakpoint on unhandled excepions */
+gboolean mono_break_on_exc = FALSE;
+
MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
GList *mono_debug_methods = NULL;
typedef void (*MonoCCtor) (void);
-
-inline static MBTree *
-mono_ctree_new_icon4 (MonoMemPool *mp, gint32 data)
-{
- MBTree *t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
- t1->data.i = data;
- return t1;
-}
-
-static int
-map_store_svt_type (int svt)
-{
- switch (svt) {
- case VAL_I32:
- return MB_TERM_STIND_I4;
- case VAL_POINTER:
- return MB_TERM_STIND_REF;
- case VAL_I64:
- return MB_TERM_STIND_I8;
- case VAL_DOUBLE:
- return MB_TERM_STIND_R8;
- default:
- g_assert_not_reached ();
- }
-
- return 0;
-}
-
-/**
- * map_stind_type:
- * @type: the type to map
- *
- * Translates the MonoType @type into the corresponding store opcode
- * for the code generator.
- */
-static int
-map_stind_type (MonoType *type)
-{
- if (type->byref)
- return MB_TERM_STIND_REF;
-
- switch (type->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
-
- return MB_TERM_STIND_I1;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- return MB_TERM_STIND_I2;
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- return MB_TERM_STIND_I4;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return MB_TERM_STIND_REF;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- return MB_TERM_STIND_I8;
- case MONO_TYPE_R4:
- return MB_TERM_STIND_R4;
- case MONO_TYPE_R8:
- return MB_TERM_STIND_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype)
- return map_stind_type (type->data.klass->enum_basetype);
- else
- return MB_TERM_STIND_OBJ;
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-/**
- * map_remote_stind_type:
- * @type: the type to map
- *
- * Translates the MonoType @type into the corresponding remote store opcode
- * for the code generator.
- */
-static int
-map_remote_stind_type (MonoType *type)
-{
- if (type->byref) {
- return MB_TERM_REMOTE_STIND_REF;
- }
-
- switch (type->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- return MB_TERM_REMOTE_STIND_I1;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- return MB_TERM_REMOTE_STIND_I2;
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- return MB_TERM_REMOTE_STIND_I4;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return MB_TERM_REMOTE_STIND_REF;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- return MB_TERM_REMOTE_STIND_I8;
- case MONO_TYPE_R4:
- return MB_TERM_REMOTE_STIND_R4;
- case MONO_TYPE_R8:
- return MB_TERM_REMOTE_STIND_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype)
- return map_remote_stind_type (type->data.klass->enum_basetype);
- else
- return MB_TERM_REMOTE_STIND_OBJ;
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-static int
-map_starg_type (MonoType *type)
-{
- if (type->byref)
- return MB_TERM_STIND_REF;
-
- switch (type->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- return MB_TERM_STIND_I4;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return MB_TERM_STIND_REF;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- return MB_TERM_STIND_I8;
- case MONO_TYPE_R4:
- return MB_TERM_STIND_R4;
- case MONO_TYPE_R8:
- return MB_TERM_STIND_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype)
- return map_starg_type (type->data.klass->enum_basetype);
- else
- return MB_TERM_STIND_OBJ;
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-static int
-map_arg_type (MonoType *type)
-{
- if (type->byref)
- return MB_TERM_ARG_I4;
-
- switch (type->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return MB_TERM_ARG_I4;
- case MONO_TYPE_STRING:
- return MB_TERM_ARG_I4;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- return MB_TERM_ARG_I8;
- case MONO_TYPE_R4:
- return MB_TERM_ARG_R4;
- case MONO_TYPE_R8:
- return MB_TERM_ARG_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype)
- return map_arg_type (type->data.klass->enum_basetype);
- else
- return MB_TERM_ARG_OBJ;
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-/**
- * map_ldind_type:
- * @type: the type to map
- *
- * Translates the MonoType @type into the corresponding load opcode
- * for the code generator.
- */
-static int
-map_ldind_type (MonoType *type, MonoValueType *svt)
-{
- if (type->byref) {
- *svt = VAL_POINTER;
- return MB_TERM_LDIND_REF;
- }
-
- switch (type->type) {
- case MONO_TYPE_I1:
- *svt = VAL_I32;
- return MB_TERM_LDIND_I1;
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- *svt = VAL_I32;
- return MB_TERM_LDIND_U1;
- case MONO_TYPE_I2:
- *svt = VAL_I32;
- return MB_TERM_LDIND_I2;
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- *svt = VAL_I32;
- return MB_TERM_LDIND_U2;
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- *svt = VAL_I32;
- return MB_TERM_LDIND_I4;
- case MONO_TYPE_U4:
- *svt = VAL_I32;
- return MB_TERM_LDIND_U4;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- *svt = VAL_POINTER;
- return MB_TERM_LDIND_REF;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- *svt = VAL_I64;
- return MB_TERM_LDIND_I8;
- case MONO_TYPE_R4:
- *svt = VAL_DOUBLE;
- return MB_TERM_LDIND_R4;
- case MONO_TYPE_R8:
- *svt = VAL_DOUBLE;
- return MB_TERM_LDIND_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype) {
- return map_ldind_type (type->data.klass->enum_basetype, svt);
- } else {
- *svt = VAL_UNKNOWN;
- return MB_TERM_LDIND_OBJ;
- }
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-static int
-map_ldarg_type (MonoType *type, MonoValueType *svt)
-{
- if (type->byref) {
- *svt = VAL_POINTER;
- return MB_TERM_LDIND_REF;
- }
-
- switch (type->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- *svt = VAL_I32;
- return MB_TERM_LDIND_U4;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- *svt = VAL_POINTER;
- return MB_TERM_LDIND_U4;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- *svt = VAL_I64;
- return MB_TERM_LDIND_I8;
- case MONO_TYPE_R4:
- *svt = VAL_DOUBLE;
- return MB_TERM_LDIND_R4;
- case MONO_TYPE_R8:
- *svt = VAL_DOUBLE;
- return MB_TERM_LDIND_R8;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype) {
- return map_ldarg_type (type->data.klass->enum_basetype, svt);
- } else {
- *svt = VAL_UNKNOWN;
- return MB_TERM_LDIND_OBJ;
- }
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-/**
- * map_call_type:
- * @type: the type to map
- *
- * Translates the MonoType @type into the corresponding call opcode
- * for the code generator.
- */
-static int
-map_call_type (MonoType *type, MonoValueType *svt)
-{
- if (type->byref)
- return MB_TERM_CALL_I4;
-
- switch (type->type) {
- case MONO_TYPE_VOID:
- *svt = VAL_UNKNOWN;
- return MB_TERM_CALL_VOID;
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- *svt = VAL_I32;
- return MB_TERM_CALL_I4;
- case MONO_TYPE_VALUETYPE:
- if (type->data.klass->enumtype) {
- return map_call_type (type->data.klass->enum_basetype, svt);
- } else {
- *svt = VAL_I32;
- return MB_TERM_CALL_VOID;
- }
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_SZARRAY:
- *svt = VAL_POINTER;
- return MB_TERM_CALL_I4;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- *svt = VAL_I64;
- return MB_TERM_CALL_I8;
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- *svt = VAL_DOUBLE;
- return MB_TERM_CALL_R8;
- default:
- g_warning ("unknown type %02x", type->type);
- g_assert_not_reached ();
- }
-
- g_assert_not_reached ();
- return -1;
-}
-
-/*
- * prints the tree to stdout
- */
-void
-mono_print_ctree (MonoFlowGraph *cfg, MBTree *tree)
-{
- int arity;
-
- if (!tree)
- return;
-
- arity = (tree->left != NULL) + (tree->right != NULL);
-
- if (arity)
- printf (" (%s", mono_burg_term_string [tree->op]);
- else
- printf (" %s", mono_burg_term_string [tree->op]);
-
- switch (tree->op) {
- case MB_TERM_CONST_I4:
- printf ("[%d]", tree->data.i);
- break;
- case MB_TERM_ADDR_L:
- if (VARINFO (cfg, tree->data.i).reg >= 0)
- printf ("[R%d]", tree->data.i);
- else
- printf ("[%d]", tree->data.i);
- break;
- }
-
- g_assert (!(tree->right && !tree->left));
-
- mono_print_ctree (cfg, tree->left);
- mono_print_ctree (cfg, tree->right);
-
- if (arity)
- printf (")");
-}
-
-/*
- * prints the whole forest to stdout
- */
-void
-mono_print_forest (MonoFlowGraph *cfg, GPtrArray *forest)
-{
- const int top = forest->len;
- int i;
-
- for (i = 0; i < top; i++) {
- MBTree *t = (MBTree *) g_ptr_array_index (forest, i);
- printf (" ");
- mono_print_ctree (cfg, t);
- printf ("\n");
- }
-
-}
-
-/**
- * mono_disassemble_code:
- * @code: a pointer to the code
- * @size: the code size in bytes
- *
- * Disassemble to code to stdout.
- */
-void
-mono_disassemble_code (guint8 *code, int size, char *id)
-{
- int i;
- FILE *ofd;
-
- if (!(ofd = fopen ("/tmp/test.s", "w")))
- g_assert_not_reached ();
-
- fprintf (ofd, "%s:\n", id);
-
- for (i = 0; i < size; ++i)
- fprintf (ofd, ".byte %d\n", (unsigned int) code [i]);
-
- fclose (ofd);
-
- system ("as /tmp/test.s -o /tmp/test.o;objdump -d /tmp/test.o");
-}
-
-inline static void
-mono_get_val_sizes (MonoValueType type, int *size, int *align)
-{
- switch (type) {
- case VAL_I32:
- *size = *align = sizeof (gint32);
- break;
- case VAL_I64:
- *size = *align = sizeof (gint64);
- break;
- case VAL_POINTER:
- *size = *align = sizeof (gpointer);
- break;
- case VAL_DOUBLE:
- *size = *align = sizeof (double);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
static int
mono_allocate_intvar (MonoFlowGraph *cfg, int slot, MonoValueType type)
{
g_assert (obj);
- if (mono_debug_format != MONO_DEBUG_FORMAT_NONE) {
- mono_debug_make_symbols ();
- G_BREAKPOINT ();
- }
-
if (jit_tls->env) {
longjmp (*jit_tls->env, (int)obj);
}
+ g_free (jit_tls);
+
ExitThread (-1);
}
static CRITICAL_SECTION ms;
-MonoDomain*
-mono_jit_init (char *file) {
+static void
+mono_runtime_install_handlers (void)
+{
#ifndef PLATFORM_WIN32
struct sigaction sa;
#endif
- MonoDomain *domain;
-
- mono_cpu_detect ();
#ifdef PLATFORM_WIN32
win32_seh_init();
g_assert (syscall (SYS_sigaction, SIGSEGV, &sa, NULL) != -1);
#endif
#endif /* PLATFORM_WIN32 */
+}
+
+MonoDomain*
+mono_jit_init (char *file) {
+ MonoDomain *domain;
+
+ mono_cpu_detect ();
+
+ mono_runtime_install_handlers ();
mono_init_icall ();
mono_add_internal_call ("System.Array::Set", ves_array_set);
#include "regset.h"
+/* fixme: configure should set that */
+#define ARCH_X86
+
+#ifdef ARCH_X86
+#define MB_TERM_LDIND_REF MB_TERM_LDIND_I4
+#define MB_TERM_LDIND_U4 MB_TERM_LDIND_I4
+#define MB_TERM_STIND_REF MB_TERM_STIND_I4
+#define MB_TERM_REMOTE_STIND_REF MB_TERM_REMOTE_STIND_I4
+#endif
+
#define ISSTRUCT(t) (!t->byref && t->type == MONO_TYPE_VALUETYPE && !t->data.klass->enumtype)
#define VARINFO(cfg,num) (g_array_index (cfg->varinfo, MonoVarInfo, num))
extern gboolean mono_jit_inline_code;
extern gboolean mono_use_linear_scan;
extern gboolean mono_use_fast_iconv;
+extern gboolean mono_break_on_exc;
extern guint32 mono_jit_tls_id;
void
mono_jit_compile_class (MonoAssembly *assembly, char *compile_class,
int compile_times, int verbose);
-MBTree *
-mono_ctree_new (MonoMemPool *mp, int op, MBTree *left,
- MBTree *right);
-MBTree *
-mono_ctree_new_leaf (MonoMemPool *mp, int op);
-
void
mono_add_jump_info (MonoFlowGraph *cfg, gpointer ip,
MonoJumpInfoType type, gpointer target);
-void
-mono_disassemble_code (guint8 *code, int size, char *id);
-
gpointer
mono_compile_method (MonoMethod *method);
MonoObject *result, MonoArray *out_args);
-/* some handy debugging functions */
-
-void
-mono_print_ctree (MonoFlowGraph *cfg, MBTree *tree);
-
-void
-mono_print_forest (MonoFlowGraph *cfg, GPtrArray *forest);
-
#endif
" --debug-args ARGS comma-separated list of additional arguments for the\n"
" symbol writer. See the manpage for details.\n"
" --profile record and dump profile info\n"
+ " --breakonex set a breakpoint for unhandled exception\n"
" --break NAME insert a breakpoint at the start of method NAME\n"
" (NAME is in `namespace.name:methodname' format)\n"
" --precompile name precompile NAME before executing the main application:\n"
mono_jit_inline_code = FALSE;
else if (strcmp (argv [i], "--nols") == 0)
mono_use_linear_scan = FALSE;
+ else if (strcmp (argv [i], "--breakonex") == 0)
+ mono_break_on_exc = TRUE;
else if (strcmp (argv [i], "--print-vtable") == 0)
mono_print_vtable = TRUE;
else if (strcmp (argv [i], "--break") == 0) {
x86_push_reg (s->code, size_reg);
x86_push_reg (s->code, source_reg);
x86_push_reg (s->code, dest_reg);
- mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, memcpy);
+ mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, memmove);
x86_call_code (s->code, 0);
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
}
return a % b;
}
-MBTree *
-mono_ctree_new (MonoMemPool *mp, int op, MBTree *left, MBTree *right)
-{
- MBTree *t = mono_mempool_alloc0 (mp, sizeof (MBTree));
-
- t->op = op;
- t->left = left;
- t->right = right;
- t->reg1 = -1;
- t->reg2 = -1;
- t->reg3 = -1;
- t->svt = VAL_UNKNOWN;
- t->cli_addr = -1;
- return t;
-}
-
-MBTree *
-mono_ctree_new_leaf (MonoMemPool *mp, int op)
-{
- return mono_ctree_new (mp, op, NULL, NULL);
-}
-
MonoArray*
mono_array_new_wrapper (MonoClass *eclass, guint32 n)
{