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:
authorZoltan Varga <vargaz@gmail.com>2004-07-08 23:15:11 +0400
committerZoltan Varga <vargaz@gmail.com>2004-07-08 23:15:11 +0400
commit3f3302374872f3afa8984d1ec2a5cb09527175ef (patch)
tree67db20383afefc5cdcfd72c8f50ae822d95873d3
parent8a2c6383e9d7412d5ef04f141e1d602e377de36a (diff)
Merge from HEAD.
svn path=/branches/mono-1-0/mono/; revision=30898
-rw-r--r--mono/mini/ChangeLog5
-rw-r--r--mono/mini/mini.c84
-rw-r--r--mono/mini/mini.h1
3 files changed, 70 insertions, 20 deletions
diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog
index cdcd480a069..dad985c6904 100644
--- a/mono/mini/ChangeLog
+++ b/mono/mini/ChangeLog
@@ -1,3 +1,8 @@
+2004-07-08 Zoltan Varga <vargaz@freemail.hu>
+
+ * mini.c (handle_stack_args): Handle some corner cases. Fixes
+ 58863.
+
2004-07-05 Zoltan Varga <vargaz@freemail.hu>
* mini.c (optimize_branches): Fix linking of bblocks in branch->branch
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index d1e340a5966..14a32f6dd6c 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -1581,23 +1581,24 @@ mono_compile_get_interface_var (MonoCompile *cfg, int slot, MonoInst *ins)
*/
static int
handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int count) {
- int i;
+ int i, bindex;
MonoBasicBlock *outb;
MonoInst *inst, **locals;
+ gboolean found;
if (!count)
return 0;
if (cfg->verbose_level > 3)
g_print ("%d item(s) on exit from B%d\n", count, bb->block_num);
if (!bb->out_scount) {
- int found = 0;
bb->out_scount = count;
//g_print ("bblock %d has out:", bb->block_num);
+ found = FALSE;
for (i = 0; i < bb->out_count; ++i) {
outb = bb->out_bb [i];
//g_print (" %d", outb->block_num);
if (outb->in_stack) {
- found = 1;
+ found = TRUE;
bb->out_stack = outb->in_stack;
break;
}
@@ -1606,19 +1607,34 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
if (!found) {
bb->out_stack = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * count);
for (i = 0; i < count; ++i) {
-/* see bug#58863, but removing this code causes regressions in gtk-sharp build
- * (SEGV running Method::Initialize() in gapi_codegen.exe)
- */
-#if 1
- /* try to reuse temps already allocated for this purpouse, if they occupy the same
- * stack slot and if they are of the same type. */
- bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
-#else
- bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
-#endif
+ /*
+ * try to reuse temps already allocated for this purpouse, if they occupy the same
+ * stack slot and if they are of the same type.
+ * This won't cause conflicts since if 'local' is used to
+ * store one of the values in the in_stack of a bblock, then
+ * the same variable will be used for the same outgoing stack
+ * slot as well.
+ * This doesn't work when inlining methods, since the bblocks
+ * in the inlined methods do not inherit their in_stack from
+ * the bblock they are inlined to. See bug #58863 for an
+ * example.
+ */
+ if (cfg->inlined_method)
+ bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
+ else
+ bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
}
}
}
+
+ for (i = 0; i < bb->out_count; ++i) {
+ outb = bb->out_bb [i];
+ if (outb->in_scount)
+ continue; /* check they are the same locals */
+ outb->in_scount = count;
+ outb->in_stack = bb->out_stack;
+ }
+
locals = bb->out_stack;
for (i = 0; i < count; ++i) {
/* add store ops at the end of the bb, before the branch */
@@ -1633,14 +1649,36 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
if (cfg->verbose_level > 3)
g_print ("storing %d to temp %d\n", i, locals [i]->inst_c0);
}
-
- for (i = 0; i < bb->out_count; ++i) {
- outb = bb->out_bb [i];
- if (outb->in_scount)
- continue; /* check they are the same locals */
- outb->in_scount = count;
- outb->in_stack = locals;
+
+ /*
+ * It is possible that the out bblocks already have in_stack assigned, and
+ * the in_stacks differ. In this case, we will store to all the different
+ * in_stacks.
+ */
+
+ found = TRUE;
+ bindex = 0;
+ while (found) {
+ /* Find a bblock which has a different in_stack */
+ found = FALSE;
+ while (bindex < bb->out_count) {
+ outb = bb->out_bb [bindex];
+ if (outb->in_stack != locals) {
+ /*
+ * Instead of storing sp [i] to locals [i], we need to store
+ * locals [i] to <new locals>[i], since the sp [i] tree can't
+ * be shared between trees.
+ */
+ for (i = 0; i < count; ++i)
+ mono_add_varcopy_to_end (cfg, bb, locals [i]->inst_c0, outb->in_stack [i]->inst_c0);
+ locals = outb->in_stack;
+ found = TRUE;
+ break;
+ }
+ bindex ++;
+ }
}
+
return 0;
}
@@ -2427,6 +2465,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
MonoMethodHeader *cheader;
MonoBasicBlock *ebblock, *sbblock;
int i, costs, new_locals_offset;
+ MonoMethod *prev_inlined_method;
if (cfg->verbose_level > 2)
g_print ("INLINE START %p %s -> %s\n", cmethod, mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
@@ -2455,8 +2494,13 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
ebblock->block_num = cfg->num_bblocks++;
ebblock->real_offset = real_offset;
+ prev_inlined_method = cfg->inlined_method;
+ cfg->inlined_method = cmethod;
+
costs = mono_method_to_ir (cfg, cmethod, sbblock, ebblock, new_locals_offset, rvar, dont_inline, sp, real_offset, *ip == CEE_CALLVIRT);
+ cfg->inlined_method = prev_inlined_method;
+
if ((costs >= 0 && costs < 60) || inline_allways) {
if (cfg->verbose_level > 2)
g_print ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index adc1e9086b5..e62be1b95cb 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -492,6 +492,7 @@ typedef struct {
MonoSpillInfo *spill_info_float; /* fp register spills */
gint spill_count;
/* unsigned char *cil_code; */
+ MonoMethod *inlined_method; /* the method which is currently inlined */
/* the exception object passed to catch/filter blocks */
MonoInst *exvar;