From 1bfa0441efd34b0d10099ee25f9d4bdbb1a6edff Mon Sep 17 00:00:00 2001 From: kumpera Date: Mon, 22 Feb 2010 21:17:53 +0000 Subject: [PATCH] 2010-02-22 Rodrigo Kumpera * metadata.c: Add mono_method_get_header_summary which returns * minimal information about the header of a method. This is the information used by the inline oracle to reject methods. This method doesn't decode local variables and doesn't cache it's result, so it should cause a minimal reduction in memory usage. * metadata-internals.h: Add MonoMethodHeaderSummary structure * and mono_method_get_header_summary. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mono@152204 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- mono/metadata/ChangeLog | 12 +++++++ mono/metadata/metadata-internals.h | 8 +++++ mono/metadata/metadata.c | 71 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index c010e6491..20d0ddb90 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,15 @@ +2010-02-22 Rodrigo Kumpera + + * metadata.c: Add mono_method_get_header_summary which returns minimal + information about the header of a method. This is the information used + by the inline oracle to reject methods. + + This method doesn't decode local variables and doesn't cache it's result, + so it should cause a minimal reduction in memory usage. + + * metadata-internals.h: Add MonoMethodHeaderSummary structure and + mono_method_get_header_summary. + 2010-02-22 Jeffrey Stedfast * threads.c (mono_thread_exit): Make sure that the main thread is diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index d6c35861d..12fe338a3 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -399,6 +399,11 @@ struct _MonoMethodHeader { MonoType *locals [MONO_ZERO_LEN_ARRAY]; }; +typedef struct { + guint32 code_size; + gboolean has_clauses; +} MonoMethodHeaderSummary; + #define MONO_SIZEOF_METHOD_HEADER (sizeof (struct _MonoMethodHeader) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P) /* for use with allocated memory blocks (assumes alignment is to 8 bytes) */ @@ -498,6 +503,9 @@ mono_metadata_parse_mh_full (MonoImage *image, MonoGenericContainer *container, const char *ptr); +gboolean +mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *summary) MONO_INTERNAL; + int* mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count) MONO_INTERNAL; gboolean mono_metadata_method_has_param_attrs (MonoImage *m, int def) MONO_INTERNAL; diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index af56ebb0b..caebbd361 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -3306,6 +3306,77 @@ parse_section_data (MonoImage *m, MonoMethodHeader *mh, const unsigned char *ptr } /* + * mono_method_get_header_summary: + * @method: The method to get the header. + * @summary: Where to store the header + * + * + * Returns: true if the header was properly decoded. + */ +gboolean +mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *summary) +{ + int idx; + guint32 rva; + MonoImage* img; + const char *ptr; + unsigned char flags, format; + guint16 fat_flags; + + /*Only the GMD has a pointer to the metadata.*/ + while (method->is_inflated) + method = ((MonoMethodInflated*)method)->declaring; + + summary->code_size = 0; + summary->has_clauses = FALSE; + + /*FIXME extract this into a MACRO and share it with mono_method_get_header*/ + if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) + return FALSE; + + if (method->klass->image->dynamic || ((MonoMethodNormal*) method)->header) { + MonoMethodHeader *header = mono_method_get_header (method); + if (!header) + return FALSE; + summary->code_size = header->code_size; + summary->has_clauses = header->num_clauses > 0; + return TRUE; + } + + + idx = mono_metadata_token_index (method->token); + img = method->klass->image; + rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA); + + /*We must run the verifier since we'll be decoding it.*/ + if (!mono_verifier_verify_method_header (img, rva, NULL)) + return FALSE; + + ptr = mono_image_rva_map (img, rva); + g_assert (ptr); + + flags = *(const unsigned char *)ptr; + format = flags & METHOD_HEADER_FORMAT_MASK; + + switch (format) { + case METHOD_HEADER_TINY_FORMAT: + ptr++; + summary->code_size = flags >> 2; + break; + case METHOD_HEADER_FAT_FORMAT: + fat_flags = read16 (ptr); + ptr += 4; + summary->code_size = read32 (ptr); + if (fat_flags & METHOD_HEADER_MORE_SECTS) + summary->has_clauses = TRUE; + break; + default: + return FALSE; + } + return TRUE; +} + +/* * mono_metadata_parse_mh_full: * @m: metadata context * @generic_context: generics context -- 2.11.4.GIT