* src/vm/jit/powerpc/codegen.c (codegen): Replaced catchtype.cls with
[cacao.git] / src / vm / jit / code.c
index 5fa6e0b6e885b06c518ac5bda586502ac95d743d..87eb8da8bb4ef4d7fe1ccbfa368ce453b0652ae2 100644 (file)
@@ -1,4 +1,4 @@
-/* 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,
 
    Authors: Edwin Steiner
 
-   Changes:
+   Changes: Christian Thalinger
 
    $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 "arch.h"
+
+
+/* code_codeinfo_new ***********************************************************
+
+   Create a new codeinfo for the given method.
+   
+   IN:
+       m................method to create a new codeinfo for
+
+   The following fields are set in codeinfo:
+       m
+          isleafmethod
+   all other fields are zeroed
+
+   RETURN VALUE:
+       a new, initialized codeinfo, or
+          NULL if an exception occurred.
+  
+*******************************************************************************/
 
 codeinfo *code_codeinfo_new(methodinfo *m)
 {
@@ -42,28 +68,179 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
        code = NEW(codeinfo);
 
-       memset(code,0,sizeof(codeinfo));
-
        code->m = m;
-       
+
+#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 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 used for synchronization
+  
+*******************************************************************************/
+
+int code_get_sync_slot_count(codeinfo *code)
+{
+#ifdef ENABLE_THREADS
+       int count;
+       
+       assert(code);
+
+       if (!checksync)
+               return 0;
+
+       if (!(code->m->flags & ACC_SYNCHRONIZED))
+               return 0;
+
+       count = 1;
+
+#ifdef HAS_4BYTE_STACKSLOT
+       /* long and double need 2 4-byte slots */
+       if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
+               count++;
+#endif
+
+#if defined(__POWERPC__)
+       /* powerpc needs an extra slot */
+       count++;
+#endif
+
+       return count;
+
+#else /* !ENABLE_THREADS */
+       
+       return 0;
+
+#endif /* ENABLE_THREADS */
+}
+
+
+/* code_get_stack_frame_size ***************************************************
+
+   Return the number of stack slots that the stack frame of the given code
+   comprises.
+
+   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.)
+   
+   IN:
+       code.............the codeinfo of the code in question
+                           (must be != NULL)
+
+   RETURN VALUE:
+       the number of stack slots
+  
+*******************************************************************************/
+
+int code_get_stack_frame_size(codeinfo *code)
+{
+#if 0
+       int count;
+       
+       assert(code);
+
+       /* slots allocated by register allocator plus saved registers */
+
+#ifdef HAS_4BYTE_STACKSLOT
+       count = code->memuse + code->savedintcount + 2*code->savedfltcount;
+#else
+       count = code->memuse + code->savedintcount + code->savedfltcount;
+#endif
+
+       /* add slots needed in synchronized methods */
+
+       count += code_get_sync_slot_count(code);
+
+       /* keep stack aligned */
+
+#if defined(__X86_64__)
+       /* the x86_64 codegen only aligns the stack in non-leaf methods */
+       if (!code->isleafmethod || opt_verbosecall)
+               count |= 1; /* even when return address is added */
+#endif
+
+       /* XXX align stack on alpha */
+#if defined(__MIPS__)
+       if (code->isleafmethod)
+               count = (count + 1) & ~1;
+       else
+               count |= 1; /* even when return address is added */
+#endif
+
+#if defined(__POWERPC__)
+       /* keep stack 16-byte aligned */
+       count = (count + 3) & ~3;
+#endif
+
+       return count;
+#endif
+
+       return 0;
+}
+
+
+/* code_codeinfo_free **********************************************************
+
+   Free the memory used by a codeinfo.
+   
+   IN:
+       code.............the codeinfo to free
+
+*******************************************************************************/
+
 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);
 
-       FREE(code,codeinfo);
+       replace_free_replacement_points(code);
+
+       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
+   
+   IN:
+       m................the method of which the codeinfos are to be freed
+
+*******************************************************************************/
+
 void code_free_code_of_method(methodinfo *m)
 {
        codeinfo *nextcode;
        codeinfo *code;
+
+       if (!m)
+               return;
        
        nextcode = m->code;
        while (nextcode) {
@@ -71,6 +248,8 @@ void code_free_code_of_method(methodinfo *m)
                nextcode = code->prev;
                code_codeinfo_free(code);
        }
+
+       m->code = NULL;
 }
 
 /*