* src/vm/jit/codegen-common.c: Moved to .cpp.
[cacao.git] / src / vm / jit / code.c
index 0ff3a43502561a85186955a3692badb7814a0be0..c277cb999209638c87b51e685e0b5f663ae02db7 100644 (file)
@@ -1,9 +1,7 @@
-/* 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,
-   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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    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 <stdint.h>
+
+#include "arch.h"
 
-#include "vm/jit/code.h"
 #include "mm/memory.h"
+
 #include "vm/options.h"
-#include "arch.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/code.h"
+#include "vm/jit/codegen-common.hpp"
+#include "vm/jit/patcher-common.h"
+#include "vm/jit/methodtree.h"
+
+
+/* code_init *******************************************************************
+
+   Initialize the code-subsystem.
+
+*******************************************************************************/
+
+void code_init(void)
+{
+       /* Check if offset of codeinfo.m == 0 (see comment in code.h). */
+
+       if (OFFSET(codeinfo, m) != 0)
+               vm_abort("code_init: offset of codeinfo.m != 0: %d != 0", OFFSET(codeinfo, m));
+}
+
 
 /* code_codeinfo_new ***********************************************************
 
@@ -52,8 +65,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 +79,147 @@ 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.
+
+   ARGUMENTS:
+       pc...............machine code position
+
+   RETURN VALUE:
+       the codeinfo * for the given PC
+
+*******************************************************************************/
+
+codeinfo *code_find_codeinfo_for_pc(void *pc)
+{
+       void *pv;
+
+       pv = methodtree_find(pc);
+
+       return code_get_codeinfo_for_pv(pv);
+}
+
+
+/* code_find_codeinfo_for_pc ***************************************************
+
+   Return the codeinfo for the compilation unit that contains the
+   given PC. This method does not check the return value and is used
+   by the GC.
+
    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, or NULL
+
 *******************************************************************************/
 
-int code_get_sync_slot_count(codeinfo *code)
+codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc)
 {
-       assert(code);
+       void *pv;
 
-#ifdef USE_THREADS
-       if (!checksync)
-               return 0;
+       pv = methodtree_find_nocheck(pc);
 
-       if (!(code->m->flags & ACC_SYNCHRONIZED))
-               return 0;
+       if (pv == NULL)
+               return NULL;
 
-       /* 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 */
+       return code_get_codeinfo_for_pv(pv);
+}
+
+
+/* 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(void *pv)
+{
+       codeinfo *code;
+
+       code = code_get_codeinfo_for_pv(pv);
+
+       /* This is the case for asm_vm_call_method. */
+
+       if (code == NULL)
+               return NULL;
+
+       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_is_synchronized(code))
+               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 +232,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