+2007-10-11 Mark Probst <mark.probst@gmail.com>
+
+ * metadata.c, metadata-internals.h: Generalized
+ mono_type_stack_size() to mono_type_stack_size_internal() which
+ takes an additional argument specifying whether it allows open
+ types.
+
2007-10-10 Rodrigo Kumpera <rkumpera@novell.com>
* verify.c (do_invoke_method): handle typedbyref params
MonoGenericInst *
mono_get_shared_generic_inst (MonoGenericContainer *container) MONO_INTERNAL;
+int
+mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open) MONO_INTERNAL;
+
#endif /* __MONO_METADATA_INTERNALS_H__ */
*/
int
mono_type_stack_size (MonoType *t, int *align)
+{
+ return mono_type_stack_size_internal (t, align, FALSE);
+}
+
+int
+mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
{
int tmp;
guint32 size;
if (t->data.klass->enumtype)
- return mono_type_stack_size (t->data.klass->enum_basetype, align);
+ return mono_type_stack_size_internal (t->data.klass->enum_basetype, align, allow_open);
else {
size = mono_class_value_size (t->data.klass, (guint32*)align);
MonoGenericClass *gclass = t->data.generic_class;
MonoClass *container_class = gclass->container_class;
- g_assert (!gclass->context.class_inst->is_open);
+ if (!allow_open)
+ g_assert (!gclass->context.class_inst->is_open);
if (container_class->valuetype) {
if (container_class->enumtype)
- return mono_type_stack_size (container_class->enum_basetype, align);
+ return mono_type_stack_size_internal (container_class->enum_basetype, align, allow_open);
else {
guint32 size = mono_class_value_size (mono_class_from_mono_type (t), (guint32*)align);
+2007-10-11 Mark Probst <mark.probst@gmail.com>
+
+ * mini.h, mini.c: Introduced the MonoGenericSharingContext, which
+ replaces the generic_shared flag and will carry more information
+ in the future.
+
+ * generic-sharing.c: Added mini_type_stack_size() which allows
+ allows open types if given a generic sharing context.
+ mini_get_basic_type_from_generic() takes a
+ MonoGenericSharingContext* instead of a MonoCompile* now.
+
+ * mini-alpha.c, mini-amd64.c, mini-arm.c, mini-hppa.c,
+ mini-ia64.c, mini-mips.c, mini-ppc.c, mini-s390.c, mini-s390x.c,
+ mini-sparc.c, mini-x86.c: Trivial changes required by the two
+ changes above. Just passing arguments through to the right
+ places.
Wed Oct 10 19:44:42 CEST 2007 Paolo Molaro <lupus@ximian.com>
}
MonoType*
-mini_get_basic_type_from_generic (MonoCompile *cfg, MonoType *type)
+mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type)
{
if (!type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
/* FIXME: we support sharing only of reference types */
- g_assert (cfg->generic_shared);
+ g_assert (gsctx);
return &mono_defaults.object_class->byval_arg;
}
return type;
}
+
+int
+mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align)
+{
+ return mono_type_stack_size_internal (t, align, gsctx != NULL);
+}
ArgInfo args [1];
} CallInfo;
-static CallInfo* get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke);
+static CallInfo* get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke);
static unsigned int *emit_call(MonoCompile *cfg, unsigned int *code,
guint32 patch_type, gconstpointer data);
}
static void
-add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *ctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
else if (sig->pinvoke)
size = mono_type_native_stack_size (&klass->byval_arg, NULL);
else
- size = mono_type_stack_size (&klass->byval_arg, NULL);
+ size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
if (!sig->pinvoke || (size == 0) || is_return) {
/* Allways pass in memory */
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
if (cinfo->ret.storage == ArgValuetypeInReg)
cfg->ret_var_is_local = TRUE;
sig = mono_method_signature (method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
if (sig->ret->type != MONO_TYPE_VOID) {
if ((cinfo->ret.storage == ArgInIReg) &&
offset = cfg->arch.args_save_area_offset;
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
if (sig->ret->type != MONO_TYPE_VOID)
{
MonoJitArgumentInfo *arg_info)
{
int k;
- CallInfo *cinfo = get_call_info (csig, FALSE);
+ CallInfo *cinfo = get_call_info (NULL, csig, FALSE);
guint32 args_size = cinfo->stack_usage;
ALPHA_DEBUG("mono_arch_get_argument_info");
int this_reg, int this_type, int vt_reg)
{
MonoCallInst *call = (MonoCallInst*)inst;
- CallInfo * cinfo = get_call_info (inst->signature, FALSE);
+ CallInfo * cinfo = get_call_info (cfg->generic_sharing_context, inst->signature, FALSE);
CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_this_vret_args");
* For x86 win32, see ???.
*/
static CallInfo*
-get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke)
{
guint32 i, gr, fr, *pgr, *pfr;
MonoType *ret_type;
{
guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
- add_valuetype (sig, &cinfo->ret, sig->ret, TRUE,
+ add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE,
&tmp_gr, &tmp_fr, &tmp_stacksize);
if (cinfo->ret.storage == ArgOnStack)
case MONO_TYPE_VALUETYPE:
/* FIXME: */
/* We allways pass valuetypes on the stack */
- add_valuetype (sig, ainfo, sig->params [i],
+ add_valuetype (gsctx, sig, ainfo, sig->params [i],
FALSE, pgr, pfr, &stack_size);
break;
case MONO_TYPE_TYPEDBYREF:
n = sig->param_count + sig->hasthis;
// Collect info about method we age going to call
- cinfo = get_call_info (sig, sig->pinvoke);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, sig->pinvoke);
CFG_DEBUG(3) g_print("ALPHA: Will call %s method with %d(%d) params. RetType: %s(0x%X)\n",
sig->pinvoke ? "PInvoke" : "Managed",
size = mono_type_native_stack_size (&in->klass->byval_arg,
&align);
else
- size = mono_type_stack_size (&in->klass->byval_arg, &align);
+ size = mini_type_stack_size (cfg->generic_sharing_context, &in->klass->byval_arg, &align);
if (ainfo->storage == ArgAggregate)
{
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
for (i = 0; i < sig->param_count + sig->hasthis; ++i)
{
/* Allocate a new area on the stack and save arguments there */
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
n = sig->param_count + sig->hasthis;
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
/* if (cfg->arch.omit_fp) {
cfg->flags |= MONO_CFG_HAS_SPILLUP;
}
static void
-add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
if (sig->pinvoke)
size = mono_type_native_stack_size (&klass->byval_arg, NULL);
else
- size = mono_type_stack_size (&klass->byval_arg, NULL);
+ size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
if (!sig->pinvoke || (size == 0) || (size > 16)) {
/* Allways pass in memory */
int n = sig->hasthis + sig->param_count;
guint32 stack_size = 0;
CallInfo *cinfo;
+ MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
if (mp)
cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
/* return value */
{
ret_type = mono_type_get_underlying_type (sig->ret);
- ret_type = mini_get_basic_type_from_generic (cfg, ret_type);
+ ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
switch (ret_type->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_VALUETYPE: {
guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
- add_valuetype (sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+ add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
if (cinfo->ret.storage == ArgOnStack)
/* The caller passes the address where the value is stored */
add_general (&gr, &stack_size, &cinfo->ret);
continue;
}
ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (cfg, ptype);
+ ptype = mini_get_basic_type_from_generic (gsctx, ptype);
switch (ptype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
}
/* fall through */
case MONO_TYPE_VALUETYPE:
- add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+ add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
break;
case MONO_TYPE_TYPEDBYREF:
stack_size += sizeof (MonoTypedRef);
size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
else {
/*
- * Other backends use mono_type_stack_size (), but that
+ * Other backends use mini_type_stack_size (), but that
* aligns the size to 8, which is larger than the size of
* the source, leading to reads of invalid memory if the
* source is at the end of address space.
if (csig->pinvoke)
size = mono_type_native_stack_size (csig->params [k], &align);
else
- size = mono_type_stack_size (csig->params [k], &align);
+ size = mini_type_stack_size (NULL, csig->params [k], &align);
/* ignore alignment for now */
align = 1;
if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype) && inst->inst_vtype->type != MONO_TYPE_TYPEDBYREF)
size = mono_class_native_size (inst->inst_vtype->data.klass, &align);
else
- size = mono_type_stack_size (inst->inst_vtype, &align);
+ size = mini_type_stack_size (cfg->generic_sharing_context, inst->inst_vtype, &align);
/*
* This is needed since structures containing doubles must be doubleword
}
static void
-add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
else if (sig->pinvoke)
size = mono_type_native_stack_size (&klass->byval_arg, NULL);
else
- size = mono_type_stack_size (&klass->byval_arg, NULL);
+ size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
if (!sig->pinvoke || (size == 0)) {
/* Allways pass in memory */
* Gude" document for more information.
*/
static CallInfo*
-get_call_info (MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke)
{
guint32 i, gr, fr;
MonoType *ret_type;
case MONO_TYPE_TYPEDBYREF: {
guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
- add_valuetype (sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+ add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
if (cinfo->ret.storage == ArgOnStack)
/* The caller passes the address where the value is stored */
add_general (&gr, &stack_size, &cinfo->ret);
case MONO_TYPE_TYPEDBYREF:
/* FIXME: */
/* We allways pass valuetypes on the stack */
- add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+ add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
break;
case MONO_TYPE_U8:
case MONO_TYPE_I8:
mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
{
int k;
- CallInfo *cinfo = get_call_info (csig, FALSE);
+ CallInfo *cinfo = get_call_info (NULL, csig, FALSE);
guint32 args_size = cinfo->stack_usage;
/* The arguments are saved to a stack area in mono_arch_instrument_prolog */
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
MonoInst *ins = cfg->args [i];
/* Already done */
return;
- cinfo = get_call_info (mono_method_signature (cfg->method), FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, mono_method_signature (cfg->method), FALSE);
header = mono_method_get_header (cfg->method);
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
/*
* Determine whenever the frame pointer can be eliminated.
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
if (cinfo->ret.storage == ArgAggregate)
cfg->ret_var_is_local = TRUE;
sig = call->signature;
n = sig->param_count + sig->hasthis;
- cinfo = get_call_info (sig, sig->pinvoke);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, sig->pinvoke);
if (cinfo->ret.storage == ArgAggregate) {
/* The code in emit_this_vret_arg needs a local */
size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
else {
/*
- * Other backends use mono_type_stack_size (), but that
+ * Other backends use mini_type_stack_size (), but that
* aligns the size to 8, which is larger than the size of
* the source, leading to reads of invalid memory if the
* source is at the end of address space.
sig = mono_method_signature (method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
/* This is the opposite of the code in emit_prolog */
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
case OP_VCALL_MEMBASE: {
ArgStorage storage;
- cinfo = get_call_info (((MonoCallInst*)ins)->signature, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, ((MonoCallInst*)ins)->signature, FALSE);
storage = cinfo->ret.storage;
if (storage == ArgAggregate) {
sig = mono_method_signature (method);
pos = 0;
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
cfg->code_size = MAX (((MonoMethodNormal *)method)->header->code_size * 4, 512);
}
/* Load returned vtypes into registers if needed */
- cinfo = get_call_info (mono_method_signature (method), FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, mono_method_signature (method), FALSE);
ainfo = &cinfo->ret;
switch (ainfo->storage) {
case ArgAggregate:
/* Allocate a new area on the stack and save arguments there */
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
n = sig->param_count + sig->hasthis;
ia64_codegen_init (code, p);
- cinfo = get_call_info (sig, FALSE);
+ cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE);
/* Save return value + pass it to func */
switch (cinfo->ret.storage) {
int out_reg = cfg->arch.reg_out0;
if (vt_reg != -1) {
- CallInfo * cinfo = get_call_info (inst->signature, FALSE);
+ CallInfo * cinfo = get_call_info (cfg->generic_sharing_context, inst->signature, FALSE);
MonoInst *vtarg;
if (cinfo->ret.storage == ArgAggregate) {
if (csig->pinvoke)
size = mono_type_native_stack_size (csig->params [k], &align);
else
- size = mono_type_stack_size (csig->params [k], &align);
+ size = mini_type_stack_size (NULL, csig->params [k], &align);
/* ignore alignment for now */
align = 1;
if (csig->pinvoke)
size = mono_type_native_stack_size (csig->params [k], &align);
else
- size = mono_type_stack_size (csig->params [k], &align);
+ size = mini_type_stack_size (NULL, csig->params [k], &align);
/* ignore alignment for now */
align = 1;
if (csig->pinvoke)
size = mono_type_native_stack_size (csig->params [k], &align);
else
- size = mono_type_stack_size (csig->params [k], &align);
+ size = mini_type_stack_size (NULL, csig->params [k], &align);
frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
arg_info [k].pad = pad;
if (csig->pinvoke)
size = mono_type_native_stack_size (csig->params [k], &align);
else
- size = mono_type_stack_size (csig->params [k], &align);
+ size = mini_type_stack_size (NULL, csig->params [k], &align);
frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
arg_info [k].pad = pad;
if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype) && inst->inst_vtype->type != MONO_TYPE_TYPEDBYREF)
size = mono_class_native_size (inst->inst_vtype->data.klass, &align);
else
- size = mono_type_stack_size (inst->inst_vtype, &align);
+ size = mini_type_stack_size (m->generic_sharing_context, inst->inst_vtype, &align);
/*
* This is needed since structures containing doubles must be doubleword
size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
else {
/*
- * Can't use mono_type_stack_size (), but that
+ * Can't use mini_type_stack_size (), but that
* aligns the size to sizeof (gpointer), which is larger
* than the size of the source, leading to reads of invalid
* memory if the source is at the end of address space or
}
static guint32*
-emit_vret_token (MonoInst *ins, guint32 *code)
+emit_vret_token (MonoGenericSharingContext *gsctx, MonoInst *ins, guint32 *code)
{
MonoCallInst *call = (MonoCallInst*)ins;
guint32 size;
*/
if (call->signature->pinvoke && MONO_TYPE_ISSTRUCT(call->signature->ret)) {
if (call->signature->ret->type == MONO_TYPE_TYPEDBYREF)
- size = mono_type_stack_size (call->signature->ret, NULL);
+ size = mini_type_stack_size (gsctx, call->signature->ret, NULL);
else
size = mono_class_native_size (call->signature->ret->data.klass, NULL);
sparc_unimp (code, size & 0xfff);
else
code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr);
- code = emit_vret_token (ins, code);
+ code = emit_vret_token (cfg->generic_sharing_context, ins, code);
code = emit_move_return_value (ins, code);
break;
case OP_FCALL_REG:
else
sparc_nop (code);
- code = emit_vret_token (ins, code);
+ code = emit_vret_token (cfg->generic_sharing_context, ins, code);
code = emit_move_return_value (ins, code);
break;
case OP_FCALL_MEMBASE:
else
sparc_nop (code);
- code = emit_vret_token (ins, code);
+ code = emit_vret_token (cfg->generic_sharing_context, ins, code);
code = emit_move_return_value (ins, code);
break;
case OP_SETFRET:
static void
-add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
gboolean is_return,
guint32 *gr, guint32 *fr, guint32 *stack_size)
{
if (sig->pinvoke)
size = mono_type_native_stack_size (&klass->byval_arg, NULL);
else
- size = mono_type_stack_size (&klass->byval_arg, NULL);
+ size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL);
#ifdef SMALL_STRUCTS_IN_REGS
if (sig->pinvoke && is_return) {
int n = sig->hasthis + sig->param_count;
guint32 stack_size = 0;
CallInfo *cinfo;
+ MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
if (mp)
cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n));
/* return value */
{
ret_type = mono_type_get_underlying_type (sig->ret);
- ret_type = mini_get_basic_type_from_generic (cfg, ret_type);
+ ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
switch (ret_type->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_VALUETYPE: {
guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
- add_valuetype (sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+ add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
if (cinfo->ret.storage == ArgOnStack)
/* The caller passes the address where the value is stored */
add_general (&gr, &stack_size, &cinfo->ret);
continue;
}
ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (cfg, ptype);
+ ptype = mini_get_basic_type_from_generic (gsctx, ptype);
switch (ptype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
}
/* Fall through */
case MONO_TYPE_VALUETYPE:
- add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+ add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
break;
case MONO_TYPE_TYPEDBYREF:
stack_size += sizeof (MonoTypedRef);
size = mono_type_native_stack_size (csig->params [k], &align);
else {
int ialign;
- size = mono_type_stack_size (csig->params [k], &ialign);
+ size = mini_type_stack_size (NULL, csig->params [k], &ialign);
align = ialign;
}
size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
else {
int ialign;
- size = mono_type_stack_size (&in->klass->byval_arg, &ialign);
+ size = mini_type_stack_size (cfg->generic_sharing_context, &in->klass->byval_arg, &ialign);
align = ialign;
}
arg->opcode = OP_OUTARG_VT;
goto exception_exit; \
} while (0)
#define GENERIC_SHARING_FAILURE do { \
- if (cfg->generic_shared) { \
+ if (cfg->generic_sharing_context) { \
/* g_print ("sharing failed for method %s.%s in %s:%d\n", method->klass->name, method->name, __FILE__, __LINE__); */ \
cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED; \
goto exception_exit; \
* later look inside cfg and see if the arg num is
* really a reference
*/
- g_assert (cfg->generic_shared);
+ g_assert (cfg->generic_sharing_context);
inst->type = STACK_OBJ;
return;
default:
static guint
mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
{
- if (cfg->generic_shared && !type->byref) {
+ if (cfg->generic_sharing_context && !type->byref) {
/* FIXME: all the arguments must be references for now,
* later look inside cfg and see if the arg num is
* really a reference
static guint
mini_type_to_stind (MonoCompile* cfg, MonoType *type)
{
- if (cfg->generic_shared && !type->byref) {
+ if (cfg->generic_sharing_context && !type->byref) {
/* FIXME: all the arguments must be references for now,
* later look inside cfg and see if the arg num is
* really a reference
* later look inside cfg and see if the arg num is
* really a reference
*/
- g_assert (cfg->generic_shared);
+ g_assert (cfg->generic_sharing_context);
if (arg->type != STACK_OBJ)
return 1;
return 0;
end = ip + header->code_size;
mono_jit_stats.cil_code_size += header->code_size;
- if (cfg->generic_shared) {
+ if (cfg->generic_sharing_context) {
g_assert (shared_context);
generic_context = shared_context;
} else if (sig->is_inflated)
if (!cmethod)
goto load_error;
- if (cfg->generic_shared && mono_method_check_context_used (cmethod, generic_context))
+ if (cfg->generic_sharing_context && mono_method_check_context_used (cmethod, generic_context))
GENERIC_SHARING_FAILURE;
if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
if (cmethod && cmethod->klass->generic_container)
UNVERIFIED;
- if (cfg->generic_shared && cmethod && mono_method_check_context_used (cmethod, generic_context))
+ if (cfg->generic_sharing_context && cmethod && mono_method_check_context_used (cmethod, generic_context))
GENERIC_SHARING_FAILURE;
CHECK_STACK (n);
if (!mono_class_init (cmethod->klass))
goto load_error;
- if (cfg->generic_shared && mono_method_check_context_used (cmethod, generic_context))
+ if (cfg->generic_sharing_context && mono_method_check_context_used (cmethod, generic_context))
GENERIC_SHARING_FAILURE;
if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
if (sp [0]->type != STACK_OBJ)
UNVERIFIED;
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
/* Needed by the code generated in inssel.brg */
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
if (mono_class_is_nullable (klass)) {
if (sp [0]->type != STACK_OBJ)
UNVERIFIED;
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
/* Needed by the code generated in inssel.brg */
if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_field (method, field))
FIELD_ACCESS_FAILURE;
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
g_assert (!(field->type->attrs & FIELD_ATTRIBUTE_LITERAL));
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (cfg->generic_shared)
+ if (cfg->generic_sharing_context)
context_used = mono_class_check_context_used (klass, generic_context);
else
context_used = 0;
mono_class_init (klass);
ins->cil_code = ip;
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
loc = mono_compile_create_var (cfg, &mono_defaults.typed_reference_class->byval_arg, OP_LOCAL);
}
else {
handle = mono_ldtoken (image, n, &handle_class, generic_context);
- if (cfg->generic_shared &&
+ if (cfg->generic_sharing_context &&
mono_class_check_context_used (handle_class, generic_context))
GENERIC_SHARING_FAILURE;
}
goto load_error;
mono_class_init (cmethod->klass);
- if (cfg->generic_shared && mono_method_check_context_used (cmethod, generic_context))
+ if (cfg->generic_sharing_context && mono_method_check_context_used (cmethod, generic_context))
GENERIC_SHARING_FAILURE;
cil_method = cmethod;
goto load_error;
mono_class_init (cmethod->klass);
- if (cfg->generic_shared && mono_method_check_context_used (cmethod, generic_context))
+ if (cfg->generic_sharing_context && mono_method_check_context_used (cmethod, generic_context))
GENERIC_SHARING_FAILURE;
if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
klass = mini_get_class (method, token, generic_context);
CHECK_TYPELOAD (klass);
- if (cfg->generic_shared && mono_class_check_context_used (klass, generic_context))
+ if (cfg->generic_sharing_context && mono_class_check_context_used (klass, generic_context))
GENERIC_SHARING_FAILURE;
if (MONO_TYPE_IS_REFERENCE (&klass->byval_arg)) {
cfg->verbose_level = mini_verbose;
cfg->compile_aot = compile_aot;
cfg->skip_visibility = method->skip_visibility;
- cfg->generic_shared = try_generic_shared;
+ if (try_generic_shared)
+ cfg->generic_sharing_context = (MonoGenericSharingContext*)&cfg->generic_sharing_context;
cfg->token_info_hash = g_hash_table_new (NULL, NULL);
if (!header) {
cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
jinfo->used_regs = cfg->used_int_regs;
jinfo->domain_neutral = (cfg->opt & MONO_OPT_SHARED) != 0;
jinfo->cas_inited = FALSE; /* initialization delayed at the first stalk walk using this method */
- jinfo->generic_shared = cfg->generic_shared;
+ jinfo->generic_shared = cfg->generic_sharing_context ? 1 : 0;
if (header->num_clauses) {
int i;
mono_internal_hash_table_insert (&target_domain->jit_code_hash, method, cfg->jit_info);
code = cfg->native_code;
- if (cfg->generic_shared && mono_method_is_generic_sharable_impl (method)) {
+ if (cfg->generic_sharing_context && mono_method_is_generic_sharable_impl (method)) {
/* g_print ("inserting method %s.%s.%s\n", method->klass->name_space, method->klass->name, method->name); */
mono_domain_register_shared_generic (target_domain,
method_get_declaring_generic_method (method), cfg->jit_info);
#define MONO_BBLOCK_IS_IN_REGION(bblock, regtype) (((bblock)->region & (0xf << 4)) == (regtype))
+/*
+ * Will contain information on the generic type arguments in the
+ * future. For now, all arguments are always reference types.
+ */
+typedef struct {
+ int dummy;
+} MonoGenericSharingContext;
+
/*
* Control Flow Graph and compilation unit information
*/
MonoDomain *domain;
+ MonoGenericSharingContext *generic_sharing_context;
+
unsigned char *cil_start;
unsigned char *native_code;
guint code_size;
guint dont_verify_stack_merge : 1;
guint unverifiable : 1;
guint skip_visibility : 1;
- guint generic_shared : 1;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;
MonoGenericContext* mono_make_shared_context (MonoCompile *cfg, MonoGenericContext *context) MONO_INTERNAL;
-MonoType* mini_get_basic_type_from_generic (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
+MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
+
+int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
#endif /* __MONO_MINI_H__ */