Imported Upstream version 4.8.0.472

Former-commit-id: 1fce58ff6397a8cf9d2fca6564b434613689c418
This commit is contained in:
Xamarin Public Jenkins (auto-signing) 2017-01-24 11:33:27 +00:00
parent e5cd25ff4f
commit 5586c61ea6
39 changed files with 646 additions and 115 deletions

View File

@ -844,6 +844,26 @@ The offsets displayed are IL offsets.
.PP
A more powerful coverage tool is available in the module `monocov'.
See the monocov(1) man page for details.
.SH AOT PROFILING
You can improve startup performance by using the AOT profiler.
.PP
Typically the AOT compiler (\fBmono --aot\fR) will not generate code
for generic instantiations. To solve this, you can run Mono with the
AOT profiler to find out all the generic instantiations that are used,
and then instructing the AOT compiler to produce code for these.
.PP
This command will run the specified app.exe and produce the
\fBout.aotprof\fR file with the data describing the generic
instantiations that are needed:
.nf
$ mono --profile=aot:output=out.aotprof app.exe
.fi
.PP
Once you have this data, you can pass this to Mono's AOT compiler to
instruct it to generate code for it:
.nf
$ mono --aot=profile=out.aotprof
.fi
.SH DEBUGGING AIDS
To debug managed applications, you can use the
.B mdb

View File

@ -11,9 +11,9 @@
namespace System.Transactions
{
public delegate Transaction HostCurrentTransactionCallback ();
public delegate void TransactionCompletedEventHandler (object o,
public delegate void TransactionCompletedEventHandler (object sender,
TransactionEventArgs e);
public delegate void TransactionStartedEventHandler (object o,
public delegate void TransactionStartedEventHandler (object sender,
TransactionEventArgs e);
}

View File

@ -189,6 +189,26 @@ namespace System.Transactions
return true;
}
public void SetDistributedTransactionIdentifier (IPromotableSinglePhaseNotification promotableNotification, Guid distributedTransactionIdentifier)
{
throw new NotImplementedException ();
}
public bool EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
{
throw new NotImplementedException ();
}
public byte[] GetPromotedToken ()
{
throw new NotImplementedException ();
}
public Guid PromoterType
{
get { throw new NotImplementedException (); }
}
[MonoTODO ("EnlistmentOptions being ignored")]
public Enlistment EnlistVolatile (
IEnlistmentNotification notification,
@ -218,6 +238,17 @@ namespace System.Transactions
return new Enlistment ();
}
[MonoTODO ("Only Local Transaction Manager supported. Cannot have more than 1 durable resource per transaction.")]
[PermissionSetAttribute (SecurityAction.LinkDemand)]
public Enlistment PromoteAndEnlistDurable (
Guid manager,
IPromotableSinglePhaseNotification promotableNotification,
ISinglePhaseNotification notification,
EnlistmentOptions options)
{
throw new NotImplementedException ("DTC unsupported, multiple durable resource managers aren't supported.");
}
public override bool Equals (object obj)
{
return Equals (obj as Transaction);

View File

@ -14,7 +14,7 @@ namespace System.Transactions
[Serializable]
public class TransactionException : SystemException
{
protected TransactionException ()
public TransactionException ()
{
}

View File

@ -14,7 +14,7 @@ namespace System.Transactions
[Serializable]
public class TransactionInDoubtException : TransactionException
{
protected TransactionInDoubtException ()
public TransactionInDoubtException ()
{
}

View File

@ -15,6 +15,8 @@ namespace System.Transactions
[MonoTODO]
public static class TransactionInterop
{
public static readonly Guid PromoterTypeDtc = new Guid ("14229753-FFE1-428D-82B7-DF73045CB8DA");
[MonoTODO]
public static IDtcTransaction GetDtcTransaction (Transaction transaction)
{

View File

@ -14,7 +14,7 @@ namespace System.Transactions
[Serializable]
public class TransactionManagerCommunicationException : TransactionException
{
protected TransactionManagerCommunicationException ()
public TransactionManagerCommunicationException ()
{
}

View File

@ -14,7 +14,7 @@ namespace System.Transactions
[Serializable]
public class TransactionPromotionException : TransactionException
{
protected TransactionPromotionException ()
public TransactionPromotionException ()
{
}

View File

@ -102,6 +102,26 @@ namespace System.Transactions
TransactionManager.DefaultTimeout, TransactionScopeAsyncFlowOption.Suppress);
}
public TransactionScope (Transaction transactionToUse,
TransactionScopeAsyncFlowOption asyncFlowOption)
{
throw new NotImplementedException ();
}
public TransactionScope (Transaction transactionToUse,
TimeSpan scopeTimeout,
TransactionScopeAsyncFlowOption asyncFlowOption)
{
throw new NotImplementedException ();
}
public TransactionScope (TransactionScopeOption scopeOption,
TransactionOptions transactionOptions,
TransactionScopeAsyncFlowOption asyncFlowOption)
{
throw new NotImplementedException ();
}
void Initialize (TransactionScopeOption scopeOption,
Transaction tx, TransactionOptions options,
DTCOption interop, TimeSpan timeout, TransactionScopeAsyncFlowOption asyncFlow)

View File

@ -20,6 +20,10 @@ $(error Unknown framework version)
endif
endif
ifeq ($(PROFILE),build)
CSC_RUNTIME_FLAGS=--profile=aot:output=$(topdir)/class/lib/build/csc.aotprofile
endif
RESOURCE_STRINGS = ../referencesource/mscorlib/mscorlib.txt
LIBRARY_COMPILE = $(BOOT_COMPILE)

View File

@ -64,6 +64,15 @@ mono_btls_ssl_ctx_new (void)
memset (ctx, 0, sizeof (MonoBtlsSslCtx));
ctx->references = 1;
ctx->ctx = SSL_CTX_new (TLS_method ());
// enable the default ciphers but disable any RC4 based ciphers
// since they're insecure: RFC 7465 "Prohibiting RC4 Cipher Suites"
SSL_CTX_set_cipher_list (ctx->ctx, "DEFAULT:!RC4");
// disable SSLv2 and SSLv3 by default, they are deprecated
// and should generally not be used according to the openssl docs
SSL_CTX_set_options (ctx->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
return ctx;
}

View File

@ -36,8 +36,6 @@ mono_btls_ssl_new (MonoBtlsSslCtx *ctx)
ptr->ctx = mono_btls_ssl_ctx_up_ref (ctx);
ptr->ssl = SSL_new (mono_btls_ssl_ctx_get_ctx (ptr->ctx));
SSL_set_options (ptr->ssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
return ptr;
}

View File

@ -1003,16 +1003,16 @@ mono_install_get_cached_class_info (MonoGetCachedClassInfo func);
void
mono_install_get_class_from_name (MonoGetClassFromName func);
MonoGenericContext*
MONO_PROFILER_API MonoGenericContext*
mono_class_get_context (MonoClass *klass);
MonoMethodSignature*
MONO_PROFILER_API MonoMethodSignature*
mono_method_signature_checked (MonoMethod *m, MonoError *err);
MonoGenericContext*
mono_method_get_context_general (MonoMethod *method, gboolean uninflated);
MonoGenericContext*
MONO_PROFILER_API MonoGenericContext*
mono_method_get_context (MonoMethod *method);
/* Used by monodis, thus cannot be MONO_INTERNAL */
@ -1296,7 +1296,7 @@ MONO_API void mono_class_describe_statics (MonoClass* klass);
/* method debugging functions, for use inside gdb */
MONO_API void mono_method_print_code (MonoMethod *method);
char *mono_signature_full_name (MonoMethodSignature *sig);
MONO_PROFILER_API char *mono_signature_full_name (MonoMethodSignature *sig);
/*Enum validation related functions*/
MONO_API gboolean
@ -1305,6 +1305,12 @@ mono_type_is_valid_enum_basetype (MonoType * type);
MONO_API gboolean
mono_class_is_valid_enum (MonoClass *klass);
MONO_PROFILER_API gboolean
mono_type_is_primitive (MonoType *type);
MONO_PROFILER_API gboolean
mono_class_is_ginst (MonoClass *klass);
MonoType *
mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error);

View File

@ -1 +1 @@
a1c77761cdbb42ae1e799cfd298fccf01c6bebeb
ba097864604e44a8d83906ee85bdb3bb4091814b

View File

@ -700,5 +700,7 @@ mono_context_init_checked (MonoDomain *domain, MonoError *error);
gboolean
mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error);
GPtrArray*
mono_domain_get_assemblies (MonoDomain *domain, gboolean refonly);
#endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */

View File

@ -2052,3 +2052,24 @@ mono_domain_unlock (MonoDomain *domain)
{
mono_locks_coop_release (&domain->lock, DomainLock);
}
GPtrArray*
mono_domain_get_assemblies (MonoDomain *domain, gboolean refonly)
{
GSList *tmp;
GPtrArray *assemblies;
MonoAssembly *ass;
assemblies = g_ptr_array_new ();
mono_domain_assemblies_lock (domain);
for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
ass = (MonoAssembly *)tmp->data;
if (refonly != ass->ref_only)
continue;
if (ass->corlib_internal)
continue;
g_ptr_array_add (assemblies, ass);
}
mono_domain_assemblies_unlock (domain);
return assemblies;
}

View File

@ -1 +1 @@
4eb9a6416a9d3d3b7e5830b49dd0629e4c81cc9a
cc83f8242571580e8173442bdbb6d4ca671db338

View File

@ -1032,6 +1032,103 @@ install_pe_loader (void)
mono_install_image_loader (&pe_loader);
}
/*
Ignored assemblies.
There are some assemblies we need to ignore because they include an implementation that doesn't work under mono.
Mono provides its own implementation of those assemblies so it's safe to do so.
The ignored_assemblies list is generated using tools/nuget-hash-extractor and feeding the problematic nugets to it.
Right now the list of nugets are the ones that provide the assemblies in $ignored_assemblies_names.
This is to be removed once a proper fix is shipped through nuget.
*/
typedef enum {
SYS_RT_INTEROP_RUNTIME_INFO = 0, //System.Runtime.InteropServices.RuntimeInformation
SYS_GLOBALIZATION_EXT = 1, //System.Globalization.Extensions
SYS_IO_COMPRESSION = 2, //System.IO.Compression
SYS_NET_HTTP = 3, //System.Net.Http
SYS_TEXT_ENC_CODEPAGES = 4, //System.Text.Encoding.CodePages
} IgnoredAssemblyNames;
typedef struct {
int hash;
int assembly_name;
const char guid [40];
} IgnoredAssembly;
const char *ignored_assemblies_names[] = {
"System.Runtime.InteropServices.RuntimeInformation.dll",
"System.Globalization.Extensions.dll",
"System.IO.Compression.dll",
"System.Net.Http.dll",
"System.Text.Encoding.CodePages.dll"
};
#define IGNORED_ASSEMBLY(HASH, NAME, GUID, VER_STR) { .hash = HASH, .assembly_name = NAME, .guid = GUID }
static const IgnoredAssembly ignored_assemblies [] = {
IGNORED_ASSEMBLY (0x1136045D, SYS_GLOBALIZATION_EXT, "475DBF02-9F68-44F1-8FB5-C9F69F1BD2B1", "4.0.0 net46"),
IGNORED_ASSEMBLY (0x358C9723, SYS_GLOBALIZATION_EXT, "5FCD54F0-4B97-4259-875D-30E481F02EA2", "4.0.1 net46"),
IGNORED_ASSEMBLY (0x450A096A, SYS_GLOBALIZATION_EXT, "E9FCFF5B-4DE1-4BDC-9CE8-08C640FC78CC", "4.3.0 net46"),
IGNORED_ASSEMBLY (0x7A39EA2D, SYS_IO_COMPRESSION, "C665DC9B-D9E5-4D00-98ED-E4F812F23545", "4.0.0 netcore50"),
IGNORED_ASSEMBLY (0x1CBD59A2, SYS_IO_COMPRESSION, "44FCA06C-A510-4B3E-BDBF-D08D697EF65A", "4.1.0 net46"),
IGNORED_ASSEMBLY (0x5E393C29, SYS_IO_COMPRESSION, "3A58A219-266B-47C3-8BE8-4E4F394147AB", "4.3.0 net46"),
IGNORED_ASSEMBLY (0x726C7CC1, SYS_NET_HTTP, "7C0B577F-A4FD-47F1-ADF5-EE65B5A04BB5", "4.0.0 netcore50"),
IGNORED_ASSEMBLY (0x27726A90, SYS_NET_HTTP, "269B562C-CC15-4736-B1B1-68D4A43CAA98", "4.1.0 net46"),
IGNORED_ASSEMBLY (0x10CADA75, SYS_NET_HTTP, "EA2EC6DC-51DD-479C-BFC2-E713FB9E7E47", "4.1.1 net46"),
IGNORED_ASSEMBLY (0x8437178B, SYS_NET_HTTP, "C0E04D9C-70CF-48A6-A179-FBFD8CE69FD0", "4.3.0 net46"),
IGNORED_ASSEMBLY (0x46A4A1C5, SYS_RT_INTEROP_RUNTIME_INFO, "F13660F8-9D0D-419F-BA4E-315693DD26EA", "4.0.0 net45"),
IGNORED_ASSEMBLY (0xD07383BB, SYS_RT_INTEROP_RUNTIME_INFO, "DD91439F-3167-478E-BD2C-BF9C036A1395", "4.3.0 net45"),
IGNORED_ASSEMBLY (0x911D9EC3, SYS_TEXT_ENC_CODEPAGES, "C142254F-DEB5-46A7-AE43-6F10320D1D1F", "4.0.1 net46"),
IGNORED_ASSEMBLY (0xFA686A38, SYS_TEXT_ENC_CODEPAGES, "FD178CD4-EF4F-44D5-9C3F-812B1E25126B", "4.3.0 net46"),
};
/*
Equivalent C# code:
static void Main () {
string str = "...";
int h = 5381;
for (int i = 0; i < str.Length; ++i)
h = ((h << 5) + h) ^ str[i];
Console.WriteLine ("{0:X}", h);
}
*/
static int
hash_guid (const char *str)
{
int h = 5381;
while (*str) {
h = ((h << 5) + h) ^ *str;
++str;
}
return h;
}
static gboolean
is_problematic_image (MonoImage *image)
{
int h = hash_guid (image->guid);
//TODO make this more cache effiecient.
// Either sort by hash and bseach or use SoA and make the linear search more cache efficient.
for (int i = 0; i < G_N_ELEMENTS (ignored_assemblies); ++i) {
if (ignored_assemblies [i].hash == h && !strcmp (image->guid, ignored_assemblies [i].guid)) {
const char *needle = ignored_assemblies_names [ignored_assemblies [i].assembly_name];
size_t needle_len = strlen (needle);
size_t asm_len = strlen (image->name);
if (asm_len > needle_len && !g_ascii_strcasecmp (image->name + (asm_len - needle_len), needle))
return TRUE;
}
}
return FALSE;
}
static MonoImage *
do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
gboolean care_about_cli, gboolean care_about_pecoff)
@ -1087,6 +1184,12 @@ do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
if (!mono_image_load_cli_data (image))
goto invalid_image;
if (!image->ref_only && is_problematic_image (image)) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Denying load of problematic image %s", image->name);
*status = MONO_IMAGE_IMAGE_INVALID;
goto invalid_image;
}
if (image->loader == &pe_loader && !image->metadata_only && !mono_verifier_verify_table_data (image, &errors))
goto invalid_image;

View File

@ -861,7 +861,7 @@ EXTRA_DIST = TestDriver.cs \
Makefile.am.in
version.h: Makefile
echo "#define FULL_VERSION \"Stable 4.8.0.459/cd26828\"" > version.h
echo "#define FULL_VERSION \"Stable 4.8.0.472/6f90ed1\"" > version.h
# Utility target for patching libtool to speed up linking
patch-libtool:

View File

@ -861,7 +861,7 @@ EXTRA_DIST = TestDriver.cs \
Makefile.am.in
version.h: Makefile
echo "#define FULL_VERSION \"Stable 4.8.0.459/cd26828\"" > version.h
echo "#define FULL_VERSION \"Stable 4.8.0.472/6f90ed1\"" > version.h
# Utility target for patching libtool to speed up linking
patch-libtool:

View File

@ -1 +1 @@
2009d30f4c7c81d73738eea5151254163a75de36
433c6642ba1f57db104a712c141ab90d44e55c49

View File

@ -1 +1 @@
6dca377cb02fbc8588f0c3c97690bde945b3a67c
c4f44c2ecbc5dc6f0532c59ad55c2f46f1ed7f73

View File

@ -1 +1 @@
941d5017d0fde6e040cd78412ee8cf2a08ca9376
2fd57cf8561234d38c90801e15fa271c5a719a82

View File

@ -15,6 +15,7 @@
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/mono-debug-debugger.h>
#include <mono/metadata/debug-mono-symfile.h>
#include <mono/utils/mono-counters.h>
#if !defined(DISABLE_JIT) && !defined(DISABLE_LLDB)
@ -49,10 +50,15 @@ typedef struct
guint32 version;
/* Align */
guint32 dummy;
/* Keep these as pointers so accessing them is atomic */
DebugEntry *entry;
/* List of all entries */
/* Keep this as a pointer so accessing it is atomic */
DebugEntry *all_entries;
/* The current entry embedded here to reduce the amount of roundtrips */
guint32 type;
guint32 dummy2;
guint64 size;
guint64 addr;
} JitDescriptor;
/*
@ -114,6 +120,8 @@ static GHashTable *codegen_regions;
static DebugEntry *last_entry;
static mono_mutex_t mutex;
static GHashTable *dyn_codegen_regions;
static double register_time;
static int num_entries;
#define lldb_lock() mono_os_mutex_lock (&mutex)
#define lldb_unlock() mono_os_mutex_unlock (&mutex)
@ -291,7 +299,17 @@ add_entry (EntryType type, Buffer *buf)
}
__mono_jit_debug_descriptor.entry = entry;
__mono_jit_debug_descriptor.type = entry->type;
__mono_jit_debug_descriptor.size = entry->size;
__mono_jit_debug_descriptor.addr = entry->addr;
mono_memory_barrier ();
GTimer *timer = mono_time_track_start ();
__mono_jit_debug_register_code ();
mono_time_track_end (&register_time, timer);
num_entries ++;
//printf ("%lf %d %d\n", register_time, num_entries, entry->type);
lldb_unlock ();
}
@ -395,6 +413,8 @@ mono_lldb_init (const char *options)
{
enabled = TRUE;
mono_os_mutex_init_recursive (&mutex);
mono_counters_register ("Time spent in LLDB", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &register_time);
}
typedef struct
@ -600,6 +620,13 @@ mono_lldb_save_trampoline_info (MonoTrampInfo *info)
void
mono_lldb_save_specific_trampoline_info (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, gpointer code, guint32 code_len)
{
/*
* Avoid emitting these for now,
* they slow down execution too much, and they are
* only needed during single stepping which doesn't
* work anyway.
*/
#if 0
TrampolineEntry *entry;
UserData udata;
int region_id;
@ -635,6 +662,7 @@ mono_lldb_save_specific_trampoline_info (gpointer arg1, MonoTrampolineType tramp
add_entry (ENTRY_TRAMPOLINE, buf);
buffer_free (buf);
#endif
}
/*

View File

@ -1 +1 @@
#define FULL_VERSION "Stable 4.8.0.459/cd26828"
#define FULL_VERSION "Stable 4.8.0.472/6f90ed1"

View File

@ -111,6 +111,7 @@ testlog: $(PLOG_TESTS)
check-local: $(check_targets)
EXTRA_DIST=mono-profiler-log.h \
mono-profiler-aot.h \
$(PLOG_TESTS_SRC) \
ptestrunner.pl \
$(suppression_DATA)

View File

@ -582,6 +582,7 @@ with_mono_path = MONO_PATH=$(CLASS)
RUNTIME = $(with_mono_path) $(top_builddir)/runtime/mono-wrapper
MCS = $(RUNTIME) $(mcs_topdir)/class/lib/build/mcs.exe -unsafe -nowarn:0162 -nowarn:0168 -nowarn:0219 -debug
EXTRA_DIST = mono-profiler-log.h \
mono-profiler-aot.h \
$(PLOG_TESTS_SRC) \
ptestrunner.pl \
$(suppression_DATA)

View File

@ -13,11 +13,16 @@
*/
#include <config.h>
#include "mono-profiler-aot.h"
#include <mono/metadata/profiler.h>
#include <mono/metadata/tokentype.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/class-internals.h>
#include <mono/utils/mono-os-mutex.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
@ -29,90 +34,16 @@
#endif
struct _MonoProfiler {
GHashTable *classes;
GHashTable *images;
GPtrArray *methods;
FILE *outfile;
int id;
char *outfile_name;
};
typedef struct {
GList *methods;
} PerImageData;
typedef struct ForeachData {
MonoProfiler *prof;
FILE *outfile;
MonoImage *image;
MonoMethod *method;
} ForeachData;
static void
foreach_method (gpointer data, gpointer user_data)
{
ForeachData *udata = (ForeachData*)user_data;
MonoMethod *method = (MonoMethod*)data;
char *name;
if (!mono_method_get_token (method) || mono_class_get_image (mono_method_get_class (method)) != udata->image)
return;
name = mono_method_full_name (method, TRUE);
fprintf (udata->outfile, "%s\n", name);
g_free (name);
}
static void
output_image (gpointer key, gpointer value, gpointer user_data)
{
MonoImage *image = (MonoImage*)key;
PerImageData *image_data = (PerImageData*)value;
MonoProfiler *prof = (MonoProfiler*)user_data;
char *tmp, *outfile_name;
FILE *outfile;
int i, err;
ForeachData data;
tmp = g_strdup_printf ("%s/.mono/aot-profile-data", g_get_home_dir ());
if (!g_file_test (tmp, G_FILE_TEST_IS_DIR)) {
#ifdef HOST_WIN32
err = mkdir (tmp);
#else
err = mkdir (tmp, 0777);
#endif
if (err) {
fprintf (stderr, "mono-profiler-aot: Unable to create output directory '%s': %s\n", tmp, g_strerror (errno));
exit (1);
}
}
i = 0;
while (TRUE) {
outfile_name = g_strdup_printf ("%s/%s-%d", tmp, mono_image_get_name (image), i);
if (!g_file_test (outfile_name, G_FILE_TEST_IS_REGULAR))
break;
i ++;
}
printf ("Creating output file: %s\n", outfile_name);
outfile = fopen (outfile_name, "w+");
g_assert (outfile);
fprintf (outfile, "#VER:%d\n", 2);
data.prof = prof;
data.outfile = outfile;
data.image = image;
g_list_foreach (image_data->methods, foreach_method, &data);
}
/* called at the end of the program */
static void
prof_shutdown (MonoProfiler *prof)
{
g_hash_table_foreach (prof->images, output_image, prof);
}
static mono_mutex_t mutex;
static gboolean verbose;
static void
prof_jit_enter (MonoProfiler *prof, MonoMethod *method)
@ -123,15 +54,66 @@ static void
prof_jit_leave (MonoProfiler *prof, MonoMethod *method, int result)
{
MonoImage *image = mono_class_get_image (mono_method_get_class (method));
PerImageData *data;
data = (PerImageData *)g_hash_table_lookup (prof->images, image);
if (!data) {
data = g_new0 (PerImageData, 1);
g_hash_table_insert (prof->images, image, data);
if (!image->assembly || method->wrapper_type)
return;
mono_os_mutex_lock (&mutex);
g_ptr_array_add (prof->methods, method);
mono_os_mutex_unlock (&mutex);
}
static void
prof_shutdown (MonoProfiler *prof);
static void
usage (int do_exit)
{
printf ("AOT profiler.\n");
printf ("Usage: mono --profile=aot[:OPTION1[,OPTION2...]] program.exe\n");
printf ("Options:\n");
printf ("\thelp show this usage info\n");
printf ("\toutput=FILENAME write the data to file FILENAME (required)\n");
printf ("\tverbose print diagnostic info\n");
if (do_exit)
exit (1);
}
static const char*
match_option (const char* p, const char *opt, char **rval)
{
int len = strlen (opt);
if (strncmp (p, opt, len) == 0) {
if (rval) {
if (p [len] == '=' && p [len + 1]) {
const char *opt = p + len + 1;
const char *end = strchr (opt, ',');
char *val;
int l;
if (end == NULL) {
l = strlen (opt);
} else {
l = end - opt;
}
val = (char *) g_malloc (l + 1);
memcpy (val, opt, l);
val [l] = 0;
*rval = val;
return opt + l;
}
if (p [len] == 0 || p [len] == ',') {
*rval = NULL;
return p + len + (p [len] == ',');
}
usage (1);
} else {
if (p [len] == 0)
return p + len;
if (p [len] == ',')
return p + len + 1;
}
}
data->methods = g_list_append (data->methods, method);
return p;
}
void
@ -142,15 +124,282 @@ void
mono_profiler_startup (const char *desc)
{
MonoProfiler *prof;
const char *p;
const char *opt;
char *outfile_name;
p = desc;
if (strncmp (p, "aot", 3))
usage (1);
p += 3;
if (*p == ':')
p++;
for (; *p; p = opt) {
char *val;
if (*p == ',') {
opt = p + 1;
continue;
}
if ((opt = match_option (p, "help", NULL)) != p) {
usage (0);
continue;
}
if ((opt = match_option (p, "verbose", NULL)) != p) {
verbose = TRUE;
continue;
}
if ((opt = match_option (p, "output", &val)) != p) {
outfile_name = val;
continue;
}
fprintf (stderr, "mono-profiler-aot: Unknown option: '%s'.\n", p);
exit (1);
}
if (!outfile_name) {
fprintf (stderr, "mono-profiler-aot: The 'output' argument is required.\n");
exit (1);
}
prof = g_new0 (MonoProfiler, 1);
prof->images = g_hash_table_new (NULL, NULL);
prof->classes = g_hash_table_new (NULL, NULL);
prof->methods = g_ptr_array_new ();
prof->outfile_name = outfile_name;
mono_os_mutex_init (&mutex);
mono_profiler_install (prof, prof_shutdown);
mono_profiler_install_jit_compile (prof_jit_enter, prof_jit_leave);
mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION);
}
static void
emit_byte (MonoProfiler *prof, guint8 value)
{
fwrite (&value, 1, 1, prof->outfile);
}
static void
emit_int32 (MonoProfiler *prof, int value)
{
// FIXME: Endianness
fwrite (&value, 4, 1, prof->outfile);
}
static void
emit_string (MonoProfiler *prof, const char *str)
{
int len = strlen (str);
emit_int32 (prof, len);
fwrite (str, len, 1, prof->outfile);
}
static void
emit_record (MonoProfiler *prof, AotProfRecordType type, int id)
{
emit_byte (prof, type);
emit_int32 (prof, id);
}
static int
add_image (MonoProfiler *prof, MonoImage *image)
{
int id = GPOINTER_TO_INT (g_hash_table_lookup (prof->images, image));
if (id)
return id - 1;
id = prof->id ++;
emit_record (prof, AOTPROF_RECORD_IMAGE, id);
emit_string (prof, image->assembly->aname.name);
emit_string (prof, image->guid);
g_hash_table_insert (prof->images, image, GINT_TO_POINTER (id + 1));
return id;
}
static int
add_class (MonoProfiler *prof, MonoClass *klass);
static int
add_type (MonoProfiler *prof, MonoType *type)
{
switch (type->type) {
#if 0
case MONO_TYPE_SZARRAY: {
int eid = add_type (prof, &type->data.klass->byval_arg);
if (eid == -1)
return -1;
int id = prof->id ++;
emit_record (prof, AOTPROF_RECORD_TYPE, id);
emit_byte (prof, MONO_TYPE_SZARRAY);
emit_int32 (prof, id);
return id;
}
#endif
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_CHAR:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
case MONO_TYPE_I2:
case MONO_TYPE_U2:
case MONO_TYPE_I4:
case MONO_TYPE_U4:
case MONO_TYPE_I8:
case MONO_TYPE_U8:
case MONO_TYPE_R4:
case MONO_TYPE_R8:
case MONO_TYPE_I:
case MONO_TYPE_U:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_GENERICINST:
return add_class (prof, mono_class_from_mono_type (type));
default:
return -1;
}
}
static int
add_ginst (MonoProfiler *prof, MonoGenericInst *inst)
{
int i, id;
int *ids;
// FIXME: Cache
ids = g_malloc0 (inst->type_argc * sizeof (int));
for (i = 0; i < inst->type_argc; ++i) {
MonoType *t = inst->type_argv [i];
ids [i] = add_type (prof, t);
if (ids [i] == -1) {
g_free (ids);
return -1;
}
}
id = prof->id ++;
emit_record (prof, AOTPROF_RECORD_GINST, id);
emit_int32 (prof, inst->type_argc);
for (i = 0; i < inst->type_argc; ++i)
emit_int32 (prof, ids [i]);
g_free (ids);
return id;
}
static int
add_class (MonoProfiler *prof, MonoClass *klass)
{
int id, inst_id = -1, image_id;
char *name;
id = GPOINTER_TO_INT (g_hash_table_lookup (prof->classes, klass));
if (id)
return id - 1;
image_id = add_image (prof, klass->image);
if (mono_class_is_ginst (klass)) {
MonoGenericContext *ctx = mono_class_get_context (klass);
inst_id = add_ginst (prof, ctx->class_inst);
if (inst_id == -1)
return -1;
}
if (klass->nested_in)
name = g_strdup_printf ("%s.%s/%s", klass->nested_in->name_space, klass->nested_in->name, klass->name);
else
name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
id = prof->id ++;
emit_record (prof, AOTPROF_RECORD_TYPE, id);
emit_byte (prof, MONO_TYPE_CLASS);
emit_int32 (prof, image_id);
emit_int32 (prof, inst_id);
emit_string (prof, name);
g_free (name);
g_hash_table_insert (prof->classes, klass, GINT_TO_POINTER (id + 1));
return id;
}
static void
add_method (MonoProfiler *prof, MonoMethod *m)
{
MonoError error;
MonoMethodSignature *sig;
char *s;
sig = mono_method_signature_checked (m, &error);
g_assert (mono_error_ok (&error));
int class_id = add_class (prof, m->klass);
if (class_id == -1)
return;
int inst_id = -1;
if (m->is_inflated) {
MonoGenericContext *ctx = mono_method_get_context (m);
if (ctx->method_inst)
inst_id = add_ginst (prof, ctx->method_inst);
}
int id = prof->id ++;
emit_record (prof, AOTPROF_RECORD_METHOD, id);
emit_int32 (prof, class_id);
emit_int32 (prof, inst_id);
emit_int32 (prof, sig->param_count);
emit_string (prof, m->name);
s = mono_signature_full_name (sig);
emit_string (prof, s);
g_free (s);
if (verbose)
printf ("%s %d\n", mono_method_full_name (m, 1), id);
}
/* called at the end of the program */
static void
prof_shutdown (MonoProfiler *prof)
{
FILE *outfile;
int mindex;
char magic [32];
printf ("Creating output file: %s\n", prof->outfile_name);
outfile = fopen (prof->outfile_name, "w+");
if (!outfile) {
fprintf (stderr, "Unable to create output file '%s': %s.\n", prof->outfile_name, strerror (errno));
return;
}
prof->outfile = outfile;
gint32 version = (AOT_PROFILER_MAJOR_VERSION << 16) | AOT_PROFILER_MINOR_VERSION;
sprintf (magic, AOT_PROFILER_MAGIC);
fwrite (magic, strlen (magic), 1, outfile);
emit_int32 (prof, version);
GHashTable *all_methods = g_hash_table_new (NULL, NULL);
for (mindex = 0; mindex < prof->methods->len; ++mindex) {
MonoMethod *m = (MonoMethod*)g_ptr_array_index (prof->methods, mindex);
if (!mono_method_get_token (m))
continue;
if (g_hash_table_lookup (all_methods, m))
continue;
g_hash_table_insert (all_methods, m, m);
add_method (prof, m);
}
emit_record (prof, AOTPROF_RECORD_NONE, 0);
fclose (outfile);
g_hash_table_destroy (all_methods);
g_hash_table_destroy (prof->classes);
g_hash_table_destroy (prof->images);
g_ptr_array_free (prof->methods, TRUE);
g_free (prof->outfile_name);
}

View File

@ -0,0 +1,33 @@
#ifndef __MONO_PROFILER_AOT_H__
#define __MONO_PROFILER_AOT_H__
#include <config.h>
/*
* File format:
* - magic
* - major/minor version as an int, i.e. 0x00010001
* - sequence of records terminated by a record with type TYPE_NONE
* Record format:
* - 1 byte record type (AotProfRecordType)
* - 1 int record id
* - record specific data
* Encoding rules:
* - int - 4 bytes little endian
* - string - int length followed by data
*/
typedef enum {
AOTPROF_RECORD_NONE,
AOTPROF_RECORD_IMAGE,
AOTPROF_RECORD_TYPE,
AOTPROF_RECORD_GINST,
AOTPROF_RECORD_METHOD
} AotProfRecordType;
#define AOT_PROFILER_MAGIC "AOTPROFILE"
#define AOT_PROFILER_MAJOR_VERSION 1
#define AOT_PROFILER_MINOR_VERSION 0
#endif /* __MONO_PROFILER_AOT_H__ */

View File

@ -275,6 +275,9 @@ typedef SSIZE_T ssize_t;
#define MONO_LLVM_INTERNAL
#endif
/* Used to mark internal functions used by the profiler modules */
#define MONO_PROFILER_API MONO_API
#ifdef __GNUC__
#define MONO_ALWAYS_INLINE __attribute__((always_inline))
#elif defined(_MSC_VER)

Binary file not shown.

View File

@ -1 +1 @@
0b495da280aeb0edcc452a19ef2728a220e29836
06d95eb77e22edab191d4d09927b233c5d2de3cb

Binary file not shown.

View File

@ -1 +1 @@
c1046188be652d3ba506a743ccd1edd5d769f03a
c414cbd1a565f26f5628939e9a70676d3653d428

Binary file not shown.

View File

@ -1 +1 @@
15cfccc89d5d9835e017c1a4fe825b3685724c8d
5030d72210cdffe84371eb3e9f1e89261daf28da

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: mono 4.8.0\n"
"Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n"
"POT-Creation-Date: 2017-01-19 13:16+0000\n"
"POT-Creation-Date: 2017-01-24 10:53+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

Binary file not shown.

View File

@ -1 +1 @@
3b041571f966e8ba5599018c48ef0a1ec7219b3e
c9139a77cfe82ac0c042be33e9c22a6461d370c6