CACAO
typeinfo.hpp
Go to the documentation of this file.
1 /* src/vm/jit/verify/typeinfo.hpp - type system used by the type checker
2 
3  Copyright (C) 1996-2014
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 #ifndef _TYPEINFO_H
26 #define _TYPEINFO_H
27 
28 #include "config.h"
29 #include "toolbox/assert.hpp"
30 #include "vm/array.hpp"
31 #include "vm/global.hpp"
32 #include "vm/globals.hpp"
33 #include "vm/references.hpp"
34 #include "vm/types.hpp"
35 
36 struct instruction;
37 struct varinfo;
38 struct typeinfo_t;
40 struct typedescriptor_t;
41 
42 /* configuration **************************************************************/
43 
44 /*
45  * TYPECHECK_STATISTICS activates gathering statistical information.
46  * TYPEINFO_DEBUG activates debug checks and debug helpers in typeinfo.cpp
47  * TYPECHECK_DEBUG activates debug checks in typecheck.c
48  * TYPEINFO_DEBUG_TEST activates the typeinfo test at startup.
49  * TYPECHECK_VERBOSE_IMPORTANT activates important debug messages
50  * TYPECHECK_VERBOSE activates all debug messages
51  * TYPEINFO_VERBOSE activates debug prints in typeinfo.c
52  */
53 #ifdef ENABLE_VERIFIER
54 #ifndef NDEBUG
55 /*#define TYPECHECK_STATISTICS*/
56 #define TYPEINFO_DEBUG
57 /*#define TYPEINFO_VERBOSE*/
58 #define TYPECHECK_DEBUG
59 /*#define TYPEINFO_DEBUG_TEST*/
60 /*#define TYPECHECK_VERBOSE*/
61 /*#define TYPECHECK_VERBOSE_IMPORTANT*/
62 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
63 #define TYPECHECK_VERBOSE_OPT
64 #endif
65 #endif
66 #endif
67 
68 #ifdef TYPECHECK_VERBOSE_OPT
69 extern bool opt_typecheckverbose;
70 #endif
71 
72 /* types **********************************************************************/
73 
74 /* typecheck_result - return type for boolean and tristate functions */
75 /* which may also throw exceptions (typecheck_FAIL). */
76 
77 /* NOTE: Use the enum values, not the uppercase #define macros! */
78 #define TYPECHECK_MAYBE 0x02
79 #define TYPECHECK_FAIL 0x04
80 
82  typecheck_FALSE = false,
86 };
87 
88 /* check that typecheck_MAYBE is not ambiguous */
89 #if TYPECHECK_MAYBE == true
90 #error "`typecheck_MAYBE` must not be the same as `true`"
91 #endif
92 #if TYPECHECK_MAYBE == false
93 #error "`typecheck_MAYBE` must not be the same as `false`"
94 #endif
95 
96 /* check that typecheck_FAIL is not ambiguous */
97 #if (true & TYPECHECK_FAIL) != 0
98 #error "`true` must not have bit 0x02 set (conflicts with typecheck_FAIL)"
99 #endif
100 
101 /* data structures for the type system ****************************************/
102 
103 /* The typeinfo structure stores detailed information on address types.
104  * (stack elements, variables, etc. with type == TYPE_ADR.)
105  *
106  * There are two kinds of address types which can be distinguished by
107  * the value of the typeclass field:
108  *
109  * 1) typeclass == NULL: returnAddress type
110  * use typeinfo::is_primitive() to test for this
111  *
112  * 2) typeclass != NULL: reference type
113  * use typeinfo::is_reference() to test for this
114  *
115  * Note: For non-address types either there is no typeinfo allocated
116  * or the fields of the typeinfo struct contain undefined values!
117  * DO NOT access the typeinfo for non-address types!
118  *
119  * CAUTION: The typeinfo structure should be considered opaque outside of
120  * typeinfo.[ch]. Please use the macros and functions defined here to
121  * access typeinfo structures!
122  */
123 
124 /* At all times *exactly one* of the following conditions is true for
125  * a particular typeinfo struct:
126  *
127  * A) typeclass == NULL
128  *
129  * This is a returnAddress type.
130  *
131  * Use typeinfo::is_primitive() to check for this.
132  * Use typeinfo::returnaddress() to access the pointer in elementclass.
133  * Don't access other fields of the struct.
134  *
135  * B) typeclass == pseudo_class_Null
136  *
137  * This is the null-reference type.
138  * Use typeinfo::is_nulltype() to check for this.
139  * Don't access other fields of the struct.
140  *
141  * C) typeclass == pseudo_class_New
142  *
143  * This is an 'uninitialized object' type. elementclass can be
144  * cast to instruction* and points to the NEW instruction
145  * responsible for creating this type.
146  *
147  * Use typeinfo::newobject_instruction to access the pointer in
148  * elementclass.
149  * Don't access other fields of the struct.
150  *
151  * D) typeclass == pseudo_class_Arraystub
152  *
153  * This type is used to represent the result of merging array types
154  * with incompatible component types. An arraystub allows no access
155  * to its components (since their type is undefined), but it allows
156  * operations which act directly on an arbitrary array type (such as
157  * requesting the array size).
158  *
159  * NOTE: An array stub does *not* count as an array. It has dimension
160  * zero.
161  *
162  * Otherwise like a normal class reference type.
163  * Don't access other fields of the struct.
164  *
165  * E) typeclass is an array class
166  *
167  * An array reference.
168  * elementclass...typeclass of the element type
169  * dimension......dimension of the array (>=1)
170  * elementtype....element type (ARRAYTYPE_...)
171  * merged.........mergedlist of the element type
172  *
173  * Use typeinfo:is_array to check for this case.
174  *
175  * The elementclass may be one of the following:
176  * 1) pseudo_class_Arraystub
177  * 2) an unresolved type
178  * 3) a loaded interface
179  * 4) a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
180  * Note: `merged` may be used
181  * 5) (BOOTSTRAP)java.lang.Object
182  * Note: `merged` may be used
183  *
184  * For the semantics of the merged field in cases 4) and 5) consult the
185  * corresponding descriptions with `elementclass` replaced by `typeclass`.
186  *
187  * F) typeclass is an unresolved type (a symbolic class/interface reference)
188  *
189  * The type has not been resolved yet. (Meaning it corresponds to an
190  * unloaded class or interface).
191  * Don't access other fields of the struct.
192  *
193  * G) typeclass is a loaded interface
194  *
195  * An interface reference type.
196  * Don't access other fields of the struct.
197  *
198  * H) typeclass is a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
199  *
200  * A loaded class type.
201  * All classref_or_classinfos in u.merged.list (if any) are
202  * loaded subclasses of typeclass (no interfaces, array classes, or
203  * unresolved types).
204  * Don't access other fields of the struct.
205  *
206  * I) typeclass is (BOOTSTRAP)java.lang.Object
207  *
208  * The most general kind of reference type.
209  * In this case u.merged.count and u.merged.list
210  * are valid and may be non-zero.
211  * The classref_or_classinfos in u.merged.list (if any) may be
212  * classes, interfaces, pseudo classes or unresolved types.
213  * Don't access other fields of the struct.
214  */
215 
216 /* The following algorithm is used to determine if the type described
217  * by this typeinfo struct supports the interface X: * XXX add MAYBE *
218  *
219  * 1) If typeclass is X or a subinterface of X the answer is "yes".
220  * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
221  * 3) If typeclass is not an array and u.merged.count>0
222  * and all classes/interfaces in u.merged.list implement X
223  * the answer is "yes".
224  * 4) If none of the above is true the answer is "no".
225  */
226 
227 /*
228  * CAUTION: The typeinfo structure should be considered opaque outside of
229  * typeinfo.[ch]. Please use the macros and functions defined here to
230  * access typeinfo structures!
231  */
232 
234 
235 struct typeinfo_t {
237  classref_or_classinfo elementclass; // valid if dimension>0 (various uses!)
240  ArrayType elementtype; // valid if dimension>0
241 
242  bool is_primitive() const { return typeclass.any == NULL; }
243  bool is_reference() const { return typeclass.any != NULL; }
244 
245  bool is_nulltype() const { return typeclass.cls == pseudo_class_Null; }
246  bool is_newobject() const { return typeclass.cls == pseudo_class_New; }
247 
248  void *returnaddress() const {
250 
251  return elementclass.any;
252  }
253 
256 
257  return (instruction*) elementclass.any;
258  }
259 
260  bool is_array() const { return is_reference() && dimension != 0; }
261  bool is_simple_array() const { return dimension == 1; }
262 
263  bool is_primitive_array(ArrayType at) const {
264  return is_simple_array() && elementtype == at;
265  }
266  bool is_array_of_refs() const {
267  return is_array() && (elementclass.any != NULL || dimension >= 2);
268  }
269 
270  // queries allowing the null type
271 
272  bool maybe_array() const {
273  return is_array() || is_nulltype();
274  }
275 
277  return is_primitive_array(at) || is_nulltype();
278  }
279 
280  bool maybe_array_of_refs() const {
281  return is_array_of_refs() || is_nulltype();
282  }
283 
284  // Check if `this' type is assignable to a given destination type.
287 
288  // initializing typeinfo structures
289 
290  void init_primitive() {
291  typeclass.any = NULL;
292  elementclass.any = NULL;
293  merged = NULL;
294  dimension = 0;
296  }
297 
298  void init_returnaddress(void *adr) {
299  typeclass.any = NULL;
300  elementclass.any = adr;
301  merged = NULL;
302  dimension = 0;
304  }
305 
307  typeclass.cls = cls;
308  elementclass.any = NULL;
309  merged = NULL;
310  dimension = 0;
312  }
313 
314  /// Initialize object type java.lang.Class
317  elementclass = cls;
318  merged = NULL;
319  dimension = 0;
321  }
322 
323  /// Initialize object type
324  void init_class(classinfo *c);
326 
329  }
330 
331  bool init_component(const typeinfo_t& srcarray);
332 
333  bool init_from_typedesc(const typedesc *desc, u1 *type);
334 
335  void init_nulltype() {
337  }
338 
341  elementclass.any = instr;
342  merged = NULL;
343  dimension = 0;
345  }
346 
347  void init_primitive_array(ArrayType arraytype) {
348  init_class(primitivetype_table[arraytype].arrayclass);
349  }
350 
351  // copying types (destinition is not checked or freed)
352 
353  /***
354  * makes a deep copy, the merged list (if any) is duplicated
355  * into a newly allocated array.
356  */
357  static void clone(const typeinfo_t& src, typeinfo_t& dst) {
358  dst = src;
359 
360  if (dst.merged)
361  clone_merged(src, dst);
362  }
363 
364  /// functions for merging types
365 
367 private:
368  static void clone_merged(const typeinfo_t& src, typeinfo_t& dst);
369 };
370 
371 
374  classref_or_classinfo list[1]; /* variable length! */
375 };
376 
377 /* a type descriptor stores a basic type and the typeinfo */
378 /* this is used for storing the type of a local variable, and for */
379 /* storing types in the signature of a method */
380 
382  typeinfo_t typeinfo; /* valid if type == TYPE_ADR */
383  Type type; /* basic type (TYPE_INT, ...) */
384 
385  bool is_returnaddress() const { return type == TYPE_RET && typeinfo.is_primitive(); }
386  bool is_reference() const { return type == TYPE_ADR && typeinfo.is_reference(); }
387 };
388 
389 
390 /****************************************************************************/
391 /* MACROS */
392 /****************************************************************************/
393 
394 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
395  * arguments. You have to dereference any pointers.
396  */
397 
398 /* typevectors **************************************************************/
399 
400 #define TYPEVECTOR_SIZE(size) \
401  ((size) * sizeof(varinfo))
402 
403 #define DNEW_TYPEVECTOR(size) \
404  ((varinfo *) DumpMemory::allocate(TYPEVECTOR_SIZE(size)))
405 
406 #define DMNEW_TYPEVECTOR(num,size) \
407  ((varinfo *) DumpMemory::allocate((num) * TYPEVECTOR_SIZE(size)))
408 
409 #define MGET_TYPEVECTOR(array,index,size) \
410  ((varinfo*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
411 
412 
413 /****************************************************************************/
414 /* FUNCTIONS */
415 /****************************************************************************/
416 
417 /* typevector functions *****************************************************/
418 
419 /* element read-only access */
420 bool typevector_checktype(varinfo *set,int index,int type);
423 
424 /* element write access */
425 void typevector_store(varinfo *set,int index, Type type,typeinfo_t *info);
427 bool typevector_init_object(varinfo *set,void *ins,classref_or_classinfo initclass,int size);
428 
429 /* vector functions */
431 void typevector_copy_inplace(varinfo *src,varinfo *dst,int size);
433 
434 /* initialization functions *************************************************/
435 
436 /* RETURN VALUE (bool):
437  * true.............ok,
438  * false............an exception has been thrown.
439  *
440  * RETURN VALUE (int):
441  * >= 0.............ok,
442  * -1...............an exception has been thrown.
443  */
445  methoddesc *desc,
446  int buflen,bool twoword,int startindex,
447  typedescriptor_t *returntype);
449  methoddesc *desc,
450  int buflen, int startindex,
451  s4 *map,
452  typedescriptor_t *returntype);
453 
454 /* debugging helpers ********************************************************/
455 
456 #ifdef TYPEINFO_DEBUG
457 
458 #include <stdio.h>
459 
460 void typeinfo_test();
461 void typeinfo_print_class(FILE *file, classref_or_classinfo c);
462 void typeinfo_print(FILE *file, const typeinfo_t *info, int indent);
463 void typeinfo_print_short(FILE *file, const typeinfo_t *info);
464 void typeinfo_print_type(FILE *file, int type, const typeinfo_t *info);
465 void typedescriptor_print(FILE *file, typedescriptor_t *td);
466 void typevector_print(FILE *file, varinfo *vec, int size);
467 
468 #endif /* TYPEINFO_DEBUG */
469 
470 #endif /* _TYPEINFO_H */
471 
472 
473 /*
474  * These are local overrides for various environment variables in Emacs.
475  * Please do not remove this and leave it at the end of the file, where
476  * Emacs will automagically detect them.
477  * ---------------------------------------------------------------------
478  * Local variables:
479  * mode: c++
480  * indent-tabs-mode: t
481  * c-basic-offset: 4
482  * tab-width: 4
483  * End:
484  */
std::size_t index
bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars, methoddesc *desc, int buflen, int startindex, s4 *map, typedescriptor_t *returntype)
Definition: typeinfo.cpp:1008
typeinfo_t typeinfo
Definition: typeinfo.hpp:382
void init_class(classinfo *c)
Initialize object type.
Definition: typeinfo.cpp:790
void init_newobject(instruction *instr)
Definition: typeinfo.hpp:339
bool maybe_primitive_array(ArrayType at) const
Definition: typeinfo.hpp:276
classref_or_classinfo list[1]
Definition: typeinfo.hpp:374
int typedescriptors_init_from_methoddesc(typedescriptor_t *td, methoddesc *desc, int buflen, bool twoword, int startindex, typedescriptor_t *returntype)
Definition: typeinfo.cpp:1088
bool maybe_array_of_refs() const
Definition: typeinfo.hpp:280
bool init_component(const typeinfo_t &srcarray)
Definition: typeinfo.cpp:1144
void init_non_array_classinfo(classinfo *cls)
Definition: typeinfo.hpp:306
classref_or_classinfo elementclass
Definition: typeinfo.hpp:237
bool is_newobject() const
Definition: typeinfo.hpp:246
bool typevector_checkretaddr(varinfo *vec, int index)
Definition: typeinfo.cpp:175
bool maybe_array() const
Definition: typeinfo.hpp:272
bool init_class(constant_classref *c)
Definition: typeinfo.hpp:327
uint8_t u1
Definition: types.hpp:40
void init_primitive_array(ArrayType arraytype)
Definition: typeinfo.hpp:347
bool is_reference() const
Definition: typeinfo.hpp:386
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
Definition: reg.hpp:43
classinfo * pseudo_class_Null
Definition: globals.cpp:107
void init_primitive()
Definition: typeinfo.hpp:290
bool is_primitive_array(ArrayType at) const
Definition: typeinfo.hpp:263
void typevector_print(FILE *file, const varinfo *vec, int size)
Definition: typeinfo.cpp:2289
bool is_array() const
Definition: typeinfo.hpp:260
void typeinfo_init_classinfo(typeinfo_t *info, classinfo *c)
typecheck_result typevector_merge(methodinfo *m, varinfo *dst, varinfo *y, int size)
Definition: typeinfo.cpp:285
bool typevector_init_object(varinfo *set, void *ins, classref_or_classinfo initclass, int size)
Definition: typeinfo.cpp:245
ArrayType
Definition: array.hpp:51
Indent indent
Definition: OStream.cpp:54
typecheck_result merge(methodinfo *m, const typeinfo_t *t)
functions for merging types
Definition: typeinfo.cpp:1672
bool is_array_of_refs() const
Definition: typeinfo.hpp:266
void init_returnaddress(void *adr)
Definition: typeinfo.hpp:298
classinfo * class_java_lang_Class
Definition: globals.cpp:35
Definition: set.cpp:44
void typeinfo_print_type(FILE *file, int type, const typeinfo_t *info)
Definition: typeinfo.cpp:2264
Type
Types used internally by JITTED code.
Definition: global.hpp:117
bool is_nulltype() const
Definition: typeinfo.hpp:245
#define TYPECHECK_FAIL
Definition: typeinfo.hpp:79
static void clone_merged(const typeinfo_t &src, typeinfo_t &dst)
Definition: typeinfo.cpp:1194
void typevector_copy_inplace(varinfo *src, varinfo *dst, int size)
Definition: typeinfo.cpp:111
typeinfo_mergedlist_t * merged
Definition: typeinfo.hpp:238
typecheck_result is_assignable_to(typeinfo_t *dest) const
Definition: typeinfo.cpp:751
bool typevector_checkreference(varinfo *vec, int index)
Definition: typeinfo.cpp:154
void * returnaddress() const
Definition: typeinfo.hpp:248
typecheck_result is_assignable_to_class(classref_or_classinfo dest) const
Definition: typeinfo.cpp:586
bool is_primitive() const
Definition: typeinfo.hpp:242
int32_t s4
Definition: types.hpp:45
void typeinfo_print(FILE *file, const typeinfo_t *info, int indent)
Definition: typeinfo.cpp:2138
instruction * newobject_instruction() const
Definition: typeinfo.hpp:254
#define EXPENSIVE_ASSERT(EXPR)
An assertion that performs computations too expensive even for a normal debug build.
Definition: assert.hpp:90
bool is_simple_array() const
Definition: typeinfo.hpp:261
void init_nulltype()
Definition: typeinfo.hpp:335
bool init_from_typedesc(const typedesc *desc, u1 *type)
Definition: typeinfo.cpp:889
classref_or_classinfo typeclass
Definition: typeinfo.hpp:236
void typeinfo_print_short(FILE *file, const typeinfo_t *info)
Definition: typeinfo.cpp:2212
void typevector_store(varinfo *vec, int index, Type type, typeinfo_t *info)
Definition: typeinfo.cpp:195
classinfo * pseudo_class_New
Definition: globals.cpp:108
void typevector_store_retaddr(varinfo *vec, int index, typeinfo_t *info)
Definition: typeinfo.cpp:216
jmethodID jint const void jint const jvmtiAddrLocationMap * map
Definition: jvmti.h:338
Additional assertion macros.
void typeinfo_print_class(FILE *file, classref_or_classinfo c)
Definition: typeinfo.cpp:2119
bool is_returnaddress() const
Definition: typeinfo.hpp:385
void typedescriptor_print(FILE *file, const typedescriptor_t *td)
Definition: typeinfo.cpp:2283
static classref_or_classinfo to_classref_or_classinfo(classinfo *c)
Functions for casting a classref/classinfo to a classref_or_classinfo.
Definition: references.hpp:176
#define TYPECHECK_MAYBE
Definition: typeinfo.hpp:78
primitivetypeinfo primitivetype_table[PRIMITIVETYPE_MAX]
Definition: primitive.cpp:59
ArrayType elementtype
Definition: typeinfo.hpp:240
void typeinfo_test()
Definition: typeinfo.cpp:2101
bool typevector_checktype(varinfo *vec, int index, int type)
Definition: typeinfo.cpp:132
bool is_reference() const
Definition: typeinfo.hpp:243
static void clone(const typeinfo_t &src, typeinfo_t &dst)
Definition: typeinfo.hpp:357
void init_java_lang_class(classref_or_classinfo cls)
Initialize object type java.lang.Class.
Definition: typeinfo.hpp:315
varinfo * typevector_copy(varinfo *src, int size)
Definition: typeinfo.cpp:87
typecheck_result
Definition: typeinfo.hpp:81