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/jit/replace.h"
43 /* replace_create_replacement_points *******************************************
45 Create the replacement points for the given code.
48 code.............codeinfo where replacement points should be stored
49 code->rplpoints must be NULL.
50 code->rplpointcount must be 0.
51 rd...............registerdata containing allocation info.
54 code->rplpoints.......set to the list of replacement points
55 code->rplpointcount...number of replacement points
56 code->regalloc........list of allocation info
57 code->regalloccount...total length of allocation info list
58 code->globalcount.....number of global allocations at the
59 start of code->regalloc
62 true.............everything ok
63 false............an exception has been thrown
65 *******************************************************************************/
67 bool replace_create_replacement_points(codeinfo *code,registerdata *rd)
81 /* assert that we wont overwrite already allocated data */
85 assert(code->rplpoints == NULL);
86 assert(code->rplpointcount == 0);
87 assert(code->regalloc == NULL);
88 assert(code->regalloccount == 0);
89 assert(code->globalcount == 0);
91 /* iterate over the basic block list to find replacement points */
97 for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
98 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
101 /* there will be a replacement point at the start of this block */
104 alloccount += bptr->indepth;
107 /* if no points were found, there's nothing to do */
112 /* count global register allocations */
114 globalcount = m->maxlocals;
115 alloccount += globalcount;
117 /* allocate replacement point array and allocation array */
119 rplpoints = MNEW(rplpoint,count);
120 regalloc = MNEW(s2,alloccount);
123 /* store global register allocations */
125 for (i=0; i<m->maxlocals; ++i) {
126 *ra++ = rd->locals[i][0].regoff; /* XXX */
129 /* initialize replacement point structs */
132 for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
133 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
136 /* there will be a replacement point at the start of this block */
138 rp->pc = NULL; /* set by codegen */
139 rp->outcode = NULL; /* set by codegen */
145 /* store local allocation info */
147 for (sp = bptr->instack; sp; sp = sp->prev) {
148 *ra++ = sp->regoff; /* XXX */
151 rp->regalloccount = ra - rp->regalloc;
156 /* store the data in the codeinfo */
158 code->rplpoints = rplpoints;
159 code->rplpointcount = count;
160 code->regalloc = regalloc;
161 code->regalloccount = alloccount;
162 code->globalcount = globalcount;
164 /* everything alright */
169 /* replace_free_replacement_points *********************************************
171 Free memory used by replacement points.
174 code.............codeinfo whose replacement points should be freed.
176 *******************************************************************************/
178 void replace_free_replacement_points(codeinfo *code)
183 MFREE(code->rplpoints,rplpoint,code->rplpointcount);
186 MFREE(code->regalloc,s2,code->regalloccount);
188 code->rplpoints = NULL;
189 code->rplpointcount = 0;
190 code->regalloc = NULL;
191 code->regalloccount = 0;
192 code->globalcount = 0;
195 /* replace_activate_replacement_point ******************************************
197 Activate a replacement point. When this function returns, the
198 replacement point is "armed", that is each thread reaching this point
199 will be replace to `target`.
202 rp...............replacement point to activate
203 target...........target of replacement
205 *******************************************************************************/
207 void replace_activate_replacement_point(rplpoint *rp,rplpoint *target)
212 md_patch_replacement_point(rp);
216 /* replace_me ******************************************************************
218 This function is called by asm_replacement_out when a thread reaches
219 a replacement point. `replace_me` must map the execution state to the
220 target replacement point and let execution continue there.
222 This function never returns!
225 rp...............replacement point that has been reached
226 es...............executions state read by asm_replacement_out
228 *******************************************************************************/
230 void replace_me(rplpoint *rp,executionstate *es)
236 printf("replace_me(%p,%p)\n",(void*)rp,(void*)es);
239 replace_replacement_point_println(rp);
240 replace_executionstate_println(es);
242 es->pc = rp->target->pc;
245 /* replace_replacement_point_println *******************************************
247 Print replacement point info.
250 rp...............the replacement point to print
252 *******************************************************************************/
255 void replace_replacement_point_println(rplpoint *rp)
260 printf("(rplpoint *)NULL\n");
264 printf("rplpoint %p pc:%p out:%p target:%p allocs:%d = [",
265 (void*)rp,rp->pc,rp->outcode,(void*)rp->target,
268 for (j=0; j<rp->regalloccount; ++j)
269 printf(" %02d",rp->regalloc[j]);
272 method_print(rp->code->m);
278 /* replace_show_replacement_points *********************************************
280 Print replacement point info.
283 code.............codeinfo whose replacement points should be printed.
285 *******************************************************************************/
288 void replace_show_replacement_points(codeinfo *code)
294 printf("(codeinfo *)NULL\n");
298 printf("\treplacement points: %d\n",code->rplpointcount);
299 printf("\tglobal allocations: %d\n",code->globalcount);
300 printf("\ttotal allocations : %d\n",code->regalloccount);
303 for (i=0; i<code->rplpointcount; ++i) {
304 rp = code->rplpoints + i;
306 assert(rp->code == code);
308 replace_replacement_point_println(rp);
313 /* replace_executionstate_println **********************************************
315 Print execution state
318 es...............the execution state to print
320 *******************************************************************************/
323 void replace_executionstate_println(executionstate *es)
328 printf("(executionstate *)NULL\n");
332 printf("executionstate %p:\n",(void*)es);
333 printf("\tpc = %p\n",(void*)es->pc);
334 for (i=0; i<3; ++i) {
335 printf("\tregs[%2d] = %016llx\n",i,(u8)es->regs[i]);
343 * These are local overrides for various environment variables in Emacs.
344 * Please do not remove this and leave it at the end of the file, where
345 * Emacs will automagically detect them.
346 * ---------------------------------------------------------------------
349 * indent-tabs-mode: t
353 * vim:noexpandtab:sw=4:ts=4: