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)
219 assert(rp->target == NULL);
222 printf("activate replacement point: ");
223 replace_replacement_point_println(rp);
229 #if defined(__I386__) && defined(ENABLE_JIT)
230 md_patch_replacement_point(rp);
234 /* replace_deactivate_replacement_point ****************************************
236 Deactivate a replacement point. When this function returns, the
237 replacement point is "un-armed", that is a each thread reaching this point
238 will just continue normally.
241 rp...............replacement point to deactivate
243 *******************************************************************************/
245 void replace_deactivate_replacement_point(rplpoint *rp)
250 printf("deactivate replacement point: ");
251 replace_replacement_point_println(rp);
257 #if defined(__I386__) && defined(ENABLE_JIT)
258 md_patch_replacement_point(rp);
262 /* replace_me ******************************************************************
264 This function is called by asm_replacement_out when a thread reaches
265 a replacement point. `replace_me` must map the execution state to the
266 target replacement point and let execution continue there.
268 This function never returns!
271 rp...............replacement point that has been reached
272 es...............executions state read by asm_replacement_out
274 *******************************************************************************/
276 void replace_me(rplpoint *rp,executionstate *es)
283 printf("replace_me(%p,%p)\n",(void*)rp,(void*)es);
285 replace_replacement_point_println(rp);
286 replace_executionstate_println(es);
289 es->pc = rp->target->pc;
292 /* replace_replacement_point_println *******************************************
294 Print replacement point info.
297 rp...............the replacement point to print
299 *******************************************************************************/
302 void replace_replacement_point_println(rplpoint *rp)
307 printf("(rplpoint *)NULL\n");
311 printf("rplpoint %p pc:%p out:%p target:%p mcode:%016llx allocs:%d = [",
312 (void*)rp,rp->pc,rp->outcode,(void*)rp->target,
313 rp->mcode,rp->regalloccount);
315 for (j=0; j<rp->regalloccount; ++j)
316 printf(" %02d",rp->regalloc[j]);
319 method_print(rp->code->m);
325 /* replace_show_replacement_points *********************************************
327 Print replacement point info.
330 code.............codeinfo whose replacement points should be printed.
332 *******************************************************************************/
335 void replace_show_replacement_points(codeinfo *code)
341 printf("(codeinfo *)NULL\n");
345 printf("\treplacement points: %d\n",code->rplpointcount);
346 printf("\tglobal allocations: %d\n",code->globalcount);
347 printf("\ttotal allocations : %d\n",code->regalloccount);
350 for (i=0; i<code->rplpointcount; ++i) {
351 rp = code->rplpoints + i;
353 assert(rp->code == code);
355 replace_replacement_point_println(rp);
360 /* replace_executionstate_println **********************************************
362 Print execution state
365 es...............the execution state to print
367 *******************************************************************************/
370 void replace_executionstate_println(executionstate *es)
375 printf("(executionstate *)NULL\n");
379 printf("executionstate %p:\n",(void*)es);
380 printf("\tpc = %p\n",(void*)es->pc);
381 for (i=0; i<3; ++i) {
382 printf("\tregs[%2d] = %016llx\n",i,(u8)es->regs[i]);
390 * These are local overrides for various environment variables in Emacs.
391 * Please do not remove this and leave it at the end of the file, where
392 * Emacs will automagically detect them.
393 * ---------------------------------------------------------------------
396 * indent-tabs-mode: t
400 * vim:noexpandtab:sw=4:ts=4: