Hi, 2009/9/5 Eduard - Gabriel Munteanu <eduard.munte...@linux360.ro>: > We must not keep the parameters we received in fixed registers because > they can be clobbered by other insn-selector rules that use them (e.g. > method invocation). > > Signed-off-by: Eduard - Gabriel Munteanu <eduard.munte...@linux360.ro> > --- > arch/x86/insn-selector.brg | 38 +++++++++++++++++++++++++++++++------- > include/jit/compilation-unit.h | 4 ++++ > 2 files changed, 35 insertions(+), 7 deletions(-) > > diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg > index f9995fc..17b68a1 100644 > --- a/arch/x86/insn-selector.brg > +++ b/arch/x86/insn-selector.brg > @@ -2280,7 +2280,7 @@ stmt: STMT_STORE(EXPR_TEMPORARY, EXPR_LOCAL) 1 > select_insn(s, tree, > memlocal_reg_insn(INSN_MOV_MEMLOCAL_REG, > slot, dest)); > } else { > - src = get_fixed_var(s->b_parent, reg); > + src = > s->b_parent->non_fixed_args[exprsrc->local_index]; > select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, > src, dest)); > } > } else { > @@ -3388,15 +3388,39 @@ static void setup_caller_saved_regs(struct > compilation_unit *cu) > #else /* CONFIG_X86_32 */ > static void setup_caller_saved_regs(struct compilation_unit *cu) > { > + struct var_info **map; > + struct var_info *rdi, *rsi, *rdx, *rcx, *r8, *r9; > + struct basic_block *bb = cu->entry_bb; > + > get_fixed_var(cu, MACH_REG_RAX); > - get_fixed_var(cu, MACH_REG_RDI); > - get_fixed_var(cu, MACH_REG_RSI); > - get_fixed_var(cu, MACH_REG_RDX); > - get_fixed_var(cu, MACH_REG_RCX); > - get_fixed_var(cu, MACH_REG_R8); > - get_fixed_var(cu, MACH_REG_R9); > get_fixed_var(cu, MACH_REG_R10); > get_fixed_var(cu, MACH_REG_R11); > + > + cu->non_fixed_args = malloc(6 * sizeof(struct var_info *)); > + if (!cu->non_fixed_args) > + abort(); > + map = cu->non_fixed_args; > + > + rdi = get_fixed_var(cu, MACH_REG_RDI); > + rsi = get_fixed_var(cu, MACH_REG_RSI); > + rdx = get_fixed_var(cu, MACH_REG_RDX); > + rcx = get_fixed_var(cu, MACH_REG_RCX); > + r8 = get_fixed_var(cu, MACH_REG_R8); > + r9 = get_fixed_var(cu, MACH_REG_R9); > + > + map[0] = get_var(cu, J_LONG); > + map[1] = get_var(cu, J_LONG); > + map[2] = get_var(cu, J_LONG); > + map[3] = get_var(cu, J_LONG); > + map[4] = get_var(cu, J_LONG); > + map[5] = get_var(cu, J_LONG); > + > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, rdi, map[0])); > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, rsi, map[1])); > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, rdx, map[2])); > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, rcx, map[3])); > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, r8, map[4])); > + eh_add_insn(bb, reg_reg_insn(INSN_MOV_REG_REG, r9, map[5])); > } > #endif /* CONFIG_X86_32 */
It is incorrect to allocate virtual registers of J_LONG type for all call arguments, regardless of their type. That's because for garbage collection to work we must track which virtual registers hold a reference and which don't. We also can't mark all registers as J_REFERENCE because it could cause that integers would be interpreted as pointers. I think the proper solution would be to iterate over method's call argument types, and for argument type T we should allocate register of type mimic_stack_type(T). I also think that we only have to emit movs for registers which are actually holding a call argument, not for all of them, but that's an optimization. -- Tomek Grabiec ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel