return mono_type_to_ldind (type);
}
+#ifndef DISABLE_JIT
+
guint
mini_type_to_stind (MonoCompile* cfg, MonoType *type)
{
bb->max_vreg = MAX (bb->max_vreg, cfg->next_vreg);
}
+#endif
+
static void
set_vreg_to_inst (MonoCompile *cfg, int vreg, MonoInst *inst)
{
return NULL;
}
-void
-mono_register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, gboolean no_throw)
+static void
+register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, const char *symbol, gboolean no_throw)
{
MonoJitICallInfo *info;
MonoMethodSignature *sig = mono_create_icall_signature (sigstr);
g_assert (!sig->hasthis);
g_assert (sig->param_count < 3);
- info = mono_register_jit_icall (func, name, sig, no_throw);
+ info = mono_register_jit_icall_full (func, name, sig, no_throw, symbol);
if (emul_opcode_num >= emul_opcode_alloced) {
int incr = emul_opcode_alloced? emul_opcode_alloced/2: 16;
emul_opcode_hit_cache [opcode >> (EMUL_HIT_SHIFT + 3)] |= (1 << (opcode & EMUL_HIT_MASK));
}
+/*
+ * For JIT icalls implemented in C.
+ * NAME should be the same as the name of the C function whose address is FUNC.
+ */
static void
register_icall (gpointer func, const char *name, const char *sigstr, gboolean save)
{
MonoMethodSignature *sig;
+ if (sigstr)
+ sig = mono_create_icall_signature (sigstr);
+ else
+ sig = NULL;
+
+ mono_register_jit_icall_full (func, name, sig, save, save ? name : NULL);
+}
+
+static void
+register_dyn_icall (gpointer func, const char *name, const char *sigstr, gboolean save)
+{
+ MonoMethodSignature *sig;
+
if (sigstr)
sig = mono_create_icall_signature (sigstr);
else
#else
MonoJitTlsData *jit_tls;
- if ((jit_tls = mono_native_tls_get_value (mono_jit_tls_id)))
+ jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ if (G_LIKELY (jit_tls))
return &jit_tls->lmf;
/*
memcpy (res->data.rgctx_entry, patch_info->data.rgctx_entry, sizeof (MonoJumpInfoRgctxEntry));
res->data.rgctx_entry->data = mono_patch_info_dup_mp (mp, res->data.rgctx_entry->data);
break;
+ case MONO_PATCH_INFO_GSHAREDVT_CALL:
+ res->data.gsharedvt = mono_mempool_alloc (mp, sizeof (MonoJumpInfoGSharedVtCall));
+ memcpy (res->data.gsharedvt, patch_info->data.gsharedvt, sizeof (MonoJumpInfoGSharedVtCall));
+ break;
default:
break;
}
case MONO_PATCH_INFO_SFLDA:
case MONO_PATCH_INFO_SEQ_POINT_INFO:
return (ji->type << 8) | (gssize)ji->data.target;
+ case MONO_PATCH_INFO_GSHAREDVT_CALL:
+ return (ji->type << 8) | (gssize)ji->data.gsharedvt->method;
default:
return (ji->type << 8);
}
break;
case MONO_PATCH_INFO_INTERNAL_METHOD:
return g_str_equal (ji1->data.name, ji2->data.name);
-
case MONO_PATCH_INFO_RGCTX_FETCH: {
MonoJumpInfoRgctxEntry *e1 = ji1->data.rgctx_entry;
MonoJumpInfoRgctxEntry *e2 = ji2->data.rgctx_entry;
return e1->method == e2->method && e1->in_mrgctx == e2->in_mrgctx && e1->info_type == e2->info_type && mono_patch_info_equal (e1->data, e2->data);
}
+ case MONO_PATCH_INFO_GSHAREDVT_CALL: {
+ MonoJumpInfoGSharedVtCall *c1 = ji1->data.gsharedvt;
+ MonoJumpInfoGSharedVtCall *c2 = ji2->data.gsharedvt;
+
+ return c1->sig == c2->sig && c1->method == c2->method;
+ }
default:
if (ji1->data.target != ji2->data.target)
return 0;
target = mono_icall_get_wrapper (mi);
break;
}
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR: {
+ MonoJitICallInfo *mi = mono_find_jit_icall_by_name (patch_info->data.name);
+ if (!mi) {
+ g_warning ("unknown MONO_PATCH_INFO_JIT_ICALL_ADDR %s", patch_info->data.name);
+ g_assert_not_reached ();
+ }
+ target = mi->func;
+ break;
+ }
case MONO_PATCH_INFO_METHOD_JUMP:
target = mono_create_jump_trampoline (domain, patch_info->data.method, FALSE);
#if defined(__native_client__) && defined(__native_client_codegen__)
g_error ("Unregistered icall '%s'\n", mono_method_full_name (patch_info->data.method, TRUE));
}
break;
- case MONO_PATCH_INFO_JIT_ICALL_ADDR: {
- MonoJitICallInfo *mi = mono_find_jit_icall_by_name (patch_info->data.name);
- if (!mi) {
- g_warning ("unknown MONO_PATCH_INFO_JIT_ICALL_ADDR %s", patch_info->data.name);
- g_assert_not_reached ();
- }
- target = mi->func;
- break;
- }
case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG:
target = mono_thread_interruption_request_flag ();
break;
case MONO_PATCH_INFO_FIELD:
slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.field, entry->info_type, mono_method_get_context (entry->method));
break;
+ case MONO_PATCH_INFO_SIGNATURE:
+ slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.sig, entry->info_type, mono_method_get_context (entry->method));
+ break;
+ case MONO_PATCH_INFO_GSHAREDVT_CALL: {
+ MonoJumpInfoGSharedVtCall *call_info = mono_domain_alloc0 (domain, sizeof (MonoJumpInfoGSharedVtCall));
+
+ memcpy (call_info, entry->data->data.gsharedvt, sizeof (MonoJumpInfoGSharedVtCall));
+ slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, call_info, entry->info_type, mono_method_get_context (entry->method));
+ break;
+ }
default:
g_assert_not_reached ();
break;
target = mono_domain_alloc0 (domain, sizeof (gpointer));
break;
}
+ case MONO_PATCH_INFO_JIT_TLS_ID: {
+ target = (gpointer)mono_jit_tls_id;
+ break;
+ }
default:
g_assert_not_reached ();
}
mono_arch_create_vars (cfg);
}
-#endif /* #ifndef DISABLE_JIT */
-
void
mono_print_code (MonoCompile *cfg, const char* msg)
{
mono_print_bb (bb, msg);
}
-#ifndef DISABLE_JIT
-
static void
mono_postprocess_patches (MonoCompile *cfg)
{
*/
if (info) {
//printf ("TEST %s %p\n", info->name, patch_info->data.target);
- // FIXME: CLEAN UP THIS MESS.
- if ((cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) &&
- strstr (cfg->method->name, info->name)) {
- /*
- * This is an icall wrapper, and this is a call to the
- * wrapped function.
- */
- if (cfg->compile_aot) {
- patch_info->type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
- patch_info->data.name = info->name;
- }
- } else {
- /* for these array methods we currently register the same function pointer
- * since it's a vararg function. But this means that mono_find_jit_icall_by_addr ()
- * will return the incorrect one depending on the order they are registered.
- * See tests/test-arr.cs
- */
- if (strstr (info->name, "ves_array_new_va_") == NULL && strstr (info->name, "ves_array_element_address_") == NULL) {
- patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
- patch_info->data.name = info->name;
- }
+ /* for these array methods we currently register the same function pointer
+ * since it's a vararg function. But this means that mono_find_jit_icall_by_addr ()
+ * will return the incorrect one depending on the order they are registered.
+ * See tests/test-arr.cs
+ */
+ if (strstr (info->name, "ves_array_new_va_") == NULL && strstr (info->name, "ves_array_element_address_") == NULL) {
+ patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
+ patch_info->data.name = info->name;
}
}
}
}
+#endif /* #ifndef DISABLE_JIT */
+
static MonoJitInfo*
create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
{
guint8 *uw_info;
guint32 info_len;
- uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+ if (info->uw_info) {
+ uw_info = info->uw_info;
+ info_len = info->uw_info_len;
+ } else {
+ uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+ }
jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
jinfo->method = wrapper;
return jinfo;
}
+#ifndef DISABLE_JIT
+
static MonoJitInfo*
create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
{
return FALSE;
}
+static gboolean
+has_ref_constraint (MonoGenericParamInfo *info)
+{
+ MonoClass **constraints;
+
+ //return FALSE;
+
+ if (info && info->constraints) {
+ constraints = info->constraints;
+
+ while (*constraints) {
+ MonoClass *cklass = *constraints;
+ if (!(cklass == mono_defaults.object_class || (cklass->image == mono_defaults.corlib && !strcmp (cklass->name, "ValueType")) || MONO_CLASS_IS_INTERFACE (cklass)))
+ return TRUE;
+ constraints ++;
+ }
+ }
+ return FALSE;
+}
+
+static MonoGenericInst*
+get_shared_inst (MonoGenericInst *inst, MonoGenericInst *shared_inst, MonoGenericContainer *container, gboolean all_vt, gboolean gsharedvt)
+{
+ MonoGenericInst *res;
+ MonoType **type_argv;
+ int i;
+
+ type_argv = g_new0 (MonoType*, inst->type_argc);
+ for (i = 0; i < inst->type_argc; ++i) {
+ if (!all_vt && (MONO_TYPE_IS_REFERENCE (inst->type_argv [i]) || inst->type_argv [i]->type == MONO_TYPE_VAR || inst->type_argv [i]->type == MONO_TYPE_MVAR)) {
+ type_argv [i] = shared_inst->type_argv [i];
+ } else if (all_vt) {
+ if (container && has_ref_constraint (&container->type_params [i].info))
+ type_argv [i] = shared_inst->type_argv [i];
+ else
+ type_argv [i] = get_gsharedvt_type (shared_inst->type_argv [i]);
+ } else if (gsharedvt) {
+ type_argv [i] = get_gsharedvt_type (shared_inst->type_argv [i]);
+ } else {
+ type_argv [i] = inst->type_argv [i];
+ }
+ }
+
+ res = mono_metadata_get_generic_inst (inst->type_argc, type_argv);
+ g_free (type_argv);
+ return res;
+}
+
/*
* mini_get_shared_method_full:
*
* Return the method which is actually compiled/registered when doing generic sharing.
* If ALL_VT is true, return the shared method belonging to an all-vtype instantiation.
* If IS_GSHAREDVT is true, treat METHOD as a gsharedvt method even if it fails some constraints.
+ * METHOD can be a non-inflated generic method.
*/
MonoMethod*
mini_get_shared_method_full (MonoMethod *method, gboolean all_vt, gboolean is_gsharedvt)
{
MonoGenericContext shared_context;
MonoMethod *declaring_method, *res;
- int i;
gboolean partial = FALSE;
gboolean gsharedvt = FALSE;
+ MonoGenericContainer *class_container, *method_container = NULL;
- if (method->is_generic || method->klass->generic_container)
+ if (method->is_generic || method->klass->generic_container) {
declaring_method = method;
- else
+ } else {
declaring_method = mono_method_get_declaring_generic_method (method);
+ }
if (declaring_method->is_generic)
shared_context = mono_method_get_generic_container (declaring_method)->context;
is_gsharedvt || mini_is_gsharedvt_sharable_method (method)) {
MonoGenericContext *context = mono_method_get_context (method);
MonoGenericInst *inst;
- MonoType **type_argv;
gsharedvt = is_gsharedvt || mini_is_gsharedvt_sharable_method (method);
+ class_container = declaring_method->klass->generic_container;
+ method_container = mono_method_get_generic_container (declaring_method);
+
/*
* Create the shared context by replacing the ref type arguments with
* type parameters, and keeping the rest.
*/
partial = TRUE;
- inst = context->class_inst;
- if (inst) {
- type_argv = g_new0 (MonoType*, inst->type_argc);
- for (i = 0; i < inst->type_argc; ++i) {
- if (!all_vt && (MONO_TYPE_IS_REFERENCE (inst->type_argv [i]) || inst->type_argv [i]->type == MONO_TYPE_VAR || inst->type_argv [i]->type == MONO_TYPE_MVAR))
- type_argv [i] = shared_context.class_inst->type_argv [i];
- else if (gsharedvt)
- type_argv [i] = get_gsharedvt_type (shared_context.class_inst->type_argv [i]);
- else
- type_argv [i] = inst->type_argv [i];
- }
-
- shared_context.class_inst = mono_metadata_get_generic_inst (inst->type_argc, type_argv);
- g_free (type_argv);
- }
-
- inst = context->method_inst;
- if (inst) {
- type_argv = g_new0 (MonoType*, inst->type_argc);
- for (i = 0; i < inst->type_argc; ++i) {
- if (!all_vt && (MONO_TYPE_IS_REFERENCE (inst->type_argv [i]) || inst->type_argv [i]->type == MONO_TYPE_VAR || inst->type_argv [i]->type == MONO_TYPE_MVAR))
- type_argv [i] = shared_context.method_inst->type_argv [i];
- else if (gsharedvt)
- type_argv [i] = get_gsharedvt_type (shared_context.method_inst->type_argv [i]);
- else
- type_argv [i] = inst->type_argv [i];
- }
+ if (context)
+ inst = context->class_inst;
+ else
+ inst = shared_context.class_inst;
+ if (inst)
+ shared_context.class_inst = get_shared_inst (inst, shared_context.class_inst, class_container, all_vt, gsharedvt);
- shared_context.method_inst = mono_metadata_get_generic_inst (inst->type_argc, type_argv);
- g_free (type_argv);
- }
+ if (context)
+ inst = context->method_inst;
+ else
+ inst = shared_context.method_inst;
+ if (inst)
+ shared_context.method_inst = get_shared_inst (inst, shared_context.method_inst, method_container, all_vt, gsharedvt);
}
res = mono_class_inflate_generic_method (declaring_method, &shared_context);
return mini_get_shared_method_full (method, FALSE, FALSE);
}
-static void
-mini_init_gsctx_full (MonoGenericContext *context, MonoGenericSharingContext *gsctx, gboolean all_vt)
+void
+mini_init_gsctx (MonoGenericContext *context, MonoGenericSharingContext *gsctx)
{
MonoGenericInst *inst;
int i;
for (i = 0; i < inst->type_argc; ++i) {
MonoType *type = inst->type_argv [i];
- if (!all_vt && (MONO_TYPE_IS_REFERENCE (type) || (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR))) {
- } else {
+ if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1)
gsctx->var_is_vt [i] = TRUE;
- }
}
}
if (context->method_inst) {
for (i = 0; i < inst->type_argc; ++i) {
MonoType *type = inst->type_argv [i];
- if (!all_vt && (MONO_TYPE_IS_REFERENCE (type) || (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR))) {
- } else {
+ if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1)
gsctx->mvar_is_vt [i] = TRUE;
- }
}
}
}
-void
-mini_init_gsctx (MonoGenericContext *context, MonoGenericSharingContext *gsctx)
-{
- mini_init_gsctx_full (context, gsctx, FALSE);
-}
-
#ifndef DISABLE_JIT
/*
* mini_method_compile:
MonoMethodInflated *inflated;
MonoGenericContext *context;
- g_assert (method->is_inflated);
- inflated = (MonoMethodInflated*)method;
- context = &inflated->context;
-
// FIXME: Free the contents of gsctx if compilation fails
if (method_is_gshared) {
+ g_assert (method->is_inflated);
+ inflated = (MonoMethodInflated*)method;
+ context = &inflated->context;
+
/* We are compiling a gsharedvt method directly */
g_assert (compile_aot);
- mini_init_gsctx_full (context, &cfg->gsctx, TRUE);
} else {
- mini_init_gsctx (context, &cfg->gsctx);
+ g_assert (method_to_compile->is_inflated);
+ inflated = (MonoMethodInflated*)method_to_compile;
+ context = &inflated->context;
}
+ mini_init_gsctx (context, &cfg->gsctx);
+
cfg->gsharedvt = TRUE;
+ // FIXME:
+ cfg->disable_llvm = TRUE;
}
if (cfg->generic_sharing_context) {
if (cfg->verbose_level > 0) {
char *method_name;
+
+ method_name = mono_method_full_name (method, TRUE);
+ g_print ("converting %s%s%smethod %s\n", COMPILE_LLVM (cfg) ? "llvm " : "", cfg->gsharedvt ? "gsharedvt " : "", (cfg->generic_sharing_context && !cfg->gsharedvt) ? "gshared " : "", method_name);
+ /*
if (COMPILE_LLVM (cfg))
g_print ("converting llvm method %s\n", method_name = mono_method_full_name (method, TRUE));
else if (cfg->gsharedvt)
g_print ("converting shared method %s\n", method_name = mono_method_full_name (method_to_compile, TRUE));
else
g_print ("converting method %s\n", method_name = mono_method_full_name (method, TRUE));
+ */
g_free (method_name);
}
WrapperInfo *info = mono_marshal_get_wrapper_info (method);
if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN || info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT) {
- static MonoTrampInfo *tinfo;
+ static MonoTrampInfo *in_tinfo, *out_tinfo;
+ MonoTrampInfo *tinfo;
MonoJitInfo *jinfo;
+ gboolean is_in = info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN;
- if (tinfo)
- return tinfo->code;
+ if (is_in && in_tinfo)
+ return in_tinfo->code;
+ else if (!is_in && out_tinfo)
+ return out_tinfo->code;
/*
* This is a special wrapper whose body is implemented in assembly, like a trampoline. We use a wrapper so EH
* works.
* FIXME: The caller signature doesn't match the callee, which might cause problems on some platforms
*/
- if (mono_aot_only) {
- // FIXME: No EH
- return mono_aot_get_trampoline ("gsharedvt_trampoline");
- } else {
+ if (mono_aot_only)
+ mono_aot_get_trampoline_full (is_in ? "gsharedvt_trampoline" : "gsharedvt_out_trampoline", &tinfo);
+ else
mono_arch_get_gsharedvt_trampoline (&tinfo, FALSE);
- jinfo = create_jit_info_for_trampoline (method, tinfo);
- mono_jit_info_table_add (mono_get_root_domain (), jinfo);
- return tinfo->code;
- }
+ jinfo = create_jit_info_for_trampoline (method, tinfo);
+ mono_jit_info_table_add (mono_get_root_domain (), jinfo);
+ if (is_in)
+ in_tinfo = tinfo;
+ else
+ out_tinfo = tinfo;
+ return tinfo->code;
}
}
MonoJitInfo *info;
gpointer code, p;
MonoJitICallInfo *callinfo = NULL;
+ WrapperInfo *winfo = NULL;
/*
* ICALL wrappers are handled specially, since there is only one copy of them
* shared by all appdomains.
*/
- if ((method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) && (strstr (method->name, "__icall_wrapper_") == method->name)) {
- const char *icall_name;
-
- icall_name = method->name + strlen ("__icall_wrapper_");
- g_assert (icall_name);
- callinfo = mono_find_jit_icall_by_name (icall_name);
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
+ winfo = mono_marshal_get_wrapper_info (method);
+ if (winfo && winfo->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER) {
+ callinfo = mono_find_jit_icall_by_addr (winfo->d.icall.func);
g_assert (callinfo);
/* Must be domain neutral since there is only one copy */
}
}
- info->compiled_method = mini_add_method_trampoline (NULL, method, info->compiled_method, NULL, mono_method_needs_static_rgctx_invoke (method, FALSE));
+ info->compiled_method = mini_add_method_trampoline (NULL, method, info->compiled_method, mono_method_needs_static_rgctx_invoke (method, FALSE));
}
/*
supported = FALSE;
}
- if (method->klass->contextbound || !info->compiled_method)
+ if (mono_class_is_contextbound (method->klass) || !info->compiled_method)
supported = FALSE;
if (supported)
mono_arch_handle_exception (ctx, exc);
}
+#ifndef DISABLE_REMOTING
/* mono_jit_create_remoting_trampoline:
* @method: pointer to the method info
*
}
if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
- (mono_method_signature (method)->hasthis && (method->klass->marshalbyref || method->klass == mono_defaults.object_class))) {
+ (mono_method_signature (method)->hasthis && (mono_class_is_marshalbyref (method->klass) || method->klass == mono_defaults.object_class))) {
nm = mono_marshal_get_remoting_invoke_for_target (method, target);
addr = mono_compile_method (nm);
- } else {
+ } else
+ {
addr = mono_compile_method (method);
}
return mono_get_addr_from_ftnptr (addr);
}
+#endif
static gpointer *vtable_trampolines;
static int vtable_trampolines_size;
g_hash_table_destroy (info->runtime_invoke_hash);
g_hash_table_destroy (info->seq_points);
g_hash_table_destroy (info->arch_seq_points);
-
if (info->agent_info)
mono_debugger_agent_free_domain_info (domain);
+ if (info->gsharedvt_arg_tramp_hash)
+ g_hash_table_destroy (info->gsharedvt_arg_tramp_hash);
g_free (domain->runtime_info);
domain->runtime_info = NULL;
if (!default_opt_set)
default_opt = mono_parse_default_optimizations (NULL);
+#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED
+ if (mono_aot_only)
+ mono_set_generic_sharing_vt_supported (TRUE);
+#endif
+
InitializeCriticalSection (&jit_mutex);
#ifdef MONO_DEBUGGER_SUPPORTED
mono_install_free_method (mono_jit_free_method);
mono_install_trampoline (mono_create_jit_trampoline);
mono_install_jump_trampoline (mono_create_jump_trampoline);
+#ifndef DISABLE_REMOTING
mono_install_remoting_trampoline (mono_jit_create_remoting_trampoline);
+#endif
mono_install_delegate_trampoline (mono_create_delegate_trampoline);
mono_install_create_domain_hook (mini_create_jit_domain_info);
mono_install_free_domain_hook (mini_free_jit_domain_info);
mono_debugger_agent_unhandled_exception);
#endif
+#ifndef DISABLE_JIT
mono_create_helper_signatures ();
+#endif
register_jit_stats ();
register_icall (mono_jit_set_domain, "mono_jit_set_domain", "void ptr", TRUE);
register_icall (mono_domain_get, "mono_domain_get", "ptr", TRUE);
- register_icall (mono_get_throw_exception (), "mono_arch_throw_exception", "void object", TRUE);
- register_icall (mono_get_rethrow_exception (), "mono_arch_rethrow_exception", "void object", TRUE);
- register_icall (mono_get_throw_corlib_exception (), "mono_arch_throw_corlib_exception",
- "void ptr", TRUE);
+ register_dyn_icall (mono_get_throw_exception (), "mono_arch_throw_exception", "void object", TRUE);
+ register_dyn_icall (mono_get_rethrow_exception (), "mono_arch_rethrow_exception", "void object", TRUE);
+ register_dyn_icall (mono_get_throw_corlib_exception (), "mono_arch_throw_corlib_exception", "void ptr", TRUE);
register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE);
register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "void", FALSE);
register_icall (mono_thread_force_interruption_checkpoint, "mono_thread_force_interruption_checkpoint", "void", FALSE);
+#ifndef DISABLE_REMOTING
register_icall (mono_load_remote_field_new, "mono_load_remote_field_new", "object object ptr ptr", FALSE);
register_icall (mono_store_remote_field_new, "mono_store_remote_field_new", "void object ptr ptr object", FALSE);
+#endif
#if defined(__native_client__) || defined(__native_client_codegen__)
register_icall (mono_nacl_gc, "mono_nacl_gc", "void", TRUE);
* rule to the burg files, because we need the arity information to be correct.
*/
#ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
- mono_register_opcode_emulation (OP_LMUL, "__emul_lmul", "long long long", mono_llmult, TRUE);
- mono_register_opcode_emulation (OP_LDIV, "__emul_ldiv", "long long long", mono_lldiv, FALSE);
- mono_register_opcode_emulation (OP_LDIV_UN, "__emul_ldiv_un", "long long long", mono_lldiv_un, FALSE);
- mono_register_opcode_emulation (OP_LREM, "__emul_lrem", "long long long", mono_llrem, FALSE);
- mono_register_opcode_emulation (OP_LREM_UN, "__emul_lrem_un", "long long long", mono_llrem_un, FALSE);
- mono_register_opcode_emulation (OP_LMUL_OVF_UN, "__emul_lmul_ovf_un", "long long long", mono_llmult_ovf_un, FALSE);
- mono_register_opcode_emulation (OP_LMUL_OVF, "__emul_lmul_ovf", "long long long", mono_llmult_ovf, FALSE);
+ register_opcode_emulation (OP_LMUL, "__emul_lmul", "long long long", mono_llmult, "mono_llmult", TRUE);
+ register_opcode_emulation (OP_LDIV, "__emul_ldiv", "long long long", mono_lldiv, "mono_lldiv", FALSE);
+ register_opcode_emulation (OP_LDIV_UN, "__emul_ldiv_un", "long long long", mono_lldiv_un, "mono_lldiv_un", FALSE);
+ register_opcode_emulation (OP_LREM, "__emul_lrem", "long long long", mono_llrem, "mono_llrem", FALSE);
+ register_opcode_emulation (OP_LREM_UN, "__emul_lrem_un", "long long long", mono_llrem_un, "mono_llrem_un", FALSE);
+ register_opcode_emulation (OP_LMUL_OVF_UN, "__emul_lmul_ovf_un", "long long long", mono_llmult_ovf_un, "mono_llmult_ovf_un", FALSE);
+ register_opcode_emulation (OP_LMUL_OVF, "__emul_lmul_ovf", "long long long", mono_llmult_ovf, "mono_llmult_ovf", FALSE);
#endif
#ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
- mono_register_opcode_emulation (OP_LSHL, "__emul_lshl", "long long int32", mono_lshl, TRUE);
- mono_register_opcode_emulation (OP_LSHR, "__emul_lshr", "long long int32", mono_lshr, TRUE);
- mono_register_opcode_emulation (OP_LSHR_UN, "__emul_lshr_un", "long long int32", mono_lshr_un, TRUE);
+ register_opcode_emulation (OP_LSHL, "__emul_lshl", "long long int32", mono_lshl, "mono_lshl", TRUE);
+ register_opcode_emulation (OP_LSHR, "__emul_lshr", "long long int32", mono_lshr, "mono_lshr", TRUE);
+ register_opcode_emulation (OP_LSHR_UN, "__emul_lshr_un", "long long int32", mono_lshr_un, "mono_lshr_un", TRUE);
#endif
#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
- mono_register_opcode_emulation (OP_IDIV, "__emul_op_idiv", "int32 int32 int32", mono_idiv, FALSE);
- mono_register_opcode_emulation (OP_IDIV_UN, "__emul_op_idiv_un", "int32 int32 int32", mono_idiv_un, FALSE);
- mono_register_opcode_emulation (OP_IREM, "__emul_op_irem", "int32 int32 int32", mono_irem, FALSE);
- mono_register_opcode_emulation (OP_IREM_UN, "__emul_op_irem_un", "int32 int32 int32", mono_irem_un, FALSE);
+ register_opcode_emulation (OP_IDIV, "__emul_op_idiv", "int32 int32 int32", mono_idiv, "mono_idiv", FALSE);
+ register_opcode_emulation (OP_IDIV_UN, "__emul_op_idiv_un", "int32 int32 int32", mono_idiv_un, "mono_idiv_un", FALSE);
+ register_opcode_emulation (OP_IREM, "__emul_op_irem", "int32 int32 int32", mono_irem, "mono_irem", FALSE);
+ register_opcode_emulation (OP_IREM_UN, "__emul_op_irem_un", "int32 int32 int32", mono_irem_un, "mono_irem_un", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_MUL_DIV
- mono_register_opcode_emulation (OP_IMUL, "__emul_op_imul", "int32 int32 int32", mono_imul, TRUE);
+ register_opcode_emulation (OP_IMUL, "__emul_op_imul", "int32 int32 int32", mono_imul, "mono_imul", TRUE);
#endif
#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF)
- mono_register_opcode_emulation (OP_IMUL_OVF, "__emul_op_imul_ovf", "int32 int32 int32", mono_imul_ovf, FALSE);
- mono_register_opcode_emulation (OP_IMUL_OVF_UN, "__emul_op_imul_ovf_un", "int32 int32 int32", mono_imul_ovf_un, FALSE);
+ register_opcode_emulation (OP_IMUL_OVF, "__emul_op_imul_ovf", "int32 int32 int32", mono_imul_ovf, "mono_imul_ovf", FALSE);
+ register_opcode_emulation (OP_IMUL_OVF_UN, "__emul_op_imul_ovf_un", "int32 int32 int32", mono_imul_ovf_un, "mono_imul_ovf_un", FALSE);
#endif
#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT)
- mono_register_opcode_emulation (OP_FDIV, "__emul_fdiv", "double double double", mono_fdiv, FALSE);
+ register_opcode_emulation (OP_FDIV, "__emul_fdiv", "double double double", mono_fdiv, "mono_fdiv", FALSE);
#endif
- mono_register_opcode_emulation (OP_FCONV_TO_U8, "__emul_fconv_to_u8", "ulong double", mono_fconv_u8, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_U4, "__emul_fconv_to_u4", "uint32 double", mono_fconv_u4, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_OVF_I8, "__emul_fconv_to_ovf_i8", "long double", mono_fconv_ovf_i8, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_OVF_U8, "__emul_fconv_to_ovf_u8", "ulong double", mono_fconv_ovf_u8, FALSE);
+ register_opcode_emulation (OP_FCONV_TO_U8, "__emul_fconv_to_u8", "ulong double", mono_fconv_u8, "mono_fconv_u8", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_U4, "__emul_fconv_to_u4", "uint32 double", mono_fconv_u4, "mono_fconv_u4", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_OVF_I8, "__emul_fconv_to_ovf_i8", "long double", mono_fconv_ovf_i8, "mono_fconv_ovf_i8", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_OVF_U8, "__emul_fconv_to_ovf_u8", "ulong double", mono_fconv_ovf_u8, "mono_fconv_ovf_u8", FALSE);
#ifdef MONO_ARCH_EMULATE_FCONV_TO_I8
- mono_register_opcode_emulation (OP_FCONV_TO_I8, "__emul_fconv_to_i8", "long double", mono_fconv_i8, FALSE);
+ register_opcode_emulation (OP_FCONV_TO_I8, "__emul_fconv_to_i8", "long double", mono_fconv_i8, "mono_fconv_i8", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_CONV_R8_UN
- mono_register_opcode_emulation (OP_ICONV_TO_R_UN, "__emul_iconv_to_r_un", "double int32", mono_conv_to_r8_un, FALSE);
+ register_opcode_emulation (OP_ICONV_TO_R_UN, "__emul_iconv_to_r_un", "double int32", mono_conv_to_r8_un, "mono_conv_to_r8_un", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_LCONV_TO_R8
- mono_register_opcode_emulation (OP_LCONV_TO_R8, "__emul_lconv_to_r8", "double long", mono_lconv_to_r8, FALSE);
+ register_opcode_emulation (OP_LCONV_TO_R8, "__emul_lconv_to_r8", "double long", mono_lconv_to_r8, "mono_lconv_to_r8", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_LCONV_TO_R4
- mono_register_opcode_emulation (OP_LCONV_TO_R4, "__emul_lconv_to_r4", "float long", mono_lconv_to_r4, FALSE);
+ register_opcode_emulation (OP_LCONV_TO_R4, "__emul_lconv_to_r4", "float long", mono_lconv_to_r4, "mono_lconv_to_r4", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_LCONV_TO_R8_UN
- mono_register_opcode_emulation (OP_LCONV_TO_R_UN, "__emul_lconv_to_r8_un", "double long", mono_lconv_to_r8_un, FALSE);
+ register_opcode_emulation (OP_LCONV_TO_R_UN, "__emul_lconv_to_r8_un", "double long", mono_lconv_to_r8_un, "mono_lconv_to_r8_un", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_FREM
#if defined(__default_codegen__)
- mono_register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", fmod, FALSE);
+ register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", fmod, "fmod", FALSE);
#elif defined(__native_client_codegen__)
- mono_register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", mono_fmod, FALSE);
+ register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", mono_fmod, "mono_fmod", FALSE);
#endif
#endif
#ifdef MONO_ARCH_SOFT_FLOAT
- mono_register_opcode_emulation (OP_FSUB, "__emul_fsub", "double double double", mono_fsub, FALSE);
- mono_register_opcode_emulation (OP_FADD, "__emul_fadd", "double double double", mono_fadd, FALSE);
- mono_register_opcode_emulation (OP_FMUL, "__emul_fmul", "double double double", mono_fmul, FALSE);
- mono_register_opcode_emulation (OP_FNEG, "__emul_fneg", "double double", mono_fneg, FALSE);
- mono_register_opcode_emulation (OP_ICONV_TO_R8, "__emul_iconv_to_r8", "double int32", mono_conv_to_r8, FALSE);
- mono_register_opcode_emulation (OP_ICONV_TO_R4, "__emul_iconv_to_r4", "double int32", mono_conv_to_r4, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_R4, "__emul_fconv_to_r4", "double double", mono_fconv_r4, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_I1, "__emul_fconv_to_i1", "int8 double", mono_fconv_i1, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_I2, "__emul_fconv_to_i2", "int16 double", mono_fconv_i2, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_I4, "__emul_fconv_to_i4", "int32 double", mono_fconv_i4, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_U1, "__emul_fconv_to_u1", "uint8 double", mono_fconv_u1, FALSE);
- mono_register_opcode_emulation (OP_FCONV_TO_U2, "__emul_fconv_to_u2", "uint16 double", mono_fconv_u2, FALSE);
+ register_opcode_emulation (OP_FSUB, "__emul_fsub", "double double double", mono_fsub, "mono_fsub", FALSE);
+ register_opcode_emulation (OP_FADD, "__emul_fadd", "double double double", mono_fadd, "mono_fadd", FALSE);
+ register_opcode_emulation (OP_FMUL, "__emul_fmul", "double double double", mono_fmul, "mono_fmul", FALSE);
+ register_opcode_emulation (OP_FNEG, "__emul_fneg", "double double", mono_fneg, "mono_fneg", FALSE);
+ register_opcode_emulation (OP_ICONV_TO_R8, "__emul_iconv_to_r8", "double int32", mono_conv_to_r8, "mono_conv_to_r8", FALSE);
+ register_opcode_emulation (OP_ICONV_TO_R4, "__emul_iconv_to_r4", "double int32", mono_conv_to_r4, "mono_conv_to_r4", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_R4, "__emul_fconv_to_r4", "double double", mono_fconv_r4, "mono_fconv_r4", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_I1, "__emul_fconv_to_i1", "int8 double", mono_fconv_i1, "mono_fconv_i1", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_I2, "__emul_fconv_to_i2", "int16 double", mono_fconv_i2, "mono_fconv_i2", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_I4, "__emul_fconv_to_i4", "int32 double", mono_fconv_i4, "mono_fconv_i4", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_U1, "__emul_fconv_to_u1", "uint8 double", mono_fconv_u1, "mono_fconv_u1", FALSE);
+ register_opcode_emulation (OP_FCONV_TO_U2, "__emul_fconv_to_u2", "uint16 double", mono_fconv_u2, "mono_fconv_u2", FALSE);
#if SIZEOF_VOID_P == 4
- mono_register_opcode_emulation (OP_FCONV_TO_I, "__emul_fconv_to_i", "int32 double", mono_fconv_i4, FALSE);
-#endif
-
- mono_register_opcode_emulation (OP_FBEQ, "__emul_fcmp_eq", "uint32 double double", mono_fcmp_eq, FALSE);
- mono_register_opcode_emulation (OP_FBLT, "__emul_fcmp_lt", "uint32 double double", mono_fcmp_lt, FALSE);
- mono_register_opcode_emulation (OP_FBGT, "__emul_fcmp_gt", "uint32 double double", mono_fcmp_gt, FALSE);
- mono_register_opcode_emulation (OP_FBLE, "__emul_fcmp_le", "uint32 double double", mono_fcmp_le, FALSE);
- mono_register_opcode_emulation (OP_FBGE, "__emul_fcmp_ge", "uint32 double double", mono_fcmp_ge, FALSE);
- mono_register_opcode_emulation (OP_FBNE_UN, "__emul_fcmp_ne_un", "uint32 double double", mono_fcmp_ne_un, FALSE);
- mono_register_opcode_emulation (OP_FBLT_UN, "__emul_fcmp_lt_un", "uint32 double double", mono_fcmp_lt_un, FALSE);
- mono_register_opcode_emulation (OP_FBGT_UN, "__emul_fcmp_gt_un", "uint32 double double", mono_fcmp_gt_un, FALSE);
- mono_register_opcode_emulation (OP_FBLE_UN, "__emul_fcmp_le_un", "uint32 double double", mono_fcmp_le_un, FALSE);
- mono_register_opcode_emulation (OP_FBGE_UN, "__emul_fcmp_ge_un", "uint32 double double", mono_fcmp_ge_un, FALSE);
-
- mono_register_opcode_emulation (OP_FCEQ, "__emul_fcmp_ceq", "uint32 double double", mono_fceq, FALSE);
- mono_register_opcode_emulation (OP_FCGT, "__emul_fcmp_cgt", "uint32 double double", mono_fcgt, FALSE);
- mono_register_opcode_emulation (OP_FCGT_UN, "__emul_fcmp_cgt_un", "uint32 double double", mono_fcgt_un, FALSE);
- mono_register_opcode_emulation (OP_FCLT, "__emul_fcmp_clt", "uint32 double double", mono_fclt, FALSE);
- mono_register_opcode_emulation (OP_FCLT_UN, "__emul_fcmp_clt_un", "uint32 double double", mono_fclt_un, FALSE);
+ register_opcode_emulation (OP_FCONV_TO_I, "__emul_fconv_to_i", "int32 double", mono_fconv_i4, "mono_fconv_i4", FALSE);
+#endif
+
+ register_opcode_emulation (OP_FBEQ, "__emul_fcmp_eq", "uint32 double double", mono_fcmp_eq, "mono_fcmp_eq", FALSE);
+ register_opcode_emulation (OP_FBLT, "__emul_fcmp_lt", "uint32 double double", mono_fcmp_lt, "mono_fcmp_lt", FALSE);
+ register_opcode_emulation (OP_FBGT, "__emul_fcmp_gt", "uint32 double double", mono_fcmp_gt, "mono_fcmp_gt", FALSE);
+ register_opcode_emulation (OP_FBLE, "__emul_fcmp_le", "uint32 double double", mono_fcmp_le, "mono_fcmp_le", FALSE);
+ register_opcode_emulation (OP_FBGE, "__emul_fcmp_ge", "uint32 double double", mono_fcmp_ge, "mono_fcmp_ge", FALSE);
+ register_opcode_emulation (OP_FBNE_UN, "__emul_fcmp_ne_un", "uint32 double double", mono_fcmp_ne_un, "mono_fcmp_ne_un", FALSE);
+ register_opcode_emulation (OP_FBLT_UN, "__emul_fcmp_lt_un", "uint32 double double", mono_fcmp_lt_un, "mono_fcmp_lt_un", FALSE);
+ register_opcode_emulation (OP_FBGT_UN, "__emul_fcmp_gt_un", "uint32 double double", mono_fcmp_gt_un, "mono_fcmp_gt_un", FALSE);
+ register_opcode_emulation (OP_FBLE_UN, "__emul_fcmp_le_un", "uint32 double double", mono_fcmp_le_un, "mono_fcmp_le_un", FALSE);
+ register_opcode_emulation (OP_FBGE_UN, "__emul_fcmp_ge_un", "uint32 double double", mono_fcmp_ge_un, "mono_fcmp_ge_un", FALSE);
+
+ register_opcode_emulation (OP_FCEQ, "__emul_fcmp_ceq", "uint32 double double", mono_fceq, "mono_fceq", FALSE);
+ register_opcode_emulation (OP_FCGT, "__emul_fcmp_cgt", "uint32 double double", mono_fcgt, "mono_fcgt", FALSE);
+ register_opcode_emulation (OP_FCGT_UN, "__emul_fcmp_cgt_un", "uint32 double double", mono_fcgt_un, "mono_fcgt_un", FALSE);
+ register_opcode_emulation (OP_FCLT, "__emul_fcmp_clt", "uint32 double double", mono_fclt, "mono_fclt", FALSE);
+ register_opcode_emulation (OP_FCLT_UN, "__emul_fcmp_clt_un", "uint32 double double", mono_fclt_un, "mono_fclt_un", FALSE);
register_icall (mono_fload_r4, "mono_fload_r4", "double ptr", FALSE);
register_icall (mono_fstore_r4, "mono_fstore_r4", "void double ptr", FALSE);
#endif
#if SIZEOF_REGISTER == 4
- mono_register_opcode_emulation (OP_FCONV_TO_U, "__emul_fconv_to_u", "uint32 double", mono_fconv_u4, TRUE);
+ register_opcode_emulation (OP_FCONV_TO_U, "__emul_fconv_to_u", "uint32 double", mono_fconv_u4, "mono_fconv_u4", TRUE);
#endif
/* other jit icalls */
"ptr ptr ptr ptr", FALSE);
register_icall (mono_get_special_static_data, "mono_get_special_static_data", "ptr int", FALSE);
register_icall (mono_ldstr, "mono_ldstr", "object ptr ptr int32", FALSE);
- register_icall (mono_helper_stelem_ref_check, "helper_stelem_ref_check", "void object object", FALSE);
+ register_icall (mono_helper_stelem_ref_check, "mono_helper_stelem_ref_check", "void object object", FALSE);
register_icall (mono_object_new, "mono_object_new", "object ptr ptr", FALSE);
register_icall (mono_object_new_specific, "mono_object_new_specific", "object ptr", FALSE);
register_icall (mono_array_new, "mono_array_new", "object ptr ptr int32", FALSE);
register_icall (mono_ldftn, "mono_ldftn", "ptr ptr", FALSE);
register_icall (mono_ldvirtfn, "mono_ldvirtfn", "ptr object ptr", FALSE);
register_icall (mono_ldvirtfn_gshared, "mono_ldvirtfn_gshared", "ptr object ptr", FALSE);
- register_icall (mono_helper_compile_generic_method, "compile_generic_method", "ptr object ptr ptr", FALSE);
- register_icall (mono_helper_ldstr, "helper_ldstr", "object ptr int", FALSE);
- register_icall (mono_helper_ldstr_mscorlib, "helper_ldstr_mscorlib", "object int", FALSE);
- register_icall (mono_helper_newobj_mscorlib, "helper_newobj_mscorlib", "object int", FALSE);
+ register_icall (mono_helper_compile_generic_method, "mono_helper_compile_generic_method", "ptr object ptr ptr", FALSE);
+ register_icall (mono_helper_ldstr, "mono_helper_ldstr", "object ptr int", FALSE);
+ register_icall (mono_helper_ldstr_mscorlib, "mono_helper_ldstr_mscorlib", "object int", FALSE);
+ register_icall (mono_helper_newobj_mscorlib, "mono_helper_newobj_mscorlib", "object int", FALSE);
register_icall (mono_value_copy, "mono_value_copy", "void ptr ptr ptr", FALSE);
register_icall (mono_object_castclass, "mono_object_castclass", "object object ptr", FALSE);
register_icall (mono_break, "mono_break", NULL, TRUE);
register_icall (mono_array_new_1, "mono_array_new_1", "object ptr int", FALSE);
register_icall (mono_array_new_2, "mono_array_new_2", "object ptr int int", FALSE);
register_icall (mono_array_new_3, "mono_array_new_3", "object ptr int int int", FALSE);
+ register_icall (mono_array_new_4, "mono_array_new_4", "object ptr int int int int", FALSE);
register_icall (mono_get_native_calli_wrapper, "mono_get_native_calli_wrapper", "ptr ptr ptr ptr", FALSE);
register_icall (mono_resume_unwind, "mono_resume_unwind", "void", TRUE);
+ register_icall (mono_object_tostring_gsharedvt, "mono_object_tostring_gsharedvt", "object ptr ptr ptr", TRUE);
+ register_icall (mono_object_gethashcode_gsharedvt, "mono_object_gethashcode_gsharedvt", "int ptr ptr ptr", TRUE);
register_icall (mono_gc_wbarrier_value_copy_bitmap, "mono_gc_wbarrier_value_copy_bitmap", "void ptr ptr int int", FALSE);
register_icall (mono_object_isinst_with_cache, "mono_object_isinst_with_cache", "object object ptr ptr", FALSE);
register_icall (mono_debugger_agent_user_break, "mono_debugger_agent_user_break", "void", FALSE);
+#endif
+#ifdef TARGET_IOS
+ register_icall (pthread_getspecific, "pthread_getspecific", NULL, TRUE);
#endif
mono_generic_sharing_init ();
#endif
#ifndef MONO_CROSS_COMPILE
- mono_runtime_shutdown ();
/*
- * mono_runtime_cleanup() and mono_domain_finalize () need to
- * be called early since they need the execution engine still
- * fully working (mono_domain_finalize may invoke managed finalizers
- * and mono_runtime_cleanup will wait for other threads to finish).
+ * mono_domain_finalize () needs to be called early since it needs the
+ * execution engine still fully working (it may invoke managed finalizers).
*/
mono_domain_finalize (domain, 2000);
#endif
DeleteCriticalSection (&jit_mutex);
DeleteCriticalSection (&mono_delegate_section);
+
+#ifdef USE_JUMP_TABLES
+ mono_jumptable_cleanup ();
+#endif
}
void
invoke = mono_marshal_get_runtime_invoke (method, FALSE);
mono_compile_method (invoke);
}
- if (method->klass->marshalbyref && mono_method_signature (method)->hasthis) {
+#ifndef DISABLE_REMOTING
+ if (mono_class_is_marshalbyref (method->klass) && mono_method_signature (method)->hasthis) {
invoke = mono_marshal_get_remoting_invoke_with_check (method);
mono_compile_method (invoke);
}
+#endif
}
/* Load and precompile referenced assemblies as well */
}
gpointer
-mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethod *normal_method, MonoMethod *gsharedvt_method, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gboolean virtual)
+mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
{
g_assert_not_reached ();
return NULL;
return NULL;
}
-#endif
+#endif
+
+#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) && !defined(MONOTOUCH) && !defined(MONO_EXTENSIONS)
+
+gboolean
+mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig)
+{
+ return FALSE;
+}
+
+gpointer
+mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
+{
+ NOT_IMPLEMENTED;
+ return NULL;
+}
+
+#endif
+
+#ifdef USE_JUMP_TABLES
+#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
+
+typedef struct MonoJumpTableChunk {
+ guint32 total;
+ guint32 active;
+ struct MonoJumpTableChunk *previous;
+ /* gpointer entries[total]; */
+} MonoJumpTableChunk;
+
+static MonoJumpTableChunk* g_jumptable = NULL;
+#define mono_jumptable_lock() EnterCriticalSection (&jumptable_mutex)
+#define mono_jumptable_unlock() LeaveCriticalSection (&jumptable_mutex)
+static CRITICAL_SECTION jumptable_mutex;
+
+static MonoJumpTableChunk*
+mono_create_jumptable_chunk (guint32 max_entries)
+{
+ guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
+ MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
+ chunk->total = max_entries;
+ return chunk;
+}
+
+void
+mono_jumptable_init (void)
+{
+ if (g_jumptable == NULL) {
+ InitializeCriticalSection (&jumptable_mutex);
+ g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
+ }
+}
+
+gpointer*
+mono_jumptable_add_entry (void)
+{
+ return mono_jumptable_add_entries (1);
+}
+
+gpointer*
+mono_jumptable_add_entries (guint32 entries)
+{
+ guint32 index;
+ gpointer *result;
+
+ mono_jumptable_init ();
+ mono_jumptable_lock ();
+ index = g_jumptable->active;
+ if (index + entries >= g_jumptable->total) {
+ /*
+ * Grow jumptable, by adding one more chunk.
+ * We cannot realloc jumptable, as there could be pointers
+ * to existing jump table entries in the code, so instead
+ * we just add one more chunk.
+ */
+ guint32 max_entries = entries;
+ MonoJumpTableChunk *new_chunk;
+
+ if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
+ max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
+ new_chunk = mono_create_jumptable_chunk (max_entries);
+ /* Link old jumptable, so that we could free it up later. */
+ new_chunk->previous = g_jumptable;
+ g_jumptable = new_chunk;
+ index = 0;
+ }
+ g_jumptable->active = index + entries;
+ result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
+ mono_jumptable_unlock();
+
+ return result;
+}
+
+void
+mono_jumptable_cleanup (void)
+{
+ if (g_jumptable) {
+ MonoJumpTableChunk *current = g_jumptable, *prev;
+ while (current != NULL) {
+ prev = current->previous;
+ g_free (current);
+ current = prev;
+ }
+ g_jumptable = NULL;
+ DeleteCriticalSection (&jumptable_mutex);
+ }
+}
+
+gpointer*
+mono_jumptable_get_entry (guint8 *code_ptr)
+{
+ return mono_arch_jumptable_entry_from_code (code_ptr);
+}
+#endif