diff options
author | Alexis Christoforides <alexis@thenull.net> | 2015-11-23 19:07:10 +0300 |
---|---|---|
committer | Alexis Christoforides <alexis@thenull.net> | 2015-11-23 19:07:10 +0300 |
commit | a7605b3ba7cc2d2ddfbf4331edb4f9a935fdb564 (patch) | |
tree | cafcb92e18fb84ec44e24cffe855367c528d5987 | |
parent | 6dd2d0d52b8bc4262d67833f44bc1537c3d17a9e (diff) | |
parent | 30015f112727e2601202b114b75e0ba8e9e1af81 (diff) |
Merge pull request #2257 from kumpera/bug_36000mono-4.2.0-branch-c6sr0
[jit] Fix memory leaks in the generic sharing code by making sure tha…
-rw-r--r-- | mono/mini/method-to-ir.c | 25 | ||||
-rw-r--r-- | mono/mini/mini-generic-sharing.c | 18 | ||||
-rw-r--r-- | mono/mini/mini.h | 16 |
3 files changed, 39 insertions, 20 deletions
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index cb63252e001..cfb7eed7bb4 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -4023,10 +4023,10 @@ handle_unbox_gsharedvt (MonoCompile *cfg, MonoClass *klass, MonoInst *obj) NEW_BBLOCK (cfg, is_nullable_bb); NEW_BBLOCK (cfg, end_bb); is_ref = emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_CLASS_BOX_TYPE); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, 1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, MONO_GSHAREDVT_BOX_TYPE_REF); MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_ref_bb); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, 2); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, MONO_GSHAREDVT_BOX_TYPE_NULLABLE); MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_nullable_bb); /* This will contain either the address of the unboxed vtype, or an address of the temporary where the ref is stored */ @@ -4221,10 +4221,10 @@ handle_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_used) NEW_BBLOCK (cfg, is_nullable_bb); NEW_BBLOCK (cfg, end_bb); is_ref = emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_CLASS_BOX_TYPE); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, 1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, MONO_GSHAREDVT_BOX_TYPE_REF); MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_ref_bb); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, 2); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, is_ref->dreg, MONO_GSHAREDVT_BOX_TYPE_NULLABLE); MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_nullable_bb); /* Non-ref case */ @@ -5072,9 +5072,12 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe args [4] = ins; if (mini_is_gsharedvt_type (cfg, fsig->params [0])) { - int addr_reg; + int addr_reg, deref_arg_reg; - args [3] = emit_get_gsharedvt_info_klass (cfg, mono_class_from_mono_type (fsig->params [0]), MONO_RGCTX_INFO_CLASS_BOX_TYPE); + ins = emit_get_gsharedvt_info_klass (cfg, mono_class_from_mono_type (fsig->params [0]), MONO_RGCTX_INFO_CLASS_BOX_TYPE); + deref_arg_reg = alloc_preg (cfg); + /* deref_arg = BOX_TYPE != MONO_GSHAREDVT_BOX_TYPE_VTYPE */ + EMIT_NEW_BIALU_IMM (cfg, args [3], OP_ISUB_IMM, deref_arg_reg, ins->dreg, 1); EMIT_NEW_VARLOADA_VREG (cfg, ins, sp [1]->dreg, fsig->params [0]); addr_reg = ins->dreg; @@ -8958,7 +8961,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b NEW_BBLOCK (cfg, end_bb); box_type = emit_get_rgctx_virt_method (cfg, mono_class_check_context_used (constrained_class), constrained_class, cmethod, MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, box_type->dreg, 1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, box_type->dreg, MONO_GSHAREDVT_BOX_TYPE_REF); MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_ref_bb); /* Non-ref case */ @@ -10939,6 +10942,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b context_used = mini_class_check_context_used (cfg, klass); offset_ins = emit_get_gsharedvt_info (cfg, field, MONO_RGCTX_INFO_FIELD_OFFSET); + /* The value is offset by 1 */ + EMIT_NEW_BIALU_IMM (cfg, ins, OP_PSUB_IMM, offset_ins->dreg, offset_ins->dreg, 1); dreg = alloc_ireg_mp (cfg); EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, sp [0]->dreg, offset_ins->dreg); /* The decomposition will call mini_emit_stobj () which will emit a wbarrier if needed */ @@ -11022,6 +11027,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MonoInst *offset_ins; offset_ins = emit_get_gsharedvt_info (cfg, field, MONO_RGCTX_INFO_FIELD_OFFSET); + /* The value is offset by 1 */ + EMIT_NEW_BIALU_IMM (cfg, ins, OP_PSUB_IMM, offset_ins->dreg, offset_ins->dreg, 1); EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, sp [0]->dreg, offset_ins->dreg); } else { EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, dreg, sp [0]->dreg, foffset); @@ -11038,6 +11045,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MonoInst *offset_ins; offset_ins = emit_get_gsharedvt_info (cfg, field, MONO_RGCTX_INFO_FIELD_OFFSET); + /* The value is offset by 1 */ + EMIT_NEW_BIALU_IMM (cfg, ins, OP_PSUB_IMM, offset_ins->dreg, offset_ins->dreg, 1); dreg = alloc_ireg_mp (cfg); EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, sp [0]->dreg, offset_ins->dreg); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, field->type, dreg, 0); @@ -11165,6 +11174,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MonoInst *offset_ins; offset_ins = emit_get_rgctx_field (cfg, context_used, field, MONO_RGCTX_INFO_FIELD_OFFSET); + /* The value is offset by 1 */ + EMIT_NEW_BIALU_IMM (cfg, ins, OP_PSUB_IMM, offset_ins->dreg, offset_ins->dreg, 1); dreg = alloc_ireg_mp (cfg); EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, static_data->dreg, offset_ins->dreg); } else if (field->offset == 0) { diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index 1f737ffe0dd..d9b3800d633 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -882,11 +882,11 @@ class_type_info (MonoDomain *domain, MonoClass *class, MonoRgctxInfoType info_ty return GUINT_TO_POINTER (mono_class_value_size (class, NULL)); case MONO_RGCTX_INFO_CLASS_BOX_TYPE: if (MONO_TYPE_IS_REFERENCE (&class->byval_arg)) - return GUINT_TO_POINTER (1); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_REF); else if (mono_class_is_nullable (class)) - return GUINT_TO_POINTER (2); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_NULLABLE); else - return GUINT_TO_POINTER (0); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_VTYPE); case MONO_RGCTX_INFO_MEMCPY: case MONO_RGCTX_INFO_BZERO: { static MonoMethod *memcpy_method [17]; @@ -1236,11 +1236,11 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti impl_class = method->klass; if (MONO_TYPE_IS_REFERENCE (&impl_class->byval_arg)) - return GUINT_TO_POINTER (1); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_REF); else if (mono_class_is_nullable (impl_class)) - return GUINT_TO_POINTER (2); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_NULLABLE); else - return GUINT_TO_POINTER (0); + return GUINT_TO_POINTER (MONO_GSHAREDVT_BOX_TYPE_VTYPE); } #ifndef DISABLE_REMOTING case MONO_RGCTX_INFO_REMOTING_INVOKE_WITH_CHECK: @@ -1253,10 +1253,11 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti case MONO_RGCTX_INFO_FIELD_OFFSET: { MonoClassField *field = data; + /* The value is offset by 1 */ if (field->parent->valuetype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) - return GUINT_TO_POINTER (field->offset - sizeof (MonoObject)); + return GUINT_TO_POINTER (field->offset - sizeof (MonoObject) + 1); else - return GUINT_TO_POINTER (field->offset); + return GUINT_TO_POINTER (field->offset + 1); } case MONO_RGCTX_INFO_METHOD_RGCTX: { MonoMethodInflated *method = data; @@ -1851,6 +1852,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex method_inst ? method_inst->type_argc : 0, slot, TRUE, TRUE, &do_free); /* This might take the loader lock */ info = instantiate_info (domain, &oti, &context, class); + g_assert (info); /* if (method_inst) diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 7c01d8b67d9..2e5dc1ce3db 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -1108,6 +1108,13 @@ enum { MONO_GENERIC_CONTEXT_USED_METHOD = 2 }; +enum { + /* Cannot be 0 since this is stored in rgctx slots, and 0 means an unitialized rgctx slot */ + MONO_GSHAREDVT_BOX_TYPE_VTYPE = 1, + MONO_GSHAREDVT_BOX_TYPE_REF = 2, + MONO_GSHAREDVT_BOX_TYPE_NULLABLE = 3 +}; + typedef enum { MONO_RGCTX_INFO_STATIC_DATA, MONO_RGCTX_INFO_KLASS, @@ -1125,6 +1132,7 @@ typedef enum { MONO_RGCTX_INFO_CAST_CACHE, MONO_RGCTX_INFO_ARRAY_ELEMENT_SIZE, MONO_RGCTX_INFO_VALUE_SIZE, + /* +1 to avoid zero values in rgctx slots */ MONO_RGCTX_INFO_FIELD_OFFSET, /* Either the code for a gsharedvt method, or the address for a gsharedvt-out trampoline for the method */ MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE, @@ -1132,11 +1140,7 @@ typedef enum { MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT, /* Same for calli, associated with a signature */ MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI, - /* - * 0 - vtype - * 1 - ref - * 2 - gsharedvt type - */ + /* One of MONO_GSHAREDVT_BOX_TYPE */ MONO_RGCTX_INFO_CLASS_BOX_TYPE, /* Resolves to a MonoGSharedVtMethodRuntimeInfo */ MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO, @@ -1796,6 +1800,7 @@ enum { #define OP_DUMMY_PCONST OP_DUMMY_I8CONST #define OP_PADD OP_LADD #define OP_PADD_IMM OP_LADD_IMM +#define OP_PSUB_IMM OP_LSUB_IMM #define OP_PAND_IMM OP_LAND_IMM #define OP_PSUB OP_LSUB #define OP_PMUL OP_LMUL @@ -1820,6 +1825,7 @@ enum { #define OP_DUMMY_PCONST OP_DUMMY_ICONST #define OP_PADD OP_IADD #define OP_PADD_IMM OP_IADD_IMM +#define OP_PSUB_IMM OP_ISUB_IMM #define OP_PAND_IMM OP_IAND_IMM #define OP_PSUB OP_ISUB #define OP_PMUL OP_IMUL |