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 4826 2006-04-24 16:06:16Z twisti $
45 #include "mm/memory.h"
46 #include "vm/jit/codegen-common.h"
49 /* desg_increase ***************************************************************
53 *******************************************************************************/
55 static 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(codegendata *cd, s4 value)
76 if (cd->dseglen > cd->dsegsize)
79 dataptr = (s4 *) (cd->dsegtop - cd->dseglen);
83 return -(cd->dseglen);
87 s4 dseg_adds8(codegendata *cd, s8 value)
91 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
93 if (cd->dseglen > cd->dsegsize)
96 dataptr = (s8 *) (cd->dsegtop - cd->dseglen);
100 return -(cd->dseglen);
104 s4 dseg_addfloat(codegendata *cd, float value)
110 if (cd->dseglen > cd->dsegsize)
113 dataptr = (float *) (cd->dsegtop - cd->dseglen);
117 return -(cd->dseglen);
121 s4 dseg_adddouble(codegendata *cd, double value)
125 cd->dseglen = ALIGN(cd->dseglen + 8, 8);
127 if (cd->dseglen > cd->dsegsize)
130 dataptr = (double *) (cd->dsegtop - cd->dseglen);
134 return -(cd->dseglen);
138 void dseg_addtarget(codegendata *cd, basicblock *target)
144 jr->tablepos = dseg_addaddress(cd, NULL);
146 jr->next = cd->jumpreferences;
148 cd->jumpreferences = jr;
152 /* dseg_addlinenumbertablesize *************************************************
156 *******************************************************************************/
158 void dseg_addlinenumbertablesize(codegendata *cd)
160 #if SIZEOF_VOID_P == 8
161 /* 4-byte ALIGNMENT PADDING */
166 cd->linenumbertablesizepos = dseg_addaddress(cd, NULL);
167 cd->linenumbertablestartpos = dseg_addaddress(cd, NULL);
169 #if SIZEOF_VOID_P == 8
170 /* 4-byte ALIGNMENT PADDING */
177 /* dseg_addlinenumber **********************************************************
179 Add a line number reference.
182 cd.............current codegen data
183 linenumber.....number of line that starts with the given mcodeptr
184 mcodeptr.......start mcodeptr of line
186 *******************************************************************************/
188 void dseg_addlinenumber(codegendata *cd, u2 linenumber)
192 lr = DNEW(linenumberref);
194 lr->linenumber = linenumber;
196 lr->targetmpc = (u1 *) cd->mcodeptr - cd->mcodebase;
197 lr->next = cd->linenumberreferences;
199 cd->linenumberreferences = lr;
203 /* dseg_addlinenumber_inline_start *********************************************
205 Add a marker to the line number table indicating the start of an inlined
206 method body. (see doc/inlining_stacktrace.txt)
209 cd.............current codegen data
210 iptr...........the ICMD_INLINE_START instruction
211 mcodeptr.......start mcodeptr of inlined body
213 *******************************************************************************/
215 void dseg_addlinenumber_inline_start(codegendata *cd, instruction *iptr)
218 insinfo_inline *insinfo;
221 lr = DNEW(linenumberref);
223 lr->linenumber = (-2); /* marks start of inlined method */
225 lr->targetmpc = (mpc = (u1 *) cd->mcodeptr - cd->mcodebase);
226 lr->next = cd->linenumberreferences;
228 cd->linenumberreferences = lr;
230 insinfo = (insinfo_inline *) iptr->target;
232 insinfo->startmpc = mpc; /* store for corresponding INLINE_END */
236 /* dseg_addlinenumber_inline_end ***********************************************
238 Add a marker to the line number table indicating the end of an inlined
239 method body. (see doc/inlining_stacktrace.txt)
242 cd.............current codegen data
243 iptr...........the ICMD_INLINE_END instruction
246 iptr->method must point to the inlined callee.
248 *******************************************************************************/
250 void dseg_addlinenumber_inline_end(codegendata *cd, instruction *iptr)
254 insinfo_inline *insinfo;
256 insinfo = (insinfo_inline *) iptr->target;
260 lr = DNEW(linenumberref);
262 /* special entry containing the methodinfo * */
263 lr->linenumber = (-3) - iptr->line;
265 lr->targetmpc = (ptrint) insinfo->method;
266 lr->next = cd->linenumberreferences;
269 lr = DNEW(linenumberref);
271 /* end marker with PC of start of body */
272 lr->linenumber = (-1);
274 lr->targetmpc = insinfo->startmpc;
277 cd->linenumberreferences = lr;
281 /* dseg_createlinenumbertable **************************************************
283 Creates a line number table in the data segment from the created
284 entries in linenumberreferences.
286 *******************************************************************************/
288 void dseg_createlinenumbertable(codegendata *cd)
292 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
293 lr->tablepos = dseg_addaddress(cd, NULL);
295 if (cd->linenumbertab == 0)
296 cd->linenumbertab = lr->tablepos;
298 dseg_addaddress(cd, lr->linenumber);
303 /* dseg_adddata ****************************************************************
305 Adds a data segment reference to the codegendata.
307 *******************************************************************************/
309 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
310 void dseg_adddata(codegendata *cd)
316 dr->datapos = (u1 *) cd->mcodeptr - cd->mcodebase;
317 dr->next = cd->datareferences;
319 cd->datareferences = dr;
324 /* dseg_resolve_datareferences *************************************************
326 Resolve data segment references.
328 *******************************************************************************/
330 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
331 void dseg_resolve_datareferences(jitdata *jd)
337 /* get required compiler data */
342 /* data segment references resolving */
344 for (dr = cd->datareferences; dr != NULL; dr = dr->next)
345 *((u1 **) (code->entrypoint + dr->datapos - SIZEOF_VOID_P)) = code->entrypoint;
350 /* dseg_display ****************************************************************
352 Displays the content of the methods' data segment.
354 *******************************************************************************/
357 void dseg_display(jitdata *jd)
364 /* get required compiler data */
369 s4ptr = (s4 *) (ptrint) code->mcode;
371 printf(" --- dump of datasegment\n");
373 for (i = cd->dseglen; i > 0 ; i -= 4) {
374 #if SIZEOF_VOID_P == 8
375 printf("0x%016lx: -%6x (%6d): %8x\n",
376 (ptrint) s4ptr, i, i, (s4) *s4ptr);
378 printf("0x%08x: -%6x (%6d): %8x\n",
379 (ptrint) s4ptr, i, i, (s4) *s4ptr);
384 printf(" --- begin of data segment: %p\n", (void *) s4ptr);
386 #endif /* !defined(NDEBUG) */
390 * These are local overrides for various environment variables in Emacs.
391 * Please do not remove this and leave it at the end of the file, where
392 * Emacs will automagically detect them.
393 * ---------------------------------------------------------------------
396 * indent-tabs-mode: t
400 * vim:noexpandtab:sw=4:ts=4: