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
33 $Id: dseg.c 4445 2006-02-05 15:26:34Z edwin $
43 #include "mm/memory.h"
44 #include "vm/jit/codegen-common.h"
47 /* desg_increase ***************************************************************
51 *******************************************************************************/
53 void dseg_increase(codegendata *cd)
57 newstorage = DMNEW(u1, cd->dsegsize * 2);
59 MCOPY(newstorage + cd->dsegsize, cd->dsegtop - cd->dsegsize, u1,
62 cd->dsegtop = newstorage;
64 cd->dsegtop += cd->dsegsize;
68 s4 dseg_adds4_increase(codegendata *cd, s4 value)
72 *((s4 *) (cd->dsegtop - cd->dseglen)) = value;
74 return -(cd->dseglen);
78 s4 dseg_adds4(codegendata *cd, s4 value)
83 dataptr = (s4 *) (cd->dsegtop - cd->dseglen);
85 if (cd->dseglen > cd->dsegsize)
86 return dseg_adds4_increase(cd, value);
90 return -(cd->dseglen);
94 s4 dseg_adds8_increase(codegendata *cd, s8 value)
98 *((s8 *) (cd->dsegtop - cd->dseglen)) = value;
100 return -(cd->dseglen);
104 s4 dseg_adds8(codegendata *cd, s8 value)
108 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
109 dataptr = (s8 *) (cd->dsegtop - cd->dseglen);
111 if (cd->dseglen > cd->dsegsize)
112 return dseg_adds8_increase(cd, value);
116 return -(cd->dseglen);
120 s4 dseg_addfloat_increase(codegendata *cd, float value)
124 *((float *) (cd->dsegtop - cd->dseglen)) = value;
126 return -(cd->dseglen);
130 s4 dseg_addfloat(codegendata *cd, float value)
135 dataptr = (float *) (cd->dsegtop - cd->dseglen);
137 if (cd->dseglen > cd->dsegsize)
138 return dseg_addfloat_increase(cd, value);
142 return -(cd->dseglen);
146 s4 dseg_adddouble_increase(codegendata *cd, double value)
150 *((double *) (cd->dsegtop - cd->dseglen)) = value;
152 return -(cd->dseglen);
156 s4 dseg_adddouble(codegendata *cd, double value)
160 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
161 dataptr = (double *) (cd->dsegtop - cd->dseglen);
163 if (cd->dseglen > cd->dsegsize)
164 return dseg_adddouble_increase(cd, value);
168 return -(cd->dseglen);
172 void dseg_addtarget(codegendata *cd, basicblock *target)
178 jr->tablepos = dseg_addaddress(cd, NULL);
180 jr->next = cd->jumpreferences;
182 cd->jumpreferences = jr;
186 /* dseg_addlinenumbertablesize *************************************************
190 *******************************************************************************/
192 void dseg_addlinenumbertablesize(codegendata *cd)
194 #if SIZEOF_VOID_P == 8
195 /* 4-byte ALIGNMENT PADDING */
200 cd->linenumbertablesizepos = dseg_addaddress(cd, NULL);
201 cd->linenumbertablestartpos = dseg_addaddress(cd, NULL);
203 #if SIZEOF_VOID_P == 8
204 /* 4-byte ALIGNMENT PADDING */
211 /* dseg_addlinenumber **********************************************************
213 Add a line number reference.
216 cd.............current codegen data
217 linenumber.....number of line that starts with the given mcodeptr
218 mcodeptr.......start mcodeptr of line
220 *******************************************************************************/
222 void dseg_addlinenumber(codegendata *cd, u2 linenumber, u1 *mcodeptr)
226 lr = DNEW(linenumberref);
228 lr->linenumber = linenumber;
230 lr->targetmpc = mcodeptr - cd->mcodebase;
231 lr->next = cd->linenumberreferences;
233 cd->linenumberreferences = lr;
237 /* dseg_addlinenumber_inline_start *********************************************
239 Add a marker to the line number table indicating the start of an inlined
240 method body. (see doc/inlining_stacktrace.txt)
243 cd.............current codegen data
244 iptr...........the ICMD_INLINE_START instruction
245 mcodeptr.......start mcodeptr of inlined body
247 *******************************************************************************/
249 void dseg_addlinenumber_inline_start(codegendata *cd,
255 lr = DNEW(linenumberref);
257 lr->linenumber = (-2); /* marks start of inlined method */
259 lr->targetmpc = mcodeptr - cd->mcodebase;
260 lr->next = cd->linenumberreferences;
262 cd->linenumberreferences = lr;
264 iptr->target = mcodeptr; /* store for corresponding INLINE_END */
268 /* dseg_addlinenumber_inline_end ***********************************************
270 Add a marker to the line number table indicating the end of an inlined
271 method body. (see doc/inlining_stacktrace.txt)
274 cd.............current codegen data
275 iptr...........the ICMD_INLINE_END instruction
278 iptr->method must point to the inlined callee.
280 *******************************************************************************/
282 void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr)
286 instruction *inlinestart;
288 /* get the pointer to the corresponding ICMD_INLINE_START */
289 inlinestart = (instruction *)iptr->target;
292 assert(iptr->method);
294 lr = DNEW(linenumberref);
296 /* special entry containing the methodinfo * */
297 lr->linenumber = (-3) - iptr->line;
299 lr->targetmpc = (ptrint) iptr->method;
300 lr->next = cd->linenumberreferences;
303 lr = DNEW(linenumberref);
305 /* end marker with PC of start of body */
306 lr->linenumber = (-1);
308 lr->targetmpc = (u1*)inlinestart->target - cd->mcodebase;
311 cd->linenumberreferences = lr;
315 /* dseg_createlinenumbertable **************************************************
317 Creates a line number table in the data segment from the created
318 entries in linenumberreferences.
320 *******************************************************************************/
322 void dseg_createlinenumbertable(codegendata *cd)
326 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
327 lr->tablepos = dseg_addaddress(cd, NULL);
329 if (cd->linenumbertab == 0)
330 cd->linenumbertab = lr->tablepos;
332 dseg_addaddress(cd, lr->linenumber);
337 /* dseg_adddata ****************************************************************
339 Adds a data segment reference to the codegendata.
341 *******************************************************************************/
343 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
344 void dseg_adddata(codegendata *cd, u1 *mcodeptr)
350 dr->datapos = mcodeptr - cd->mcodebase;
351 dr->next = cd->datareferences;
353 cd->datareferences = dr;
358 /* dseg_resolve_datareferences *************************************************
360 Resolve data segment references.
362 *******************************************************************************/
364 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
365 void dseg_resolve_datareferences(codegendata *cd, methodinfo *m)
369 /* data segment references resolving */
371 for (dr = cd->datareferences; dr != NULL; dr = dr->next)
372 *((u1 **) (m->entrypoint + dr->datapos - SIZEOF_VOID_P)) = m->entrypoint;
377 /* dseg_display ****************************************************************
379 Displays the content of the methods' data segment.
381 *******************************************************************************/
384 void dseg_display(methodinfo *m, codegendata *cd)
389 s4ptr = (s4 *) (ptrint) m->mcode;
391 printf(" --- dump of datasegment\n");
393 for (i = cd->dseglen; i > 0 ; i -= 4) {
394 #if SIZEOF_VOID_P == 8
395 printf("0x%016lx: -%6x (%6d): %8x\n",
396 (ptrint) s4ptr, i, i, (s4) *s4ptr);
398 printf("0x%08x: -%6x (%6d): %8x\n",
399 (ptrint) s4ptr, i, i, (s4) *s4ptr);
404 printf(" --- begin of data segment: %p\n", (void *) s4ptr);
406 #endif /* !defined(NDEBUG) */
410 * These are local overrides for various environment variables in Emacs.
411 * Please do not remove this and leave it at the end of the file, where
412 * Emacs will automagically detect them.
413 * ---------------------------------------------------------------------
416 * indent-tabs-mode: t
420 * vim:noexpandtab:sw=4:ts=4: