* src/vm/jit/code.h (codeinfo) [ENABLE_REPLACEMENT]: Removed obsolet pointer
[cacao.git] / src / vm / jit / code.c
index a07dc5372809584f66c4a83fa524141f82d79614..8fce23ec4a2bca89213a3287124f3024a51ea8bb 100644 (file)
@@ -1,6 +1,6 @@
-/* vm/jit/code.c - codeinfo struct for representing compiled code
+/* src/vm/jit/code.c - codeinfo struct for representing compiled code
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
    $Id$
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
-#include "vm/jit/code.h"
-#include "mm/memory.h"
-#include "vm/options.h"
+#include "vm/types.h"
+
 #include "arch.h"
 
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
+#include "vm/jit/code.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodheader.h"
+#include "vm/jit/patcher-common.h"
+
+#include "vmcore/options.h"
+
+
+/* code_init *******************************************************************
+
+   Initialize the code-subsystem.
+
+*******************************************************************************/
+
+bool code_init(void)
+{
+       /* check for offset of code->m == 0 (see comment in code.h) */
+
+       assert(OFFSET(codeinfo, m) == 0);
+
+       /* everything's ok */
+
+       return true;
+}
+
+
 /* code_codeinfo_new ***********************************************************
 
    Create a new codeinfo for the given method.
@@ -50,7 +74,9 @@
    IN:
        m................method to create a new codeinfo for
 
-   Note: codeinfo.m is set to m, all other fields are zeroed.
+   The following fields are set in codeinfo:
+       m
+       patchers
 
    RETURN VALUE:
        a new, initialized codeinfo, or
@@ -64,93 +90,116 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
        code = NEW(codeinfo);
 
-       memset(code,0,sizeof(codeinfo));
-
        code->m = m;
-       
+
+       patcher_list_create(code);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_codeinfo += sizeof(codeinfo);
+#endif
+
        return code;
 }
 
-/* code_get_sync_slot_count ****************************************************
 
-   Return the number of stack slots used for storing the synchronized object
-   (and the return value around monitorExit calls) by the given code.
-   
+/* code_find_codeinfo_for_pc ***************************************************
+
+   Return the codeinfo for the compilation unit that contains the
+   given PC.
+
    IN:
-       code.............the codeinfo of the code in question
-                           (must be != NULL)
+       pc...............machine code position
 
    RETURN VALUE:
-       the number of stack slots used for synchronization
-  
+       the codeinfo * for the given PC
+
 *******************************************************************************/
 
-int code_get_sync_slot_count(codeinfo *code)
+codeinfo *code_find_codeinfo_for_pc(u1 *pc)
 {
-       assert(code);
+       u1 *pv;
 
-#ifdef USE_THREADS
-       if (!checksync)
-               return 0;
+       pv = codegen_get_pv_from_pc(pc);
+       assert(pv);
 
-       if (!(code->m->flags & ACC_SYNCHRONIZED))
-               return 0;
+       return *(codeinfo **)(pv + CodeinfoPointer);
+}
 
-       /* XXX generalize to all archs */
-#ifdef HAS_4BYTE_STACKSLOT
-       return (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type)) ? 2 : 1;
-#else
-       return 1;
-#endif
-#else /* !USE_THREADS */
-       return 0;
-#endif /* USE_THREADS */
+
+/* code_get_methodinfo_for_pv **************************************************
+
+   Return the methodinfo for the given PV.
+
+   IN:
+       pv...............PV
+
+   RETURN VALUE:
+       the methodinfo *
+
+*******************************************************************************/
+
+methodinfo *code_get_methodinfo_for_pv(u1 *pv)
+{
+       codeinfo *code;
+
+       code = *((codeinfo **) (pv + CodeinfoPointer));
+
+       return code->m;
 }
 
-/* code_get_stack_frame_size ***************************************************
 
-   Return the number of stack slots that the stack frame of the given code
-   comprises.
+/* code_get_sync_slot_count ****************************************************
 
-   IMPORTANT: The return value does *not* include the saved return address 
-              slot, although it is part of non-leaf stack frames on RISC
-                         architectures. The rationale behind this is that the saved
-                         return address is never moved or changed by replacement, and
-                         this way CISC and RISC architectures can be treated the same.
-                         (See also doc/stack_frames.txt.)
+   Return the number of stack slots used for storing the synchronized object
+   (and the return value around lock_monitor_exit calls) by the given code.
    
    IN:
        code.............the codeinfo of the code in question
                            (must be != NULL)
 
    RETURN VALUE:
-       the number of stack slots
+       the number of stack slots used for synchronization
   
 *******************************************************************************/
 
-int code_get_stack_frame_size(codeinfo *code)
+#if defined(ENABLE_REPLACEMENT)
+int code_get_sync_slot_count(codeinfo *code)
 {
+#ifdef ENABLE_THREADS
        int count;
        
        assert(code);
 
-       /* XXX generalize to all archs */
+       if (!checksync)
+               return 0;
+
+       if (!(code->m->flags & ACC_SYNCHRONIZED))
+               return 0;
+
+       count = 1;
+
 #ifdef HAS_4BYTE_STACKSLOT
-       count = code->memuse + code->savedintcount + 2*code->savedfltcount;
-#else
-       count = code->memuse + code->savedintcount + code->savedfltcount;
+       /* long and double need 2 4-byte slots */
+       if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
+               count++;
 #endif
 
-       count += code_get_sync_slot_count(code);
-
-#if defined(__X86_64__)
-       /* keep stack 16-byte aligned */
-       if (!code->isleafmethod || opt_verbosecall)
-               count |= 1;
+#if defined(__POWERPC__)
+       /* powerpc needs an extra slot */
+       count++;
 #endif
 
        return count;
+
+#else /* !ENABLE_THREADS */
+       
+       return 0;
+
+#endif /* ENABLE_THREADS */
 }
+#endif /* defined(ENABLE_REPLACEMENT) */
+
 
 /* code_codeinfo_free **********************************************************
 
@@ -163,17 +212,27 @@ int code_get_stack_frame_size(codeinfo *code)
 
 void code_codeinfo_free(codeinfo *code)
 {
-       if (!code)
+       if (code == NULL)
                return;
 
-       if (code->mcode)
+       if (code->mcode != NULL)
                CFREE((void *) (ptrint) code->mcode, code->mcodelength);
 
+       patcher_list_free(code);
+
+#if defined(ENABLE_REPLACEMENT)
        replace_free_replacement_points(code);
+#endif
+
+       FREE(code, codeinfo);
 
-       FREE(code,codeinfo);
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_codeinfo -= sizeof(codeinfo);
+#endif
 }
 
+
 /* code_free_code_of_method ****************************************************
 
    Free all codeinfos of the given method