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 4734 2006-04-05 09:57:55Z edwin $
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,
256 insinfo_inline *insinfo;
259 lr = DNEW(linenumberref);
261 lr->linenumber = (-2); /* marks start of inlined method */
263 lr->targetmpc = (mpc = mcodeptr - cd->mcodebase);
264 lr->next = cd->linenumberreferences;
266 cd->linenumberreferences = lr;
268 insinfo = (insinfo_inline *) iptr->target;
270 insinfo->startmpc = mpc; /* store for corresponding INLINE_END */
274 /* dseg_addlinenumber_inline_end ***********************************************
276 Add a marker to the line number table indicating the end of an inlined
277 method body. (see doc/inlining_stacktrace.txt)
280 cd.............current codegen data
281 iptr...........the ICMD_INLINE_END instruction
284 iptr->method must point to the inlined callee.
286 *******************************************************************************/
288 void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr)
292 insinfo_inline *insinfo;
294 insinfo = (insinfo_inline *) iptr->target;
298 lr = DNEW(linenumberref);
300 /* special entry containing the methodinfo * */
301 lr->linenumber = (-3) - iptr->line;
303 lr->targetmpc = (ptrint) insinfo->method;
304 lr->next = cd->linenumberreferences;
307 lr = DNEW(linenumberref);
309 /* end marker with PC of start of body */
310 lr->linenumber = (-1);
312 lr->targetmpc = insinfo->startmpc;
315 cd->linenumberreferences = lr;
319 /* dseg_createlinenumbertable **************************************************
321 Creates a line number table in the data segment from the created
322 entries in linenumberreferences.
324 *******************************************************************************/
326 void dseg_createlinenumbertable(codegendata *cd)
330 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
331 lr->tablepos = dseg_addaddress(cd, NULL);
333 if (cd->linenumbertab == 0)
334 cd->linenumbertab = lr->tablepos;
336 dseg_addaddress(cd, lr->linenumber);
341 /* dseg_adddata ****************************************************************
343 Adds a data segment reference to the codegendata.
345 *******************************************************************************/
347 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
348 void dseg_adddata(codegendata *cd, u1 *mcodeptr)
354 dr->datapos = mcodeptr - cd->mcodebase;
355 dr->next = cd->datareferences;
357 cd->datareferences = dr;
362 /* dseg_resolve_datareferences *************************************************
364 Resolve data segment references.
366 *******************************************************************************/
368 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
369 void dseg_resolve_datareferences(jitdata *jd)
375 /* get required compiler data */
380 /* data segment references resolving */
382 for (dr = cd->datareferences; dr != NULL; dr = dr->next)
383 *((u1 **) (code->entrypoint + dr->datapos - SIZEOF_VOID_P)) = code->entrypoint;
388 /* dseg_display ****************************************************************
390 Displays the content of the methods' data segment.
392 *******************************************************************************/
395 void dseg_display(jitdata *jd)
402 /* get required compiler data */
407 s4ptr = (s4 *) (ptrint) code->mcode;
409 printf(" --- dump of datasegment\n");
411 for (i = cd->dseglen; i > 0 ; i -= 4) {
412 #if SIZEOF_VOID_P == 8
413 printf("0x%016lx: -%6x (%6d): %8x\n",
414 (ptrint) s4ptr, i, i, (s4) *s4ptr);
416 printf("0x%08x: -%6x (%6d): %8x\n",
417 (ptrint) s4ptr, i, i, (s4) *s4ptr);
422 printf(" --- begin of data segment: %p\n", (void *) s4ptr);
424 #endif /* !defined(NDEBUG) */
428 * These are local overrides for various environment variables in Emacs.
429 * Please do not remove this and leave it at the end of the file, where
430 * Emacs will automagically detect them.
431 * ---------------------------------------------------------------------
434 * indent-tabs-mode: t
438 * vim:noexpandtab:sw=4:ts=4: