return class1;
}
-static int
-count_fields_nested (MonoClass *klass, gboolean pinvoke)
-{
- MonoMarshalType *info;
- int i, count;
-
- count = 0;
- if (pinvoke) {
- info = mono_marshal_load_type_info (klass);
- g_assert(info);
- for (i = 0; i < info->num_fields; ++i) {
- if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type))
- count += count_fields_nested (mono_class_from_mono_type (info->fields [i].field->type), pinvoke);
- else
- count ++;
- }
- } else {
- gpointer iter;
- MonoClassField *field;
-
- iter = NULL;
- while ((field = mono_class_get_fields (klass, &iter))) {
- if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
- continue;
- if (MONO_TYPE_ISSTRUCT (field->type))
- count += count_fields_nested (mono_class_from_mono_type (field->type), pinvoke);
- else
- count ++;
- }
- }
- return count;
-}
-
typedef struct {
MonoType *type;
int size, offset;
*
* Collect field info from KLASS recursively into FIELDS.
*/
-static int
-collect_field_info_nested (MonoClass *klass, StructFieldInfo *fields, int index, int offset, gboolean pinvoke, gboolean unicode)
+static void
+collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, gboolean pinvoke, gboolean unicode)
{
MonoMarshalType *info;
int i;
g_assert(info);
for (i = 0; i < info->num_fields; ++i) {
if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) {
- index = collect_field_info_nested (mono_class_from_mono_type (info->fields [i].field->type), fields, index, info->fields [i].offset, pinvoke, unicode);
+ collect_field_info_nested (mono_class_from_mono_type (info->fields [i].field->type), fields_array, info->fields [i].offset, pinvoke, unicode);
} else {
guint32 align;
+ StructFieldInfo f;
- fields [index].type = info->fields [i].field->type;
- fields [index].size = mono_marshal_type_size (info->fields [i].field->type,
+ f.type = info->fields [i].field->type;
+ f.size = mono_marshal_type_size (info->fields [i].field->type,
info->fields [i].mspec,
&align, TRUE, unicode);
- fields [index].offset = offset + info->fields [i].offset;
- if (i == info->num_fields - 1 && fields [index].size + fields [index].offset < info->native_size) {
+ f.offset = offset + info->fields [i].offset;
+ if (i == info->num_fields - 1 && f.size + f.offset < info->native_size) {
/* This can happen with .pack directives eg. 'fixed' arrays */
- fields [index].size = info->native_size - fields [index].offset;
+ if (MONO_TYPE_IS_PRIMITIVE (f.type)) {
+ /* Replicate the last field to fill out the remaining place, since the code in add_valuetype () needs type information */
+ g_array_append_val (fields_array, f);
+ while (f.size + f.offset < info->native_size) {
+ f.offset += f.size;
+ g_array_append_val (fields_array, f);
+ }
+ } else {
+ f.size = info->native_size - f.offset;
+ g_array_append_val (fields_array, f);
+ }
+ } else {
+ g_array_append_val (fields_array, f);
}
- index ++;
}
}
} else {
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
continue;
if (MONO_TYPE_ISSTRUCT (field->type)) {
- index = collect_field_info_nested (mono_class_from_mono_type (field->type), fields, index, field->offset - sizeof (MonoObject), pinvoke, unicode);
+ collect_field_info_nested (mono_class_from_mono_type (field->type), fields_array, field->offset - sizeof (MonoObject), pinvoke, unicode);
} else {
int align;
+ StructFieldInfo f;
+
+ f.type = field->type;
+ f.size = mono_type_size (field->type, &align);
+ f.offset = field->offset - sizeof (MonoObject) + offset;
- fields [index].type = field->type;
- fields [index].size = mono_type_size (field->type, &align);
- fields [index].offset = field->offset - sizeof (MonoObject) + offset;
- index ++;
+ g_array_append_val (fields_array, f);
}
}
}
- return index;
}
#ifdef TARGET_WIN32
#define MONO_WIN64_VALUE_TYPE_FITS_REG(arg_size) (arg_size <= SIZEOF_REGISTER && (arg_size == 1 || arg_size == 2 || arg_size == 4 || arg_size == 8))
static gboolean
-allocate_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, AMD64_Reg_No int_regs [], int int_reg_count, AMD64_Reg_No float_regs [], int float_reg_count, guint32 *current_int_reg, guint32 *current_float_reg)
+allocate_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, AMD64_Reg_No int_regs [], int int_reg_count, AMD64_XMM_Reg_No float_regs [], int float_reg_count, guint32 *current_int_reg, guint32 *current_float_reg)
{
gboolean result = FALSE;
return result;
}
-inline gboolean
+static inline gboolean
allocate_parameter_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, guint32 *current_int_reg, guint32 *current_float_reg)
{
return allocate_register_for_valuetype_win64 (arg_info, arg_class, arg_size, param_regs, PARAM_REGS, float_param_regs, FLOAT_PARAM_REGS, current_int_reg, current_float_reg);
}
-inline gboolean
+static inline gboolean
allocate_return_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, guint32 *current_int_reg, guint32 *current_float_reg)
{
return allocate_register_for_valuetype_win64 (arg_info, arg_class, arg_size, return_regs, RETURN_REGS, float_return_regs, FLOAT_RETURN_REGS, current_int_reg, current_float_reg);
guint32 quadsize [2] = {8, 8};
ArgumentClass args [2];
StructFieldInfo *fields = NULL;
+ GArray *fields_array;
MonoClass *klass;
gboolean pass_on_stack = FALSE;
int struct_size;
* Collect field information recursively to be able to
* handle nested structures.
*/
- nfields = count_fields_nested (klass, sig->pinvoke);
- fields = g_new0 (StructFieldInfo, nfields);
- collect_field_info_nested (klass, fields, 0, 0, sig->pinvoke, klass->unicode);
+ fields_array = g_array_new (FALSE, TRUE, sizeof (StructFieldInfo));
+ collect_field_info_nested (klass, fields_array, 0, sig->pinvoke, klass->unicode);
+ fields = (StructFieldInfo*)fields_array->data;
+ nfields = fields_array->len;
for (i = 0; i < nfields; ++i) {
if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) {
if (!is_return)
ainfo->arg_size = ALIGN_TO (size, 8);
- g_free (fields);
+ g_array_free (fields_array, TRUE);
return;
}
if (!is_return)
ainfo->arg_size = ALIGN_TO (struct_size, 8);
- g_free (fields);
+ g_array_free (fields_array, TRUE);
return;
}
}
}
- g_free (fields);
+ g_array_free (fields_array, TRUE);
/* Post merger cleanup */
if ((args [0] == ARG_CLASS_MEMORY) || (args [1] == ARG_CLASS_MEMORY))
* LOCKING: called with the domain lock held
*/
gpointer
-mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
+mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
gpointer fail_tramp)
{
int i;
size += item->chunk_size;
}
if (fail_tramp)
- code = (guint8 *)mono_method_alloc_generic_virtual_thunk (domain, size);
+ code = (guint8 *)mono_method_alloc_generic_virtual_trampoline (domain, size);
else
code = (guint8 *)mono_domain_code_reserve (domain, size);
start = code;
}
if (!fail_tramp)
- mono_stats.imt_thunks_size += code - start;
+ mono_stats.imt_trampolines_size += code - start;
g_assert (code - start <= size);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);