Skip to content

Commit

Permalink
2010-02-22 Rodrigo Kumpera <rkumpera@novell.com>
Browse files Browse the repository at this point in the history
	* 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.

svn path=/branches/mono-2-6/mono/; revision=152209
  • Loading branch information
kumpera committed Feb 22, 2010
1 parent faf43f0 commit bdc5f67
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
12 changes: 12 additions & 0 deletions mono/metadata/ChangeLog
@@ -1,3 +1,15 @@
2010-02-22 Rodrigo Kumpera <rkumpera@novell.com>

* 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.

2009-09-25 Zoltan Varga <vargaz@gmail.com>

* debug-helpers.c (dis_one): Avoid unaligned accesses on platforms where that is
Expand Down
8 changes: 8 additions & 0 deletions mono/metadata/metadata-internals.h
Expand Up @@ -377,6 +377,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) */
Expand Down Expand Up @@ -467,6 +472,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;

Expand Down
71 changes: 71 additions & 0 deletions mono/metadata/metadata.c
Expand Up @@ -2942,6 +2942,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
Expand Down

0 comments on commit bdc5f67

Please sign in to comment.