-/* 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 ***********************************************************
The following fields are set in codeinfo:
m
- isleafmethod
- all other fields are zeroed
+ patchers
RETURN VALUE:
a new, initialized codeinfo, or
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_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:
+ pc...............machine code position
+
+ RETURN VALUE:
+ the codeinfo * for the given PC, or NULL
+
+*******************************************************************************/
+
+codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc)
+{
+ void *pv;
+
+ pv = methodtree_find_nocheck(pc);
+
+ if (pv == NULL)
+ return NULL;
+
+ 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_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.
+ (and the return value around lock_monitor_exit calls) by the given code.
IN:
code.............the codeinfo of the code in question
*******************************************************************************/
+#if defined(ENABLE_REPLACEMENT)
int code_get_sync_slot_count(codeinfo *code)
{
-#ifdef USE_THREADS
+#ifdef ENABLE_THREADS
int count;
assert(code);
if (!checksync)
return 0;
- if (!(code->m->flags & ACC_SYNCHRONIZED))
+ if (!code_is_synchronized(code))
return 0;
count = 1;
return count;
-#else /* !USE_THREADS */
+#else /* !ENABLE_THREADS */
return 0;
-#endif /* USE_THREADS */
+#endif /* ENABLE_THREADS */
}
+#endif /* defined(ENABLE_REPLACEMENT) */
-/* 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)
-{
- int count;
-
- assert(code);
-
-#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);
-
-#if defined(__X86_64__)
- /* keep stack 16-byte aligned */
- if (!code->isleafmethod || opt_verbosecall)
- count |= 1; /* even when return address is added */
-#endif
-
-#if defined(__POWERPC__)
- /* keep stack 16-byte aligned */
- count = (count + 3) & ~3;
-#endif
-
- return count;
-}
/* code_codeinfo_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);
+ 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