1 /* src/vm/jit/dseg.c - data segment handling stuff
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: Reinhard Grafl
30 Changes: Christian Thalinger
34 $Id: dseg.c 4699 2006-03-28 14:52:32Z twisti $
45 #include "mm/memory.h"
46 #include "vm/jit/codegen-common.h"
49 /* desg_increase ***************************************************************
53 *******************************************************************************/
55 void dseg_increase(codegendata *cd)
59 newstorage = DMNEW(u1, cd->dsegsize * 2);
61 MCOPY(newstorage + cd->dsegsize, cd->dsegtop - cd->dsegsize, u1,
64 cd->dsegtop = newstorage;
66 cd->dsegtop += cd->dsegsize;
70 s4 dseg_adds4_increase(codegendata *cd, s4 value)
74 *((s4 *) (cd->dsegtop - cd->dseglen)) = value;
76 return -(cd->dseglen);
80 s4 dseg_adds4(codegendata *cd, s4 value)
85 dataptr = (s4 *) (cd->dsegtop - cd->dseglen);
87 if (cd->dseglen > cd->dsegsize)
88 return dseg_adds4_increase(cd, value);
92 return -(cd->dseglen);
96 s4 dseg_adds8_increase(codegendata *cd, s8 value)
100 *((s8 *) (cd->dsegtop - cd->dseglen)) = value;
102 return -(cd->dseglen);
106 s4 dseg_adds8(codegendata *cd, s8 value)
110 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
111 dataptr = (s8 *) (cd->dsegtop - cd->dseglen);
113 if (cd->dseglen > cd->dsegsize)
114 return dseg_adds8_increase(cd, value);
118 return -(cd->dseglen);
122 s4 dseg_addfloat_increase(codegendata *cd, float value)
126 *((float *) (cd->dsegtop - cd->dseglen)) = value;
128 return -(cd->dseglen);
132 s4 dseg_addfloat(codegendata *cd, float value)
137 dataptr = (float *) (cd->dsegtop - cd->dseglen);
139 if (cd->dseglen > cd->dsegsize)
140 return dseg_addfloat_increase(cd, value);
144 return -(cd->dseglen);
148 s4 dseg_adddouble_increase(codegendata *cd, double value)
152 *((double *) (cd->dsegtop - cd->dseglen)) = value;
154 return -(cd->dseglen);
158 s4 dseg_adddouble(codegendata *cd, double value)
162 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
163 dataptr = (double *) (cd->dsegtop - cd->dseglen);
165 if (cd->dseglen > cd->dsegsize)
166 return dseg_adddouble_increase(cd, value);
170 return -(cd->dseglen);
174 void dseg_addtarget(codegendata *cd, basicblock *target)
180 jr->tablepos = dseg_addaddress(cd, NULL);
182 jr->next = cd->jumpreferences;
184 cd->jumpreferences = jr;
188 /* dseg_addlinenumbertablesize *************************************************
192 *******************************************************************************/
194 void dseg_addlinenumbertablesize(codegendata *cd)
196 #if SIZEOF_VOID_P == 8
197 /* 4-byte ALIGNMENT PADDING */
202 cd->linenumbertablesizepos = dseg_addaddress(cd, NULL);
203 cd->linenumbertablestartpos = dseg_addaddress(cd, NULL);
205 #if SIZEOF_VOID_P == 8
206 /* 4-byte ALIGNMENT PADDING */
213 /* dseg_addlinenumber **********************************************************
215 Add a line number reference.
218 cd.............current codegen data
219 linenumber.....number of line that starts with the given mcodeptr
220 mcodeptr.......start mcodeptr of line
222 *******************************************************************************/
224 void dseg_addlinenumber(codegendata *cd, u2 linenumber, u1 *mcodeptr)
228 lr = DNEW(linenumberref);
230 lr->linenumber = linenumber;
232 lr->targetmpc = mcodeptr - cd->mcodebase;
233 lr->next = cd->linenumberreferences;
235 cd->linenumberreferences = lr;
239 /* dseg_addlinenumber_inline_start *********************************************
241 Add a marker to the line number table indicating the start of an inlined
242 method body. (see doc/inlining_stacktrace.txt)
245 cd.............current codegen data
246 iptr...........the ICMD_INLINE_START instruction
247 mcodeptr.......start mcodeptr of inlined body
249 *******************************************************************************/
251 void dseg_addlinenumber_inline_start(codegendata *cd,
257 lr = DNEW(linenumberref);
259 lr->linenumber = (-2); /* marks start of inlined method */
261 lr->targetmpc = mcodeptr - cd->mcodebase;
262 lr->next = cd->linenumberreferences;
264 cd->linenumberreferences = lr;
266 iptr->target = mcodeptr; /* store for corresponding INLINE_END */
270 /* dseg_addlinenumber_inline_end ***********************************************
272 Add a marker to the line number table indicating the end of an inlined
273 method body. (see doc/inlining_stacktrace.txt)
276 cd.............current codegen data
277 iptr...........the ICMD_INLINE_END instruction
280 iptr->method must point to the inlined callee.
282 *******************************************************************************/
284 void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr)
288 instruction *inlinestart;
290 /* get the pointer to the corresponding ICMD_INLINE_START */
291 inlinestart = (instruction *)iptr->target;
294 assert(iptr->method);
296 lr = DNEW(linenumberref);
298 /* special entry containing the methodinfo * */
299 lr->linenumber = (-3) - iptr->line;
301 lr->targetmpc = (ptrint) iptr->method;
302 lr->next = cd->linenumberreferences;
305 lr = DNEW(linenumberref);
307 /* end marker with PC of start of body */
308 lr->linenumber = (-1);
310 lr->targetmpc = (u1*)inlinestart->target - cd->mcodebase;
313 cd->linenumberreferences = lr;
317 /* dseg_createlinenumbertable **************************************************
319 Creates a line number table in the data segment from the created
320 entries in linenumberreferences.
322 *******************************************************************************/
324 void dseg_createlinenumbertable(codegendata *cd)
328 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
329 lr->tablepos = dseg_addaddress(cd, NULL);
331 if (cd->linenumbertab == 0)
332 cd->linenumbertab = lr->tablepos;
334 dseg_addaddress(cd, lr->linenumber);
339 /* dseg_adddata ****************************************************************
341 Adds a data segment reference to the codegendata.
343 *******************************************************************************/
345 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
346 void dseg_adddata(codegendata *cd, u1 *mcodeptr)
352 dr->datapos = mcodeptr - cd->mcodebase;
353 dr->next = cd->datareferences;
355 cd->datareferences = dr;
360 /* dseg_resolve_datareferences *************************************************
362 Resolve data segment references.
364 *******************************************************************************/
366 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
367 void dseg_resolve_datareferences(jitdata *jd)
373 /* get required compiler data */
378 /* data segment references resolving */
380 for (dr = cd->datareferences; dr != NULL; dr = dr->next)
381 *((u1 **) (code->entrypoint + dr->datapos - SIZEOF_VOID_P)) = code->entrypoint;
386 /* dseg_display ****************************************************************
388 Displays the content of the methods' data segment.
390 *******************************************************************************/
393 void dseg_display(jitdata *jd)
400 /* get required compiler data */
405 s4ptr = (s4 *) (ptrint) code->mcode;
407 printf(" --- dump of datasegment\n");
409 for (i = cd->dseglen; i > 0 ; i -= 4) {
410 #if SIZEOF_VOID_P == 8
411 printf("0x%016lx: -%6x (%6d): %8x\n",
412 (ptrint) s4ptr, i, i, (s4) *s4ptr);
414 printf("0x%08x: -%6x (%6d): %8x\n",
415 (ptrint) s4ptr, i, i, (s4) *s4ptr);
420 printf(" --- begin of data segment: %p\n", (void *) s4ptr);
422 #endif /* !defined(NDEBUG) */
426 * These are local overrides for various environment variables in Emacs.
427 * Please do not remove this and leave it at the end of the file, where
428 * Emacs will automagically detect them.
429 * ---------------------------------------------------------------------
432 * indent-tabs-mode: t
436 * vim:noexpandtab:sw=4:ts=4: