* Removed all Id tags.
[cacao.git] / src / vm / jit / code.c
index 0ff3a43502561a85186955a3692badb7814a0be0..e02bdcadf1f796e5a805e2bcfe13fd3f19500660 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:
+#include "config.h"
 
-   $Id$
+#include <assert.h>
 
-*/
+#include "vm/types.h"
 
+#include "arch.h"
 
-#include "config.h"
-#include "vm/types.h"
+#include "mm/memory.h"
 
-#include <assert.h>
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
 
 #include "vm/jit/code.h"
-#include "mm/memory.h"
-#include "vm/options.h"
-#include "arch.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 ***********************************************************
 
@@ -52,8 +74,7 @@
 
    The following fields are set in codeinfo:
        m
-          isleafmethod
-   all other fields are zeroed
+       patchers
 
    RETURN VALUE:
        a new, initialized codeinfo, or
@@ -67,94 +88,116 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
        code = NEW(codeinfo);
 
-       memset(code,0,sizeof(codeinfo));
-
        code->m = m;
-       code->isleafmethod = m->isleafmethod; /* XXX will be moved to codeinfo */
-       
+
+       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 **********************************************************
 
@@ -167,17 +210,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