LCOV - code coverage report
Current view: top level - vm/jit/verify - typeinfo.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 70 94.3 %
Date: 2015-06-10 18:10:59 Functions: 21 24 87.5 %

          Line data    Source code
       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;
      39             : struct typeinfo_mergedlist_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             : 
      81             : enum typecheck_result {
      82             :         typecheck_FALSE = false,
      83             :         typecheck_TRUE  = true,
      84             :         typecheck_MAYBE = TYPECHECK_MAYBE,
      85             :         typecheck_FAIL  = TYPECHECK_FAIL
      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             : 
     233             : void typeinfo_init_classinfo(typeinfo_t *info,classinfo *c);
     234             : 
     235             : struct typeinfo_t {
     236             :         classref_or_classinfo  typeclass;
     237             :         classref_or_classinfo  elementclass; // valid if dimension>0 (various uses!)
     238             :         typeinfo_mergedlist_t *merged;
     239             :         u1                     dimension;
     240             :         ArrayType              elementtype;  // valid if dimension>0
     241             : 
     242     2882340 :         bool is_primitive() const { return typeclass.any == NULL; }
     243      900630 :         bool is_reference() const { return typeclass.any != NULL; }
     244             : 
     245      844196 :         bool is_nulltype()  const { return typeclass.cls == pseudo_class_Null;     }
     246     2520103 :         bool is_newobject() const { return typeclass.cls == pseudo_class_New;      }
     247             : 
     248           0 :         void *returnaddress() const {
     249             :                 EXPENSIVE_ASSERT(is_primitive());
     250             : 
     251           0 :                 return elementclass.any;
     252             :         }
     253             : 
     254      225166 :         instruction *newobject_instruction() const {
     255             :                 EXPENSIVE_ASSERT(is_newobject());
     256             : 
     257      225166 :                 return (instruction*) elementclass.any;
     258             :         }
     259             : 
     260      282723 :         bool is_array()        const { return is_reference() && dimension != 0; }
     261      521032 :         bool is_simple_array() const { return dimension == 1; }
     262             : 
     263      521032 :         bool is_primitive_array(ArrayType at) const {
     264      521032 :                 return is_simple_array() && elementtype == at;
     265             :         }
     266       85850 :         bool is_array_of_refs() const {
     267       85850 :                 return is_array() && (elementclass.any != NULL || dimension >= 2);
     268             :         }
     269             : 
     270             :         // queries allowing the null type
     271             : 
     272        9830 :         bool maybe_array() const {
     273        9830 :                 return is_array() || is_nulltype();
     274             :         }
     275             : 
     276      521032 :         bool maybe_primitive_array(ArrayType at) const {
     277      521032 :                 return is_primitive_array(at) || is_nulltype();
     278             :         }
     279             : 
     280       85850 :         bool maybe_array_of_refs() const {
     281       85850 :                 return is_array_of_refs() || is_nulltype();
     282             :         }
     283             : 
     284             :         // Check if `this' type is assignable to a given destination type.
     285             :         typecheck_result is_assignable_to(typeinfo_t *dest) const;
     286             :         typecheck_result is_assignable_to_class(classref_or_classinfo dest) const;
     287             : 
     288             :         // initializing typeinfo structures
     289             : 
     290      136016 :         void init_primitive() {
     291      136016 :                 typeclass.any    = NULL;
     292      136016 :                 elementclass.any = NULL;
     293      136016 :                 merged           = NULL;
     294      136016 :                 dimension        = 0;
     295      136016 :                 elementtype      = ARRAYTYPE_INT;
     296      136016 :         }
     297             : 
     298          18 :         void init_returnaddress(void *adr) {
     299          18 :                 typeclass.any    = NULL;
     300          18 :                 elementclass.any = adr;
     301          18 :                 merged           = NULL;
     302          18 :                 dimension        = 0;
     303          18 :                 elementtype      = ARRAYTYPE_INT;
     304          18 :         }
     305             : 
     306       16910 :         void init_non_array_classinfo(classinfo *cls) {
     307       16910 :                 typeclass.cls    = cls;
     308       16910 :                 elementclass.any = NULL;
     309       16910 :                 merged           = NULL;
     310       16910 :                 dimension        = 0;
     311       16910 :                 elementtype      = ARRAYTYPE_INT;
     312       16910 :         }
     313             : 
     314             :         /// Initialize object type java.lang.Class
     315       64184 :         void init_java_lang_class(classref_or_classinfo cls) {
     316       64184 :                 typeclass.cls    = class_java_lang_Class;
     317       64184 :                 elementclass     = cls;
     318       64184 :                 merged           = NULL;
     319       64184 :                 dimension        = 0;
     320       64184 :                 elementtype      = ARRAYTYPE_INT;
     321       64184 :         }
     322             : 
     323             :         /// Initialize object type
     324             :         void init_class(classinfo *c);
     325             :         bool init_class(classref_or_classinfo c);
     326             : 
     327      305647 :         bool init_class(constant_classref *c) {
     328      305647 :                 return init_class(to_classref_or_classinfo(c));
     329             :         }
     330             : 
     331             :         bool init_component(const typeinfo_t& srcarray);
     332             : 
     333             :         bool init_from_typedesc(const typedesc *desc, u1 *type);
     334             : 
     335       16910 :         void init_nulltype() {
     336       16910 :                 init_non_array_classinfo(pseudo_class_Null);
     337       16910 :         }
     338             : 
     339       78467 :         void init_newobject(instruction *instr) {
     340       78467 :                 typeclass.cls    = pseudo_class_New;
     341       78467 :                 elementclass.any = instr;
     342       78467 :                 merged           = NULL;
     343       78467 :                 dimension        = 0;
     344       78467 :                 elementtype      = ARRAYTYPE_INT;
     345       78467 :         }
     346             : 
     347        5937 :         void init_primitive_array(ArrayType arraytype) {
     348        5937 :                 init_class(primitivetype_table[arraytype].arrayclass);
     349        5937 :         }
     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       15380 :         static void clone(const typeinfo_t& src, typeinfo_t& dst) {
     358       15380 :                 dst = src;
     359             : 
     360       15380 :                 if (dst.merged)
     361        2268 :                         clone_merged(src, dst);
     362       15380 :         }
     363             : 
     364             :         /// functions for merging types
     365             : 
     366             :         typecheck_result merge(methodinfo *m, const typeinfo_t* t);
     367             : private:
     368             :         static void clone_merged(const typeinfo_t& src, typeinfo_t& dst);
     369             : };
     370             : 
     371             : 
     372             : struct typeinfo_mergedlist_t {
     373             :         s4                    count;
     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             : 
     381             : struct typedescriptor_t {
     382             :         typeinfo_t      typeinfo; /* valid if type == TYPE_ADR               */
     383             :         Type            type;     /* basic type (TYPE_INT, ...)              */
     384             : 
     385           0 :         bool is_returnaddress() const { return type == TYPE_RET && typeinfo.is_primitive(); }
     386           0 :         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);
     421             : bool typevector_checkreference(varinfo *set,int index);
     422             : bool typevector_checkretaddr(varinfo *set,int index);
     423             : 
     424             : /* element write access */
     425             : void typevector_store(varinfo *set,int index, Type type,typeinfo_t *info);
     426             : void typevector_store_retaddr(varinfo *set,int index,typeinfo_t *info);
     427             : bool typevector_init_object(varinfo *set,void *ins,classref_or_classinfo initclass,int size);
     428             : 
     429             : /* vector functions */
     430             : varinfo         *typevector_copy(varinfo *src,int size);
     431             : void             typevector_copy_inplace(varinfo *src,varinfo *dst,int size);
     432             : typecheck_result typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,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             :  */
     444             : int  typedescriptors_init_from_methoddesc(typedescriptor_t *td,
     445             :                                                                                   methoddesc *desc,
     446             :                                                                                   int buflen,bool twoword,int startindex,
     447             :                                                                                   typedescriptor_t *returntype);
     448             : bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
     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             :  */

Generated by: LCOV version 1.11