* src/mm/cacao-gc/gc.h: Added SPARC64 to the architectures that support exactGC
authorajordan <none@none>
Fri, 22 Jun 2007 08:47:15 +0000 (08:47 +0000)
committerajordan <none@none>
Fri, 22 Jun 2007 08:47:15 +0000 (08:47 +0000)
* src/vm/jit/sparc64/emit.c (emit_replacement_stubs): Added stub-like
implementation only non-trappable GC points will work.

* src/vm/jit/sparc64/codegen.c (codegen_emit): Added replacement points.
(codegen_emit_stub_builtin): Implemented.

* src/vm/jit/sparc64/patcher.c (patcher_wrapper): Temp debug print, to see when
extern sfi is created.

--HG--
branch : exact-gc

src/mm/cacao-gc/gc.h
src/vm/jit/arm/arch.h
src/vm/jit/arm/asmpart.S
src/vm/jit/m68k/linux/md-abi.h [new file with mode: 0644]
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/patcher.c

index 7dc8e9e7254cc57a65f4ea6cbc682fd7cde6b6cb..c99074dbe6233107549cc542993d7fb6175f3b91 100644 (file)
@@ -93,7 +93,7 @@
 # error "GC does only work with replacement enabled!"
 #endif
 
-#if 1 && !defined(__ALPHA__) && !defined(__I386__) && !defined(__POWERPC__) && !defined(__X86_64__) && !defined(__M68K__)
+#if 1 && !defined(__ALPHA__) && !defined(__I386__) && !defined(__POWERPC__) && !defined(__X86_64__) && !defined(__M68K__) && !defined(__SPARC_64__)
 # error "GC was only ported to i386 so far!"
 #endif
 
index 70264ab5e13c953b476390e34b76d5974a5eb8e8..bd7674707f20e56606152f2bbac1e7bf2106f143 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: arch.h 7695 2007-04-12 19:49:34Z twisti $
+   $Id: arch.h 7701 2007-04-15 00:38:00Z michi $
 
 */
 
index 934ba993e72b7e5bc4a80e19a1a9ec51f6d2c6c6..5f2c9289af49ed51ae4bac7b203d37b300f0f4e0 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: asmpart.S 7932 2007-05-22 07:00:57Z michi $
+   $Id: asmpart.S 7940 2007-05-23 09:42:08Z michi $
 
 */
 
diff --git a/src/vm/jit/m68k/linux/md-abi.h b/src/vm/jit/m68k/linux/md-abi.h
new file mode 100644 (file)
index 0000000..f6a72e2
--- /dev/null
@@ -0,0 +1,150 @@
+/* src/vm/jit/m68k/linux/md-abi.h - defines for m68k Linux ABI
+
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Roland Lezuo
+
+   Changes:
+
+   $Id: md-abi.h 5940 2006-11-09 09:59:28Z tbfg $
+
+*/
+
+
+#ifndef _MD_ABI_H
+#define _MD_ABI_H
+
+/* preallocated registers *****************************************************/
+
+/* integer registers */
+
+#define REG_RESULT       0   /* to deliver method results                     */
+#define REG_RESULT2      1   /* to deliver long method results                */
+
+#define REG_D0          0   /* register may be trashed by callee */
+#define REG_D1          1
+
+
+
+#define REG_ITMP1        2   /* temporary register                            */
+#define REG_ITMP2        3   /* temporary register and method pointer         */
+#define REG_ITMP3        4   /* temporary register                            */
+
+
+
+/* floating point registers */
+
+#define REG_F0          0   /* registers may be trashed by callee */
+#define REG_F1          1
+
+#define REG_FRESULT      0   /* to deliver floating point method results      */
+#define REG_FTMP1        2   /* temporary floating point register             */
+#define REG_FTMP2        3   /* temporary floating point register             */
+#define REG_FTMP3        4   /* temporary floating point register             */
+
+#define REG_IFTMP        2   /* temporary integer and floating point register */
+
+
+/* address registers */
+
+#define REG_A0          0   /* registers may be trashed by callee */
+#define REG_A1          1
+
+#define REG_ATMP1        2
+#define REG_ATMP2        3
+#define REG_METHODPTR    REG_ATMP2   /* pointer to the place from where the procedure */
+#define REG_ATMP3        4
+
+#define REG_ATMP1_XPTR   REG_ATMP1   /* exception pointer = temporary register 1      */
+#define REG_ATMP2_XPC    REG_ATMP2   /* exception pc = temporary register 2           */
+
+#define        REG_FP           6   /* frame pointer                                 */
+#define REG_SP           7   /* stack pointer                                 */
+
+/* number for the register allocator */
+
+#define INT_REG_CNT      8   /* number of integer registers                   */
+#define INT_SAV_CNT      3   /* number of int callee saved registers          */
+#define INT_ARG_CNT      0   /* number of int argument registers              */
+#define INT_TMP_CNT      2   /* number of integer temporary registers         */
+#define INT_RES_CNT      3   /* number of integer reserved registers          */
+
+#if !defined(ENABLE_SOFTFLOAT)
+       #define FLT_REG_CNT      8   /* number of float registers                     */
+       #define FLT_SAV_CNT      3   /* number of float callee saved registers        */
+       #define FLT_ARG_CNT      0   /* number of float argument registers            */
+       #define FLT_TMP_CNT      2   /* number of float temporary registers           */
+       #define FLT_RES_CNT      3   /* number of float reserved registers            */
+#else
+       #define FLT_REG_CNT      8   /* number of float registers                     */
+       #define FLT_SAV_CNT      0   /* number of float callee saved registers        */
+       #define FLT_ARG_CNT      0   /* number of float argument registers            */
+       #define FLT_TMP_CNT      0   /* number of float temporary registers           */
+       #define FLT_RES_CNT      8   /* number of float reserved registers            */
+#endif
+
+#define ADR_REG_CNT      8
+#define ADR_SAV_CNT      2
+#define ADR_ARG_CNT      0
+#define ADR_TMP_CNT      2
+#define ADR_RES_CNT      4
+
+
+/* packed register defines ***************************************************/
+
+#define REG_RESULT_PACKED      PACK_REGS(REG_RESULT2, REG_RESULT)
+#define REG_ITMP12_PACKED      PACK_REGS(REG_ITMP1, REG_ITMP2)
+#define REG_ITMP23_PACKED      PACK_REGS(REG_ITMP2, REG_ITMP3)
+
+/* ABI defines ****************************************************************/
+
+/* TODO */
+
+#define LA_SIZE_IN_POINTERS    0
+#if 0 
+#define LA_SIZE         48   /* linkage area size                             */
+#define LA_SIZE_ALIGNED 16   /* linkage area size aligned to 16-byte          */
+#define LA_SIZE_IN_POINTERS    (LA_SIZE / SIZEOF_VOID_P)
+#define LA_LR_OFFSET    16   /* link register offset in linkage area          */
+#define PA_SIZE                (PA_SIZE_IN_POINTERS*8) 
+#define PA_SIZE_IN_POINTERS    8 /* linux/ppc64 has a minimun parameter save area size, XXX:darwin? */
+#endif
+/* #define ALIGN_FRAME_SIZE(sp)       (sp) */
+
+#endif /* _MD_ABI_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index 08f7e426c332c1d4b385789f6f95736f0d525a58..63106331f4b0b4fad17b80a7bd7a6810a518454d 100644 (file)
@@ -390,13 +390,8 @@ bool codegen_emit(jitdata *jd)
                
                /* handle replacement points */
 
-#if 0
-               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
-                       replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
-                       
-                       replacementpoint++;
-               }
-#endif
+               REPLACEMENT_POINT_BLOCK_START(cd, bptr);
+
 
                /* copy interface registers to their destination */
 
@@ -2218,12 +2213,16 @@ bool codegen_emit(jitdata *jd)
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_LRETURN:
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
+
                        s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
                        M_INTMOVE(s1, REG_RESULT_CALLEE);
                        goto nowperformreturn;
 
                case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
+
                        s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
                        M_INTMOVE(s1, REG_RESULT_CALLEE);
 
@@ -2239,11 +2238,15 @@ bool codegen_emit(jitdata *jd)
                case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_DRETURN:
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
+
                        s1 = emit_load_s1(jd, iptr, REG_FRESULT);
                        M_DBLMOVE(s1, REG_FRESULT);
                        goto nowperformreturn;
 
                case ICMD_RETURN:       /* ...  ==> ...                               */
