-
Notifications
You must be signed in to change notification settings - Fork 526
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] Optionally preload all the assemblies from the apk #2724
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -779,6 +779,16 @@ AndroidSystem::setup_environment (jstring_wrapper& name, jstring_wrapper& value) | |
knownEnvVars.MonoLLVM = true; | ||
return; | ||
} | ||
|
||
if (strcmp (k, "mono.enable_assembly_preload") == 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...and regardless of what the default is, this should actually use the value specified. If someone does:
i.e. explicitly disable it via a user-provided There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
if (*v == '\0') | ||
knownEnvVars.EnableAssemblyPreload = KnownEnvironmentVariables::AssemblyPreloadDefault; | ||
else if (v[0] == '1') | ||
knownEnvVars.EnableAssemblyPreload = true; | ||
else | ||
knownEnvVars.EnableAssemblyPreload = false; | ||
return; | ||
} | ||
} | ||
|
||
add_system_property (k, v); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -957,7 +957,7 @@ mono_runtime_init (char *runtime_args) | |
} | ||
|
||
static MonoDomain* | ||
create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring assembly, jobject loader, bool is_root_domain) | ||
create_domain (JNIEnv *env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jobject loader, bool is_root_domain) | ||
{ | ||
MonoDomain *domain; | ||
int user_assemblies_count = 0;; | ||
|
@@ -1779,21 +1779,75 @@ _monodroid_counters_dump (const char *format, ...) | |
monoFunctions.counters_dump (XA_LOG_COUNTERS, counters); | ||
} | ||
|
||
static void | ||
load_assembly (MonoDomain *domain, JNIEnv *env, jstring_wrapper &assembly) | ||
{ | ||
timing_period total_time; | ||
if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) | ||
total_time.mark_start (); | ||
|
||
const char *assm_name = assembly.get_cstr (); | ||
MonoAssemblyName *aname; | ||
|
||
aname = monoFunctions.assembly_name_new (assm_name); | ||
|
||
if (domain != monoFunctions.domain_get ()) { | ||
MonoDomain *current = monoFunctions.domain_get (); | ||
monoFunctions.domain_set (domain, FALSE); | ||
monoFunctions.assembly_load_full (aname, NULL, NULL, 0); | ||
monoFunctions.domain_set (current, FALSE); | ||
} else { | ||
monoFunctions.assembly_load_full (aname, NULL, NULL, 0); | ||
} | ||
|
||
monoFunctions.assembly_name_free (aname); | ||
|
||
if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) { | ||
total_time.mark_end (); | ||
|
||
timing_diff diff (total_time); | ||
log_info (LOG_TIMING, "Assembly load: %s preloaded; elapsed: %lis:%lu::%lu", assm_name, diff.sec, diff.ms, diff.ns); | ||
} | ||
} | ||
|
||
static void | ||
load_assemblies (MonoDomain *domain, JNIEnv *env, jstring_array_wrapper &assemblies) | ||
{ | ||
timing_period total_time; | ||
if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) | ||
total_time.mark_start (); | ||
|
||
/* skip element 0, as that's loaded in create_domain() */ | ||
for (size_t i = 1; i < assemblies.get_length (); ++i) { | ||
jstring_wrapper &assembly = assemblies [i]; | ||
load_assembly (domain, env, assembly); | ||
} | ||
|
||
if (XA_UNLIKELY (utils.should_log (LOG_TIMING))) { | ||
total_time.mark_end (); | ||
|
||
timing_diff diff (total_time); | ||
log_info (LOG_TIMING, "Finished loading assemblies: preloaded %u assemblies; wasted time: %lis:%lu::%lu", assemblies.get_length (), diff.sec, diff.ms, diff.ns); | ||
} | ||
} | ||
|
||
static void | ||
monodroid_Mono_UnhandledException_internal (MonoException *ex) | ||
{ | ||
// Do nothing with it here, we let the exception naturally propagate on the managed side | ||
} | ||
|
||
static MonoDomain* | ||
create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jobjectArray assemblies, jobject loader, bool is_root_domain) | ||
create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring_array_wrapper &assemblies, jobject loader, bool is_root_domain) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @grendello I take it this means we can't get rid of the list of assemblies being passed in from the Java side now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dellis1972: that's exactly what this means There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alas |
||
{ | ||
MonoDomain* domain = create_domain (env, runtimeClass, runtimeApks, reinterpret_cast <jstring> (env->GetObjectArrayElement (assemblies, 0)), loader, is_root_domain); | ||
MonoDomain* domain = create_domain (env, runtimeClass, runtimeApks, loader, is_root_domain); | ||
|
||
// When running on desktop, the root domain is only a dummy so don't initialize it | ||
if (is_running_on_desktop && is_root_domain) | ||
return domain; | ||
|
||
if (androidSystem.is_assembly_preload_enabled ()) | ||
load_assemblies (domain, env, assemblies); | ||
init_android_runtime (domain, env, runtimeClass, loader); | ||
|
||
osBridge.add_monodroid_domain (domain); | ||
|
@@ -1804,7 +1858,7 @@ create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wr | |
JNIEXPORT void JNICALL | ||
Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, | ||
jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, | ||
jobjectArray externalStorageDirs, jobjectArray assemblies, jstring packageName, | ||
jobjectArray externalStorageDirs, jobjectArray assembliesJava, jstring packageName, | ||
jint apiLevel, jobjectArray environmentVariables) | ||
{ | ||
init_logging_categories (); | ||
|
@@ -1987,6 +2041,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject | |
log_info_nocheck (LOG_TIMING, "Runtime.init: Mono runtime init; elapsed: %lis:%lu::%lu", diff.sec, diff.ms, diff.ns); | ||
} | ||
|
||
jstring_array_wrapper assemblies (env, assembliesJava); | ||
/* the first assembly is used to initialize the AppDomain name */ | ||
create_and_initialize_domain (env, klass, runtimeApks, assemblies, loader, /*is_root_domain:*/ true); | ||
|
||
|
@@ -2070,14 +2125,15 @@ reinitialize_android_runtime_type_manager (JNIEnv *env) | |
} | ||
|
||
JNIEXPORT jint | ||
JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assemblies, jobject loader) | ||
JNICALL Java_mono_android_Runtime_createNewContext (JNIEnv *env, jclass klass, jobjectArray runtimeApksJava, jobjectArray assembliesJava, jobject loader) | ||
{ | ||
log_info (LOG_DEFAULT, "CREATING NEW CONTEXT"); | ||
reinitialize_android_runtime_type_manager (env); | ||
MonoDomain *root_domain = monoFunctions.get_root_domain (); | ||
monoFunctions.jit_thread_attach (root_domain); | ||
|
||
jstring_array_wrapper runtimeApks (env, runtimeApksJava); | ||
jstring_array_wrapper assemblies (env, assembliesJava); | ||
MonoDomain *domain = create_and_initialize_domain (env, klass, runtimeApks, assemblies, loader, /*is_root_domain:*/ false); | ||
monoFunctions.domain_set (domain, FALSE); | ||
int domain_id = monoFunctions.domain_get_id (domain); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.featureHeader { | ||
font-size: 20; | ||
font-style: bold; | ||
margin: 0,20,0,10; | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<TabbedPage | ||
xmlns="http://xamarin.com/schemas/2014/forms" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
x:Class="Xamarin.Forms.Performance.Integration.MainPage" | ||
Resources="{StyleSheet Source=../Global.css}"> | ||
</TabbedPage> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
|
||
using Xamarin.Forms; | ||
|
||
namespace Xamarin.Forms.Performance.Integration | ||
{ | ||
public partial class MainPage : TabbedPage | ||
{ | ||
public MainPage () | ||
{ | ||
InitializeComponent (); | ||
|
||
Page itemsPage, aboutPage = null; | ||
|
||
switch (Device.RuntimePlatform) { | ||
case Device.iOS: | ||
itemsPage = new NavigationPage (new ItemsPage ()) { | ||
Title = "Browse" | ||
}; | ||
|
||
aboutPage = new NavigationPage (new AboutPage ()) { | ||
Title = "About" | ||
}; | ||
itemsPage.Icon = "tab_feed.png"; | ||
aboutPage.Icon = "tab_about.png"; | ||
break; | ||
default: | ||
itemsPage = new ItemsPage () { | ||
Title = "Browse" | ||
}; | ||
|
||
aboutPage = new AboutPage () { | ||
Title = "About" | ||
}; | ||
break; | ||
} | ||
|
||
Children.Add (itemsPage); | ||
Children.Add (aboutPage); | ||
|
||
Title = Children [0].Title; | ||
} | ||
|
||
protected override void OnCurrentPageChanged () | ||
{ | ||
base.OnCurrentPageChanged (); | ||
Title = CurrentPage?.Title ?? string.Empty; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't immediately understand why this would use
$(IntermediateOutputPath)javastubs.cache
as an input...though that is what_SetupEmbeddedDSOs
does...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think an appropriate
Inputs
/Outputs
exists for this target, since there isn't a file that would influence what this does. I think we could just use<WriteLinesToFile WriteOnlyWhenDifferent="True"/>
and not use anyInputs
/Outputs
. msbuild docs_GenerateJavaStubs
writesjavastubs.cache
looking atandroid:extractNativeLibs="false"
, which determines the value of$(_EmbeddedDSOsEnabled)
. So that makes sense for_SetupEmbeddedDSOs
to usejavastubs.cache
as an input.