2 * generic-sharing.c: Support functions for generic sharing.
5 * Mark Probst (mark.probst@gmail.com)
7 * (C) 2007 Novell, Inc.
12 #include <mono/metadata/class.h>
13 #include <mono/utils/mono-counters.h>
18 * mono_get_generic_context_from_code:
20 * Return the runtime generic context belonging to the method whose native code
23 MonoGenericSharingContext
*
24 mono_get_generic_context_from_code (guint8
*code
)
26 MonoJitInfo
*jit_info
= mono_jit_info_table_find (mono_domain_get (), (char*)code
);
30 return mono_jit_info_get_generic_sharing_context (jit_info
);
34 mini_method_get_context (MonoMethod
*method
)
36 return mono_method_get_context_general (method
, TRUE
);
40 * mono_method_check_context_used:
43 * Checks whether the method's generic context uses a type variable.
44 * Returns an int with the bits MONO_GENERIC_CONTEXT_USED_CLASS and
45 * MONO_GENERIC_CONTEXT_USED_METHOD set to reflect whether the
46 * context's class or method instantiation uses type variables.
49 mono_method_check_context_used (MonoMethod
*method
)
51 MonoGenericContext
*method_context
= mini_method_get_context (method
);
54 if (!method_context
) {
55 /* It might be a method of an array of an open generic type */
56 if (method
->klass
->rank
)
57 context_used
= mono_class_check_context_used (method
->klass
);
59 context_used
= mono_generic_context_check_used (method_context
);
60 context_used
|= mono_class_check_context_used (method
->klass
);
67 generic_inst_equal (MonoGenericInst
*inst1
, MonoGenericInst
*inst2
)
78 if (inst1
->type_argc
!= inst2
->type_argc
)
81 for (i
= 0; i
< inst1
->type_argc
; ++i
)
82 if (!mono_metadata_type_equal (inst1
->type_argv
[i
], inst2
->type_argv
[i
]))
89 * mono_generic_context_equal_deep:
90 * @context1: a generic context
91 * @context2: a generic context
93 * Returns whether context1's type arguments are equal to context2's
97 mono_generic_context_equal_deep (MonoGenericContext
*context1
, MonoGenericContext
*context2
)
99 return generic_inst_equal (context1
->class_inst
, context2
->class_inst
) &&
100 generic_inst_equal (context1
->method_inst
, context2
->method_inst
);
104 * mini_class_get_container_class:
105 * @class: a generic class
107 * Returns the class's container class, which is the class itself if
108 * it doesn't have generic_class set.
111 mini_class_get_container_class (MonoClass
*class)
113 if (class->generic_class
)
114 return class->generic_class
->container_class
;
116 g_assert (class->generic_container
);
121 * mini_class_get_context:
122 * @class: a generic class
124 * Returns the class's generic context.
127 mini_class_get_context (MonoClass
*class)
129 if (class->generic_class
)
130 return &class->generic_class
->context
;
132 g_assert (class->generic_container
);
133 return &class->generic_container
->context
;
137 * mini_get_basic_type_from_generic:
138 * @gsctx: a generic sharing context
141 * Returns a closed type corresponding to the possibly open type
145 mini_get_basic_type_from_generic (MonoGenericSharingContext
*gsctx
, MonoType
*type
)
147 if (!type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
))
150 return mono_type_get_basic_type_from_generic (type
);
154 * mini_type_get_underlying_type:
156 * Return the underlying type of TYPE, taking into account enums and generic
160 mini_type_get_underlying_type (MonoGenericSharingContext
*gsctx
, MonoType
*type
)
162 return mono_type_get_basic_type_from_generic (mono_type_get_underlying_type (type
));
166 * mini_type_stack_size:
167 * @gsctx: a generic sharing context
169 * @align: Pointer to an int for returning the alignment
171 * Returns the type's stack size and the alignment in *align. The
172 * type is allowed to be open.
175 mini_type_stack_size (MonoGenericSharingContext
*gsctx
, MonoType
*t
, int *align
)
177 gboolean allow_open
= TRUE
;
179 // FIXME: Some callers might not pass in a gsctx
180 //allow_open = gsctx != NULL;
181 return mono_type_stack_size_internal (t
, align
, allow_open
);
185 * mini_type_stack_size_full:
187 * Same as mini_type_stack_size, but handle pinvoke data types as well.
190 mini_type_stack_size_full (MonoGenericSharingContext
*gsctx
, MonoType
*t
, guint32
*align
, gboolean pinvoke
)
195 size
= mono_type_native_stack_size (t
, align
);
200 size
= mini_type_stack_size (gsctx
, t
, &ialign
);
203 size
= mini_type_stack_size (gsctx
, t
, NULL
);
211 * mono_generic_sharing_init:
213 * Register the generic sharing counters.
216 mono_generic_sharing_init (void)