1 /* src/vm/jit/methodtree.c - AVL tree of methods
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include "mm/memory.h"
32 #include "toolbox/avl.h"
34 #include "vm/jit/asmpart.h"
35 #include "vm/jit/methodtree.h"
38 /* methodtree_element *********************************************************/
40 typedef struct methodtree_element_t methodtree_element_t;
42 struct methodtree_element_t {
48 /* in this tree we store all method addresses *********************************/
50 static avl_tree_t *methodtree = NULL;
53 /* static functions ***********************************************************/
55 static int methodtree_comparator(const void *treenode, const void *node);
58 /* methodtree_init *************************************************************
60 Initialize the global method tree.
62 *******************************************************************************/
64 void methodtree_init(void)
66 #if defined(ENABLE_JIT)
67 methodtree_element_t *mte;
70 methodtree = avl_create(&methodtree_comparator);
72 #if defined(ENABLE_JIT)
73 /* Insert asm_vm_call_method. */
75 mte = NEW(methodtree_element_t);
77 mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
78 mte->endpc = (u1 *) (ptrint) asm_vm_call_method_end;
80 avl_insert(methodtree, mte);
85 /* methodtree_comparator *******************************************************
87 Comparator function used for the AVL tree of methods.
90 treenode ... the node from the tree
91 node ....... the node to compare to the tree-node
98 *******************************************************************************/
100 static int methodtree_comparator(const void *treenode, const void *node)
102 methodtree_element_t *mte;
103 methodtree_element_t *mtepc;
105 mte = (methodtree_element_t *) treenode;
106 mtepc = (methodtree_element_t *) node;
108 /* compare both startpc and endpc of pc, even if they have the same value,
109 otherwise the avl_probe sometimes thinks the element is already in the
113 /* On S390 addresses are 31 bit. Compare only 31 bits of value.
115 # define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
117 # define ADDR_MASK(a) (a)
120 if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
121 ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
122 ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
123 ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
126 } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
137 /* methodtree_insert ***********************************************************
139 Insert the machine code range of a method into the AVL tree of
143 startpc ... start address of the method
144 endpc ..... end address of the method
146 *******************************************************************************/
148 void methodtree_insert(void *startpc, void *endpc)
150 methodtree_element_t *mte;
152 /* Allocate new method entry. */
154 mte = NEW(methodtree_element_t);
156 mte->startpc = startpc;
159 /* This function does not return an error, but asserts for
160 duplicate entries. */
162 avl_insert(methodtree, mte);
166 /* methodtree_find *************************************************************
168 Find the PV for the given PC by searching in the AVL tree of
171 *******************************************************************************/
173 void *methodtree_find(void *pc)
177 /* Try to find a method. */
179 pv = methodtree_find_nocheck(pc);
182 /* No method was found. Let's dump a stacktrace. */
184 #if defined(ENABLE_VMLOG)
185 vmlog_cacao_signl("SIGSEGV");
188 log_println("We received a SIGSEGV and tried to handle it, but we were");
189 log_println("unable to find a Java method at:");
191 #if SIZEOF_VOID_P == 8
192 log_println("PC=0x%016lx", pc);
194 log_println("PC=0x%08x", pc);
198 log_println("Dumping the current stacktrace:");
200 #if defined(ENABLE_THREADS)
201 /* XXX michi: This should be available even without threads! */
202 threads_print_stacktrace();
205 vm_abort("Exiting...");
212 /* methodtree_find_nocheck *****************************************************
214 Find the PV for the given PC by searching in the AVL tree of
215 methods. This method does not check the return value and is used
218 *******************************************************************************/
220 void *methodtree_find_nocheck(void *pc)
222 methodtree_element_t mtepc;
223 methodtree_element_t *mte;
228 mte = avl_find(methodtree, &mtepc);
238 * These are local overrides for various environment variables in Emacs.
239 * Please do not remove this and leave it at the end of the file, where
240 * Emacs will automagically detect them.
241 * ---------------------------------------------------------------------
244 * indent-tabs-mode: t
248 * vim:noexpandtab:sw=4:ts=4: