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:
37 * Returns the generic context of a method or NULL if it doesn't have
38 * one. For an inflated method that's the context stored in the
39 * method. Otherwise it's in the method's generic container or in the
40 * generic container of the method's class.
43 mini_method_get_context (MonoMethod *method)
45 if (method->is_inflated)
46 return mono_method_get_context (method);
47 if (method->is_generic)
48 return &(mono_method_get_generic_container (method)->context);
49 if (method->klass->generic_container)
50 return &method->klass->generic_container->context;
55 * mono_method_check_context_used:
58 * Checks whether the method's generic context uses a type variable.
59 * Returns an int with the bits MONO_GENERIC_CONTEXT_USED_CLASS and
60 * MONO_GENERIC_CONTEXT_USED_METHOD set to reflect whether the
61 * context's class or method instantiation uses type variables.
64 mono_method_check_context_used (MonoMethod *method)
66 MonoGenericContext *method_context = mini_method_get_context (method);
69 if (!method_context) {
70 /* It might be a method of an array of an open generic type */
71 if (method->klass->rank)
72 context_used = mono_class_check_context_used (method->klass);
74 context_used = mono_generic_context_check_used (method_context);
75 context_used |= mono_class_check_context_used (method->klass);
82 generic_inst_equal (MonoGenericInst *inst1, MonoGenericInst *inst2)
93 if (inst1->type_argc != inst2->type_argc)
96 for (i = 0; i < inst1->type_argc; ++i)
97 if (!mono_metadata_type_equal (inst1->type_argv [i], inst2->type_argv [i]))
104 * mono_generic_context_equal_deep:
105 * @context1: a generic context
106 * @context2: a generic context
108 * Returns whether context1's type arguments are equal to context2's
112 mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContext *context2)
114 return generic_inst_equal (context1->class_inst, context2->class_inst) &&
115 generic_inst_equal (context1->method_inst, context2->method_inst);
119 * mini_class_get_container_class:
120 * @class: a generic class
122 * Returns the class's container class, which is the class itself if
123 * it doesn't have generic_class set.
126 mini_class_get_container_class (MonoClass *class)
128 if (class->generic_class)
129 return class->generic_class->container_class;
131 g_assert (class->generic_container);
136 * mini_class_get_context:
137 * @class: a generic class
139 * Returns the class's generic context.
142 mini_class_get_context (MonoClass *class)
144 if (class->generic_class)
145 return &class->generic_class->context;
147 g_assert (class->generic_container);
148 return &class->generic_container->context;
152 * mini_get_basic_type_from_generic:
153 * @gsctx: a generic sharing context
156 * Returns a closed type corresponding to the possibly open type
160 mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type)
162 if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR))
165 return mono_type_get_basic_type_from_generic (type);
169 * mini_type_get_underlying_type:
171 * Return the underlying type of TYPE, taking into account enums and generic
175 mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type)
177 return mono_type_get_basic_type_from_generic (mono_type_get_underlying_type (type));
181 * mini_type_stack_size:
182 * @gsctx: a generic sharing context
184 * @align: Pointer to an int for returning the alignment
186 * Returns the type's stack size and the alignment in *align. The
187 * type is allowed to be open.
190 mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align)
192 gboolean allow_open = TRUE;
194 // FIXME: Some callers might not pass in a gsctx
195 //allow_open = gsctx != NULL;
196 return mono_type_stack_size_internal (t, align, allow_open);
200 * mini_type_stack_size_full:
202 * Same as mini_type_stack_size, but handle pinvoke data types as well.
205 mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke)
210 size = mono_type_native_stack_size (t, align);
215 size = mini_type_stack_size (gsctx, t, &ialign);
218 size = mini_type_stack_size (gsctx, t, NULL);
226 * mono_generic_sharing_init:
228 * Register the generic sharing counters.
231 mono_generic_sharing_init (void)