diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs
index 94cb9eb7feea62..a8bf7fdc42bfc5 100644
--- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs
+++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs
@@ -144,6 +144,11 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr
if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length))
return;
+ CopySlow(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable);
+ }
+
+ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable)
+ {
int source_pos = sourceIndex - sourceArray.GetLowerBound(0);
int dest_pos = destinationIndex - destinationArray.GetLowerBound(0);
diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml
index 50b70144d16a68..5b047e47e1e765 100644
--- a/src/mono/mono/cil/cil-opcodes.xml
+++ b/src/mono/mono/cil/cil-opcodes.xml
@@ -327,4 +327,5 @@
+
diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def
index 4b0769de95ebbb..47bccb295e99b2 100644
--- a/src/mono/mono/cil/opcode.def
+++ b/src/mono/mono/cil/opcode.def
@@ -327,6 +327,7 @@ OPDEF(CEE_MONO_RETHROW, "mono_rethrow", PopRef, Push0, InlineNone, 0, 2, 0xF0, 0
OPDEF(CEE_MONO_GET_SP, "mono_get_sp", Pop0, PushI, InlineNone, 0, 2, 0xF0, 0x20, NEXT)
OPDEF(CEE_MONO_METHODCONST, "mono_methodconst", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x21, NEXT)
OPDEF(CEE_MONO_PINVOKE_ADDR_CACHE, "mono_pinvoke_addr_cache", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x22, NEXT)
+OPDEF(CEE_MONO_REMAP_OVF_EXC, "mono_remap_ovf_exc", Pop0, Push0, InlineI, 0, 2, 0xF0, 0x23, NEXT)
#ifndef OPALIAS
#define _MONO_CIL_OPALIAS_DEFINED_
#define OPALIAS(a,s,r)
diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h
index 577a14eb656191..804431515d1f4a 100644
--- a/src/mono/mono/metadata/jit-icall-reg.h
+++ b/src/mono/mono/metadata/jit-icall-reg.h
@@ -181,6 +181,7 @@ MONO_JIT_ICALL (mono_delegate_end_invoke) \
MONO_JIT_ICALL (mono_delegate_to_ftnptr) \
MONO_JIT_ICALL (mono_domain_get) \
MONO_JIT_ICALL (mono_dummy_jit_icall) \
+MONO_JIT_ICALL (mono_dummy_jit_icall_val) \
MONO_JIT_ICALL (mono_exception_from_token) \
MONO_JIT_ICALL (mono_fill_class_rgctx) \
MONO_JIT_ICALL (mono_fill_method_rgctx) \
diff --git a/src/mono/mono/metadata/sgen-mono-ilgen.c b/src/mono/mono/metadata/sgen-mono-ilgen.c
index f9887161d37df6..aa5e034dbc6f9d 100644
--- a/src/mono/mono/metadata/sgen-mono-ilgen.c
+++ b/src/mono/mono/metadata/sgen-mono-ilgen.c
@@ -233,11 +233,7 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean
mono_mb_emit_byte (mb, CEE_CONV_I);
mono_mb_emit_stloc (mb, size_var);
} else if (atype == ATYPE_VECTOR) {
- ERROR_DECL (error);
- MonoExceptionClause *clause;
- int pos, pos_leave, pos_error;
- MonoClass *oom_exc_class;
- MonoMethod *ctor;
+ int pos, pos_error;
/*
* n > MONO_ARRAY_MAX_INDEX => OutOfMemoryException
@@ -262,9 +258,6 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean
mono_mb_patch_short_branch (mb, pos);
- clause = (MonoExceptionClause *)mono_image_alloc0 (mono_defaults.corlib, sizeof (MonoExceptionClause));
- clause->try_offset = mono_mb_get_label (mb);
-
/* vtable->klass->sizes.element_size */
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoVTable, klass));
@@ -279,35 +272,15 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean
/* * n */
mono_mb_emit_ldarg (mb, 1);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_REMAP_OVF_EXC, (gpointer)"OutOfMemoryException");
mono_mb_emit_byte (mb, CEE_MUL_OVF_UN);
/* + sizeof (MonoArray) */
mono_mb_emit_icon (mb, MONO_SIZEOF_MONO_ARRAY);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_REMAP_OVF_EXC, (gpointer)"OutOfMemoryException");
mono_mb_emit_byte (mb, CEE_ADD_OVF_UN);
mono_mb_emit_stloc (mb, size_var);
-
- pos_leave = mono_mb_emit_branch (mb, CEE_LEAVE);
-
- /* catch */
- clause->flags = MONO_EXCEPTION_CLAUSE_NONE;
- clause->try_len = mono_mb_get_pos (mb) - clause->try_offset;
- clause->data.catch_class = mono_class_load_from_name (mono_defaults.corlib,
- "System", "OverflowException");
- clause->handler_offset = mono_mb_get_label (mb);
-
- oom_exc_class = mono_class_load_from_name (mono_defaults.corlib,
- "System", "OutOfMemoryException");
- ctor = mono_class_get_method_from_name_checked (oom_exc_class, ".ctor", 0, 0, error);
- mono_error_assert_ok (error);
- g_assert (ctor);
-
- mono_mb_emit_byte (mb, CEE_POP);
- mono_mb_emit_op (mb, CEE_NEWOBJ, ctor);
- mono_mb_emit_byte (mb, CEE_THROW);
-
- clause->handler_len = mono_mb_get_pos (mb) - clause->handler_offset;
- mono_mb_set_clauses (mb, 1, clause);
- mono_mb_patch_branch (mb, pos_leave);
- /* end catch */
} else if (atype == ATYPE_STRING) {
/*
* a string allocator method takes the args: (vtable, len)
diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c
index 46de11de21c927..efc8bfd6f06bcd 100644
--- a/src/mono/mono/mini/decompose.c
+++ b/src/mono/mono/mini/decompose.c
@@ -81,7 +81,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins)
else
opcode = OP_ADDCC;
EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2);
- MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, OV, ins->inst_exc_name);
NULLIFY_INS (ins);
break;
}
@@ -95,7 +95,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins)
else
opcode = OP_ADDCC;
EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2);
- MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, C, ins->inst_exc_name);
NULLIFY_INS (ins);
break;
}
@@ -110,7 +110,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins)
else
opcode = OP_SUBCC;
EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2);
- MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, OV, ins->inst_exc_name);
NULLIFY_INS (ins);
break;
}
@@ -124,7 +124,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins)
else
opcode = OP_SUBCC;
EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2);
- MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, C, ins->inst_exc_name);
NULLIFY_INS (ins);
break;
}
@@ -327,7 +327,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
if (COMPILE_LLVM (cfg))
break;
ins->opcode = OP_IADDCC;
- MONO_EMIT_NEW_COND_EXC (cfg, IC, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, IC, ins->inst_exc_name);
break;
case OP_ISUB_OVF:
if (COMPILE_LLVM (cfg))
@@ -859,25 +859,25 @@ mono_decompose_long_opts (MonoCompile *cfg)
/* ADC sets the condition code */
MONO_EMIT_NEW_BIALU (cfg, OP_IADDCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2));
MONO_EMIT_NEW_BIALU (cfg, OP_IADC, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2));
- MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, OV, tree->inst_exc_name);
break;
case OP_LADD_OVF_UN:
/* ADC sets the condition code */
MONO_EMIT_NEW_BIALU (cfg, OP_IADDCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2));
MONO_EMIT_NEW_BIALU (cfg, OP_IADC, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2));
- MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, C, tree->inst_exc_name);
break;
case OP_LSUB_OVF:
/* SBB sets the condition code */
MONO_EMIT_NEW_BIALU (cfg, OP_ISUBCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2));
MONO_EMIT_NEW_BIALU (cfg, OP_ISBB, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2));
- MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, OV, tree->inst_exc_name);
break;
case OP_LSUB_OVF_UN:
/* SBB sets the condition code */
MONO_EMIT_NEW_BIALU (cfg, OP_ISUBCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2));
MONO_EMIT_NEW_BIALU (cfg, OP_ISBB, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2));
- MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (cfg, C, tree->inst_exc_name);
break;
case OP_LAND:
MONO_EMIT_NEW_BIALU (cfg, OP_IAND, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2));
@@ -1445,8 +1445,11 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
src->klass = ins->klass;
src->dreg = ins->sreg1;
}
+
+ cfg->disable_inline_rgctx_fetch = TRUE;
MonoInst *tmp = mini_emit_box (cfg, src, ins->klass, mini_class_check_context_used (cfg, ins->klass));
g_assert (tmp);
+ cfg->disable_inline_rgctx_fetch = FALSE;
MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ins->dreg, tmp->dreg);
diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c
index a0078c45656987..b55fe7fc2d790b 100644
--- a/src/mono/mono/mini/jit-icalls.c
+++ b/src/mono/mono/mini/jit-icalls.c
@@ -1622,3 +1622,8 @@ void
mono_dummy_jit_icall (void)
{
}
+
+void
+mono_dummy_jit_icall_val (gpointer val)
+{
+}
diff --git a/src/mono/mono/mini/jit-icalls.h b/src/mono/mono/mini/jit-icalls.h
index 646e888b471f84..1df30a95e737f8 100644
--- a/src/mono/mono/mini/jit-icalls.h
+++ b/src/mono/mono/mini/jit-icalls.h
@@ -229,4 +229,6 @@ ICALL_EXPORT void mono_throw_invalid_program (const char *msg);
ICALL_EXPORT void mono_dummy_jit_icall (void);
+ICALL_EXPORT void mono_dummy_jit_icall_val (gpointer ptr);
+
#endif /* __MONO_JIT_ICALLS_H__ */
diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c
index d1da9506106686..85ca8d262702b6 100644
--- a/src/mono/mono/mini/method-to-ir.c
+++ b/src/mono/mono/mini/method-to-ir.c
@@ -524,6 +524,7 @@ add_widen_op (MonoCompile *cfg, MonoInst *ins, MonoInst **arg1_ref, MonoInst **a
ins->sreg2 = sp [1]->dreg; \
type_from_op (cfg, ins, sp [0], sp [1]); \
CHECK_TYPE (ins); \
+ if (ovf_exc) ins->inst_exc_name = ovf_exc; else ins->inst_exc_name = "OverflowException"; ovf_exc = NULL; \
/* Have to insert a widening op */ \
add_widen_op (cfg, ins, &sp [0], &sp [1]); \
ins->dreg = alloc_dreg ((cfg), (MonoStackType)(ins)->type); \
@@ -6149,6 +6150,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
MonoDebugMethodInfo *minfo;
MonoBitSet *seq_point_locs = NULL;
MonoBitSet *seq_point_set_locs = NULL;
+ const char *ovf_exc = NULL;
gboolean emitted_funccall_seq_point = FALSE;
gboolean detached_before_ret = FALSE;
gboolean ins_has_side_effect;
@@ -11084,6 +11086,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
*sp++ = ins;
break;
}
+ case MONO_CEE_MONO_REMAP_OVF_EXC:
+ /* Remap the exception thrown by the next _OVF opcode */
+ g_assert (method->wrapper_type != MONO_WRAPPER_NONE);
+ ovf_exc = (const char*)mono_method_get_wrapper_data (method, token);
+ break;
case MONO_CEE_ARGLIST: {
/* somewhat similar to LDTOKEN */
diff --git a/src/mono/mono/mini/mini-codegen.c b/src/mono/mono/mini/mini-codegen.c
index 44a60604b94068..77464dcf88cbb7 100644
--- a/src/mono/mono/mini/mini-codegen.c
+++ b/src/mono/mono/mini/mini-codegen.c
@@ -2716,6 +2716,8 @@ mini_exception_id_by_name (const char *name)
return MONO_EXC_ARGUMENT;
if (strcmp (name, "ArgumentOutOfRangeException") == 0)
return MONO_EXC_ARGUMENT_OUT_OF_RANGE;
+ if (strcmp (name, "OutOfMemoryException") == 0)
+ return MONO_EXC_ARGUMENT_OUT_OF_MEMORY;
g_error ("Unknown intrinsic exception %s\n", name);
return -1;
}
diff --git a/src/mono/mono/mini/mini-llvm-cpp.cpp b/src/mono/mono/mini/mini-llvm-cpp.cpp
index d2bf4eb7c77421..fc87c556ae3842 100644
--- a/src/mono/mono/mini/mini-llvm-cpp.cpp
+++ b/src/mono/mono/mini/mini-llvm-cpp.cpp
@@ -105,7 +105,7 @@ mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, LLVMValueRef Arr
auto sz = unwrap (ArraySize);
auto b = unwrap (builder);
auto ins = alignment > 0
- ? b->Insert (new AllocaInst (ty, 0, sz, to_align (alignment), Name))
+ ? b->Insert (new AllocaInst (ty, 0, sz, to_align (alignment)), Name)
: b->CreateAlloca (ty, 0, sz, Name);
return wrap (ins);
}
diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c
index 4193900b324c53..75c45652b06a5a 100644
--- a/src/mono/mono/mini/mini-llvm.c
+++ b/src/mono/mono/mini/mini-llvm.c
@@ -7287,7 +7287,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
val = call_intrins (ctx, intrins, args, "");
values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
ovf = LLVMBuildExtractValue (builder, val, 1, "");
- emit_cond_system_exception (ctx, bb, "OverflowException", ovf, FALSE);
+ emit_cond_system_exception (ctx, bb, ins->inst_exc_name, ovf, FALSE);
if (!ctx_ok (ctx))
break;
builder = ctx->builder;
diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c
index 83078470df3b74..0841d15ae72b9d 100644
--- a/src/mono/mono/mini/mini-runtime.c
+++ b/src/mono/mono/mini/mini-runtime.c
@@ -4919,6 +4919,7 @@ register_icalls (void)
register_icall (mono_throw_platform_not_supported, mono_icall_sig_void, FALSE);
register_icall (mono_throw_invalid_program, mono_icall_sig_void_ptr, FALSE);
register_icall_no_wrapper (mono_dummy_jit_icall, mono_icall_sig_void);
+ //register_icall_no_wrapper (mono_dummy_jit_icall_val, mono_icall_sig_void_ptr);
register_icall_with_wrapper (mono_monitor_enter_internal, mono_icall_sig_int32_obj);
register_icall_with_wrapper (mono_monitor_enter_v4_internal, mono_icall_sig_void_obj_ptr);
diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h
index b693081d6311f8..e671ca86b11ae6 100644
--- a/src/mono/mono/mini/mini.h
+++ b/src/mono/mono/mini/mini.h
@@ -757,6 +757,7 @@ struct MonoInst {
int *phi_args;
MonoCallInst *call_inst;
GList *exception_clauses;
+ const char *exc_name;
} op [2];
gint64 i8const;
double r8const;
@@ -908,6 +909,9 @@ enum {
#define inst_newa_len data.op[0].src
#define inst_newa_class data.op[1].klass
+/* In _OVF opcodes */
+#define inst_exc_name data.op[0].exc_name
+
#define inst_var data.op[0].var
#define inst_vtype data.op[1].vtype
/* in branch instructions */
@@ -1991,6 +1995,7 @@ enum {
MONO_EXC_ARRAY_TYPE_MISMATCH,
MONO_EXC_ARGUMENT,
MONO_EXC_ARGUMENT_OUT_OF_RANGE,
+ MONO_EXC_ARGUMENT_OUT_OF_MEMORY,
MONO_EXC_INTRINS_NUM
};
diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile
index d3f9b3bf08cb2a..d171b9395a716a 100644
--- a/src/mono/wasm/Makefile
+++ b/src/mono/wasm/Makefile
@@ -3,6 +3,10 @@ TOP=$(realpath $(CURDIR)/../../..)
escape_quote = $(subst ",\",$(1))
+ifneq ($(V),)
+MSBUILD_ARGS+=/p:MonoVerboseBuild=true
+endif
+
DOTNET=$(TOP)/dotnet.sh
JSVU=$(HOME)/.jsvu
CHROMEDRIVER?=$(HOME)/.chromedriver
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index ea282f9638cf1e..6fb3e5beda18a7 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -502,6 +502,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_
+
<_AotInputAssemblies Include="@(_WasmAssembliesInternal)">
@@ -561,7 +562,8 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_
CacheFilePath="$(_AOTCompilerCacheFile)"
LLVMDebug="dwarfdebug"
LLVMPath="$(EmscriptenUpstreamBinPath)"
- IntermediateOutputPath="$(_WasmIntermediateOutputPath)">
+ IntermediateOutputPath="$(_WasmIntermediateOutputPath)"
+ AotProfilePath="@(AotProfilePath)">
diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets
index 1df620145bea36..145e5c8f7ee909 100644
--- a/src/mono/wasm/build/WasmApp.targets
+++ b/src/mono/wasm/build/WasmApp.targets
@@ -61,6 +61,7 @@
- $(WasmBuildOnlyAfterPublish) - Causes relinking to be done only for Publish. Defaults to false.
- $(RunAOTCompilationAfterBuild) - Run AOT compilation even after Build. By default, it is run only for publish.
Defaults to false.
+ - $(WasmAotProfilePath) - Path to an AOT profile file.
Public items:
- @(WasmExtraFilesToDeploy) - Files to copy to $(WasmAppDir).