1 /* vm/jit/replace.c - on-stack replacement of methods
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
40 #include "mm/memory.h"
41 #include "vm/options.h"
42 #include "vm/jit/replace.h"
44 /* replace_create_replacement_points *******************************************
46 Create the replacement points for the given code.
49 code.............codeinfo where replacement points should be stored
50 code->rplpoints must be NULL.
51 code->rplpointcount must be 0.
52 rd...............registerdata containing allocation info.
55 code->rplpoints.......set to the list of replacement points
56 code->rplpointcount...number of replacement points
57 code->regalloc........list of allocation info
58 code->regalloccount...total length of allocation info list
59 code->globalcount.....number of global allocations at the
60 start of code->regalloc
63 true.............everything ok
64 false............an exception has been thrown
66 *******************************************************************************/
68 bool replace_create_replacement_points(codeinfo *code,registerdata *rd)
82 /* assert that we wont overwrite already allocated data */
86 assert(code->rplpoints == NULL);
87 assert(code->rplpointcount == 0);
88 assert(code->regalloc == NULL);
89 assert(code->regalloccount == 0);
90 assert(code->globalcount == 0);
92 /* iterate over the basic block list to find replacement points */
98 for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
99 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
102 /* there will be a replacement point at the start of this block */
105 alloccount += bptr->indepth;
108 /* if no points were found, there's nothing to do */
113 /* count global register allocations */
115 globalcount = m->maxlocals;
116 alloccount += globalcount;
118 /* allocate replacement point array and allocation array */
120 rplpoints = MNEW(rplpoint,count);
121 regalloc = MNEW(s2,alloccount);
124 /* store global register allocations */
126 for (i=0; i<m->maxlocals; ++i) {
127 #if defined(ENABLE_INTRP)
130 *ra++ = rd->locals[i][0].regoff; /* XXX */
131 #if defined(ENABLE_INTRP)
139 /* initialize replacement point structs */
142 for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
143 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
146 /* there will be a replacement point at the start of this block */
148 rp->pc = NULL; /* set by codegen */
149 rp->outcode = NULL; /* set by codegen */
155 /* store local allocation info */
157 for (sp = bptr->instack; sp; sp = sp->prev) {
158 *ra++ = sp->regoff; /* XXX */
161 rp->regalloccount = ra - rp->regalloc;
166 /* store the data in the codeinfo */
168 code->rplpoints = rplpoints;
169 code->rplpointcount = count;
170 code->regalloc = regalloc;
171 code->regalloccount = alloccount;
172 code->globalcount = globalcount;
174 /* everything alright */
179 /* replace_free_replacement_points *********************************************
181 Free memory used by replacement points.
184 code.............codeinfo whose replacement points should be freed.
186 *******************************************************************************/
188 void replace_free_replacement_points(codeinfo *code)
193 MFREE(code->rplpoints,rplpoint,code->rplpointcount);
196 MFREE(code->regalloc,s2,code->regalloccount);
198 code->rplpoints = NULL;
199 code->rplpointcount = 0;
200 code->regalloc = NULL;
201 code->regalloccount = 0;
202 code->globalcount = 0;
205 /* replace_activate_replacement_point ******************************************
207 Activate a replacement point. When this function returns, the
208 replacement point is "armed", that is each thread reaching this point
209 will be replace to `target`.
212 rp...............replacement point to activate
213 target...........target of replacement
215 *******************************************************************************/
217 void replace_activate_replacement_point(rplpoint *rp,rplpoint *target)
221 #if defined(__I386__) && defined(ENABLE_JIT)
222 md_patch_replacement_point(rp);
226 /* replace_me ******************************************************************
228 This function is called by asm_replacement_out when a thread reaches
229 a replacement point. `replace_me` must map the execution state to the
230 target replacement point and let execution continue there.
232 This function never returns!
235 rp...............replacement point that has been reached
236 es...............executions state read by asm_replacement_out
238 *******************************************************************************/
240 void replace_me(rplpoint *rp,executionstate *es)
246 printf("replace_me(%p,%p)\n",(void*)rp,(void*)es);
249 replace_replacement_point_println(rp);
250 replace_executionstate_println(es);
252 es->pc = rp->target->pc;
255 /* replace_replacement_point_println *******************************************
257 Print replacement point info.
260 rp...............the replacement point to print
262 *******************************************************************************/
265 void replace_replacement_point_println(rplpoint *rp)
270 printf("(rplpoint *)NULL\n");
274 printf("rplpoint %p pc:%p out:%p target:%p allocs:%d = [",
275 (void*)rp,rp->pc,rp->outcode,(void*)rp->target,
278 for (j=0; j<rp->regalloccount; ++j)
279 printf(" %02d",rp->regalloc[j]);
282 method_print(rp->code->m);
288 /* replace_show_replacement_points *********************************************
290 Print replacement point info.
293 code.............codeinfo whose replacement points should be printed.
295 *******************************************************************************/
298 void replace_show_replacement_points(codeinfo *code)
304 printf("(codeinfo *)NULL\n");
308 printf("\treplacement points: %d\n",code->rplpointcount);
309 printf("\tglobal allocations: %d\n",code->globalcount);
310 printf("\ttotal allocations : %d\n",code->regalloccount);
313 for (i=0; i<code->rplpointcount; ++i) {
314 rp = code->rplpoints + i;
316 assert(rp->code == code);
318 replace_replacement_point_println(rp);
323 /* replace_executionstate_println **********************************************
325 Print execution state
328 es...............the execution state to print
330 *******************************************************************************/
333 void replace_executionstate_println(executionstate *es)
338 printf("(executionstate *)NULL\n");
342 printf("executionstate %p:\n",(void*)es);
343 printf("\tpc = %p\n",(void*)es->pc);
344 for (i=0; i<3; ++i) {
345 printf("\tregs[%2d] = %016llx\n",i,(u8)es->regs[i]);
353 * These are local overrides for various environment variables in Emacs.
354 * Please do not remove this and leave it at the end of the file, where
355 * Emacs will automagically detect them.
356 * ---------------------------------------------------------------------
359 * indent-tabs-mode: t
363 * vim:noexpandtab:sw=4:ts=4: