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 "threads/thread.h"
34 #include "toolbox/avl.h"
36 #include "vm/jit/asmpart.h"
37 #include "vm/jit/methodtree.h"
40 /* methodtree_element *********************************************************/
42 typedef struct methodtree_element_t methodtree_element_t;
44 struct methodtree_element_t {
50 /* in this tree we store all method addresses *********************************/
52 static avl_tree_t *methodtree = NULL;
55 /* static functions ***********************************************************/
57 static int methodtree_comparator(const void *treenode, const void *node);
60 /* methodtree_init *************************************************************
62 Initialize the global method tree.
64 *******************************************************************************/
66 void methodtree_init(void)
68 #if defined(ENABLE_JIT)
69 methodtree_element_t *mte;
72 methodtree = avl_create(&methodtree_comparator);
74 #if defined(ENABLE_JIT)
75 /* Insert asm_vm_call_method. */
77 mte = NEW(methodtree_element_t);
79 mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
80 mte->endpc = (u1 *) (ptrint) asm_vm_call_method_end;
82 avl_insert(methodtree, mte);
87 /* methodtree_comparator *******************************************************
89 Comparator function used for the AVL tree of methods.
92 treenode ... the node from the tree
93 node ....... the node to compare to the tree-node
100 *******************************************************************************/
102 static int methodtree_comparator(const void *treenode, const void *node)
104 methodtree_element_t *mte;
105 methodtree_element_t *mtepc;
107 mte = (methodtree_element_t *) treenode;
108 mtepc = (methodtree_element_t *) node;
110 /* compare both startpc and endpc of pc, even if they have the same value,
111 otherwise the avl_probe sometimes thinks the element is already in the
115 /* On S390 addresses are 31 bit. Compare only 31 bits of value.
117 # define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
119 # define ADDR_MASK(a) (a)
122 if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
123 ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
124 ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
125 ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
128 } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
139 /* methodtree_insert ***********************************************************
141 Insert the machine code range of a method into the AVL tree of
145 startpc ... start address of the method
146 endpc ..... end address of the method
148 *******************************************************************************/
150 void methodtree_insert(void *startpc, void *endpc)
152 methodtree_element_t *mte;
154 /* Allocate new method entry. */
156 mte = NEW(methodtree_element_t);
158 mte->startpc = startpc;
161 /* This function does not return an error, but asserts for
162 duplicate entries. */
164 avl_insert(methodtree, mte);
168 /* methodtree_find *************************************************************
170 Find the PV for the given PC by searching in the AVL tree of
173 *******************************************************************************/
175 void *methodtree_find(void *pc)
179 /* Try to find a method. */
181 pv = methodtree_find_nocheck(pc);
184 /* No method was found. Let's dump a stacktrace. */
186 #if defined(ENABLE_VMLOG)
187 vmlog_cacao_signl("SIGSEGV");
190 log_println("We received a SIGSEGV and tried to handle it, but we were");
191 log_println("unable to find a Java method at:");
193 #if SIZEOF_VOID_P == 8
194 log_println("PC=0x%016lx", pc);
196 log_println("PC=0x%08x", pc);
200 log_println("Dumping the current stacktrace:");
202 stacktrace_print_current();
204 vm_abort("Exiting...");
211 /* methodtree_find_nocheck *****************************************************
213 Find the PV for the given PC by searching in the AVL tree of
214 methods. This method does not check the return value and is used
217 *******************************************************************************/
219 void *methodtree_find_nocheck(void *pc)
221 methodtree_element_t mtepc;
222 methodtree_element_t *mte;
227 mte = avl_find(methodtree, &mtepc);
237 * These are local overrides for various environment variables in Emacs.
238 * Please do not remove this and leave it at the end of the file, where
239 * Emacs will automagically detect them.
240 * ---------------------------------------------------------------------
243 * indent-tabs-mode: t
247 * vim:noexpandtab:sw=4:ts=4: