Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Christoforides <alexis@thenull.net>2015-11-23 19:07:10 +0300
committerAlexis Christoforides <alexis@thenull.net>2015-11-23 19:07:10 +0300
commita7605b3ba7cc2d2ddfbf4331edb4f9a935fdb564 (patch)
treecafcb92e18fb84ec44e24cffe855367c528d5987
parent6dd2d0d52b8bc4262d67833f44bc1537c3d17a9e (diff)
parent30015f112727e2601202b114b75e0ba8e9e1af81 (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.c25
-rw-r--r--mono/mini/mini-generic-sharing.c18
-rw-r--r--mono/mini/mini.h16
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