зеркало из https://github.com/mono/mono.git
[interp] avoid leaking MonoMethodHeader data structure by freeing or avoiding it
This commit is contained in:
Родитель
d055f9e21f
Коммит
acb5f68e3e
|
@ -91,6 +91,7 @@ typedef struct _InterpMethod
|
||||||
guint32 stack_size;
|
guint32 stack_size;
|
||||||
guint32 vt_stack_size;
|
guint32 vt_stack_size;
|
||||||
guint32 alloca_size;
|
guint32 alloca_size;
|
||||||
|
unsigned int init_locals : 1;
|
||||||
unsigned short *code;
|
unsigned short *code;
|
||||||
unsigned short *new_body_start; /* after all STINARG instrs */
|
unsigned short *new_body_start; /* after all STINARG instrs */
|
||||||
MonoPIFunc func;
|
MonoPIFunc func;
|
||||||
|
|
|
@ -229,13 +229,12 @@ ves_real_abort (int line, MonoMethod *mh,
|
||||||
const unsigned short *ip, stackval *stack, stackval *sp)
|
const unsigned short *ip, stackval *stack, stackval *sp)
|
||||||
{
|
{
|
||||||
MonoError error;
|
MonoError error;
|
||||||
fprintf (stderr, "Execution aborted in method: %s::%s\n", mh->klass->name, mh->name);
|
MonoMethodHeader *header = mono_method_get_header_checked (mh, &error);
|
||||||
fprintf (stderr, "Line=%d IP=0x%04lx, Aborted execution\n", line,
|
|
||||||
ip-(const unsigned short *)mono_method_get_header_checked (mh, &error)->code);
|
|
||||||
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
|
||||||
g_print ("0x%04x %02x\n",
|
|
||||||
ip-(const unsigned short *)mono_method_get_header_checked (mh, &error)->code, *ip);
|
|
||||||
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
||||||
|
g_printerr ("Execution aborted in method: %s::%s\n", mh->klass->name, mh->name);
|
||||||
|
g_printerr ("Line=%d IP=0x%04lx, Aborted execution\n", line, ip-(const unsigned short *) header->code);
|
||||||
|
g_print ("0x%04x %02x\n", ip-(const unsigned short *) header->code, *ip);
|
||||||
|
mono_metadata_free_mh (header);
|
||||||
if (sp > stack)
|
if (sp > stack)
|
||||||
printf ("\t[%ld] 0x%08x %0.5f\n", sp-stack, sp[-1].data.i, sp[-1].data.f);
|
printf ("\t[%ld] 0x%08x %0.5f\n", sp-stack, sp[-1].data.i, sp[-1].data.f);
|
||||||
}
|
}
|
||||||
|
@ -776,6 +775,7 @@ interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUn
|
||||||
fi.il_offset = frame->ip - (const unsigned short *) hd->code;
|
fi.il_offset = frame->ip - (const unsigned short *) hd->code;
|
||||||
if (!fi.method->wrapper_type)
|
if (!fi.method->wrapper_type)
|
||||||
fi.managed = TRUE;
|
fi.managed = TRUE;
|
||||||
|
mono_metadata_free_mh (hd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func (&fi, ctx, user_data))
|
if (func (&fi, ctx, user_data))
|
||||||
|
@ -1240,6 +1240,7 @@ dump_frame (InterpFrame *inv)
|
||||||
MonoDebugSourceLocation *minfo = mono_debug_lookup_method (method);
|
MonoDebugSourceLocation *minfo = mono_debug_lookup_method (method);
|
||||||
source = mono_debug_method_lookup_location (minfo, codep);
|
source = mono_debug_method_lookup_location (minfo, codep);
|
||||||
#endif
|
#endif
|
||||||
|
mono_metadata_free_mh (hd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args = dump_args (inv);
|
args = dump_args (inv);
|
||||||
|
@ -4929,9 +4930,8 @@ array_constructed:
|
||||||
|
|
||||||
int len = sp [-1].data.i;
|
int len = sp [-1].data.i;
|
||||||
sp [-1].data.p = alloca (len);
|
sp [-1].data.p = alloca (len);
|
||||||
MonoMethodHeader *header = mono_method_get_header_checked (frame->imethod->method, &error);
|
|
||||||
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
if (frame->imethod->init_locals)
|
||||||
if (header && header->init_locals)
|
|
||||||
memset (sp [-1].data.p, 0, len);
|
memset (sp [-1].data.p, 0, len);
|
||||||
++ip;
|
++ip;
|
||||||
MINT_IN_BREAK;
|
MINT_IN_BREAK;
|
||||||
|
@ -5103,8 +5103,6 @@ die_on_ex:
|
||||||
MonoExceptionClause *clause;
|
MonoExceptionClause *clause;
|
||||||
GSList *old_list = finally_ips;
|
GSList *old_list = finally_ips;
|
||||||
MonoMethod *method = frame->imethod->method;
|
MonoMethod *method = frame->imethod->method;
|
||||||
MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
|
|
||||||
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
|
||||||
|
|
||||||
#if DEBUG_INTERP
|
#if DEBUG_INTERP
|
||||||
if (tracing)
|
if (tracing)
|
||||||
|
@ -5118,9 +5116,10 @@ die_on_ex:
|
||||||
|
|
||||||
if (endfinally_ip != NULL)
|
if (endfinally_ip != NULL)
|
||||||
finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip);
|
finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip);
|
||||||
for (i = 0; i < header->num_clauses; ++i)
|
for (i = 0; i < rtm->num_clauses; ++i)
|
||||||
if (frame->ex_handler == &rtm->clauses [i])
|
if (frame->ex_handler == &rtm->clauses [i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
clause = &rtm->clauses [i];
|
clause = &rtm->clauses [i];
|
||||||
|
@ -5159,16 +5158,14 @@ die_on_ex:
|
||||||
guint32 ip_offset;
|
guint32 ip_offset;
|
||||||
MonoExceptionClause *clause;
|
MonoExceptionClause *clause;
|
||||||
GSList *old_list = finally_ips;
|
GSList *old_list = finally_ips;
|
||||||
MonoMethod *method = frame->imethod->method;
|
|
||||||
MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
|
|
||||||
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
|
|
||||||
|
|
||||||
#if DEBUG_INTERP
|
#if DEBUG_INTERP
|
||||||
if (tracing)
|
if (tracing)
|
||||||
g_print ("* Handle fault\n");
|
g_print ("* Handle fault\n");
|
||||||
#endif
|
#endif
|
||||||
ip_offset = frame->ip - rtm->code;
|
ip_offset = frame->ip - rtm->code;
|
||||||
for (i = 0; i < header->num_clauses; ++i) {
|
|
||||||
|
for (i = 0; i < rtm->num_clauses; ++i) {
|
||||||
clause = &rtm->clauses [i];
|
clause = &rtm->clauses [i];
|
||||||
if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) {
|
if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) {
|
||||||
ip = rtm->code + clause->handler_offset;
|
ip = rtm->code + clause->handler_offset;
|
||||||
|
|
|
@ -1062,7 +1062,6 @@ no_intrinsic:
|
||||||
(target_method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0 &&
|
(target_method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0 &&
|
||||||
!(target_method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING)) {
|
!(target_method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING)) {
|
||||||
int called_inited = mono_class_vtable (domain, target_method->klass)->initialized;
|
int called_inited = mono_class_vtable (domain, target_method->klass)->initialized;
|
||||||
MonoMethodHeader *mheader = mono_method_get_header (target_method);
|
|
||||||
|
|
||||||
if (/*mono_metadata_signature_equal (method->signature, target_method->signature) */ method == target_method && *(td->ip + 5) == CEE_RET) {
|
if (/*mono_metadata_signature_equal (method->signature, target_method->signature) */ method == target_method && *(td->ip + 5) == CEE_RET) {
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -1080,12 +1079,17 @@ no_intrinsic:
|
||||||
td->ip += 5;
|
td->ip += 5;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
MonoMethodHeader *mheader = mono_method_get_header (target_method);
|
||||||
/* mheader might not exist if this is a delegate invoc, etc */
|
/* mheader might not exist if this is a delegate invoc, etc */
|
||||||
gboolean has_vt_arg = FALSE;
|
gboolean has_vt_arg = FALSE;
|
||||||
for (i = 0; i < csignature->param_count; i++)
|
for (i = 0; i < csignature->param_count; i++)
|
||||||
has_vt_arg |= !mini_type_is_reference (csignature->params [i]);
|
has_vt_arg |= !mini_type_is_reference (csignature->params [i]);
|
||||||
|
|
||||||
if (mheader && *mheader->code == CEE_RET && called_inited && !has_vt_arg) {
|
gboolean empty_callee = mheader && *mheader->code == CEE_RET;
|
||||||
|
if (mheader)
|
||||||
|
mono_metadata_free_mh (mheader);
|
||||||
|
|
||||||
|
if (empty_callee && called_inited && !has_vt_arg) {
|
||||||
if (td->verbose_level)
|
if (td->verbose_level)
|
||||||
g_print ("Inline (empty) call of %s.%s\n", target_method->klass->name, target_method->name);
|
g_print ("Inline (empty) call of %s.%s\n", target_method->klass->name, target_method->name);
|
||||||
for (i = 0; i < csignature->param_count; i++) {
|
for (i = 0; i < csignature->param_count; i++) {
|
||||||
|
@ -1336,7 +1340,7 @@ interp_save_debug_info (InterpMethod *rtm, MonoMethodHeader *header, TransformDa
|
||||||
}
|
}
|
||||||
for (i = 0; i < dinfo->num_locals; i++) {
|
for (i = 0; i < dinfo->num_locals; i++) {
|
||||||
MonoDebugVarInfo *var = &dinfo->locals [i];
|
MonoDebugVarInfo *var = &dinfo->locals [i];
|
||||||
var->type = header->locals [i];
|
var->type = mono_metadata_type_dup (NULL, header->locals [i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < dinfo->num_line_numbers; i++)
|
for (i = 0; i < dinfo->num_line_numbers; i++)
|
||||||
|
@ -1550,9 +1554,8 @@ emit_seq_point (TransformData *td, int il_offset, InterpBasicBlock *cbb, gboolea
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generate (MonoMethod *method, InterpMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context, MonoError *error)
|
generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context, MonoError *error)
|
||||||
{
|
{
|
||||||
MonoMethodHeader *header = mono_method_get_header (method);
|
|
||||||
MonoMethodSignature *signature = mono_method_signature (method);
|
MonoMethodSignature *signature = mono_method_signature (method);
|
||||||
MonoImage *image = method->klass->image;
|
MonoImage *image = method->klass->image;
|
||||||
MonoDomain *domain = rtm->domain;
|
MonoDomain *domain = rtm->domain;
|
||||||
|
@ -4140,6 +4143,7 @@ generate (MonoMethod *method, InterpMethod *rtm, unsigned char *is_bb_start, Mon
|
||||||
memcpy (rtm->code, td->new_code, (td->new_ip - td->new_code) * sizeof(gushort));
|
memcpy (rtm->code, td->new_code, (td->new_ip - td->new_code) * sizeof(gushort));
|
||||||
g_free (td->new_code);
|
g_free (td->new_code);
|
||||||
rtm->new_body_start = rtm->code + body_start_offset;
|
rtm->new_body_start = rtm->code + body_start_offset;
|
||||||
|
rtm->init_locals = header->init_locals;
|
||||||
rtm->num_clauses = header->num_clauses;
|
rtm->num_clauses = header->num_clauses;
|
||||||
for (i = 0; i < header->num_clauses; i++) {
|
for (i = 0; i < header->num_clauses; i++) {
|
||||||
MonoExceptionClause *c = rtm->clauses + i;
|
MonoExceptionClause *c = rtm->clauses + i;
|
||||||
|
@ -4216,7 +4220,7 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
|
||||||
int i, align, size, offset;
|
int i, align, size, offset;
|
||||||
MonoMethod *method = imethod->method;
|
MonoMethod *method = imethod->method;
|
||||||
MonoImage *image = method->klass->image;
|
MonoImage *image = method->klass->image;
|
||||||
MonoMethodHeader *header = mono_method_get_header (method);
|
MonoMethodHeader *header = NULL;
|
||||||
MonoMethodSignature *signature = mono_method_signature (method);
|
MonoMethodSignature *signature = mono_method_signature (method);
|
||||||
register const unsigned char *ip, *end;
|
register const unsigned char *ip, *end;
|
||||||
const MonoOpcode *opcode;
|
const MonoOpcode *opcode;
|
||||||
|
@ -4331,6 +4335,10 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
|
||||||
g_error ("TODO");
|
g_error ("TODO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!header)
|
||||||
|
header = mono_method_get_header (method);
|
||||||
|
|
||||||
g_assert ((signature->param_count + signature->hasthis) < 1000);
|
g_assert ((signature->param_count + signature->hasthis) < 1000);
|
||||||
g_assert (header->max_stack < 10000);
|
g_assert (header->max_stack < 10000);
|
||||||
/* intern the strings in the method. */
|
/* intern the strings in the method. */
|
||||||
|
@ -4447,6 +4455,8 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
|
||||||
if (imethod->transformed) {
|
if (imethod->transformed) {
|
||||||
mono_os_mutex_unlock(&calc_section);
|
mono_os_mutex_unlock(&calc_section);
|
||||||
g_free (is_bb_start);
|
g_free (is_bb_start);
|
||||||
|
if (header)
|
||||||
|
mono_metadata_free_mh (header);
|
||||||
MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo));
|
MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -4503,7 +4513,9 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
|
||||||
g_assert (imethod->args_size < 10000);
|
g_assert (imethod->args_size < 10000);
|
||||||
|
|
||||||
error_init (&error);
|
error_init (&error);
|
||||||
generate (method, imethod, is_bb_start, generic_context, &error);
|
generate (method, header, imethod, is_bb_start, generic_context, &error);
|
||||||
|
|
||||||
|
mono_metadata_free_mh (header);
|
||||||
|
|
||||||
if (!mono_error_ok (&error)) {
|
if (!mono_error_ok (&error)) {
|
||||||
mono_os_mutex_unlock (&calc_section);
|
mono_os_mutex_unlock (&calc_section);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче