Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime startup performance improvements #2515

Merged
merged 1 commit into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-tools/scripts/cmake-common.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_CmakeCommonFlags>-GNinja -DCMAKE_MAKE_PROGRAM=$(NinjaPath)</_CmakeCommonFlags>
<_CmakeAndroidFlags>$(_CmakeCommonFlags) -DANDROID_TOOLCHAIN=clang -DANDROID_NATIVE_API_LEVEL=$(AndroidNdkApiLevel) -DANDROID_PLATFORM=android-$(AndroidNdkApiLevel) -DCMAKE_TOOLCHAIN_FILE=$(AndroidNdkDirectory)\build\cmake\android.toolchain.cmake -DANDROID_NDK=$(AndroidNdkDirectory)</_CmakeAndroidFlags>
<_CmakeAndroidFlags>$(_CmakeCommonFlags) -DANDROID_STL="system" -DANDROID_CPP_FEATURES="" -DANDROID_TOOLCHAIN=clang -DANDROID_NATIVE_API_LEVEL=$(AndroidNdkApiLevel) -DANDROID_PLATFORM=android-$(AndroidNdkApiLevel) -DCMAKE_TOOLCHAIN_FILE=$(AndroidNdkDirectory)\build\cmake\android.toolchain.cmake -DANDROID_NDK=$(AndroidNdkDirectory)</_CmakeAndroidFlags>
</PropertyGroup>
</Project>
41 changes: 20 additions & 21 deletions src/Mono.Android/Android.Runtime/JNIEnv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,16 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
{
Logger.Categories = (LogCategories) args->logCategories;

var __start = new DateTime ();
Stopwatch stopper = null;
long elapsed, totalElapsed = 0;
if (Logger.LogTiming) {
__start = DateTime.UtcNow;
Logger.Log (LogLevel.Info,
"monodroid-timing",
"JNIEnv.Initialize start: " + (__start - new DateTime (1970, 1, 1)).TotalMilliseconds);
Logger.Log (LogLevel.Info,
"monodroid-timing",
"JNIEnv.Initialize: Logger JIT/etc. time: " + (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalMilliseconds + " [elapsed: " + (DateTime.UtcNow - __start).TotalMilliseconds + " ms]");
stopper = new Stopwatch ();
jonpryor marked this conversation as resolved.
Show resolved Hide resolved
stopper.Start ();
Logger.Log (LogLevel.Info, "monodroid-timing", "JNIEnv.Initialize start");
elapsed = stopper.ElapsedMilliseconds;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should call stopper.Stop() before accessing stopper.ElapsedMilliseconds, for consistency. (Otherwise it'll keep "running".)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's restarted a few lines after that. Calling .Stop before taking the measure costs time, thus making the measurement less accurate. And .Restart() later has the desired effect of resetting the timer after all the accounting work is done - thus, again, making the measurement more accurate.

totalElapsed += elapsed;
Logger.Log (LogLevel.Info, "monodroid-timing", $"JNIEnv.Initialize: Logger JIT/etc. time: elapsed {elapsed} ms]");
stopper.Restart ();
}

gref_gc_threshold = args->grefGcThreshold;
Expand Down Expand Up @@ -195,16 +196,14 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
#endif // JAVA_INTEROP

if (Logger.LogTiming) {
var __end = DateTime.UtcNow;
Logger.Log (LogLevel.Info,
"monodroid-timing",
"JNIEnv.Initialize: time: " + (__end - new DateTime (1970, 1, 1)).TotalMilliseconds + " [elapsed: " + (__end - __start).TotalMilliseconds + " ms]");
__start = DateTime.UtcNow;
elapsed = stopper.ElapsedMilliseconds;
totalElapsed += elapsed;
Logger.Log (LogLevel.Info, "monodroid-timing", $"JNIEnv.Initialize: managed runtime init time: elapsed {elapsed} ms]");
stopper.Restart ();
var _ = Java.Interop.TypeManager.jniToManaged;
__end = DateTime.UtcNow;
Logger.Log (LogLevel.Info,
"monodroid-timing",
"JNIEnv.Initialize: TypeManager init time: " + (__end - new DateTime (1970, 1, 1)).TotalMilliseconds + " [elapsed: " + (__end - __start).TotalMilliseconds + " ms]");
elapsed = stopper.ElapsedMilliseconds;
totalElapsed += elapsed;
Logger.Log (LogLevel.Info, "monodroid-timing", $"JNIEnv.Initialize: TypeManager init time: elapsed {elapsed} ms]");
}

AllocObjectSupported = androidSdkVersion > 10;
Expand Down Expand Up @@ -238,10 +237,10 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
Java.Lang.Thread.DefaultUncaughtExceptionHandler = defaultUncaughtExceptionHandler;
}

if (Logger.LogTiming)
Logger.Log (LogLevel.Info,
"monodroid-timing",
"JNIEnv.Initialize end: " + (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalMilliseconds);
if (Logger.LogTiming) {
totalElapsed += stopper.ElapsedMilliseconds;
Logger.Log (LogLevel.Info, "monodroid-timing", $"JNIEnv.Initialize end: elapsed {totalElapsed} ms");
}
}

internal static void Exit ()
Expand Down
7 changes: 6 additions & 1 deletion src/Mono.Android/java/mono/android/Runtime.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package mono.android;

public class Runtime {
static java.lang.Class java_lang_Class = java.lang.Class.class;;
static java.lang.Class java_lang_System = java.lang.System.class;
static java.lang.Class java_util_TimeZone = java.util.TimeZone.class;
static java.lang.Class mono_android_IGCUserPeer = mono.android.IGCUserPeer.class;
static java.lang.Class mono_android_GCUserPeer = mono.android.GCUserPeer.class;

private Runtime ()
{
}

public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName);
public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName, int apiLevel, String[] environmentVariables);
jonpryor marked this conversation as resolved.
Show resolved Hide resolved
public static native void register (String managedType, java.lang.Class nativeClass, String methods);
public static native void notifyTimeZoneChanged ();
public static native int createNewContext (String[] runtimeApks, String[] assemblies, ClassLoader loader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
externalLegacyDir
},
MonoPackageManager_Resources.Assemblies,
context.getPackageName ());
context.getPackageName (),
android.os.Build.VERSION.SDK_INT,
mono.android.app.XamarinAndroidEnvironmentVariables.Variables);

