* src/vmcore/linker.c (build_display_inner): Use MNEW instead of malloc.
[cacao.git] / src / vm / jit / stack.h
1 /* src/vm/jit/stack.h - stack analysis header
2
3    Copyright (C) 1996-2005, 2006, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #ifndef _STACK_H
27 #define _STACK_H
28
29 /* forward typedefs ***********************************************************/
30
31 typedef struct stackelement_t stackelement_t;
32
33
34 #include "config.h"
35
36 #include <stdint.h>
37
38 #include "vm/types.h"
39
40 #include "vm/exceptions.h"
41 #include "vm/global.h"
42
43 #include "vm/jit/jit.h"
44 #include "vm/jit/reg.h"
45
46
47 /* stack element structure ****************************************************/
48
49 /* flags */
50
51 #define SAVEDVAR      1         /* variable has to survive method invocations */
52 #define INMEMORY      2         /* variable stored in memory                  */
53 #define SAVREG        4         /* allocated to a saved register              */
54 #define ARGREG        8         /* allocated to an arg register               */
55 #define PASSTHROUGH  32         /* stackslot was passed-through by an ICMD    */
56 #define PREALLOC     64         /* preallocated var like for ARGVARS. Used    */
57                                 /* with the new var system */
58 #define INOUT    128            /* variable is an invar or/and an outvar      */
59
60 #define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
61 #define IS_INMEMORY(x)    ((x) & INMEMORY)
62
63
64 /* variable kinds */
65
66 #define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
67 #define TEMPVAR    1            /* stack slot is temp register                */
68 #define STACKVAR   2            /* stack slot is numbered stack slot          */
69 #define LOCALVAR   3            /* stack slot is local variable               */
70 #define ARGVAR     4            /* stack slot is argument variable            */
71
72
73 struct stackelement_t {
74         stackelement_t *prev;       /* pointer to next element towards bottom     */
75         instruction    *creator;    /* instruction that created this element      */
76         s4              type;       /* slot type of stack element                 */
77         s4              flags;      /* flags (SAVED, INMEMORY)                    */
78         s4              varkind;    /* kind of variable or register               */
79         s4              varnum;     /* number of variable                         */
80 };
81
82
83 /* macros used internally by analyse_stack ************************************/
84
85 /*--------------------------------------------------*/
86 /* BASIC TYPE CHECKING                              */
87 /*--------------------------------------------------*/
88
89 /* XXX would be nice if we did not have to pass the expected type */
90
91 #if defined(ENABLE_VERIFIER)
92 #define CHECK_BASIC_TYPE(expected,actual)                            \
93     do {                                                             \
94         if ((actual) != (expected)) {                                \
95             expectedtype = (expected);                               \
96             goto throw_stack_type_error;                             \
97         }                                                            \
98     } while (0)
99 #else /* !ENABLE_VERIFIER */
100 #define CHECK_BASIC_TYPE(expected,actual)
101 #endif /* ENABLE_VERIFIER */
102
103 /*--------------------------------------------------*/
104 /* STACK UNDERFLOW/OVERFLOW CHECKS                  */
105 /*--------------------------------------------------*/
106
107 /* underflow checks */
108
109 #if defined(ENABLE_VERIFIER)
110 #define REQUIRE(num)                                                 \
111     do {                                                             \
112         if (stackdepth < (num))                                      \
113             goto throw_stack_underflow;                              \
114     } while (0)
115 #else /* !ENABLE_VERIFIER */
116 #define REQUIRE(num)
117 #endif /* ENABLE_VERIFIER */
118
119
120 /* overflow check */
121 /* We allow ACONST instructions inserted as arguments to builtin
122  * functions to exceed the maximum stack depth.  Maybe we should check
123  * against maximum stack depth only at block boundaries?
124  */
125
126 /* XXX we should find a way to remove the opc/op1 check */
127 #if defined(ENABLE_VERIFIER)
128 #define CHECKOVERFLOW                                                \
129     do {                                                             \
130         if (stackdepth > m->maxstack)                                \
131             if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr))\
132                 goto throw_stack_overflow;                           \
133     } while(0)
134 #else /* !ENABLE_VERIFIER */
135 #define CHECKOVERFLOW
136 #endif /* ENABLE_VERIFIER */
137
138 /*--------------------------------------------------*/
139 /* ALLOCATING STACK SLOTS                           */
140 /*--------------------------------------------------*/
141
142 #define NEWSTACK(s,v,n)                                              \
143     do {                                                             \
144         sd.new->prev = curstack;                                     \
145         sd.new->type = (s);                                          \
146         sd.new->flags = 0;                                           \
147         sd.new->varkind = (v);                                       \
148         sd.new->varnum = (n);                                        \
149         curstack = sd.new;                                           \
150         sd.var[(n)].type = (s);                                      \
151         sd.var[(n)].flags = 0;                                       \
152         sd.new++;                                                    \
153     } while (0)
154
155 /* Initialize regoff, so -sia can show regnames even before reg.inc */
156 /* regs[rd->intregargnum] has to be set for this                    */
157 /* new->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; }       */
158
159 #define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
160 #define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
161
162
163 /* function prototypes ********************************************************/
164
165 bool stack_init(void);
166
167 bool stack_analyse(jitdata *jd);
168
169 void stack_javalocals_store(instruction *iptr, s4 *javalocals);
170
171 #endif /* _STACK_H */
172
173
174 /*
175  * These are local overrides for various environment variables in Emacs.
176  * Please do not remove this and leave it at the end of the file, where
177  * Emacs will automagically detect them.
178  * ---------------------------------------------------------------------
179  * Local variables:
180  * mode: c
181  * indent-tabs-mode: t
182  * c-basic-offset: 4
183  * tab-width: 4
184  * End:
185  * vim:noexpandtab:sw=4:ts=4:
186  */