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).