CACAO
instruction.hpp
Go to the documentation of this file.
1 /* src/vm/jit/ir/instruction.hpp - IR instruction
2 
3  Copyright (C) 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 _INSTRUCTION_HPP
27 #define _INSTRUCTION_HPP
28 
29 #include "config.h" // for SIZEOF_VOID_PTR
30 #include <stdint.h> // for int32_t, uint32_t, etc
31 #include "vm/global.hpp" // for Type, Type::Type_Void, etc
32 #include "vm/jit/ir/icmd.hpp" // for icmdtable_entry_t, etc
33 #include "vm/references.hpp" // for classref_or_classinfo, etc
34 #include "vm/resolve.hpp" // for unresolved_method (used in macro)
35 #include "vm/types.hpp" // for u2, u4
36 
37 struct basicblock;
38 struct insinfo_inline;
39 struct instruction;
40 struct methoddesc;
41 struct methodinfo;
42 struct rplpoint;
43 
44 // Instruction structure.
45 
46 /* branch_target_t: used in TABLESWITCH tables */
47 
48 typedef union {
49  int32_t insindex; /* used in parse */
50  basicblock *block; /* valid after parse */
52 
53 /* lookup_target_t: used in LOOKUPSWITCH tables */
54 
55 typedef struct {
56  int32_t value; /* case value */
57  branch_target_t target; /* branch target, see above */
59 
60 /*** s1 operand ***/
61 
62 typedef union {
63  int32_t varindex;
64  int32_t argcount;
65 } s1_operand_t;
66 
67 /*** s2 operand ***/
68 
69 typedef union {
70  int32_t varindex;
71  int32_t *args;
74  uintptr_t constval; /* for PUT*CONST */
75  int32_t tablelow; /* for TABLESWITCH */
76  uint32_t lookupcount; /* for LOOKUPSWITCH */
77  int32_t retaddrnr; /* for ASTORE */
78  instruction **iargs; /* for PHI */
79 } s2_operand_t;
80 
81 /*** s3 operand ***/
82 
83 typedef union {
84  int32_t varindex;
85  uintptr_t constval;
90  insinfo_inline *inlineinfo; /* for INLINE_START/END */
91  int32_t tablehigh; /* for TABLESWITCH */
92  branch_target_t lookupdefault; /* for LOOKUPSWITCH */
93  branch_target_t jsrtarget; /* for JSR */
94  int32_t javaindex; /* for *STORE */
96 } s3_operand_t;
97 
98 /*** val operand ***/
99 
100 typedef union {
101  int32_t i;
102  uint32_t u;
103  int64_t l;
104  float f;
105  double d;
106  void *anyptr;
107  java_handle_t *stringconst; /* for ACONST with string */
108  classref_or_classinfo c; /* for ACONST with class */
109 } val_operand_t;
110 
111 /*** dst operand ***/
112 
113 typedef union {
114  int32_t varindex;
115  basicblock *block; /* valid after parse */
116  branch_target_t *table; /* for TABLESWITCH */
117  lookup_target_t *lookup; /* for LOOKUPSWITCH */
118  int32_t insindex; /* used in parse */
119 } dst_operand_t;
120 
121 /*** flags (32 bits) ***/
122 
124  INS_FLAG_BASICBLOCK = 0x01, // marks a basic block start
125  INS_FLAG_UNRESOLVED = 0x02, // contains unresolved field/meth/class
126  INS_FLAG_CLASS = 0x04, // for ACONST, PUT*CONST with class
127  INS_FLAG_ARRAY = 0x08, // for CHECKCAST/INSTANCEOF with array
128  INS_FLAG_CHECK = 0x10, // for *ALOAD|*ASTORE: check index
129  // for BUILTIN: check exception
130  INS_FLAG_KILL_PREV = 0x04, // for *STORE, invalidate prev local
131  INS_FLAG_KILL_NEXT = 0x08, // for *STORE, invalidate next local
132  INS_FLAG_RETADDR = 0x10 // for ASTORE: op is a returnAddress
133 };
134 
135 #define INS_FLAG_ID_SHIFT 5
136 #define INS_FLAG_ID_MASK (~0 << INS_FLAG_ID_SHIFT)
137 
138 typedef union {
141 
142 
143 // Instruction.
144 
145 /* The instruction format for the intermediate representation: */
146 
147 struct instruction {
148  ICMD opc : 16; // opcode
149  u2 line; // line number
150 #if SIZEOF_VOID_P == 8
151  flags_operand_t flags; // 4 bytes
152 #endif
153  s1_operand_t s1; // pointer-size
154  union {
155  struct {
156  s2_operand_t s2; // pointer-size
157  s3_operand_t s3; // pointer-size
158  } s23; // XOR
159  val_operand_t val; // long-size
160  } sx;
161  dst_operand_t dst; // pointer-size
162 #if SIZEOF_VOID_P == 4
163  flags_operand_t flags; // 4 bytes
164 #endif
165 #if defined(ENABLE_ESCAPE_REASON)
166  void *escape_reasons;
167 #endif
168 
169 #if defined(ENABLE_COMPILER2)
170  /// The stack vars that are alive after this instruction.
171  ///
172  /// This liveness information is needed for deoptimization and hence will
173  /// only be generated if the current method is recompiled due to a
174  /// decompilation request.
175  s4 *stack_after;
176 
177  /// The size of stack_after.
178  s4 stackdepth_after;
179 #endif
180 };
181 
182 
183 #define INSTRUCTION_STARTS_BASICBLOCK(iptr) \
184  ((iptr)->flags.bits & INS_FLAG_BASICBLOCK)
185 
186 #define INSTRUCTION_IS_RESOLVED(iptr) \
187  (!((iptr)->flags.bits & INS_FLAG_UNRESOLVED))
188 
189 #define INSTRUCTION_IS_UNRESOLVED(iptr) \
190  ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
191 
192 #define INSTRUCTION_MUST_CHECK(iptr) \
193  ((iptr)->flags.bits & INS_FLAG_CHECK)
194 
195 #define INSTRUCTION_GET_FIELDREF(iptr,fref) \
196  do { \
197  if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
198  fref = iptr->sx.s23.s3.uf->fieldref; \
199  else \
200  fref = iptr->sx.s23.s3.fmiref; \
201  } while (0)
202 
203 #define INSTRUCTION_GET_METHODREF(iptr,mref) \
204  do { \
205  if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
206  mref = iptr->sx.s23.s3.um->methodref; \
207  else \
208  mref = iptr->sx.s23.s3.fmiref; \
209  } while (0)
210 
211 #define INSTRUCTION_GET_METHODDESC(iptr, md) \
212  do { \
213  if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
214  md = iptr->sx.s23.s3.um->methodref->parseddesc.md; \
215  else \
216  md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
217  } while (0)
218 
219 
220 /* additional info structs for special instructions ***************************/
221 
222 /* for ICMD_INLINE_START and ICMD_INLINE_END */
223 
225  /* fields copied from the inlining tree ----------------------------------*/
226  insinfo_inline *parent; /* insinfo of the surrounding inlining, if any*/
227  methodinfo *method; /* the inlined method starting/ending here */
228  methodinfo *outer; /* the outer method suspended/resumed here */
229  int32_t synclocal; /* local index used for synchronization */
230  bool synchronize; /* true if synchronization is needed */
231  int32_t throughcount; /* total # of pass-through variables */
232  int32_t paramcount; /* number of parameters of original call */
233  int32_t stackvarscount; /* source stackdepth at INLINE_START */
234  int32_t *stackvars; /* stack vars at INLINE_START */
235 
236  /* fields set by inlining ------------------------------------------------*/
237  int32_t *javalocals_start; /* javalocals at start of inlined body */
238  int32_t *javalocals_end; /* javalocals after inlined body */
239 
240  /* fields set by replacement point creation ------------------------------*/
241 #if defined(ENABLE_COMPILER2)
242  rplpoint *rp; /* replacement point at INLINE_START */
243 #endif
244 
245  /* fields set by the codegen ---------------------------------------------*/
246  int32_t startmpc; /* machine code offset of start of inlining */
247 };
248 
249 
250 /* Additional instruction accessors */
251 
254 
255 static inline bool instruction_has_dst(const instruction* iptr)
256 {
257  if (
258  (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
259  (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
260  ) {
262  }
263  else {
264  return icmd_table[iptr->opc].dataflow >= DF_DST_BASE;
265  }
266 }
267 
268 static inline bool instruction_has_side_effects(const instruction *iptr)
269 {
270  int opc = iptr->opc;
271  return opc == ICMD_INVOKESTATIC
272  || opc == ICMD_INVOKEVIRTUAL
273  || opc == ICMD_INVOKEINTERFACE
274  || opc == ICMD_INVOKESPECIAL
275  || opc == ICMD_BUILTIN
276  || opc == ICMD_PUTSTATIC
277  || opc == ICMD_PUTFIELD
278  || opc == ICMD_PUTSTATICCONST
279  || opc == ICMD_PUTFIELDCONST
280  || opc == ICMD_ASTORE
281  || opc == ICMD_IASTORE
282  || opc == ICMD_LASTORE
283  || opc == ICMD_FASTORE
284  || opc == ICMD_DASTORE
285  || opc == ICMD_AASTORE
286  || opc == ICMD_BASTORE
287  || opc == ICMD_CASTORE
288  || opc == ICMD_SASTORE
289  || opc == ICMD_BASTORECONST
290  || opc == ICMD_CASTORECONST
291  || opc == ICMD_SASTORECONST
292  || opc == ICMD_AASTORECONST
293  || opc == ICMD_IASTORECONST
294  || opc == ICMD_LASTORECONST
295  || opc == ICMD_NEW
296  || opc == ICMD_MONITORENTER
297  || opc == ICMD_MONITOREXIT;
298 }
299 
300 
301 #endif // _INSTRUCTION_HPP
302 
303 
304 /*
305  * These are local overrides for various environment variables in Emacs.
306  * Please do not remove this and leave it at the end of the file, where
307  * Emacs will automagically detect them.
308  * ---------------------------------------------------------------------
309  * Local variables:
310  * mode: c++
311  * indent-tabs-mode: t
312  * c-basic-offset: 4
313  * tab-width: 4
314  * End:
315  * vim:noexpandtab:sw=4:ts=4:
316  */
val_operand_t val
methodinfo * outer
basicblock * block
static bool instruction_has_side_effects(const instruction *iptr)
int32_t retaddrnr
Definition: instruction.hpp:77
constant_FMIref * fmiref
Definition: instruction.hpp:87
insinfo_inline * parent
static bool instruction_has_dst(const instruction *iptr)
struct builtintable_entry * bte
Definition: instruction.hpp:95
int32_t * stackvars
int32_t argcount
Definition: instruction.hpp:64
int32_t varindex
Definition: instruction.hpp:63
int32_t tablehigh
Definition: instruction.hpp:91
int32_t varindex
Definition: instruction.hpp:70
insinfo_inline * inlineinfo
Definition: instruction.hpp:90
s3_operand_t s3
lookup_target_t * lookup
unresolved_field * uf
Definition: instruction.hpp:89
methoddesc * instruction_call_site(const instruction *iptr)
Definition: instruction.cpp:31
uintptr_t constval
Definition: instruction.hpp:74
int32_t insindex
instruction ** iargs
Definition: instruction.hpp:78
classref_or_classinfo c
Definition: instruction.hpp:72
classref_or_classinfo c
uint32_t lookupcount
Definition: instruction.hpp:76
uintptr_t constval
Definition: instruction.hpp:85
branch_target_t target
Definition: instruction.hpp:57
dst_operand_t dst
flags_operand_t flags
methodinfo * method
uint16_t u2
Definition: types.hpp:43
int32_t dataflow
Definition: icmd.hpp:395
int32_t paramcount
Type
Types used internally by JITTED code.
Definition: global.hpp:117
InstructionFlag
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
int32_t s4
Definition: types.hpp:45
int32_t * javalocals_start
ICMD
Definition: icmd.hpp:37
union instruction::@12 sx
int32_t varindex
icmdtable_entry_t icmd_table[256]
Definition: icmd.cpp:60
s1_operand_t s1
uint32_t u4
Definition: types.hpp:46
basicblock * block
Definition: instruction.hpp:50
branch_target_t jsrtarget
Definition: instruction.hpp:93
branch_target_t lookupdefault
Definition: instruction.hpp:92
Definition: builtin.hpp:60
#define DF_INVOKE
Definition: icmd.hpp:347
java_handle_t * stringconst
struct instruction::@12::@13 s23
int32_t * args
Definition: instruction.hpp:71
unresolved_method * um
Definition: instruction.hpp:88
int32_t tablelow
Definition: instruction.hpp:75
int32_t throughcount
int32_t javaindex
Definition: instruction.hpp:94
Type instruction_call_site_return_type(const instruction *iptr)
Definition: instruction.cpp:44
int32_t stackvarscount
#define DF_BUILTIN
Definition: icmd.hpp:348
unresolved_class * uc
Definition: instruction.hpp:73
s2_operand_t s2
classref_or_classinfo c
Definition: instruction.hpp:86
#define DF_DST_BASE
Definition: icmd.hpp:339
branch_target_t * table
int32_t varindex
Definition: instruction.hpp:84
int32_t * javalocals_end