+                       
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
 
 nowperformreturn:
                        {
@@ -2384,11 +2387,13 @@ nowperformreturn:
 
                case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
 
+                       REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
+
                        bte = iptr->sx.s23.s3.bte;
                        md = bte->md;
                        
                        /* XXX: builtin calling with stack arguments not implemented */
-                       assert(md->paramcount <= 5 && md->argfltreguse <= 16);
+                       assert(md->paramcount <= 4 && md->argfltreguse <= 16);
                        
                        s3 = md->paramcount;
 
@@ -2435,11 +2440,12 @@ nowperformreturn:
                        goto gen_method;
 
                case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
-
                case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
                case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
                case ICMD_INVOKEINTERFACE:
 
+                       REPLACEMENT_POINT_INVOKE(cd, iptr);
+
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                lm = NULL;
                                um = iptr->sx.s23.s3.um;
@@ -2497,7 +2503,12 @@ gen_method:
 
                        switch (iptr->opc) {
                        case ICMD_BUILTIN:
-                               disp = dseg_add_functionptr(cd, bte->fp);
+                               if (bte->stub == NULL) {
+                                       disp = dseg_add_functionptr(cd, bte->fp);
+                               }
+                               else {
+                                       disp = dseg_add_functionptr(cd, bte->stub);
+                               }
 
                                M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
 
@@ -2506,6 +2517,8 @@ gen_method:
     
                            M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
                            M_NOP;
+                               REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+                               REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
                            disp = (s4) (cd->mcodeptr - cd->mcodebase);
                            /* REG_RA holds the value of the jmp instruction, therefore +8 */
                            M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
@@ -2537,6 +2550,7 @@ gen_method:
     
                            M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
                            M_NOP;
+                               REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
                            disp = (s4) (cd->mcodeptr - cd->mcodebase);
                            /* REG_RA holds the value of the jmp instruction, therefore +8 */
                            M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
@@ -2562,6 +2576,7 @@ gen_method:
     
                            M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
                            M_NOP;
+                               REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
                            disp = (s4) (cd->mcodeptr - cd->mcodebase);
                            /* REG_RA holds the value of the jmp instruction, therefore +8 */
                            M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
@@ -2592,6 +2607,7 @@ gen_method:
     
                            M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
                            M_NOP;
+                               REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
                            disp = (s4) (cd->mcodeptr - cd->mcodebase);
                            /* REG_RA holds the value of the jmp instruction, therefore +8 */
                            M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
@@ -3040,6 +3056,177 @@ void codegen_emit_stub_compiler(jitdata *jd)
 }
 
 
+/* codegen_emit_stub_builtin ***************************************************
+
+   Creates a stub routine which calls a builtin function.
+
+*******************************************************************************/
+
+void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
+{
+       codeinfo    *code;
+       codegendata *cd;
+       methoddesc  *md;
+       s4           i;
+       s4           disp;
+       s4           s1, s2;
+
+       /* get required compiler data */
+       code = jd->code;
+       cd   = jd->cd;
+
+       /* set some variables */
+       md = bte->md;
+
+       /* calculate stack frame size */
+       cd->stackframesize =
+               WINSAVE_CNT +
+               ABIPARAMS_CNT +
+               FLT_ARG_CNT +
+               sizeof(stackframeinfo) / SIZEOF_VOID_P +
+               4;                              /* 4 arguments or return value        */
+
+
+       /* keep stack 16-byte aligned (ABI requirement) */
+
+       if (cd->stackframesize & 1)
+               cd->stackframesize++;
+
+       /* create method header */
+       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
+       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
+       (void) dseg_addlinenumbertablesize(cd);
+       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
+
+
+       /* generate stub code */
+       M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
+
+#if defined(ENABLE_GC_CACAO)
+       /* Save callee saved integer registers in stackframeinfo (GC may
+          need to recover them during a collection). */
+
+       disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
+               OFFSET(stackframeinfo, intregs) + BIAS;
+
+       for (i = 0; i < INT_SAV_CNT; i++)
+               M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
+#endif
+
+       for (i = 0; i < md->paramcount; i++) {
+               s1 = md->params[i].regoff;
+
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       break;
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       M_DST(s1, REG_SP, JITSTACK + i * 8);
+                       break;
+               }
+       }
+
+       /* create dynamic stack info */
+
+       M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
+       M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
+       M_MOV(REG_FP, REG_OUT2); /* java sp */
+       M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
+
+       disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP; /* XXX fill me! */
+
+
+       /* builtins are allowed to have 5 arguments max */
+
+       assert(md->paramcount <= 5);
+
+       /* copy arguments into position */
+
+       for (i = 0; i < md->paramcount; i++) {
+               assert(!md->params[i].inmemory);
+
+               s1 = md->params[i].regoff;
+
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
+                       break;
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       M_DLD(s1, REG_SP, JITSTACK + i * 8);
+                       break;
+               }
+
+       }
+
+       /* call the builtin function */
+
+       disp = dseg_add_functionptr(cd, bte->fp);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin                */
+       M_NOP;                              /* delay slot                         */
+
+
+       /* save return value */
+
+       if (md->returntype.type != TYPE_VOID) {
+               if (IS_INT_LNG_TYPE(md->returntype.type))
+                       M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
+               else
+                       M_DST(REG_FRESULT, REG_SP, CSTACK);
+       }       
+
+
+       /* remove native stackframe info */
+
+       M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
+       disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP;
+
+       /* restore float return value, int return value already in our return reg */
+
+       if (md->returntype.type != TYPE_VOID) {
+               if (IS_FLT_DBL_TYPE(md->returntype.type)) {
+                       if (IS_2_WORD_TYPE(md->returntype.type))
+                               M_DLD(REG_FRESULT, REG_SP, CSTACK);
+                       else
+                               M_FLD(REG_FRESULT, REG_SP, CSTACK);
+               }
+       }
+
+
+#if defined(ENABLE_GC_CACAO)
+       /* Restore callee saved integer registers from stackframeinfo (GC
+          might have modified them during a collection). */
+        
+       disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
+               OFFSET(stackframeinfo, intregs) + BIAS;
+
+       for (i = 0; i < INT_SAV_CNT; i++)
+               M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
+#endif
+
+       /* return */
+       M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
+       M_NOP;
+
+       /* assert(0); */
+}
+
+
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
index 7eaa9df98a8dcb18b1ef70a12e9dc9833cffe34c..2e9b22e050d00ea53ee1ed5696f82ac47df71917 100644 (file)
@@ -689,6 +689,64 @@ void emit_patcher_stubs(jitdata *jd)
 #if defined(ENABLE_REPLACEMENT)
 void emit_replacement_stubs(jitdata *jd)
 {
+       codegendata *cd;
+       codeinfo    *code;
+       rplpoint    *rplp;
+       s4           disp;
+       s4           i;
+#if !defined(NDEBUG)
+       u1          *savedmcodeptr;
+#endif
+
+       /* get required compiler data */
+
+       cd   = jd->cd;
+       code = jd->code;
+
+       rplp = code->rplpoints;
+
+       /* store beginning of replacement stubs */
+
+       code->replacementstubs = (u1*) (cd->mcodeptr - cd->mcodebase);
+
+       for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
+               /* do not generate stubs for non-trappable points */
+
+               if (rplp->flags & RPLPOINT_FLAG_NOTRAP)
+                       continue;
+
+               M_LDX(0,0,0);
+
+/* this is just a stub rpl point for the GC */
+#if 0 
+
+               /* check code segment size */
+
+               MCODECHECK(100);
+
+#if !defined(NDEBUG)
+               savedmcodeptr = cd->mcodeptr;
+#endif
+
+               /* create stack frame - 16-byte aligned */
+
+               M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
+
+               /* push address of `rplpoint` struct */
+
+               disp = dseg_add_address(cd, rplp);
+               M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+               M_AST(REG_ITMP3, REG_SP, JITSTACK + 0 * 8);
+
+               /* jump to replacement function */
+
+               disp = dseg_add_functionptr(cd, asm_replacement_out);
+               M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+               M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);
+
+               assert((cd->mcodeptr - savedmcodeptr) == 4*REPLACEMENT_STUB_SIZE);
+#endif
+       }
 }
 #endif /* defined(ENABLE_REPLACEMENT) */
 
index e9467d192a458a845388223da9c84351e8ff2c54..c675e0e77aa6677e1e754d3c80ce5f6a09bb6630 100644 (file)
@@ -113,6 +113,8 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
 
        /* create the stackframeinfo */
 
+       printf("patcher opening sfi for xpc=%p\n", xpc);
+
        stacktrace_create_extern_stackframeinfo(&sfi, pv, javasp, ra, xpc);
 
        /* call the proper patcher function */
@@ -122,6 +124,7 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
        /* remove the stackframeinfo */
 
        stacktrace_remove_stackframeinfo(&sfi);
+       printf("patcher closing sfi for xpc=%p\n", xpc);
 
        /* check for return value and exit accordingly */