Skip to content

Commit

Permalink
imported delegate patches from Daniel, new GetHashCode icalls
Browse files Browse the repository at this point in the history
svn path=/trunk/mono/; revision=3060
  • Loading branch information
Dietmar Maurer committed Mar 12, 2002
1 parent 7fd884c commit 84d0f82
Show file tree
Hide file tree
Showing 20 changed files with 270 additions and 129 deletions.
3 changes: 3 additions & 0 deletions mono/interpreter/ChangeLog
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,6 @@
2002-03-11 Dietmar Maurer <dietmar@ximian.com>

* interp.c (ves_runtime_method): set method_info field


Mon Mar 11 14:48:07 CET 2002 Paolo Molaro <lupus@ximian.com> Mon Mar 11 14:48:07 CET 2002 Paolo Molaro <lupus@ximian.com>


Expand Down
27 changes: 17 additions & 10 deletions mono/interpreter/interp.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -533,27 +533,34 @@ ves_runtime_method (MonoInvocation *frame)
{ {
const char *name = frame->method->name; const char *name = frame->method->name;
MonoObject *obj = (MonoObject*)frame->obj; MonoObject *obj = (MonoObject*)frame->obj;
MonoDelegate *delegate = (MonoDelegate*)frame->obj; MonoMulticastDelegate *delegate = (MonoMulticastDelegate*)frame->obj;
MonoInvocation call; MonoInvocation call;


mono_class_init (mono_defaults.delegate_class); mono_class_init (mono_defaults.multicastdelegate_class);


if (*name == '.' && (strcmp (name, ".ctor") == 0) && obj && if (*name == '.' && (strcmp (name, ".ctor") == 0) && obj &&
mono_object_isinst (obj, mono_defaults.delegate_class)) { mono_object_isinst (obj, mono_defaults.multicastdelegate_class)) {
delegate->target = frame->stack_args[0].data.p; delegate->delegate.target = frame->stack_args[0].data.p;
delegate->method_ptr = frame->stack_args[1].data.p; delegate->delegate.method_ptr = frame->stack_args[1].data.p;
if (!delegate->delegate.target) {
MonoDomain *domain = mono_domain_get ();
MonoMethod *m = mono_method_pointer_get (delegate->delegate.method_ptr);
delegate->delegate.method_info = mono_method_get_object (domain, m);
}
return; return;
} }
if (*name == 'I' && (strcmp (name, "Invoke") == 0) && obj && if (*name == 'I' && (strcmp (name, "Invoke") == 0) && obj &&
mono_object_isinst (obj, mono_defaults.delegate_class)) { mono_object_isinst (obj, mono_defaults.multicastdelegate_class)) {
MonoPIFunc func;
guchar *code; guchar *code;
MonoMethod *method; MonoMethod *method;


code = (guchar*)delegate->method_ptr; // FIXME: support multicast delegates
g_assert (!delegate->prev);

code = (guchar*)delegate->delegate.method_ptr;
method = mono_method_pointer_get (code); method = mono_method_pointer_get (code);
/* FIXME: check for NULL method */ /* FIXME: check for NULL method */
INIT_FRAME(&call,frame,delegate->target,frame->stack_args,frame->retval,method); INIT_FRAME(&call,frame,delegate->delegate.target,frame->stack_args,frame->retval,method);
ves_exec_method (&call); ves_exec_method (&call);
#if 0 #if 0
if (!method->addr) if (!method->addr)
Expand Down Expand Up @@ -3702,7 +3709,7 @@ output_profile (GList *funcs)
g_snprintf (buf, sizeof (buf), "%s.%s::%s(%d)", g_snprintf (buf, sizeof (buf), "%s.%s::%s(%d)",
p->u.method->klass->name_space, p->u.method->klass->name, p->u.method->klass->name_space, p->u.method->klass->name,
p->u.method->name, p->u.method->signature->param_count); p->u.method->name, p->u.method->signature->param_count);
printf ("%-52s %7d %7ld %7d\n", buf, printf ("%-52s %7d %7llu %7d\n", buf,
(gint)(p->total*1000), p->count, (gint)((p->total*1000)/p->count)); (gint)(p->total*1000), p->count, (gint)((p->total*1000)/p->count));
} }
} }
Expand Down
5 changes: 5 additions & 0 deletions mono/jit/ChangeLog
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,9 @@
2002-03-11 Dietmar Maurer <dietmar@ximian.com>


* emit-x86.c (mono_delegate_ctor): use C impl. instead of x86_*
macros, included new delegate code from Daniel Stodden.


Mon Mar 11 14:47:21 CET 2002 Paolo Molaro <lupus@ximian.com> Mon Mar 11 14:47:21 CET 2002 Paolo Molaro <lupus@ximian.com>


* jit.c: verify that corlib and runtime are in sync. * jit.c: verify that corlib and runtime are in sync.
Expand Down
178 changes: 106 additions & 72 deletions mono/jit/emit-x86.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -876,6 +876,27 @@ match_debug_method (MonoMethod* method)
return 0; return 0;
} }


static void
mono_delegate_ctor (MonoDelegate *this, MonoObject *target,
gpointer addr)
{
MonoDomain *domain = mono_domain_get ();
MonoClass *class;
MonoJitInfo *ji;

g_assert (this);
g_assert (addr);

class = this->object.vtable->klass;

if (!target && (ji = mono_jit_info_table_find (mono_jit_info_table, addr)))
this->method_info = mono_method_get_object (domain, ji->method);

this->target = target;
this->method_ptr = addr;

}

/** /**
* arch_compile_method: * arch_compile_method:
* @method: pointer to the method info * @method: pointer to the method info
Expand Down Expand Up @@ -916,51 +937,26 @@ arch_compile_method (MonoMethod *method)
} }


if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) { if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
MonoClassField *field;
const char *name = method->name; const char *name = method->name;
static guint target_offset = 0;
static guint method_offset = 0;
guint8 *code; guint8 *code;
gboolean delegate = FALSE; gboolean delegate = FALSE;


if (method->klass->parent && if (method->klass->parent == mono_defaults.multicastdelegate_class)
method->klass->parent->parent == mono_defaults.delegate_class)
delegate = TRUE; delegate = TRUE;


if (!target_offset) {
mono_class_init (mono_defaults.delegate_class);

field = mono_class_get_field_from_name (mono_defaults.delegate_class, "m_target");
target_offset = field->offset;
field = mono_class_get_field_from_name (mono_defaults.delegate_class, "method_ptr");
method_offset = field->offset;
}

if (delegate && *name == '.' && (strcmp (name, ".ctor") == 0)) { if (delegate && *name == '.' && (strcmp (name, ".ctor") == 0)) {
addr = code = g_malloc (32); addr = (gpointer)mono_delegate_ctor;
x86_push_reg (code, X86_EBP);
x86_mov_reg_reg (code, X86_EBP, X86_ESP, 4);

/* load the this pointer */
x86_mov_reg_membase (code, X86_EAX, X86_EBP, 8, 4);
/* load m_target arg */
x86_mov_reg_membase (code, X86_EDX, X86_EBP, 12, 4);
/* store mtarget */
x86_mov_membase_reg (code, X86_EAX, target_offset, X86_EDX, 4);
/* load method_ptr arg */
x86_mov_reg_membase (code, X86_EDX, X86_EBP, 16, 4);
/* store method_ptr */
x86_mov_membase_reg (code, X86_EAX, method_offset, X86_EDX, 4);

x86_leave (code);
x86_ret (code);

g_assert ((code - (guint8*)addr) < 32);

} else if (delegate && *name == 'I' && (strcmp (name, "Invoke") == 0)) { } else if (delegate && *name == 'I' && (strcmp (name, "Invoke") == 0)) {
/*
* Invoke( args .. ) {
* if ( prev )
* prev.Invoke();
* return this.<m_target>( args );
* }
*/
MonoMethodSignature *csig = method->signature; MonoMethodSignature *csig = method->signature;
int i, arg_size, target, this_pos = 4; guint8 *br[2], *pos[2];
guint8 *source; int i, arg_size, this_pos = 4;


if (csig->ret->type == MONO_TYPE_VALUETYPE) { if (csig->ret->type == MONO_TYPE_VALUETYPE) {
g_assert (!csig->ret->byref); g_assert (!csig->ret->byref);
Expand All @@ -979,50 +975,89 @@ arch_compile_method (MonoMethod *method)


addr = g_malloc (64 + arg_size); addr = g_malloc (64 + arg_size);


for (i = 0; i < 2; i ++) { code = addr;
int j; /* load the this pointer */

x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_pos, 4);
code = addr;
/* load the this pointer */ /* load prev */
x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_pos, 4); x86_mov_reg_membase (code, X86_EDX, X86_EAX, G_STRUCT_OFFSET (MonoMulticastDelegate, prev), 4);
/* load mtarget */
x86_mov_reg_membase (code, X86_EDX, X86_EAX, target_offset, 4); /* prev == 0 ? */
/* check if zero (static method call without this pointer) */ x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0);
x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0); br[0] = code; x86_branch32 (code, X86_CC_EQ, 0, TRUE );
x86_branch32 (code, X86_CC_EQ, target, TRUE); pos[0] = code;
source = code;

x86_push_reg( code, X86_EAX );
/* virtual delegate methods: we have to replace the this pointer /* push args */
* withe the actual target */ for ( i = 0; i < (arg_size>>2); i++ )
x86_mov_membase_reg (code, X86_ESP, this_pos, X86_EDX, 4); x86_push_membase( code, X86_ESP, (arg_size + this_pos + 4) );
/* jump to method_ptr() */ /* push next */
x86_jump_membase (code, X86_EAX, method_offset); x86_push_reg( code, X86_EDX );

if (this_pos == 8)
/* static delegate methods: we have to remove the this pointer x86_push_membase (code, X86_ESP, (arg_size + 8));
* from the activation frame - I do this do creating a new /* recurse */
* stack frame an copy all arguments except the this pointer */ br[1] = code; x86_call_imm( code, 0 );

pos[1] = code; x86_call_imm( br[1], addr - pos[1] );
target = code - source;
g_assert ((arg_size & 3) == 0); if (this_pos == 8)
for (j = 0; j < (arg_size>>2); j++) { x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 8);
x86_push_membase (code, X86_ESP, (arg_size + this_pos)); else
} x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 4);
x86_pop_reg( code, X86_EAX );

/* prev == 0 */
x86_branch32( br[0], X86_CC_EQ, code - pos[0], TRUE );

/* load mtarget */
x86_mov_reg_membase (code, X86_EDX, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, target), 4);
/* mtarget == 0 ? */
x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0);
br[0] = code; x86_branch32 (code, X86_CC_EQ, 0, TRUE);
pos[0] = code;

/*
* virtual delegate methods: we have to
* replace the this pointer with the actual
* target
*/
x86_mov_membase_reg (code, X86_ESP, this_pos, X86_EDX, 4);
/* jump to method_ptr() */
x86_jump_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr));

/* mtarget != 0 */
x86_branch32( br[0], X86_CC_EQ, code - pos[0], TRUE);
/*
* static delegate methods: we have to remove
* the this pointer from the activation frame
* - I do this creating a new stack frame anx
* copy all arguments except the this pointer
*/
g_assert ((arg_size & 3) == 0);
for (i = 0; i < (arg_size>>2); i++) {
x86_push_membase (code, X86_ESP, (arg_size + this_pos));
}


if (this_pos == 8) if (this_pos == 8)
x86_push_membase (code, X86_ESP, (arg_size + 4)); x86_push_membase (code, X86_ESP, (arg_size + 4));


x86_call_membase (code, X86_EAX, method_offset); x86_call_membase (code, X86_EAX, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
if (arg_size) {
if (this_pos == 8) if (this_pos == 8)
x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 4); x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 4);
else else
x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size); x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size);

x86_ret (code);

} }


x86_ret (code);

g_assert ((code - (guint8*)addr) < (64 + arg_size)); g_assert ((code - (guint8*)addr) < (64 + arg_size));


if (mono_jit_dump_asm) {
char *id = g_strdup_printf ("%s.%s_%s", method->klass->name_space,
method->klass->name, method->name);
mono_disassemble_code( addr, code - (guint8*)addr, id );
g_free (id);
}
} else { } else {
if (mono_debug_handle) if (mono_debug_handle)
return NULL; return NULL;
Expand Down Expand Up @@ -1190,7 +1225,6 @@ arch_get_restore_context ()


/* get return address, stored in EDX */ /* get return address, stored in EDX */
x86_mov_reg_membase (code, X86_EDX, X86_EAX, G_STRUCT_OFFSET (struct sigcontext, eip), 4); x86_mov_reg_membase (code, X86_EDX, X86_EAX, G_STRUCT_OFFSET (struct sigcontext, eip), 4);

/* restore EBX */ /* restore EBX */
x86_mov_reg_membase (code, X86_EBX, X86_EAX, G_STRUCT_OFFSET (struct sigcontext, ebx), 4); x86_mov_reg_membase (code, X86_EBX, X86_EAX, G_STRUCT_OFFSET (struct sigcontext, ebx), 4);
/* restore EDI */ /* restore EDI */
Expand Down
7 changes: 7 additions & 0 deletions mono/metadata/ChangeLog
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,10 @@
2002-03-12 Dietmar Maurer <dietmar@ximian.com>

* icall.c (ves_icall_System_Object_GetHashCode): impl.

2002-03-11 Dietmar Maurer <dietmar@ximian.com>

* icall.c (ves_icall_System_ValueType_GetHashCode): impl.


Mon Mar 11 14:45:42 CET 2002 Paolo Molaro <lupus@ximian.com> Mon Mar 11 14:45:42 CET 2002 Paolo Molaro <lupus@ximian.com>


Expand Down
6 changes: 3 additions & 3 deletions mono/metadata/appdomain.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ mono_init (const char *filename)
mono_defaults.corlib, "System", "Array"); mono_defaults.corlib, "System", "Array");
g_assert (mono_defaults.array_class != 0); g_assert (mono_defaults.array_class != 0);


mono_defaults.delegate_class = mono_class_from_name ( mono_defaults.multicastdelegate_class = mono_class_from_name (
mono_defaults.corlib, "System", "Delegate"); mono_defaults.corlib, "System", "MulticastDelegate");
g_assert (mono_defaults.delegate_class != 0); g_assert (mono_defaults.multicastdelegate_class != 0 );


mono_defaults.typehandle_class = mono_class_from_name ( mono_defaults.typehandle_class = mono_class_from_name (
mono_defaults.corlib, "System", "RuntimeTypeHandle"); mono_defaults.corlib, "System", "RuntimeTypeHandle");
Expand Down
17 changes: 17 additions & 0 deletions mono/metadata/class.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ mono_class_init (MonoClass *class)
MonoClass *k, *ic; MonoClass *k, *ic;
MonoMethod **vtable = class->vtable; MonoMethod **vtable = class->vtable;
int i, max_iid, cur_slot = 0; int i, max_iid, cur_slot = 0;
static MonoMethod *default_ghc = NULL;


g_assert (class); g_assert (class);


Expand Down Expand Up @@ -624,6 +625,22 @@ mono_class_init (MonoClass *class)
} }
} }
} }

#define GHC_SLOT 2

if (!default_ghc) {
if (class == mono_defaults.object_class) {
default_ghc = vtable [GHC_SLOT];
g_assert (!strcmp (default_ghc->name, "GetHashCode"));
}
}

class->ghcimpl = 1;
if (class != mono_defaults.object_class) {
if (vtable [GHC_SLOT] == default_ghc) {
class->ghcimpl = 0;
}
}
} }


/** /**
Expand Down
1 change: 1 addition & 0 deletions mono/metadata/class.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct _MonoClass {
guint inited : 1; guint inited : 1;
guint valuetype : 1; /* derives from System.ValueType */ guint valuetype : 1; /* derives from System.ValueType */
guint enumtype : 1; /* derives from System.Enum */ guint enumtype : 1; /* derives from System.Enum */
guint ghcimpl : 1; /* class has its own GetHashCode impl */
guint min_align : 4; guint min_align : 4;


MonoClass *parent; MonoClass *parent;
Expand Down
Loading

0 comments on commit 84d0f82

Please sign in to comment.