* src/vm/jit/methodtree.h: Likewise.
* src/vm/jit/Makefile.am (libjit_la_SOURCES): Added methodtree.[ch].
* src/vm/jit/codegen-common.c (methodtree): Removed.
(codegen_init): Removed methodtree stuff.
(methodtree_comparator): Removed.
(codegen_insertmethod): Likewise.
(codegen_get_pv_from_pc): Likewise.
(codegen_get_pv_from_pc_nocheck): Likewise.
(codegen_finish): Call methodtree_insert.
* src/vm/jit/codegen-common.h (methodtree_element): Removed.
(codegen_insertmethod): Likewise.
(codegen_get_pv_from_pc): Likewise.
(codegen_get_pv_from_pc_nocheck): Likewise.
* src/vm/vm.c (vm_create): Call methodtree_init.
* src/vm/jit/code.c,
src/vm/jit/optimizing/profile.c,
src/vm/jit/stacktrace.c,
src/vm/jit/x86_64/asmpart.S,
src/vm/jit/x86_64/md.h,
src/vm/signal.c: Replaced codegen_get_pv_from_pc* with
methodtree_find*.
--HG--
branch : methodtree-branch
## src/vm/jit/Makefile.am
##
-## 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
+## Copyright (C) 1996-2005, 2006, 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
##
## This file is part of CACAO.
##
jit.h \
linenumbertable.c \
linenumbertable.h \
+ methodtree.c \
+ methodtree.h \
parse.c \
parse.h \
patcher-common.c \
#include "vm/jit/code.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/patcher-common.h"
+#include "vm/jit/methodtree.h"
#include "vmcore/options.h"
Return the codeinfo for the compilation unit that contains the
given PC.
- IN:
+ ARGUMENTS:
pc...............machine code position
RETURN VALUE:
{
void *pv;
- pv = codegen_get_pv_from_pc(pc);
- assert(pv);
+ pv = methodtree_find(pc);
return code_get_codeinfo_for_pv(pv);
}
{
void *pv;
- pv = codegen_get_pv_from_pc_nocheck(pc);
+ pv = methodtree_find_nocheck(pc);
if (pv == NULL)
return NULL;
#include "vm/jit/jit.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#if defined(ENABLE_SSA)
#include "show.h"
-/* in this tree we store all method addresses *********************************/
-
-static avl_tree_t *methodtree = NULL;
-static s4 methodtree_comparator(const void *treenode, const void *node);
-
/* codegen_init ****************************************************************
void codegen_init(void)
{
- /* this tree is global, not method specific */
-
- if (!methodtree) {
-#if defined(ENABLE_JIT)
- methodtree_element *mte;
-#endif
-
- methodtree = avl_create(&methodtree_comparator);
-
-#if defined(ENABLE_JIT)
- /* insert asm_vm_call_method */
-
- mte = NEW(methodtree_element);
-
- mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
- mte->endpc = (u1 *) (ptrint) asm_vm_call_method_end;
-
- avl_insert(methodtree, mte);
-#endif /* defined(ENABLE_JIT) */
-
- }
-
}
#endif
-/* methodtree_comparator *******************************************************
-
- Comparator function used for the AVL tree of methods.
-
- ARGUMENTS:
- treenode....the node from the tree
- node........the node to compare to the tree-node
-
-*******************************************************************************/
-
-static s4 methodtree_comparator(const void *treenode, const void *node)
-{
- methodtree_element *mte;
- methodtree_element *mtepc;
-
- mte = (methodtree_element *) treenode;
- mtepc = (methodtree_element *) node;
-
- /* compare both startpc and endpc of pc, even if they have the same value,
- otherwise the avl_probe sometimes thinks the element is already in the
- tree */
-
-#ifdef __S390__
- /* On S390 addresses are 31 bit. Compare only 31 bits of value.
- */
-# define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
-#else
-# define ADDR_MASK(a) (a)
-#endif
-
- if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
- ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
- ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
- ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
- return 0;
-
- } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
- return -1;
-
- } else {
- return 1;
- }
-
-# undef ADDR_MASK
-}
-
-
-/* codegen_insertmethod ********************************************************
-
- Insert the machine code range of a method into the AVL tree of methods.
-
-*******************************************************************************/
-
-void codegen_insertmethod(u1 *startpc, u1 *endpc)
-{
- methodtree_element *mte;
-
- /* allocate new method entry */
-
- mte = NEW(methodtree_element);
-
- mte->startpc = startpc;
- mte->endpc = endpc;
-
- /* this function does not return an error, but asserts for
- duplicate entries */
-
- avl_insert(methodtree, mte);
-}
-
-
-/* codegen_get_pv_from_pc ******************************************************
-
- Find the PV for the given PC by searching in the AVL tree of
- methods.
-
-*******************************************************************************/
-
-u1 *codegen_get_pv_from_pc(u1 *pc)
-{
- methodtree_element mtepc;
- methodtree_element *mte;
-
- /* allocation of the search structure on the stack is much faster */
-
- mtepc.startpc = pc;
- mtepc.endpc = pc;
-
- mte = avl_find(methodtree, &mtepc);
-
- if (mte == NULL) {
- /* No method was found. Let's dump a stacktrace. */
-
-#if defined(ENABLE_VMLOG)
- vmlog_cacao_signl("SIGSEGV");
-#endif
-
- log_println("We received a SIGSEGV and tried to handle it, but we were");
- log_println("unable to find a Java method at:");
- log_println("");
-#if SIZEOF_VOID_P == 8
- log_println("PC=0x%016lx", pc);
-#else
- log_println("PC=0x%08x", pc);
-#endif
- log_println("");
- assert(0);
- log_println("Dumping the current stacktrace:");
-
-#if defined(ENABLE_THREADS)
- /* XXX michi: This should be available even without threads! */
- threads_print_stacktrace();
-#endif
-
- vm_abort("Exiting...");
- }
-
- return mte->startpc;
-}
-
-
-/* codegen_get_pv_from_pc_nocheck **********************************************
-
- Find the PV for the given PC by searching in the AVL tree of
- methods. This method does not check the return value and is used
- by the profiler.
-
-*******************************************************************************/
-
-u1 *codegen_get_pv_from_pc_nocheck(u1 *pc)
-{
- methodtree_element mtepc;
- methodtree_element *mte;
-
- /* allocation of the search structure on the stack is much faster */
-
- mtepc.startpc = pc;
- mtepc.endpc = pc;
-
- mte = avl_find(methodtree, &mtepc);
-
- if (mte == NULL)
- return NULL;
- else
- return mte->startpc;
-}
-
-
/* codegen_set_replacement_point_notrap ****************************************
Record the position of a non-trappable replacement point.
}
#endif /* defined(ENABLE_REPLACEMENT) */
- /* add method into methodtree to find the entrypoint */
+ /* Insert method into methodtree to find the entrypoint. */
- codegen_insertmethod(code->entrypoint, code->entrypoint + mcodelen);
+ methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
/* resolve data segment references */
};
-/* methodtree_element *********************************************************/
-
-typedef struct methodtree_element methodtree_element;
-
-struct methodtree_element {
- u1 *startpc;
- u1 *endpc;
-};
-
-
/* function prototypes ********************************************************/
void codegen_init(void);
void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
-void codegen_insertmethod(u1 *startpc, u1 *endpc);
-u1 *codegen_get_pv_from_pc(u1 *pc);
-u1 *codegen_get_pv_from_pc_nocheck(u1 *pc);
-
#if defined(ENABLE_REPLACEMENT)
#if !defined(NDEBUG)
void codegen_set_replacement_point_notrap(codegendata *cd, s4 type);
--- /dev/null
+/* src/vm/jit/methodtree.c - AVL tree of methods
+
+ Copyright (C) 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "mm/memory.h"
+
+#include "toolbox/avl.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/methodtree.h"
+
+
+/* methodtree_element *********************************************************/
+
+typedef struct methodtree_element_t methodtree_element_t;
+
+struct methodtree_element_t {
+ void *startpc;
+ void *endpc;
+};
+
+
+/* in this tree we store all method addresses *********************************/
+
+static avl_tree_t *methodtree = NULL;
+
+
+/* static functions ***********************************************************/
+
+static int methodtree_comparator(const void *treenode, const void *node);
+
+
+/* methodtree_init *************************************************************
+
+ Initialize the global method tree.
+
+*******************************************************************************/
+
+void methodtree_init(void)
+{
+#if defined(ENABLE_JIT)
+ methodtree_element_t *mte;
+#endif
+
+ methodtree = avl_create(&methodtree_comparator);
+
+#if defined(ENABLE_JIT)
+ /* Insert asm_vm_call_method. */
+
+ mte = NEW(methodtree_element_t);
+
+ mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
+ mte->endpc = (u1 *) (ptrint) asm_vm_call_method_end;
+
+ avl_insert(methodtree, mte);
+#endif
+}
+
+
+/* methodtree_comparator *******************************************************
+
+ Comparator function used for the AVL tree of methods.
+
+ ARGUMENTS:
+ treenode ... the node from the tree
+ node ....... the node to compare to the tree-node
+
+ RETURN VALUE:
+ 0 .... found
+ -1 ... go left
+ 1 .... go right
+
+*******************************************************************************/
+
+static int methodtree_comparator(const void *treenode, const void *node)
+{
+ methodtree_element_t *mte;
+ methodtree_element_t *mtepc;
+
+ mte = (methodtree_element_t *) treenode;
+ mtepc = (methodtree_element_t *) node;
+
+ /* compare both startpc and endpc of pc, even if they have the same value,
+ otherwise the avl_probe sometimes thinks the element is already in the
+ tree */
+
+#ifdef __S390__
+ /* On S390 addresses are 31 bit. Compare only 31 bits of value.
+ */
+# define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
+#else
+# define ADDR_MASK(a) (a)
+#endif
+
+ if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
+ ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
+ ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
+ ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
+ return 0;
+
+ } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
+ return -1;
+
+ } else {
+ return 1;
+ }
+
+# undef ADDR_MASK
+}
+
+
+/* methodtree_insert ***********************************************************
+
+ Insert the machine code range of a method into the AVL tree of
+ methods.
+
+ ARGUMENTS:
+ startpc ... start address of the method
+ endpc ..... end address of the method
+
+*******************************************************************************/
+
+void methodtree_insert(void *startpc, void *endpc)
+{
+ methodtree_element_t *mte;
+
+ /* Allocate new method entry. */
+
+ mte = NEW(methodtree_element_t);
+
+ mte->startpc = startpc;
+ mte->endpc = endpc;
+
+ /* This function does not return an error, but asserts for
+ duplicate entries. */
+
+ avl_insert(methodtree, mte);
+}
+
+
+/* methodtree_find *************************************************************
+
+ Find the PV for the given PC by searching in the AVL tree of
+ methods.
+
+*******************************************************************************/
+
+void *methodtree_find(void *pc)
+{
+ void *pv;
+
+ /* Try to find a method. */
+
+ pv = methodtree_find_nocheck(pc);
+
+ if (pv == NULL) {
+ /* No method was found. Let's dump a stacktrace. */
+
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_signl("SIGSEGV");
+#endif
+
+ log_println("We received a SIGSEGV and tried to handle it, but we were");
+ log_println("unable to find a Java method at:");
+ log_println("");
+#if SIZEOF_VOID_P == 8
+ log_println("PC=0x%016lx", pc);
+#else
+ log_println("PC=0x%08x", pc);
+#endif
+ log_println("");
+ assert(0);
+ log_println("Dumping the current stacktrace:");
+
+#if defined(ENABLE_THREADS)
+ /* XXX michi: This should be available even without threads! */
+ threads_print_stacktrace();
+#endif
+
+ vm_abort("Exiting...");
+ }
+
+ return pv;
+}
+
+
+/* methodtree_find_nocheck *****************************************************
+
+ Find the PV for the given PC by searching in the AVL tree of
+ methods. This method does not check the return value and is used
+ by the profiler.
+
+*******************************************************************************/
+
+void *methodtree_find_nocheck(void *pc)
+{
+ methodtree_element_t mtepc;
+ methodtree_element_t *mte;
+
+ mtepc.startpc = pc;
+ mtepc.endpc = pc;
+
+ mte = avl_find(methodtree, &mtepc);
+
+ if (mte == NULL)
+ return NULL;
+ else
+ return mte->startpc;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
--- /dev/null
+/* src/vm/jit/methodtree.h - AVL tree of methods
+
+ Copyright (C) 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _METHODTREE_H
+#define _METHODTREE_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "toolbox/avl.h"
+
+
+/* function prototypes ********************************************************/
+
+void methodtree_init(void);
+void methodtree_insert(void *startpc, void *endpc);
+void *methodtree_find(void *pc);
+void *methodtree_find_nocheck(void *pc);
+
+#endif /* _METHODTREE_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/jit/jit.h"
#include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
+
#include "vm/jit/optimizing/recompile.h"
#include "vmcore/class.h"
pc = t->pc;
- /* get the PV for the current PC */
+ /* Get the PV for the current PC. */
- pv = codegen_get_pv_from_pc_nocheck(pc);
+ pv = methodtree_find_nocheck(pc);
/* get methodinfo pointer from data segment */
#include "vm/jit/codegen-common.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
#include "vmcore/class.h"
#include "vmcore/loader.h"
if (pv == NULL) {
#if defined(ENABLE_INTRP)
if (opt_intrp)
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
else
#endif
{
#if defined(ENABLE_INTRP)
if (opt_intrp)
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
else
#endif
{
mov t0,4*8(sp) /* save maybe-leaf flag */
mov xpc,a0 /* exception pc */
- call codegen_get_pv_from_pc@PLT
+ call methodtree_find@PLT
mov v0,2*8(sp) /* save data segment pointer */
mov 0*8(sp),a0 /* pass exception pointer */
-/* src/vm/jit/x86_64/md.c - machine dependent x86_64 functions
+/* src/vm/jit/x86_64/md.h - machine dependent x86_64 functions
- 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
+ Copyright (C) 1996-2005, 2006, 2007, 2008
This file is part of CACAO.
#include <stdint.h>
#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
/* inline functions ***********************************************************/
/* md_codegen_get_pv_from_pc ***************************************************
- On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
+ On this architecture this is just a wrapper to methodtree_find.
*******************************************************************************/
void *pv;
/* Get the start address of the function which contains this
- address from the method table. */
+ address from the method tree. */
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
return pv;
}
#include "vm/jit/codegen-common.h"
#include "vm/jit/disass.h"
+#include "vm/jit/methodtree.h"
#include "vm/jit/patcher-common.h"
#include "vmcore/options.h"
default:
/* Let's try to get a backtrace. */
- codegen_get_pv_from_pc(xpc);
+ (void) methodtree_find(xpc);
/* If that does not work, print more debug info. */
#endif
#include "vm/jit/jit.h"
+#include "vm/jit/methodtree.h"
#if defined(ENABLE_PROFILING)
# include "vm/jit/optimizing/profile.h"
if (!finalizer_init())
vm_abort("vm_create: finalizer_init failed");
- /* Initialize JIT compiler. */
+ /* Initialize the JIT compiler. */
jit_init();
code_init();
+ methodtree_init();
#if defined(ENABLE_PYTHON)
pythonpass_init();