#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-digest.h>
+#include <mono/utils/mono-threads-coop.h>
#include "mini.h"
#include "seq-points.h"
}
break;
}
- case MONO_WRAPPER_LDFLD_REMOTE:
- ref->method = mono_marshal_get_ldfld_remote_wrapper (NULL);
- break;
- case MONO_WRAPPER_STFLD_REMOTE:
- ref->method = mono_marshal_get_stfld_remote_wrapper (NULL);
- break;
#endif
case MONO_WRAPPER_ALLOC: {
int atype = decode_value (p, &p);
+ ManagedAllocatorVariant variant =
+ mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS ?
+ MANAGED_ALLOCATOR_SLOW_PATH : MANAGED_ALLOCATOR_REGULAR;
- ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
+ ref->method = mono_gc_get_managed_allocator_by_type (atype, variant);
if (!ref->method) {
mono_error_set_bad_image_name (error, module->aot_name, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
return FALSE;
msg = g_strdup_printf ("not compiled with --aot=llvmonly");
usable = FALSE;
}
-#ifdef TARGET_ARM
- /* mono_arch_find_imt_method () requires this */
- if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
- msg = g_strdup_printf ("compiled against LLVM");
- usable = FALSE;
- }
- if (!(info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && mono_use_llvm) {
- msg = g_strdup_printf ("not compiled against LLVM");
- usable = FALSE;
- }
-#endif
if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
msg = g_strdup_printf ("not compiled for debugging");
usable = FALSE;
find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info);
}
+ // Copy aotid to MonoImage
+ memcpy(&assembly->image->aotid, info->aotid, 16);
+
if (version_symbol) {
/* Old file format */
version = atoi (version_symbol);
}
gpointer
-mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error)
{
- MonoError error;
int i;
MonoClass *klass = vtable->klass;
MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
gboolean err;
MethodRef ref;
gboolean res;
+ gpointer addr;
+ MonoError inner_error;
+
+ mono_error_init (error);
if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !amodule)
return NULL;
return NULL;
for (i = 0; i < slot; ++i) {
- decode_method_ref (amodule, &ref, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ decode_method_ref (amodule, &ref, p, &p, &inner_error);
+ mono_error_cleanup (&inner_error); /* FIXME don't swallow the error */
}
- res = decode_method_ref (amodule, &ref, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ res = decode_method_ref (amodule, &ref, p, &p, &inner_error);
+ mono_error_cleanup (&inner_error); /* FIXME don't swallow the error */
if (!res)
return NULL;
if (ref.no_aot_trampoline)
if (mono_metadata_token_index (ref.token) == 0 || mono_metadata_token_table (ref.token) != MONO_TABLE_METHOD)
return NULL;
- return mono_aot_get_method_from_token (domain, ref.image, ref.token);
+ addr = mono_aot_get_method_from_token (domain, ref.image, ref.token, error);
+ return addr;
}
gboolean
return FALSE;
}
+static void
+init_llvmonly_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoGenericContext *context)
+{
+ gboolean res;
+ MonoError error;
+
+ res = init_method (amodule, method_index, method, init_class, context, &error);
+ if (!is_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ /* Its okay to raise in llvmonly mode */
+ if (ex)
+ mono_llvm_throw_exception ((MonoObject*)ex);
+ }
+}
+
void
mono_aot_init_llvm_method (gpointer aot_module, guint32 method_index)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
- MonoError error;
- res = init_method (amodule, method_index, NULL, NULL, NULL, &error);
- // FIXME: Pass the exception up to the caller ?
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, NULL, NULL);
}
void
mono_aot_init_gshared_method_this (gpointer aot_module, guint32 method_index, MonoObject *this_obj)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoClass *klass;
MonoGenericContext *context;
MonoMethod *method;
- MonoError error;
// FIXME:
g_assert (this_obj);
context = mono_method_get_context (method);
g_assert (context);
- res = init_method (amodule, method_index, NULL, klass, context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, klass, context);
}
void
mono_aot_init_gshared_method_mrgctx (gpointer aot_module, guint32 method_index, MonoMethodRuntimeGenericContext *rgctx)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoGenericContext context = { NULL, NULL };
MonoClass *klass = rgctx->class_vtable->klass;
- MonoError error;
if (klass->generic_class)
context.class_inst = klass->generic_class->context.class_inst;
context.class_inst = klass->generic_container->context.class_inst;
context.method_inst = rgctx->method_inst;
- res = init_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context);
}
void
mono_aot_init_gshared_method_vtable (gpointer aot_module, guint32 method_index, MonoVTable *vtable)
{
MonoAotModule *amodule = (MonoAotModule *)aot_module;
- gboolean res;
MonoClass *klass;
MonoGenericContext *context;
MonoMethod *method;
- MonoError error;
klass = vtable->klass;
context = mono_method_get_context (method);
g_assert (context);
- res = init_method (amodule, method_index, NULL, klass, context, &error);
- /* Its okay to raise in llvmonly mode */
- mono_error_raise_exception (&error);
+ init_llvmonly_method (amodule, method_index, NULL, klass, context);
}
/*
MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
guint8 *code;
gboolean cache_result = FALSE;
+ MonoError inner_error;
mono_error_init (error);
* remoting.
*/
if (mono_aot_only && method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK)
- return mono_aot_get_method (domain, mono_marshal_method_from_wrapper (method));
+ return mono_aot_get_method_checked (domain, mono_marshal_method_from_wrapper (method), error);
g_assert (klass->inited);
if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED && method->klass->rank && strstr (method->name, "System.Collections.Generic")) {
MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method);
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+ mono_error_cleanup (&inner_error);
if (code)
return code;
}
* an out parameter, so the managed-to-native wrappers can share the same code.
*/
if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE && method->klass == mono_defaults.array_class && !strcmp (method->name, "GetGenericValueImpl")) {
- MonoError error;
MonoMethod *m;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &mono_defaults.object_class->byval_arg;
ctx.method_inst = mono_metadata_get_generic_inst (1, args);
- m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, &error), TRUE, TRUE);
+ m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, error), TRUE, TRUE);
if (!m)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ g_error ("AOT runtime could not load method due to %s", mono_error_get_message (error)); /* FIXME don't swallow the error */
/*
* Get the code for the <object> instantiation which should be emitted into
* the mscorlib aot image by the AOT compiler.
*/
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+ mono_error_cleanup (&inner_error);
if (code)
return code;
}
((!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Interlocked") && (!strcmp (method->name, "CompareExchange") || !strcmp (method->name, "Exchange")) && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->params [1]))) ||
(!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Volatile") && (!strcmp (method->name, "Read") && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->ret)))) ||
(!strcmp (method->klass->name_space, "System.Threading") && !strcmp (method->klass->name, "Volatile") && (!strcmp (method->name, "Write") && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (mono_method_signature (method)->params [1])))))) {
- MonoError error;
MonoMethod *m;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &mono_defaults.object_class->byval_arg;
ctx.method_inst = mono_metadata_get_generic_inst (1, args);
- m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, &error), TRUE, TRUE);
+ m = mono_marshal_get_native_wrapper (mono_class_inflate_generic_method_checked (m, &ctx, error), TRUE, TRUE);
if (!m)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ g_error ("AOT runtime could not load method due to %s", mono_error_get_message (error)); /* FIXME don't swallow the error */
/* Avoid recursion */
if (method == m)
* Get the code for the <object> instantiation which should be emitted into
* the mscorlib aot image by the AOT compiler.
*/
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+ mono_error_cleanup (&inner_error);
if (code)
return code;
}
if (info->subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR) {
MonoMethod *array_method = info->d.array_accessor.method;
if (MONO_TYPE_IS_REFERENCE (&array_method->klass->element_class->byval_arg)) {
- MonoClass *obj_array_class = mono_array_class_get (mono_defaults.object_class, 1);
+ int rank;
+
+ if (!strcmp (array_method->name, "Set"))
+ rank = mono_method_signature (array_method)->param_count - 1;
+ else if (!strcmp (array_method->name, "Get") || !strcmp (array_method->name, "Address"))
+ rank = mono_method_signature (array_method)->param_count;
+ else
+ g_assert_not_reached ();
+ MonoClass *obj_array_class = mono_array_class_get (mono_defaults.object_class, rank);
MonoMethod *m = mono_class_get_method_from_name (obj_array_class, array_method->name, mono_method_signature (array_method)->param_count);
g_assert (m);
m = mono_marshal_get_array_accessor_wrapper (m);
if (m != method) {
- code = (guint8 *)mono_aot_get_method (domain, m);
+ code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+ mono_error_cleanup (&inner_error);
if (code)
return code;
}
MonoError error;
gpointer res = mono_aot_get_method_checked (domain, method, &error);
- mono_error_raise_exception (&error);
+ /* This is external only, so its ok to raise here */
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
return res;
}
* method.
*/
gpointer
-mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
+mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error)
{
MonoAotModule *aot_module = (MonoAotModule *)image->aot_module;
int method_index;
- MonoError error;
gpointer res;
+ mono_error_init (error);
+
if (!aot_module)
return NULL;
method_index = mono_metadata_token_index (token) - 1;
- res = load_method (domain, aot_module, image, NULL, token, method_index, &error);
- mono_error_raise_exception (&error); /* FIXME: Don't raise here */
+ res = load_method (domain, aot_module, image, NULL, token, method_index, error);
return res;
}
return NULL;
}
+gpointer
+mono_aot_get_method_checked (MonoDomain *domain,
+ MonoMethod *method, MonoError *error)
+{
+ mono_error_init (error);
+ return NULL;
+}
+
gboolean
mono_aot_is_got_entry (guint8 *code, guint8 *addr)
{
}
gpointer
-mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
+mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error)
{
+ mono_error_init (error);
return NULL;
}
}
gpointer
-mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error)
{
+ mono_error_init (error);
+
return NULL;
}