+2009-03-05 Mark Probst <mark.probst@gmail.com>
+
+ * method-to-ir.c (mono_method_to_ir): Only force the vtable var
+ for methods which actually have one. For all other methods, make
+ sure the this argument var is live the whole method.
+
+ * mini.c (mini_method_compile): Every shared method has a
+ this/vtable/mrgctx info. Fixes #480807.
+
2009-03-05 Mark Probst <mark.probst@gmail.com>
* mini-ppc.c (mono_arch_build_imt_thunk): Add support for mixed
/* We force the vtable variable here for all shared methods
for the possibility that they might show up in a stack
trace where their exact instantiation is needed. */
- if (cfg->generic_sharing_context)
- mono_get_vtable_var (cfg);
+ if (cfg->generic_sharing_context && method == cfg->method) {
+ if ((method->flags & METHOD_ATTRIBUTE_STATIC) ||
+ mini_method_get_context (method)->method_inst ||
+ method->klass->valuetype) {
+ mono_get_vtable_var (cfg);
+ } else {
+ /* FIXME: Is there a better way to do this?
+ We need the variable live for the duration
+ of the whole method. */
+ cfg->args [0]->flags |= MONO_INST_INDIRECT;
+ }
+ }
/* add a check for this != NULL to inlined methods */
if (is_virtual_call) {
gi->generic_sharing_context = cfg->generic_sharing_context;
- /*
- * Non-generic static methods only get a "this" info
- * if they use the rgctx variable (which they are
- * forced to if they have any open catch clauses).
- */
- if (cfg->rgctx_var ||
- (!(method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) &&
- !mini_method_get_context (method_to_compile)->method_inst &&
- !method_to_compile->klass->valuetype)) {
- gi->has_this = 1;
-
- if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
- mini_method_get_context (method_to_compile)->method_inst ||
- method_to_compile->klass->valuetype) {
- inst = cfg->rgctx_var;
- g_assert (inst->opcode == OP_REGOFFSET);
- } else {
- inst = cfg->args [0];
- }
+ if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
+ mini_method_get_context (method_to_compile)->method_inst ||
+ method_to_compile->klass->valuetype) {
+ g_assert (cfg->rgctx_var);
+ }
- if (inst->opcode == OP_REGVAR) {
- gi->this_in_reg = 1;
- gi->this_reg = inst->dreg;
+ gi->has_this = 1;
- //g_print ("this in reg %d\n", inst->dreg);
- } else {
- g_assert (inst->opcode == OP_REGOFFSET);
+ if ((method_to_compile->flags & METHOD_ATTRIBUTE_STATIC) ||
+ mini_method_get_context (method_to_compile)->method_inst ||
+ method_to_compile->klass->valuetype) {
+ inst = cfg->rgctx_var;
+ g_assert (inst->opcode == OP_REGOFFSET);
+ } else {
+ inst = cfg->args [0];
+ }
+
+ if (inst->opcode == OP_REGVAR) {
+ gi->this_in_reg = 1;
+ gi->this_reg = inst->dreg;
+ } else {
+ g_assert (inst->opcode == OP_REGOFFSET);
#ifdef __i386__
- g_assert (inst->inst_basereg == X86_EBP);
+ g_assert (inst->inst_basereg == X86_EBP);
#elif defined(__x86_64__)
- g_assert (inst->inst_basereg == X86_EBP || inst->inst_basereg == X86_ESP);
+ g_assert (inst->inst_basereg == X86_EBP || inst->inst_basereg == X86_ESP);
#endif
- g_assert (inst->inst_offset >= G_MININT32 && inst->inst_offset <= G_MAXINT32);
+ g_assert (inst->inst_offset >= G_MININT32 && inst->inst_offset <= G_MAXINT32);
- gi->this_in_reg = 0;
- gi->this_reg = inst->inst_basereg;
- gi->this_offset = inst->inst_offset;
-
- //g_print ("this at offset %d from reg %d\n", gi->this_offset, gi->this_reg);
- }
- } else {
- gi->has_this = 0;
+ gi->this_in_reg = 0;
+ gi->this_reg = inst->inst_basereg;
+ gi->this_offset = inst->inst_offset;
}
}