* src/vm/jit/code.c (code_get_stack_frame_size): Implement stack alignment
[cacao.git] / src / vm / jit / code.c
1 /* vm/jit/code.c - codeinfo struct for representing compiled code
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
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include <assert.h>
40
41 #include "vm/jit/code.h"
42 #include "mm/memory.h"
43 #include "vm/options.h"
44 #include "arch.h"
45
46 /* code_codeinfo_new ***********************************************************
47
48    Create a new codeinfo for the given method.
49    
50    IN:
51        m................method to create a new codeinfo for
52
53    The following fields are set in codeinfo:
54        m
55            isleafmethod
56    all other fields are zeroed
57
58    RETURN VALUE:
59        a new, initialized codeinfo, or
60            NULL if an exception occurred.
61   
62 *******************************************************************************/
63
64 codeinfo *code_codeinfo_new(methodinfo *m)
65 {
66         codeinfo *code;
67
68         code = NEW(codeinfo);
69
70         memset(code,0,sizeof(codeinfo));
71
72         code->m = m;
73         code->isleafmethod = m->isleafmethod; /* XXX will be moved to codeinfo */
74         
75         return code;
76 }
77
78 /* code_get_sync_slot_count ****************************************************
79
80    Return the number of stack slots used for storing the synchronized object
81    (and the return value around monitorExit calls) by the given code.
82    
83    IN:
84        code.............the codeinfo of the code in question
85                             (must be != NULL)
86
87    RETURN VALUE:
88        the number of stack slots used for synchronization
89   
90 *******************************************************************************/
91
92 int code_get_sync_slot_count(codeinfo *code)
93 {
94 #ifdef USE_THREADS
95         int count;
96         
97         assert(code);
98
99         if (!checksync)
100                 return 0;
101
102         if (!(code->m->flags & ACC_SYNCHRONIZED))
103                 return 0;
104
105         count = 1;
106
107 #ifdef HAS_4BYTE_STACKSLOT
108         /* long and double need 2 4-byte slots */
109         if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
110                 count++;
111 #endif
112
113 #if defined(__POWERPC__)
114         /* powerpc needs an extra slot */
115         count++;
116 #endif
117
118         return count;
119
120 #else /* !USE_THREADS */
121         
122         return 0;
123
124 #endif /* USE_THREADS */
125 }
126
127 /* code_get_stack_frame_size ***************************************************
128
129    Return the number of stack slots that the stack frame of the given code
130    comprises.
131
132    IMPORTANT: The return value does *not* include the saved return address 
133               slot, although it is part of non-leaf stack frames on RISC
134                           architectures. The rationale behind this is that the saved
135                           return address is never moved or changed by replacement, and
136                           this way CISC and RISC architectures can be treated the same.
137                           (See also doc/stack_frames.txt.)
138    
139    IN:
140        code.............the codeinfo of the code in question
141                             (must be != NULL)
142
143    RETURN VALUE:
144        the number of stack slots
145   
146 *******************************************************************************/
147
148 int code_get_stack_frame_size(codeinfo *code)
149 {
150         int count;
151         
152         assert(code);
153
154         /* slots allocated by register allocator plus saved registers */
155
156 #ifdef HAS_4BYTE_STACKSLOT
157         count = code->memuse + code->savedintcount + 2*code->savedfltcount;
158 #else
159         count = code->memuse + code->savedintcount + code->savedfltcount;
160 #endif
161
162         /* add slots needed in synchronized methods */
163
164         count += code_get_sync_slot_count(code);
165
166         /* keep stack aligned */
167
168 #if defined(__X86_64__)
169         /* the x86_64 codegen only aligns the stack in non-leaf methods */
170         if (!code->isleafmethod || opt_verbosecall)
171                 count |= 1; /* even when return address is added */
172 #endif
173
174         /* XXX align stack on alpha */
175 #if defined(__MIPS__)
176         if (code->isleafmethod)
177                 count = (count + 1) & ~1;
178         else
179                 count |= 1; /* even when return address is added */
180 #endif
181
182 #if defined(__POWERPC__)
183         /* keep stack 16-byte aligned */
184         count = (count + 3) & ~3;
185 #endif
186
187         return count;
188 }
189
190 /* code_codeinfo_free **********************************************************
191
192    Free the memory used by a codeinfo.
193    
194    IN:
195        code.............the codeinfo to free
196
197 *******************************************************************************/
198
199 void code_codeinfo_free(codeinfo *code)
200 {
201         if (!code)
202                 return;
203
204         if (code->mcode)
205                 CFREE((void *) (ptrint) code->mcode, code->mcodelength);
206
207         replace_free_replacement_points(code);
208
209         FREE(code,codeinfo);
210 }
211
212 /* code_free_code_of_method ****************************************************
213
214    Free all codeinfos of the given method
215    
216    IN:
217        m................the method of which the codeinfos are to be freed
218
219 *******************************************************************************/
220
221 void code_free_code_of_method(methodinfo *m)
222 {
223         codeinfo *nextcode;
224         codeinfo *code;
225
226         if (!m)
227                 return;
228         
229         nextcode = m->code;
230         while (nextcode) {
231                 code = nextcode;
232                 nextcode = code->prev;
233                 code_codeinfo_free(code);
234         }
235
236         m->code = NULL;
237 }
238
239 /*
240  * These are local overrides for various environment variables in Emacs.
241  * Please do not remove this and leave it at the end of the file, where
242  * Emacs will automagically detect them.
243  * ---------------------------------------------------------------------
244  * Local variables:
245  * mode: c
246  * indent-tabs-mode: t
247  * c-basic-offset: 4
248  * tab-width: 4
249  * End:
250  * vim:noexpandtab:sw=4:ts=4:
251  */