[interp/tramp] use MONO_STRUCT_OFFSET infrastructure and extract constants
authorBernhard Urban <bernhard.urban@xamarin.com>
Wed, 17 May 2017 11:40:57 +0000 (13:40 +0200)
committerBernhard Urban <bernhard.urban@xamarin.com>
Wed, 17 May 2017 15:36:43 +0000 (17:36 +0200)
mono/mini/interp/interp.c
mono/mini/interp/interp.h
mono/mini/tramp-amd64.c
mono/mini/tramp-arm64.c

index 64c101a30abf76c83ba629403c8a022818f180d8..8cf7bec464ca320de00f1ab8ef38f8ef6dd6e57b 100644 (file)
@@ -758,22 +758,10 @@ interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUn
 
 static MonoPIFunc mono_interp_enter_icall_trampoline = NULL;
 
-struct _MethodArguments {
-       size_t ilen;
-       gpointer *iargs;
-       size_t flen;
-       double *fargs;
-       gpointer *retval;
-       size_t is_float_ret;
-};
-
-typedef struct _MethodArguments MethodArguments;
-
 // TODO: this function is also arch dependent (register width).
-static MethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvocation *frame)
+static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvocation *frame)
 {
-       // TODO: don't malloc this data structure.
-       MethodArguments *margs = g_malloc0 (sizeof (MethodArguments));
+       InterpMethodArguments *margs = g_malloc0 (sizeof (InterpMethodArguments));
 
        if (sig->hasthis)
                margs->ilen++;
@@ -816,10 +804,10 @@ static MethodArguments* build_args_from_sig (MonoMethodSignature *sig, MonoInvoc
        if (margs->flen > 0)
                margs->fargs = g_malloc0 (sizeof (double) * margs->flen);
 
-       if (margs->ilen > 12)
+       if (margs->ilen > INTERP_ICALL_TRAMP_IARGS)
                g_error ("build_args_from_sig: TODO, allocate gregs: %d\n", margs->ilen);
 
-       if (margs->flen > 3)
+       if (margs->flen > INTERP_ICALL_TRAMP_FARGS)
                g_error ("build_args_from_sig: TODO, allocate fregs: %d\n", margs->flen);
 
 
@@ -939,7 +927,7 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
                // mono_tramp_info_register (info, NULL);
        }
 
-       MethodArguments *margs = build_args_from_sig (sig, frame);
+       InterpMethodArguments *margs = build_args_from_sig (sig, frame);
 #if DEBUG_INTERP
        g_print ("ICALL: mono_interp_enter_icall_trampoline = %p, addr = %p\n", mono_interp_enter_icall_trampoline, addr);
        g_print ("margs(out): ilen=%d, flen=%d\n", margs->ilen, margs->flen);
index 8d83bf401495426f661669c63ce4efc86c3aa531..8ec9862e2e5a7c4d13f1f0960a0e691406ace07c 100644 (file)
@@ -6,6 +6,21 @@
 #define __MONO_MINI_INTERPRETER_H__
 #include <mono/mini/mini.h>
 
+#define INTERP_ICALL_TRAMP_IARGS 12
+#define INTERP_ICALL_TRAMP_FARGS 3
+
+struct _InterpMethodArguments {
+       size_t ilen;
+       gpointer *iargs;
+       size_t flen;
+       double *fargs;
+       gpointer *retval;
+       size_t is_float_ret;
+};
+
+typedef struct _InterpMethodArguments InterpMethodArguments;
+
+
 typedef struct _MonoInterpStackIter MonoInterpStackIter;
 
 /* Needed for stack allocation */
index aa61977cd8f0395c40dedd758282a9acd35e72f1..634203bc2e0c92404a2551b3241ccf6c47afae64 100644 (file)
 #include "mini-amd64.h"
 #include "debugger-agent.h"
 
+#ifdef ENABLE_INTERPRETER
+#include "interp/interp.h"
+#endif
+
 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
 
 #define IS_REX(inst) (((inst) >= 0x40) && ((inst) <= 0x4f))
@@ -1001,16 +1005,18 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
 /*
  * mono_arch_get_enter_icall_trampoline:
  *
- *   A trampoline that handles the transition from interpreter into native world.
- *   It requiers to set up a descriptor (MethodArguments) that describes the
- *   required arguments passed to the callee.
+ *   A trampoline that handles the transition from interpreter into native
+ *   world. It requiers to set up a descriptor (InterpMethodArguments), so the
+ *   trampoline can translate the arguments into the native calling convention.
+ *
+ *   See also `build_args_from_sig ()` in interp.c.
  */
 gpointer
 mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
 {
 #ifdef ENABLE_INTERPRETER
-       const int gregs_num = 12;
-       const int fregs_num = 3;
+       const int gregs_num = INTERP_ICALL_TRAMP_IARGS;
+       const int fregs_num = INTERP_ICALL_TRAMP_FARGS;
        guint8 *start = NULL, *code, *label_gexits [gregs_num], *label_fexits [fregs_num], *label_leave_tramp [3], *label_is_float_ret;
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
@@ -1034,19 +1040,19 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        amd64_mov_reg_reg (code, AMD64_RBP, AMD64_RSP, sizeof (mgreg_t));
        amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT));
 
-       /* save MethodArguments* onto stack */
+       /* save InterpMethodArguments* onto stack */
        amd64_mov_membase_reg (code, AMD64_RBP, off_methodargs, AMD64_ARG_REG2, sizeof (mgreg_t));
 
        /* save target address on stack */
        amd64_mov_membase_reg (code, AMD64_RBP, off_targetaddr, AMD64_ARG_REG1, sizeof (mgreg_t));
 
-       /* load pointer to MethodArguments* into R11 */
+       /* load pointer to InterpMethodArguments* into R11 */
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_ARG_REG2, 8);
        
-       /* move flen into RAX */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 16, sizeof (mgreg_t));
-       /* load pointer to fregs into R11 */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 24, sizeof (mgreg_t));
+       /* move flen into RAX */
+       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, flen), sizeof (mgreg_t));
+       /* load pointer to fargs into R11 */
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, fargs), sizeof (mgreg_t));
 
        for (i = 0; i < fregs_num; ++i) {
                amd64_test_reg_reg (code, AMD64_RAX, AMD64_RAX);
@@ -1060,10 +1066,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        for (i = 0; i < fregs_num; i++)
                x86_patch (label_fexits [i], code);
 
-       /* load pointer to MethodArguments* into R11 */
+       /* load pointer to InterpMethodArguments* into R11 */
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_ARG_REG2, sizeof (mgreg_t));
-       /* move ilen into RAX */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 0, sizeof (mgreg_t));
+       /* move ilen into RAX */
+       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen), sizeof (mgreg_t));
 
        int stack_offset = 0;
        for (i = 0; i < gregs_num; i++) {
@@ -1071,10 +1077,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
                label_gexits [i] = code;
                x86_branch32 (code, X86_CC_Z, 0, FALSE);
 
-               /* load pointer to MethodArguments* into R11 */
+               /* load pointer to InterpMethodArguments* into R11 */
                amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
-               /* load pointer to iregs into R11 */ // TODO: struct offset
-               amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 8, sizeof (mgreg_t));
+               /* load pointer to iargs into R11 */
+               amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, iargs), sizeof (mgreg_t));
 
                if (i < PARAM_REGS) {
                        amd64_mov_reg_membase (code, param_regs [i], AMD64_R11, i * sizeof (mgreg_t), sizeof (mgreg_t));
@@ -1095,11 +1101,11 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        /* call into native function */
        amd64_call_reg (code, AMD64_R11);
 
-       /* load MethodArguments */
+       /* load InterpMethodArguments */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
 
-       /* load is_float_ret */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x28, sizeof (mgreg_t));
+       /* load is_float_ret */
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret), sizeof (mgreg_t));
 
        /* check if a float return value is expected */
        amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
@@ -1108,10 +1114,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        x86_branch8 (code, X86_CC_NZ, 0, FALSE);
 
        /* greg return */
-       /* load MethodArguments */
+       /* load InterpMethodArguments */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
-       /* load retval */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x20, sizeof (mgreg_t));
+       /* load retval */
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, retval), sizeof (mgreg_t));
 
        amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
        label_leave_tramp [0] = code;
@@ -1124,10 +1130,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
 
        /* freg return */
        x86_patch (label_is_float_ret, code);
-       /* load MethodArguments */
+       /* load InterpMethodArguments */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
-       /* load retval */ // TODO: struct offset
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x20, sizeof (mgreg_t));
+       /* load retval */
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, retval), sizeof (mgreg_t));
 
        amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
        label_leave_tramp [2] = code;
index aa44b062c41014f53ba571eb2820efd63293a059..da998d4b1aa72bf4197d648a21d7dea3d42d85ec 100644 (file)
 #include <mono/arch/arm64/arm64-codegen.h>
 #include <mono/metadata/abi-details.h>
 
+#ifdef ENABLE_INTERPRETER
+#include "interp/interp.h"
+#endif
+
+
 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
 
 void
@@ -668,10 +673,8 @@ gpointer
 mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
 {
 #ifdef ENABLE_INTERPRETER
-       /* sync with constants in interp.c */
-       /* TODO: should be shared with other platforms */
-       const int gregs_num = ARMREG_R12;
-       const int fregs_num = 3;
+       const int gregs_num = INTERP_ICALL_TRAMP_IARGS;
+       const int fregs_num = INTERP_ICALL_TRAMP_FARGS;
 
        guint8 *start = NULL, *code, *label_gexits [gregs_num], *label_fexits [fregs_num], *label_leave_tramp [3], *label_is_float_ret;
        MonoJumpInfo *ji = NULL;
@@ -699,25 +702,26 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, stack_space);
        arm_addx_imm (code, ARMREG_FP, ARMREG_SP, stack_space);
 
-       /* save MethodArguments* onto stack */
+       /* save InterpMethodArguments* onto stack */
        arm_strx (code, ARMREG_R1, ARMREG_FP, off_methodargs);
 
        /* save target address onto stack */
        arm_strx (code, ARMREG_R0, ARMREG_FP, off_targetaddr);
 
-       /* load pointer to MethodArguments* into IP0 */
+       /* load pointer to InterpMethodArguments* into IP0 */
        arm_movx (code, ARMREG_IP0, ARMREG_R1);
 
-       /* move flen into R9 */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R9, ARMREG_IP0, 16);
-       /* load pointer to fregs into R10 */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R10, ARMREG_IP0, 24);
+       /* move flen into R9 */
+       arm_ldrx (code, ARMREG_R9, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, flen));
+       /* load pointer to fargs into R10 */
+       arm_ldrx (code, ARMREG_R10, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, fargs));
 
        for (i = 0; i < fregs_num; ++i) {
                arm_cmpx_imm (code, ARMREG_R9, 0);
                label_fexits [i] = code;
                arm_bcc (code, ARMCOND_EQ, 0);
 
+               g_assert (i <= ARMREG_D7); /* otherwise, need to pass args on stack */
                arm_ldrfpx (code, i, ARMREG_R10, i * sizeof (double));
                arm_subx_imm (code, ARMREG_R9, ARMREG_R9, 1);
        }
@@ -725,10 +729,10 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        for (i = 0; i < fregs_num; i++)
                mono_arm_patch (label_fexits [i], code, MONO_R_ARM64_BCC);
 
-       /* move ilen into R9 */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R9, ARMREG_IP0, 0);
-       /* load pointer to iregs into R10 */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R10, ARMREG_IP0, 8);
+       /* move ilen into R9 */
+       arm_ldrx (code, ARMREG_R9, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen));
+       /* load pointer to iargs into R10 */
+       arm_ldrx (code, ARMREG_R10, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, iargs));
 
        int stack_offset = 0;
        for (i = 0; i < gregs_num; i++) {
@@ -755,11 +759,11 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        /* call into native function */
        arm_blrx (code, ARMREG_R11);
 
-       /* load MethodArguments */
+       /* load InterpMethodArguments */
        arm_ldrx (code, ARMREG_IP0, ARMREG_FP, off_methodargs);
 
-       /* load is_float_ret */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x28);
+       /* load is_float_ret */
+       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret));
 
        /* check if a float return value is expected */
        arm_cmpx_imm (code, ARMREG_R11, 0);
@@ -767,8 +771,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
        arm_bcc (code, ARMCOND_NE, 0);
 
        /* greg return */
-       /* load retval */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x20);
+       /* load retval */
+       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
 
        arm_cmpx_imm (code, ARMREG_R11, 0);
        label_leave_tramp [0] = code;
@@ -782,8 +786,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
 
        /* freg return */
        mono_arm_patch (label_is_float_ret, code, MONO_R_ARM64_BCC);
-       /* load retval */ // TODO: struct offset
-       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x20);
+       /* load retval */
+       arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
 
        arm_cmpx_imm (code, ARMREG_R11, 0);
        label_leave_tramp [2] = code;