mono.android.app.ApplicationRegistration.registerApplications ();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package mono.android.app;

public class XamarinAndroidEnvironmentVariables
{
// Variables are specified the in "name", "value" pairs
public static final String[] Variables = new String[] {
//@ENVVARS@
};
}
101 changes: 0 additions & 101 deletions src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ public class BuildApk : Task

public ITaskItem[] BundleNativeLibraries { get; set; }

public ITaskItem[] Environments { get; set; }

public ITaskItem[] TypeMappings { get; set; }

[Required]
Expand Down Expand Up @@ -74,37 +72,24 @@ public class BuildApk : Task

public bool PreferNativeLibrariesWithDebugSymbols { get; set; }

public string AndroidAotMode { get; set; }

public string AndroidSequencePointsMode { get; set; }

public bool EnableLLVM { get; set; }

public bool EnableSGenConcurrent { get; set; }

public string AndroidEmbedProfilers { get; set; }
public string HttpClientHandlerType { get; set; }
public string TlsProvider { get; set; }
public string UncompressedFileExtensions { get; set; }


static readonly string MSBuildXamarinAndroidDirectory = Path.GetDirectoryName (typeof (BuildApk).Assembly.Location);

[Output]
public ITaskItem[] OutputFiles { get; set; }

[Output]
public string BuildId { get; set; }

bool _Debug {
get {
return string.Equals (Debug, "true", StringComparison.OrdinalIgnoreCase);
}
}

SequencePointsMode sequencePointsMode = SequencePointsMode.None;

Guid buildId = Guid.NewGuid ();

public ITaskItem[] LibraryProjectJars { get; set; }
string [] uncompressedFileExtensions;
Expand All @@ -125,7 +110,6 @@ void ExecuteWithAbi (string supportedAbis, string apkInputPath, string apkOutput
if (EmbedAssemblies && !BundleAssemblies)
AddAssemblies (apk);

AddEnvironment (apk);
AddRuntimeLibraries (apk, supportedAbis);
apk.Flush();
AddNativeLibraries (files, supportedAbis);
Expand Down Expand Up @@ -206,11 +190,9 @@ public override bool Execute ()
Log.LogDebugMessage (" Debug: {0}", Debug ?? "no");
Log.LogDebugMessage (" PreferNativeLibrariesWithDebugSymbols: {0}", PreferNativeLibrariesWithDebugSymbols);
Log.LogDebugMessage (" EmbedAssemblies: {0}", EmbedAssemblies);
Log.LogDebugMessage (" AndroidAotMode: {0}", AndroidAotMode);
Log.LogDebugMessage (" AndroidSequencePointsMode: {0}", AndroidSequencePointsMode);
Log.LogDebugMessage (" CreatePackagePerAbi: {0}", CreatePackagePerAbi);
Log.LogDebugMessage (" UncompressedFileExtensions: {0}", UncompressedFileExtensions);
Log.LogDebugTaskItems (" Environments:", Environments);
Log.LogDebugTaskItems (" ResolvedUserAssemblies:", ResolvedUserAssemblies);
Log.LogDebugTaskItems (" ResolvedFrameworkAssemblies:", ResolvedFrameworkAssemblies);
Log.LogDebugTaskItems (" NativeLibraries:", NativeLibraries);
Expand All @@ -220,8 +202,6 @@ public override bool Execute ()
Log.LogDebugTaskItems (" JavaLibraries:", JavaLibraries);
Log.LogDebugTaskItems (" LibraryProjectJars:", LibraryProjectJars);
Log.LogDebugTaskItems (" AdditionalNativeLibraryReferences:", AdditionalNativeLibraryReferences);
Log.LogDebugTaskItems (" HttpClientHandlerType:", HttpClientHandlerType);
Log.LogDebugMessage (" TlsProvider: {0}", TlsProvider);

Aot.TryGetSequencePointsMode (AndroidSequencePointsMode, out sequencePointsMode);

Expand All @@ -246,10 +226,6 @@ public override bool Execute ()
}
}

