* configure.ac: New switch for disabling -O2 (--disable-optimizations).
[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/global.h"
41
42 #include "vm/jit/jit.hpp"
43 #include "vm/jit/reg.h"
44
45
46 /* stack element structure ****************************************************/
47
48 /* flags */
49
50 #define SAVEDVAR      1         /* variable has to survive method invocations */
51 #define INMEMORY      2         /* variable stored in memory                  */
52 #define SAVREG        4         /* allocated to a saved register              */
53 #define ARGREG        8         /* allocated to an arg register               */
54 #define PASSTHROUGH  32         /* stackslot was passed-through by an ICMD    */
55 #define PREALLOC     64         /* preallocated var like for ARGVARS. Used    */
56                                 /* with the new var system */
57 #define INOUT    128            /* variable is an invar or/and an outvar      */
58
59 #define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
60 #define IS_INMEMORY(x)    ((x) & INMEMORY)
61
62
63 /* variable kinds */
64
65 #define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
66 #define TEMPVAR    1            /* stack slot is temp register                */
67 #define STACKVAR   2            /* stack slot is numbered stack slot          */
68 #define LOCALVAR   3            /* stack slot is local variable               */
69 #define ARGVAR     4            /* stack slot is argument variable            */
70
71
72 struct stackelement_t {
73         stackelement_t *prev;       /* pointer to next element towards bottom     */
74         instruction    *creator;    /* instruction that created this element      */
75         s4              type;       /* slot type of stack element                 */
76         s4              flags;      /* flags (SAVED, INMEMORY)                    */
77         s4              varkind;    /* kind of variable or register               */
78         s4              varnum;     /* number of variable                         */
79 };
80
81
82 /* macros used internally by analyse_stack ************************************/
83
84 /*--------------------------------------------------*/
85 /* BASIC TYPE CHECKING                              */
86 /*--------------------------------------------------*/
87
88 /* XXX would be nice if we did not have to pass the expected type */
89
90 #if defined(ENABLE_VERIFIER)
91 #define CHECK_BASIC_TYPE(expected,actual)                            \
92     do {                                                             \
93         if ((actual) != (expected)) {                                \
94             expectedtype = (expected);                               \
95             goto throw_stack_type_error;                             \
96         }                                                            \
97     } while (0)
98 #else /* !ENABLE_VERIFIER */
99 #define CHECK_BASIC_TYPE(expected,actual)
100 #endif /* ENABLE_VERIFIER */
101
102 /*--------------------------------------------------*/
103 /* STACK UNDERFLOW/OVERFLOW CHECKS                  */
104 /*--------------------------------------------------*/
105
106 /* underflow checks */
107
108 #if defined(ENABLE_VERIFIER)
109 #define REQUIRE(num)                                                 \
110     do {                                                             \
111         if (stackdepth < (num))                                      \
112             goto throw_stack_underflow;                              \
113     } while (0)
114 #else /* !ENABLE_VERIFIER */
115 #define REQUIRE(num)
116 #endif /* ENABLE_VERIFIER */
117
118
119 /* overflow check */
120 /* We allow ACONST instructions inserted as arguments to builtin
121  * functions to exceed the maximum stack depth.  Maybe we should check
122  * against maximum stack depth only at block boundaries?
123  */
124
125 /* XXX we should find a way to remove the opc/op1 check */
126 #if defined(ENABLE_VERIFIER)
127 #define CHECKOVERFLOW                                                \
128     do {                                                             \
129         if (stackdepth > m->maxstack)                                \
130             if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr))\
131                 goto throw_stack_overflow;                           \
132     } while(0)
133 #else /* !ENABLE_VERIFIER */
134 #define CHECKOVERFLOW
135 #endif /* ENABLE_VERIFIER */
136
137 /*--------------------------------------------------*/
138 /* ALLOCATING STACK SLOTS                           */
139 /*--------------------------------------------------*/
140
141 #define NEWSTACK(s,v,n)                                              \
142     do {                                                             \
143         sd.new->prev = curstack;                                     \
144         sd.new->type = (s);                                          \
145         sd.new->flags = 0;                                           \
146         sd.new->varkind = (v);                                       \
147         sd.new->varnum = (n);                                        \
148         curstack = sd.new;                                           \
149         sd.var[(n)].type = (s);                                      \
150         sd.var[(n)].flags = 0;                                       \
151         sd.new++;                                                    \
152     } while (0)
153
154 /* Initialize regoff, so -sia can show regnames even before reg.inc */
155 /* regs[rd->intregargnum] has to be set for this                    */
156 /* new->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; }       */
157
158 #define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
159 #define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
160
161
162 /* function prototypes ********************************************************/
163
164 #ifdef __cplusplus
165 extern "C" {
166 #endif
167
168 bool stack_init(void);
169
170 bool stack_analyse(jitdata *jd);
171
172 void stack_javalocals_store(instruction *iptr, s4 *javalocals);
173
174 #ifdef __cplusplus
175 }
176 #endif
177
178 #endif /* _STACK_H */
179
180
181 /*
182  * These are local overrides for various environment variables in Emacs.
183  * Please do not remove this and leave it at the end of the file, where
184  * Emacs will automagically detect them.
185  * ---------------------------------------------------------------------
186  * Local variables:
187  * mode: c
188  * indent-tabs-mode: t
189  * c-basic-offset: 4
190  * tab-width: 4
191  * End:
192  * vim:noexpandtab:sw=4:ts=4:
193  */