* src/vm/jit/replace.h, src/vm/jit/replace.c
[cacao.git] / src / vm / jit / replace.c
1 /* vm/jit/replace.c - on-stack replacement of methods
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Edwin Steiner
28
29    Changes:
30
31    $Id$
32
33 */
34
35 #include "config.h"
36 #include "vm/types.h"
37
38 #include <assert.h>
39
40 #include "mm/memory.h"
41 #include "vm/jit/replace.h"
42
43 /* replace_create_replacement_points *******************************************
44  
45    Create the replacement points for the given code.
46   
47    IN:
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.
52   
53    OUT:
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
60   
61    RETURN VALUE:
62        true.............everything ok 
63        false............an exception has been thrown
64    
65 *******************************************************************************/
66
67 bool replace_create_replacement_points(codeinfo *code,registerdata *rd)
68 {
69         basicblock *bptr;
70         int count;
71         methodinfo *m;
72         rplpoint *rplpoints;
73         rplpoint *rp;
74         int alloccount;
75         int globalcount;
76         s2 *regalloc;
77         s2 *ra;
78         int i;
79         stackptr sp;
80
81         /* assert that we wont overwrite already allocated data */
82         
83         assert(code);
84         assert(code->m);
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);
90
91         /* iterate over the basic block list to find replacement points */
92
93         m = code->m;
94
95         count = 0;
96         alloccount = 0;
97         for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
98                 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
99                         continue;
100
101                 /* there will be a replacement point at the start of this block */
102                 
103                 count++;
104                 alloccount += bptr->indepth;
105         }
106
107         /* if no points were found, there's nothing to do */
108         
109         if (!count)
110                 return true;
111
112         /* count global register allocations */
113
114         globalcount = m->maxlocals;
115         alloccount += globalcount;
116
117         /* allocate replacement point array and allocation array */
118         
119         rplpoints = MNEW(rplpoint,count);
120         regalloc = MNEW(s2,alloccount);
121         ra = regalloc;
122
123         /* store global register allocations */
124
125         for (i=0; i<m->maxlocals; ++i) {
126                 *ra++ = rd->locals[i][0].regoff; /* XXX */
127         }
128
129         /* initialize replacement point structs */
130
131         rp = rplpoints;
132         for (bptr = m->basicblocks; bptr; bptr = bptr->next) {
133                 if (!(bptr->bitflags & BBFLAG_REPLACEMENT))
134                         continue;
135
136                 /* there will be a replacement point at the start of this block */
137
138                 rp->pc = NULL;        /* set by codegen */
139                 rp->outcode = NULL;   /* set by codegen */
140                 rp->hashlink = NULL;
141                 rp->code = code;
142                 rp->target = NULL;
143                 rp->regalloc = ra;
144
145                 /* store local allocation info */
146
147                 for (sp = bptr->instack; sp; sp = sp->prev) {
148                         *ra++ = sp->regoff; /* XXX */
149                 }
150
151                 rp->regalloccount = ra - rp->regalloc;
152                 
153                 rp++;
154         }
155
156         /* store the data in the codeinfo */
157
158         code->rplpoints = rplpoints;
159         code->rplpointcount = count;
160         code->regalloc = regalloc;
161         code->regalloccount = alloccount;
162         code->globalcount = globalcount;
163
164         /* everything alright */
165
166         return true;
167 }
168
169 /* replace_free_replacement_points *********************************************
170  
171    Free memory used by replacement points.
172   
173    IN:
174        code.............codeinfo whose replacement points should be freed.
175   
176 *******************************************************************************/
177
178 void replace_free_replacement_points(codeinfo *code)
179 {
180         assert(code);
181
182         if (code->rplpoints)
183                 MFREE(code->rplpoints,rplpoint,code->rplpointcount);
184
185         if (code->regalloc)
186                 MFREE(code->regalloc,s2,code->regalloccount);
187
188         code->rplpoints = NULL;
189         code->rplpointcount = 0;
190         code->regalloc = NULL;
191         code->regalloccount = 0;
192         code->globalcount = 0;
193 }
194
195 /* replace_show_replacement_points *********************************************
196  
197    Print replacement point info.
198   
199    IN:
200        code.............codeinfo whose replacement points should be freed.
201   
202 *******************************************************************************/
203
204 #ifndef NDEBUG
205 void replace_show_replacement_points(codeinfo *code)
206 {
207         int i;
208         int j;
209         rplpoint *rp;
210         
211         if (!code) {
212                 printf("(codeinfo *)NULL\n");
213                 return;
214         }
215
216         printf("\treplacement points: %d\n",code->rplpointcount);
217         printf("\tglobal allocations: %d\n",code->globalcount);
218         printf("\ttotal allocations : %d\n",code->regalloccount);
219         printf("\n");
220
221         for (i=0; i<code->rplpointcount; ++i) {
222                 rp = code->rplpoints + i;
223
224                 assert(rp->code == code);
225                 
226                 printf("\trplpoint %p pc:%p out:%p target:%p allocs:%d =",
227                                 (void*)rp,rp->pc,rp->outcode,(void*)rp->target,
228                                 rp->regalloccount);
229
230                 for (j=0; j<rp->regalloccount; ++j)
231                         printf(" %02d",rp->regalloc[j]);
232
233                 printf("\n");
234         }
235 }
236 #endif
237
238 /*
239  * These are local overrides for various environment variables in Emacs.
240  * Please do not remove this and leave it at the end of the file, where
241  * Emacs will automagically detect them.
242  * ---------------------------------------------------------------------
243  * Local variables:
244  * mode: c
245  * indent-tabs-mode: t
246  * c-basic-offset: 4
247  * tab-width: 4
248  * End:
249  * vim:noexpandtab:sw=4:ts=4:
250  */