BuildId = buildId.ToString ();

Log.LogDebugMessage (" [Output] BuildId: {0}", BuildId);

OutputFiles = outputFiles.Select (a => new TaskItem (a)).ToArray ();

Log.LogDebugTaskItems (" [Output] OutputFiles :", OutputFiles);
Expand Down Expand Up @@ -349,83 +325,6 @@ static string GetTargetDirectory (string path)
return "assemblies";
}

void AddEnvironment (ZipArchiveEx apk)
{
var environment = new StringWriter () {
NewLine = "\n",
};

if (EnableLLVM) {
environment.WriteLine ("mono.llvm=true");
}

AotMode aotMode;
if (AndroidAotMode != null && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode)) {
environment.WriteLine ("mono.aot={0}", aotMode.ToString().ToLowerInvariant());
}

const string defaultLogLevel = "MONO_LOG_LEVEL=info";
const string defaultMonoDebug = "MONO_DEBUG=gen-compact-seq-points";
const string defaultHttpMessageHandler = "XA_HTTP_CLIENT_HANDLER_TYPE=System.Net.Http.HttpClientHandler, System.Net.Http";
const string defaultTlsProvider = "XA_TLS_PROVIDER=btls";
string xamarinBuildId = string.Format ("XAMARIN_BUILD_ID={0}", buildId);

bool haveLogLevel = false;
bool haveMonoDebug = false;
bool havebuildId = false;
bool haveHttpMessageHandler = false;
bool haveTlsProvider = false;
bool haveMonoGCParams = false;

foreach (ITaskItem env in Environments ?? new TaskItem[0]) {
environment.WriteLine ("## Source File: {0}", env.ItemSpec);
foreach (string line in File.ReadLines (env.ItemSpec)) {
var lineToWrite = line;
if (lineToWrite.StartsWith ("MONO_LOG_LEVEL=", StringComparison.Ordinal))
haveLogLevel = true;
if (lineToWrite.StartsWith ("MONO_GC_PARAMS=", StringComparison.Ordinal))
haveMonoGCParams = true;
if (lineToWrite.StartsWith ("XAMARIN_BUILD_ID=", StringComparison.Ordinal))
havebuildId = true;
if (lineToWrite.StartsWith ("MONO_DEBUG=", StringComparison.Ordinal)) {
haveMonoDebug = true;
if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains ("gen-compact-seq-points"))
lineToWrite = line + ",gen-compact-seq-points";
}
if (lineToWrite.StartsWith ("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal))
haveHttpMessageHandler = true;
if (lineToWrite.StartsWith ("XA_TLS_PROVIDER=", StringComparison.Ordinal))
haveTlsProvider = true;
environment.WriteLine (lineToWrite);
}
}

if (_Debug && !haveLogLevel) {
environment.WriteLine (defaultLogLevel);
}

if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug) {
environment.WriteLine (defaultMonoDebug);
}

if (!havebuildId)
environment.WriteLine (xamarinBuildId);

if (!haveHttpMessageHandler)
environment.WriteLine (HttpClientHandlerType == null ? defaultHttpMessageHandler : $"XA_HTTP_CLIENT_HANDLER_TYPE={HttpClientHandlerType.Trim ()}");
if (!haveTlsProvider)
environment.WriteLine (TlsProvider == null ? defaultTlsProvider : $"XA_TLS_PROVIDER={TlsProvider.Trim ()}");
if (!haveMonoGCParams) {
if (EnableSGenConcurrent)
environment.WriteLine ("MONO_GC_PARAMS=major=marksweep-conc");
else
environment.WriteLine ("MONO_GC_PARAMS=major=marksweep");
}

apk.Archive.AddEntry ("environment", environment.ToString (),
new UTF8Encoding (encoderShouldEmitUTF8Identifier:false));
}

class LibInfo
{
public string Path;
Expand Down
Loading