2008-06-13 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / metadata / class-internals.h
index 945757db3aaf84e816e2f9301e421ff870e51ab4..5ba44b169f0c939bea99e500653e47938d45a62a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <mono/metadata/class.h>
 #include <mono/metadata/object.h>
+#include <mono/metadata/mempool.h>
 #include <mono/io-layer/io-layer.h>
 #include "mono/utils/mono-compiler.h"
 
@@ -12,6 +13,8 @@
 
 extern gboolean mono_print_vtable;
 
+extern gboolean mono_setup_vtable_in_class_init;
+
 typedef void     (*MonoStackWalkImpl) (MonoStackWalk func, gboolean do_il_offset, gpointer user_data);
 
 typedef struct _MonoMethodNormal MonoMethodNormal;
@@ -19,6 +22,13 @@ typedef struct _MonoMethodWrapper MonoMethodWrapper;
 typedef struct _MonoMethodInflated MonoMethodInflated;
 typedef struct _MonoMethodPInvoke MonoMethodPInvoke;
 
+/* Properties that applies to a group of structs should better use a higher number
+ * to avoid colision with type specific properties.
+ * 
+ * This prop applies to class, method, property, event, assembly and image.
+ */
+#define MONO_PROP_DYNAMIC_CATTR 0x1000
+
 typedef enum {
 #define WRAPPER(e,n) MONO_WRAPPER_ ## e,
 #include "wrapper-types.h"
@@ -39,25 +49,33 @@ typedef enum {
        MONO_REMOTING_TARGET_COMINTEROP
 } MonoRemotingTarget;
 
+#define MONO_METHOD_PROP_GENERIC_CONTAINER 0
+
 struct _MonoMethod {
        guint16 flags;  /* method flags */
        guint16 iflags; /* method implementation flags */
        guint32 token;
        MonoClass *klass;
        MonoMethodSignature *signature;
-       MonoGenericContainer *generic_container;
        /* name is useful mostly for debugging */
        const char *name;
        /* this is used by the inlining algorithm */
        unsigned int inline_info:1;
-       unsigned int uses_this:1;
+       unsigned int inline_failure:1;
        unsigned int wrapper_type:5;
        unsigned int string_ctor:1;
        unsigned int save_lmf:1;
        unsigned int dynamic:1; /* created & destroyed during runtime */
+       unsigned int is_generic:1; /* whenever this is a generic method definition */
        unsigned int is_inflated:1; /* whether we're a MonoMethodInflated */
        unsigned int skip_visibility:1; /* whenever to skip JIT visibility checks */
-       signed int slot : 20;
+       unsigned int verification_success:1; /* whether this method has been verified successfully.*/
+       signed int slot : 18;
+
+       /*
+        * If is_generic is TRUE, the generic_container is stored in image->property_hash, 
+        * using the key MONO_METHOD_PROP_GENERIC_CONTAINER.
+        */
 };
 
 struct _MonoMethodNormal {
@@ -171,7 +189,12 @@ enum {
        MONO_EXCEPTION_UNVERIFIABLE_IL = 4,
        MONO_EXCEPTION_MISSING_METHOD = 5,
        MONO_EXCEPTION_MISSING_FIELD = 6,
-       MONO_EXCEPTION_TYPE_LOAD = 7
+       MONO_EXCEPTION_TYPE_LOAD = 7,
+       MONO_EXCEPTION_FILE_NOT_FOUND = 8,
+       MONO_EXCEPTION_METHOD_ACCESS = 9,
+       MONO_EXCEPTION_FIELD_ACCESS = 10,
+       MONO_EXCEPTION_GENERIC_SHARING_FAILED = 11,
+       MONO_EXCEPTION_BAD_IMAGE = 12
        /* add other exception type */
 };
 
@@ -184,18 +207,59 @@ typedef struct {
        MonoVTable *domain_vtables [MONO_ZERO_LEN_ARRAY];
 } MonoClassRuntimeInfo;
 
-struct _MonoClass {
-       MonoImage *image;
+enum {
+       MONO_RGCTX_INFO_STATIC_DATA,
+       MONO_RGCTX_INFO_KLASS,
+       MONO_RGCTX_INFO_VTABLE,
+       MONO_RGCTX_INFO_TYPE,
+       MONO_RGCTX_INFO_REFLECTION_TYPE,
+       MONO_RGCTX_INFO_METHOD,
+       MONO_RGCTX_INFO_GENERIC_METHOD_CODE,
+       MONO_RGCTX_INFO_CLASS_FIELD,
+       MONO_RGCTX_INFO_METHOD_RGCTX
+};
 
-       /* The underlying type of the enum */
-       MonoType *enum_basetype;
+typedef struct _MonoRuntimeGenericContextOtherInfoTemplate {
+       int info_type;
+       gpointer data;
+       struct _MonoRuntimeGenericContextOtherInfoTemplate *next;
+} MonoRuntimeGenericContextOtherInfoTemplate;
+
+typedef struct {
+       MonoClass *next_subclass;
+       MonoRuntimeGenericContextOtherInfoTemplate *other_infos;
+       GSList *method_templates;
+} MonoRuntimeGenericContextTemplate;
+
+typedef struct {
+       MonoVTable *class_vtable; /* must be the first element */
+       MonoGenericInst *method_inst;
+       gpointer infos [MONO_ZERO_LEN_ARRAY];
+} MonoMethodRuntimeGenericContext;
+
+#define MONO_RGCTX_SLOT_MAKE_RGCTX(i)  (i)
+#define MONO_RGCTX_SLOT_MAKE_MRGCTX(i) ((i) | 0x80000000)
+#define MONO_RGCTX_SLOT_INDEX(s)       ((s) & 0x7fffffff)
+#define MONO_RGCTX_SLOT_IS_MRGCTX(s)   (((s) & 0x80000000) ? TRUE : FALSE)
+
+
+#define MONO_CLASS_PROP_EXCEPTION_DATA 0
+
+struct _MonoClass {
        /* element class for arrays and enum */
        MonoClass *element_class; 
        /* used for subtype checks */
        MonoClass *cast_class; 
+
+       /* for fast subtype checks */
+       MonoClass **supertypes;
+       guint16     idepth;
+
        /* array dimension */
        guint8     rank;          
 
+       int        instance_size; /* object instance size */
+
        guint inited          : 1;
        /* We use init_pending to detect cyclic calls to mono_class_init */
        guint init_pending    : 1;
@@ -237,20 +301,25 @@ struct _MonoClass {
        guint is_com_object : 1; 
 
        guint8     exception_type;      /* MONO_EXCEPTION_* */
-       void*      exception_data;      /* Additional information about the exception */
-       guint32    declsec_flags;       /* declarative security attributes flags */
+
+       /* Additional information about the exception */
+       /* Stored as property MONO_CLASS_PROP_EXCEPTION_DATA */
+       //void       *exception_data;
 
        MonoClass  *parent;
        MonoClass  *nested_in;
        GList      *nested_classes;
 
-       guint32    type_token;
+       MonoImage *image;
        const char *name;
        const char *name_space;
-       
-       /* for fast subtype checks */
-       MonoClass **supertypes;
-       guint16     idepth;
+
+       /* The underlying type of the enum */
+       MonoType *enum_basetype;
+
+       guint32    declsec_flags;       /* declarative security attributes flags */
+       guint32    type_token;
+       int        vtable_size; /* number of slots */
 
        guint16     interface_count;
        guint16     interface_id;        /* unique inderface id (for interfaces) */
@@ -263,14 +332,10 @@ struct _MonoClass {
        
        MonoClass **interfaces;
 
-       /*
-        * Computed object instance size, total.
-        */
-       int        instance_size;
-       int        vtable_size; /* number of slots */
        union {
                int class_size; /* size of area for static fields */
                int element_size; /* for array types */
+               int generic_param_token; /* for generic param types, both var and mvar */
        } sizes;
 
        /*
@@ -320,6 +385,8 @@ struct _MonoClass {
 #define MONO_CLASS_IMPLEMENTS_INTERFACE(k,uiid) (((uiid) <= (k)->max_interface_id) && ((k)->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7))))
 int mono_class_interface_offset (MonoClass *klass, MonoClass *itf);
 
+typedef gpointer MonoRuntimeGenericContext;
+
 /* the interface_offsets array is stored in memory before this struct */
 struct MonoVTable {
        MonoClass  *klass;
@@ -337,6 +404,8 @@ struct MonoVTable {
        guint remote          : 1; /* class is remotely activated */
        guint initialized     : 1; /* cctor has been run */
        guint init_failed     : 1; /* cctor execution failed */
+       guint32     imt_collisions_bitmap;
+       MonoRuntimeGenericContext *runtime_generic_context;
        /* do not add any fields after vtable, the structure is dynamically extended */
         gpointer    vtable [MONO_ZERO_LEN_ARRAY];      
 };
@@ -357,7 +426,6 @@ struct _MonoGenericInst {
        guint id;                       /* unique ID for debugging */
        guint type_argc    : 22;        /* number of type arguments */
        guint is_open      :  1;        /* if this is an open type */
-       guint is_reference :  1;        /* if this is a reference type */
        MonoType **type_argv;
 };
 
@@ -386,7 +454,9 @@ struct _MonoMethodInflated {
        } method;
        MonoMethod *declaring;          /* the generic method definition. */
        MonoGenericContext context;     /* The current instantiation */
-       gpointer reflection_info;
+
+       /* TODO we MUST get rid of this field, it's an ugly hack nobody is proud of. */
+       guint is_mb_open : 1;           /* This is the fully open instantiation of a generic method_builder. Worse than is_tb_open, but it's temporary */
 };
 
 /*
@@ -396,6 +466,7 @@ struct _MonoGenericClass {
        MonoClass *container_class;     /* the generic type definition */
        MonoGenericContext context;     /* a context that contains the type instantiation doesn't contain any method instantiation */
        guint is_dynamic  : 1;          /* We're a MonoDynamicGenericClass */
+       guint is_tb_open  : 1;          /* This is the fully open instantiation for a type_builder. Quite ugly, but it's temporary.*/
        MonoClass *cached_class;        /* if present, the MonoClass corresponding to the instantiation.  */
 };
 
@@ -428,8 +499,6 @@ struct _MonoGenericContainer {
        /* If we're a generic method definition in a generic type definition,
           the generic container of the containing class. */
        MonoGenericContainer *parent;
-       /* If we're a generic method definition, caches all their instantiations. */
-       GHashTable *method_hash;
        /* the generic type definition or the generic method definition corresponding to this container */
        union {
                MonoClass *klass;
@@ -453,6 +522,8 @@ struct _MonoGenericParam {
        guint16 flags;
        guint16 num;
        MonoClass** constraints; /* NULL means end of list */
+       /* If owner is NULL, this is the image whose mempool this struct was allocated from */
+       MonoImage *image;
 };
 
 /*
@@ -488,23 +559,14 @@ typedef struct {
        MonoMethodSignature *sig;
 } MonoJitICallInfo;
 
-/*
- * Information about a type load error encountered by the loader.
- */
-typedef enum {
-       MONO_LOADER_ERROR_TYPE,
-       MONO_LOADER_ERROR_METHOD,
-       MONO_LOADER_ERROR_FIELD,
-       MONO_LOADER_ERROR_ASSEMBLY
-} MonoLoaderErrorKind;
-
 typedef struct {
-       MonoLoaderErrorKind kind;
+       guint8 exception_type;
        char *class_name; /* If kind == TYPE */
        char *assembly_name; /* If kind == TYPE or ASSEMBLY */
        MonoClass *klass; /* If kind != TYPE */
        const char *member_name; /* If kind != TYPE */
        gboolean ref_only; /* If kind == ASSEMBLY */
+       char *msg; /* If kind == BAD_IMAGE */
 } MonoLoaderError;
 
 #define mono_class_has_parent(klass,parent) (((klass)->idepth >= (parent)->idepth) && ((klass)->supertypes [(parent)->idepth - 1] == (parent)))
@@ -526,9 +588,44 @@ typedef struct {
        gulong dynamic_code_alloc_count;
        gulong dynamic_code_bytes_count;
        gulong dynamic_code_frees_count;
+       gulong delegate_creations;
+       gulong imt_tables_size;
+       gulong imt_number_of_tables;
+       gulong imt_number_of_methods;
+       gulong imt_used_slots;
+       gulong imt_slots_with_collisions;
+       gulong imt_max_collisions_in_slot;
+       gulong imt_method_count_when_max_collisions;
+       gulong imt_thunks_size;
+       gulong jit_info_table_insert_count;
+       gulong jit_info_table_remove_count;
+       gulong jit_info_table_lookup_count;
+       gulong hazardous_pointer_count;
+       gulong generics_sharable_methods;
+       gulong generics_unsharable_methods;
+       gulong generics_shared_methods;
+       gulong minor_gc_count;
+       gulong major_gc_count;
+       gulong minor_gc_time_usecs;
+       gulong major_gc_time_usecs;
        gboolean enabled;
 } MonoStats;
 
+/* 
+ * new structure to hold performace counters values that are exported
+ * to managed code.
+ * Note: never remove fields from this structure and only add them to the end.
+ * Size of fields and type should not be changed as well.
+ */
+typedef struct {
+       gulong methods_jitted;
+       gulong aspnet_requests_queued;
+} MonoPerfCounters;
+
+extern MonoPerfCounters *mono_perfcounters MONO_INTERNAL;
+
+void mono_perfcounters_init (void);
+
 /*
  * The definition of the first field in SafeHandle,
  * Keep in sync with SafeHandle.cs, this is only used
@@ -547,13 +644,30 @@ typedef struct {
        void       *handle;
 } MonoHandleRef;
 
+enum {
+       MONO_GENERIC_SHARING_NONE,
+       MONO_GENERIC_SHARING_CORLIB,
+       MONO_GENERIC_SHARING_ALL
+};
+
+/*
+ * Flags for which contexts were used in inflating a generic.
+ */
+enum {
+       MONO_GENERIC_CONTEXT_USED_CLASS = 1,
+       MONO_GENERIC_CONTEXT_USED_METHOD = 2
+};
+
+#define MONO_GENERIC_CONTEXT_USED_BOTH         (MONO_GENERIC_CONTEXT_USED_CLASS | MONO_GENERIC_CONTEXT_USED_METHOD)
+
 extern MonoStats mono_stats MONO_INTERNAL;
 
 typedef gpointer (*MonoTrampoline)       (MonoMethod *method);
+typedef gpointer (*MonoJumpTrampoline)       (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
 typedef gpointer (*MonoRemotingTrampoline)       (MonoMethod *method, MonoRemotingTarget target);
 typedef gpointer (*MonoDelegateTrampoline)       (MonoClass *klass);
 
-typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, MonoClass **handle_class);
+typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context);
 
 typedef gboolean (*MonoGetCachedClassInfo) (MonoClass *klass, MonoCachedClassInfo *res);
 
@@ -589,6 +703,9 @@ mono_class_setup_parent    (MonoClass *klass, MonoClass *parent) MONO_INTERNAL;
 void
 mono_class_setup_supertypes (MonoClass *klass) MONO_INTERNAL;
 
+MonoMethod*
+mono_class_get_method_by_index (MonoClass *class, int index) MONO_INTERNAL;
+
 GPtrArray*
 mono_class_get_implemented_interfaces (MonoClass *klass) MONO_INTERNAL;
 
@@ -611,9 +728,15 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller) MONO_INTERNAL;
 gboolean
 mono_class_has_special_static_fields (MonoClass *klass) MONO_INTERNAL;
 
+const char*
+mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_type) MONO_INTERNAL;
+
 void
 mono_install_trampoline (MonoTrampoline func) MONO_INTERNAL;
 
+void
+mono_install_jump_trampoline (MonoJumpTrampoline func) MONO_INTERNAL;
+
 void
 mono_install_remoting_trampoline (MonoRemotingTrampoline func) MONO_INTERNAL;
 
@@ -621,14 +744,20 @@ void
 mono_install_delegate_trampoline (MonoDelegateTrampoline func) MONO_INTERNAL;
 
 gpointer
-mono_lookup_dynamic_token (MonoImage *image, guint32 token) MONO_INTERNAL;
+mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context) MONO_INTERNAL;
 
 gpointer
-mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, MonoClass **handle_class) MONO_INTERNAL;
+mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context) MONO_INTERNAL;
 
 void
 mono_install_lookup_dynamic_token (MonoLookupDynamicToken func) MONO_INTERNAL;
 
+gpointer
+mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper) MONO_INTERNAL;
+
+gpointer
+mono_runtime_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
+
 void
 mono_install_get_cached_class_info (MonoGetCachedClassInfo func) MONO_INTERNAL;
 
@@ -641,15 +770,30 @@ mono_class_get_context (MonoClass *class) MONO_INTERNAL;
 MonoGenericContext*
 mono_method_get_context (MonoMethod *method) MONO_INTERNAL;
 
+/* Used by monodis, thus cannot be MONO_INTERNAL */
+MonoGenericContainer*
+mono_method_get_generic_container (MonoMethod *method);
+
 MonoGenericContext*
 mono_generic_class_get_context (MonoGenericClass *gclass) MONO_INTERNAL;
 
 MonoClass*
 mono_generic_class_get_class (MonoGenericClass *gclass) MONO_INTERNAL;
 
+void
+mono_method_set_generic_container (MonoMethod *method, MonoGenericContainer* container) MONO_INTERNAL;
+
 MonoMethod*
 mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hint, MonoGenericContext *context);
 
+MonoMethodInflated*
+mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache) MONO_INTERNAL;
+
+MonoMethodSignature *
+mono_metadata_get_inflated_signature (MonoMethodSignature *sig, MonoGenericContext *context);
+
+void
+mono_metadata_free_inflated_signature (MonoMethodSignature *sig);
 
 typedef struct {
        MonoImage *corlib;
@@ -744,6 +888,8 @@ mono_loader_set_error_method_load (const char *class_name, const char *member_na
 
 void
 mono_loader_set_error_field_load (MonoClass *klass, const char *member_name) MONO_INTERNAL;
+void
+mono_loader_set_error_bad_image (char *msg) MONO_INTERNAL;
 
 MonoException *
 mono_loader_error_prepare_exception (MonoLoaderError *error) MONO_INTERNAL;
@@ -798,6 +944,9 @@ mono_find_jit_icall_by_addr (gconstpointer addr) MONO_INTERNAL;
 gboolean
 mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data) MONO_INTERNAL;
 
+gpointer
+mono_class_get_exception_data (MonoClass *klass) MONO_INTERNAL;
+
 MonoException*
 mono_class_get_exception_for_failure (MonoClass *klass) MONO_INTERNAL;
 
@@ -807,8 +956,8 @@ mono_type_get_name_full (MonoType *type, MonoTypeNameFormat format) MONO_INTERNA
 char*
 mono_type_get_full_name (MonoClass *class) MONO_INTERNAL;
 
-MonoArrayType *mono_dup_array_type (MonoArrayType *a) MONO_INTERNAL;
-MonoMethodSignature *mono_metadata_signature_deep_dup (MonoMethodSignature *sig) MONO_INTERNAL;
+MonoArrayType *mono_dup_array_type (MonoMemPool *mp, MonoArrayType *a) MONO_INTERNAL;
+MonoMethodSignature *mono_metadata_signature_deep_dup (MonoMemPool *mp, MonoMethodSignature *sig) MONO_INTERNAL;
 
 void
 mono_image_init_name_cache (MonoImage *image);
@@ -822,5 +971,57 @@ void mono_object_describe_fields (MonoObject *obj);
 void mono_value_describe_fields  (MonoClass* klass, const char* addr);
 void mono_class_describe_statics (MonoClass* klass);
 
-#endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */
+/*Enum validation related functions*/
+gboolean
+mono_type_is_valid_enum_basetype (MonoType * type);
+
+gboolean
+mono_class_is_valid_enum (MonoClass *klass);
+
+MonoType *
+mono_type_get_full        (MonoImage *image, guint32 type_token, MonoGenericContext *context) MONO_INTERNAL;
+
+gboolean
+mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL;
+
+MonoMethod*
+mono_method_get_declaring_generic_method (MonoMethod *method) MONO_INTERNAL;
+
+MonoType*
+mono_type_get_basic_type_from_generic (MonoType *type) MONO_INTERNAL;
+
+gboolean
+mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
+
+gpointer
+mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot) MONO_INTERNAL;
 
+gpointer
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot) MONO_INTERNAL;
+
+MonoMethodRuntimeGenericContext*
+mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst) MONO_INTERNAL;
+
+int
+mono_class_rgctx_get_array_size (int n, gboolean mrgctx) MONO_INTERNAL;
+
+guint32
+mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgctx, gpointer data,
+       int info_type, MonoGenericContext *generic_context) MONO_INTERNAL;
+
+int
+mono_generic_context_check_used (MonoGenericContext *context) MONO_INTERNAL;
+
+int
+mono_class_check_context_used (MonoClass *class) MONO_INTERNAL;
+
+void
+mono_class_unregister_image_generic_subclasses (MonoImage *image) MONO_INTERNAL;
+
+gboolean
+mono_method_can_access_method_full (MonoMethod *method, MonoMethod *called, MonoClass *context_klass) MONO_INTERNAL;
+
+gboolean
+mono_method_can_access_field_full (MonoMethod *method, MonoClassField *field, MonoClass *context_klass) MONO_INTERNAL;
+
+#endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */