Hi,
Rodrigo Kumpera wrote:
From your email the advantage of the patch is that by replacing some icalls
with managed code we would get rid of some managed-native transitions.
The long term goal would be to replace all native icalls with managed
icalls (build by icall builders) that call no native code that could
eliminate all unnecessary managed to native transitions.
-It makes the new full AOT mode a bit more complicated as these would be
another
kind of wrappers that would need to be AOT'ed.
The current string constructor hach is implemented using
managed-to-managed wrappers. If that works, there should be no problem
with AOT. But I don't use AOT so I have little experience with it.
-Increases the footprint by just a bit, as we need to store the icalls
internal representation
as well. The amount of extra code generated is bounded, specially since
we replace a
managed-to-native wrapper with a managed-to-managed with more code.
All the three reference implementations implement very small and fast
code blocks and I believe that it's worth to aviod managed to native
transitions. OffsetToStringData is an exception because that is managed
already but I wanted to show that mini_get_inst_for_method could be
replaced by icall builders.
-JIT time should not change much, but this is only a guess.
JIT time should be the same as for IL code contained in assemblies. Lots
of our current icalls are native because we couldn't implement them in
C#. Other icalls are native calls because they call external native code
so it's faster to have only one managed to native transition. I don't
think that there are icalls that are in native code because have better
performance than an IL implementation.
I wonder if it is really an advantage of following this patch as, for
example, OffsetToStringData
has 22 lines in your patch but 6 in the current setup. Of course the
code in your patch ends more
organized and I find it easier to follow, but should be interesting to
rear from the others.
The 22 lines are the builder but that gets executed only once. After
that only the generated (and JITed) code is used. The actual IL code
just returns a constant.
-For simple methods such as OffsetToStringData the method call overhead
might be a killer. We
should make sure that these new wrappers get a change to be inlined.
Currently it doesn't get inlined because the JIT has some logic
preventing (at least types) of wrappers being inlined but should be
possible to inline them.
-I'm not aware of how stack traces behave with wrappers, but are they
preserved with your patch?
As long as they are not inlined the stack trace is preserved. But this
is true for Class Library methods implemented in C# so icall builders
should not be treated differently.
-Does it work under trunk?
It should but the patch may be outdated.
-Do you have performance numbers on your change? Since it changes
performance sensitive
parts of the runtime, attaching a benchmark (or pointing to an existing
one) showing the implications is
fundamental.
These are only reference implementations and OffsetToStringData for
example is slower for sure because it don't get inlined. I expect string
.ctors to have the same performance because the generated IL code is the
same but using icall builder is a clean way as opposed to the current
hack. UnsafeAddrOfPinnedArrayElement should benefit because no native
code will be called.
As for OffsetToStringData I don't know whether mini_get_inst_for_method
or an icall builder is faster when generating the code but using an
icall builder solves the things at the highest possible level letting
low level optimizations do their job.
I don't insist on getting these reference icall builder implementations
into trunk I just would like to get approval for the concept and the
support code of icall builders. Actual icall builder implementations
could be evaluated independently.
With the attched test I got:
mono r109162: 99060
mono r109162 with my patch: 17375 (5.7x faster)
MS.NET 2.0 SP1: 17898
The imporvement is purely because of the method being implemented in
managed code. So mono would benefit form icall builders for sure.
The code that decides what to be inlined is too cryptic to me because I
believe that there are redundant checks against wrappers but if someone
could enable the inlining of managed-to-managed wrappers icall builders
could provide even more performance improvement.
I also have attached an updated patch. (Only line numbers were updated
no code modification was necessary.)
Kornél
2008/7/29 Kornél Pál <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>
Hi,
There is a pending patch:
http://lists.ximian.com/pipermail/mono-devel-list/2008-June/028291.html
As far as I can remember I didn't get any feedback regarding this patch.
Please review the patch. Thanks.
Kornél
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
<mailto:Mono-devel-list@lists.ximian.com>
http://lists.ximian.com/mailman/listinfo/mono-devel-list
------------------------------------------------------------------------
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list
using System;
using System.Globalization;
using System.Runtime.InteropServices;
class ICallBuilderPerfTest
{
static void Main()
{
DateTime startTime = DateTime.Now;
DateTime endTime;
byte[] array = new byte[0x1000];
for (int i = 0; i < 0x100000; i++)
for (int j = 0; j < 0x1000; j++)
Marshal.UnsafeAddrOfPinnedArrayElement(array, j);
endTime = DateTime.Now;
Console.WriteLine(((long)endTime.Subtract(startTime).TotalMilliseconds).ToString(CultureInfo.InvariantCulture));
}
}
Index: mono/mono/metadata/string-icalls.c
===================================================================
--- mono/mono/metadata/string-icalls.c (revision 109162)
+++ mono/mono/metadata/string-icalls.c (working copy)
@@ -27,14 +27,6 @@
static gboolean
string_icall_is_in_array (MonoArray *chars, gint32 arraylength, gunichar2 chr);
-/* This function is redirected to String.CreateString ()
- by mono_marshal_get_native_wrapper () */
-void
-ves_icall_System_String_ctor_RedirectToCreateString (void)
-{
- g_assert_not_reached ();
-}
-
MonoString *
ves_icall_System_String_InternalJoin (MonoString *separator, MonoArray *
value, gint32 sindex, gint32 count)
{
Index: mono/mono/metadata/string-icalls.h
===================================================================
--- mono/mono/metadata/string-icalls.h (revision 109162)
+++ mono/mono/metadata/string-icalls.h (working copy)
@@ -14,9 +14,6 @@
#include <mono/metadata/object.h>
#include "mono/utils/mono-compiler.h"
-void
-ves_icall_System_String_ctor_RedirectToCreateString (void) MONO_INTERNAL;
-
MonoString *
ves_icall_System_String_InternalJoin (MonoString *separator, MonoArray *
value, gint32 sindex, gint32 count) MONO_INTERNAL;
Index: mono/mono/metadata/icall-def.h
===================================================================
--- mono/mono/metadata/icall-def.h (revision 109162)
+++ mono/mono/metadata/icall-def.h (working copy)
@@ -604,12 +604,10 @@
ICALL_TYPE(RUNH, "System.Runtime.CompilerServices.RuntimeHelpers", RUNH_1)
ICALL(RUNH_1, "GetObjectValue",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue)
- /* REMOVEME: no longer needed, just so we dont break things when not
needed */
-ICALL(RUNH_2, "GetOffsetToStringData",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData)
ICALL(RUNH_3, "InitializeArray",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray)
ICALL(RUNH_4, "RunClassConstructor",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor)
ICALL(RUNH_5, "RunModuleConstructor",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor)
-ICALL(RUNH_6, "get_OffsetToStringData",
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData)
+ICALL_METHOD(RUNH_6, "get_OffsetToStringData",
build_icall_System_Runtime_CompilerServices_RuntimeHelpers_get_OffsetToStringData,
BUILDER)
ICALL_TYPE(GCH, "System.Runtime.InteropServices.GCHandle", GCH_1)
ICALL(GCH_1, "CheckCurrentDomain", GCHandle_CheckCurrentDomain)
@@ -660,7 +658,7 @@
ICALL(MARSHAL_32, "StringToHGlobalAnsi",
ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi)
ICALL(MARSHAL_33, "StringToHGlobalUni",
ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni)
ICALL(MARSHAL_34, "StructureToPtr",
ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr)
-ICALL(MARSHAL_35, "UnsafeAddrOfPinnedArrayElement",
ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement)
+ICALL_METHOD(MARSHAL_35, "UnsafeAddrOfPinnedArrayElement",
build_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement,
BUILDER)
ICALL(MARSHAL_36, "WriteByte",
ves_icall_System_Runtime_InteropServices_Marshal_WriteByte)
ICALL(MARSHAL_37, "WriteInt16",
ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16)
ICALL(MARSHAL_38, "WriteInt32",
ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32)
@@ -725,14 +723,7 @@
ICALL(SECMAN_5, "set_SecurityEnabled",
ves_icall_System_Security_SecurityManager_set_SecurityEnabled)
ICALL_TYPE(STRING, "System.String", STRING_1)
-ICALL(STRING_1, ".ctor(char*)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_2, ".ctor(char*,int,int)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_3, ".ctor(char,int)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_4, ".ctor(char[])",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_5, ".ctor(char[],int,int)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_6, ".ctor(sbyte*)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_7, ".ctor(sbyte*,int,int)",
ves_icall_System_String_ctor_RedirectToCreateString)
-ICALL(STRING_8, ".ctor(sbyte*,int,int,System.Text.Encoding)",
ves_icall_System_String_ctor_RedirectToCreateString)
+ICALL_METHOD(STRING_1, ".ctor", build_icall_System_String_ctor, BUILDER)
ICALL(STRING_9, "InternalAllocateStr",
ves_icall_System_String_InternalAllocateStr)
ICALL(STRING_11, "InternalCopyTo", ves_icall_System_String_InternalCopyTo)
ICALL(STRING_14, "InternalIntern", ves_icall_System_String_InternalIntern)
Index: mono/mono/metadata/marshal.c
===================================================================
--- mono/mono/metadata/marshal.c (revision 109162)
+++ mono/mono/metadata/marshal.c (working copy)
@@ -2744,6 +2744,13 @@
return res;
}
+static inline MonoMethod*
+mono_mb_create_icall_and_cache (MonoMethod *method, MonoMethodBuilder *mb,
+
MonoMethodSignature *sig, int max_stack)
+{
+ return mono_mb_create_and_cache
(method->klass->image->native_wrapper_cache,
+ method, mb, sig, max_stack);
+}
static inline MonoMethod*
mono_marshal_remoting_find_in_cache (MonoMethod *method, int wrapper_type)
@@ -8475,7 +8482,6 @@
MonoMethod *res;
GHashTable *cache;
gboolean pinvoke = FALSE;
- gpointer iter;
int i;
const char *exc_class = "MissingMethodException";
const char *exc_arg = NULL;
@@ -8502,51 +8508,24 @@
exc_arg = "Method contains unsupported native
code";
else
mono_lookup_pinvoke_call (method, &exc_class,
&exc_arg);
- else
- piinfo->addr = mono_lookup_internal_call (method);
- }
+ else {
+ const ICallDescriptor *icall_desc =
mono_lookup_icall_descriptor (method);
- /* hack - redirect certain string constructors to CreateString */
- if (piinfo->addr ==
ves_icall_System_String_ctor_RedirectToCreateString) {
- g_assert (!pinvoke);
- g_assert (method->string_ctor);
- g_assert (sig->hasthis);
-
- /* CreateString returns a value */
- csig = signature_dup (method->klass->image, sig);
- csig->ret = &mono_defaults.string_class->byval_arg;
- csig->pinvoke = 0;
-
- iter = NULL;
- while ((res = mono_class_get_methods
(mono_defaults.string_class, &iter))) {
- if (!strcmp ("CreateString", res->name) &&
- mono_metadata_signature_equal (csig,
mono_method_signature (res))) {
-
- g_assert (!(res->iflags &
METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL));
- g_assert (!(res->flags &
METHOD_ATTRIBUTE_PINVOKE_IMPL));
-
- /* create a wrapper to preserve .ctor in stack
trace */
- mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_MANAGED);
-
- mono_mb_emit_byte (mb, CEE_LDARG_0);
- for (i = 1; i <= csig->param_count; i++)
- mono_mb_emit_ldarg (mb, i);
- mono_mb_emit_managed_call (mb, res, NULL);
- mono_mb_emit_byte (mb, CEE_RET);
-
- /* use native_wrapper_cache because internal
calls are looked up there */
- res = mono_mb_create_and_cache (cache, method,
- mb, csig, csig->param_count + 1);
-
- mono_mb_free (mb);
-
- return res;
+ if (icall_desc) {
+ switch (icall_desc->type) {
+ case ICALL_TYPE_FTNPTR:
+ piinfo->addr = icall_desc->ftnptr;
+ break;
+ case ICALL_TYPE_BUILDER:
+ res = icall_desc->builder (method);
+ if (res)
+ return res;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
}
-
- /* exception will be thrown */
- piinfo->addr = NULL;
- g_warning ("cannot find CreateString for .ctor");
}
mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_NATIVE);
@@ -10782,10 +10761,44 @@
#endif
}
-void*
-ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement
(MonoArray *arrayobj, int index)
+MonoMethod*
+build_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement
(MonoMethod *method)
{
- return mono_array_addr_with_size (arrayobj, mono_array_element_size
(arrayobj->obj.vtable->klass), index);
+ MonoMethod *res;
+ MonoMethodSignature *csig;
+ MonoMethodBuilder *mb;
+
+ csig = signature_dup (method->klass->image, mono_method_signature
(method));
+ csig->pinvoke = 0;
+
+ mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_MANAGED);
+
+ /* static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
*/
+ /* return (char*) &arr->vector +
arr->obj.vtable->klass->sizes.element_size * index; */
+
+ mono_mb_emit_byte (mb, CEE_LDARG_0);
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoArray, vector));
+ mono_mb_emit_byte (mb, CEE_ADD);
+
+ mono_mb_emit_byte (mb, CEE_LDARG_0);
+ mono_mb_emit_byte (mb, CEE_LDIND_I); /* vtable */
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoVTable, klass));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoClass, sizes));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_LDIND_I4);
+
+ mono_mb_emit_byte (mb, CEE_LDARG_1);
+ mono_mb_emit_byte (mb, CEE_MUL);
+
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ res = mono_mb_create_icall_and_cache (method, mb, csig, 3);
+ mono_mb_free (mb);
+ return res;
}
MonoDelegate*
@@ -10888,6 +10901,77 @@
return proxy;
}
+MonoMethod*
+build_icall_System_Runtime_CompilerServices_RuntimeHelpers_get_OffsetToStringData
(MonoMethod *method)
+{
+ MonoMethod *res;
+ MonoMethodSignature *csig;
+ MonoMethodBuilder *mb;
+
+ csig = signature_dup (method->klass->image, mono_method_signature
(method));
+ csig->pinvoke = 0;
+
+ mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_MANAGED);
+
+ /* static int get_OffsetToStringData (); */
+ /* return offsetof (MonoString, chars); */
+
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoString, chars));
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ res = mono_mb_create_icall_and_cache (method, mb, csig, 1);
+ mono_mb_free (mb);
+ return res;
+
+}
+
+/* Redirect String constructors to CreateString () */
+MonoMethod*
+build_icall_System_String_ctor (MonoMethod *method)
+{
+ MonoMethod *res;
+ MonoMethodSignature *csig;
+ MonoMethodBuilder *mb;
+ gpointer iter;
+ gboolean found;
+ int i;
+
+ g_assert (method->string_ctor);
+
+ /* CreateString returns a value */
+ csig = signature_dup (method->klass->image, mono_method_signature
(method));
+ csig->ret = &mono_defaults.string_class->byval_arg;
+ csig->pinvoke = 0;
+
+ /* create a wrapper to preserve .ctor in stack trace */
+ mb = mono_mb_new (method->klass, method->name,
MONO_WRAPPER_MANAGED_TO_MANAGED);
+
+ iter = NULL;
+ found = FALSE;
+ while ((res = mono_class_get_methods (mono_defaults.string_class,
&iter))) {
+ if (res->name [0] == 'C' && !strcmp ("CreateString", res->name)
&&
+ mono_metadata_signature_equal (csig,
mono_method_signature (res))) {
+
+ mono_mb_emit_byte (mb, CEE_LDARG_0);
+ for (i = 1; i <= csig->param_count; i++)
+ mono_mb_emit_ldarg (mb, i);
+ mono_mb_emit_managed_call (mb, res, NULL);
+ mono_mb_emit_byte (mb, CEE_RET);
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ g_warning ("Cannot find CreateString for string constructor.");
+ mono_mb_emit_exception (mb, "MissingMethodException", NULL);
+ }
+
+ res = mono_mb_create_icall_and_cache (method, mb, csig,
csig->param_count + 1);
+ mono_mb_free (mb);
+ return res;
+}
+
/**
* mono_marshal_is_loading_type_info:
*
Index: mono/mono/metadata/marshal.h
===================================================================
--- mono/mono/metadata/marshal.h (revision 109162)
+++ mono/mono/metadata/marshal.h (working copy)
@@ -30,6 +30,22 @@
/* marshaling helper functions */
+enum {
+ ICALL_TYPE_FTNPTR,
+ ICALL_TYPE_BUILDER
+};
+
+typedef struct {
+ union {
+ gpointer ftnptr;
+ MonoMethod* (*builder) (MonoMethod *method);
+ };
+ guint8 type;
+} ICallDescriptor;
+
+const ICallDescriptor*
+mono_lookup_icall_descriptor (MonoMethod *method) MONO_INTERNAL;
+
void
mono_marshal_init (void) MONO_INTERNAL;
@@ -322,8 +338,8 @@
void
ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (void *ptr)
MONO_INTERNAL;
-void*
-ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement
(MonoArray *arrayobj, int index) MONO_INTERNAL;
+MonoMethod*
+build_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement
(MonoMethod *method) MONO_INTERNAL;
MonoDelegate*
ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal
(void *ftn, MonoReflectionType *type) MONO_INTERNAL;
@@ -370,6 +386,12 @@
MonoComInteropProxy*
ves_icall_Mono_Interop_ComInteropProxy_FindProxy (gpointer pUnk) MONO_INTERNAL;
+MonoMethod*
+build_icall_System_Runtime_CompilerServices_RuntimeHelpers_get_OffsetToStringData
(MonoMethod *method) MONO_INTERNAL;
+
+MonoMethod*
+build_icall_System_String_ctor (MonoMethod *method) MONO_INTERNAL;
+
void
mono_win32_compat_CopyMemory (gpointer dest, gconstpointer source, gsize
length);
Index: mono/mono/metadata/icall.c
===================================================================
--- mono/mono/metadata/icall.c (revision 109162)
+++ mono/mono/metadata/icall.c (working copy)
@@ -850,14 +850,6 @@
#endif
}
-static gint
-ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData
(void)
-{
- MONO_ARCH_SAVE_REGS;
-
- return offsetof (MonoString, chars);
-}
-
static MonoObject *
ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue
(MonoObject *obj)
{
@@ -7365,6 +7357,7 @@
}
#define ICALL_TYPE(id,name,first)
+#define ICALL_METHOD(id,name,data,type) ICALL(id,name,data)
#define ICALL(id,name,func) Icall_ ## id,
enum {
@@ -7469,13 +7462,15 @@
#endif /* !HAVE_ARRAY_ELEM_INIT */
#undef ICALL_TYPE
+#undef ICALL_METHOD
#undef ICALL
#define ICALL_TYPE(id,name,first)
-#define ICALL(id,name,func) func,
-static const gconstpointer
-icall_functions [] = {
+#define ICALL_METHOD(id,name,data,type) {data, ICALL_TYPE_ ## type},
+#define ICALL(id,name,func) ICALL_METHOD(id,name,func,FTNPTR)
+static const ICallDescriptor
+icall_descriptors [] = {
#include "metadata/icall-def.h"
- NULL
+ {NULL, 0}
};
static GHashTable *icall_hash = NULL;
@@ -7512,7 +7507,7 @@
}
}
- icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
NULL);
+ icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
g_free);
}
void
@@ -7526,9 +7521,14 @@
void
mono_add_internal_call (const char *name, gconstpointer method)
{
+ ICallDescriptor *icall_desc = g_new(ICallDescriptor, 1);
+
+ icall_desc->ftnptr = (gpointer) method;
+ icall_desc->type = ICALL_TYPE_FTNPTR;
+
mono_loader_lock ();
- g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
+ g_hash_table_insert (icall_hash, g_strdup (name), (gpointer)
icall_desc);
mono_loader_unlock ();
}
@@ -7541,13 +7541,13 @@
return strcmp (key, method_name);
}
-static gpointer
+static const ICallDescriptor*
find_method_icall (const IcallTypeDesc *imap, const char *name)
{
const guint16 *nameslot = bsearch (name, icall_names_idx +
imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]),
compare_method_imap);
if (!nameslot)
return NULL;
- return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
+ return &icall_descriptors [(nameslot - &icall_names_idx [0])];
}
static int
@@ -7574,13 +7574,13 @@
return strcmp (key, *method_name);
}
-static gpointer
+static const ICallDescriptor*
find_method_icall (const IcallTypeDesc *imap, const char *name)
{
const char **nameslot = bsearch (name, icall_names + imap->first_icall,
icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
if (!nameslot)
return NULL;
- return (gpointer)icall_functions [(nameslot - icall_names)];
+ return &icall_descriptors [(nameslot - icall_names)];
}
static int
@@ -7622,14 +7622,14 @@
return nspacelen + cnamelen;
}
-gpointer
-mono_lookup_internal_call (MonoMethod *method)
+const ICallDescriptor*
+mono_lookup_icall_descriptor (MonoMethod *method)
{
char *sigstart;
char *tmpsig;
char mname [2048];
int typelen = 0, mlen, siglen;
- gpointer res;
+ const ICallDescriptor *res;
const IcallTypeDesc *imap;
g_assert (method != NULL);
@@ -7722,6 +7722,14 @@
return NULL;
}
+gpointer
+mono_lookup_internal_call (MonoMethod *method)
+{
+ const ICallDescriptor *icall_desc = mono_lookup_icall_descriptor
(method);
+
+ return icall_desc->type == ICALL_TYPE_FTNPTR ? icall_desc->ftnptr :
NULL;
+}
+
static MonoType*
type_from_typename (char *typename)
{
Index: mono/mono/mini/mini.c
===================================================================
--- mono/mono/mini/mini.c (revision 109162)
+++ mono/mono/mini/mini.c (working copy)
@@ -4020,11 +4020,6 @@
{
MonoInst *ins = NULL;
- static MonoClass *runtime_helpers_class = NULL;
- if (! runtime_helpers_class)
- runtime_helpers_class = mono_class_from_name
(mono_defaults.corlib,
- "System.Runtime.CompilerServices", "RuntimeHelpers");
-
if (cmethod->klass == mono_defaults.string_class) {
if (strcmp (cmethod->name, "get_Chars") == 0) {
MONO_INST_NEW (cfg, ins, OP_GETCHR);
@@ -4077,12 +4072,6 @@
return ins;
} else
return NULL;
- } else if (cmethod->klass == runtime_helpers_class) {
- if (strcmp (cmethod->name, "get_OffsetToStringData") == 0) {
- NEW_ICONST (cfg, ins, G_STRUCT_OFFSET (MonoString,
chars));
- return ins;
- } else
- return NULL;
} else if (cmethod->klass == mono_defaults.thread_class) {
if (strcmp (cmethod->name, "get_CurrentThread") == 0 && (ins =
mono_arch_get_thread_intrinsic (cfg)))
return ins;
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list