Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Add targets for AOT profiling (#3964)
Browse files Browse the repository at this point in the history
Fixes: #3792

Context: #3740
Context: #3963

Add the following targets to simplify Profiled AOT usage:

  * `BuildAndStartAotProfiling`
  * `FinishAotProfiling`

The `BuildAndStartAotProfiling` target builds an Application `.csproj`
with the AOT profiler embedded into the `.apk`, installs the `.apk`,
sets the AOT profiler socket port to `$(AndroidAotProfilerPort)`, and
starts the *launch* Activity on the target device.

`$(AndroidAotProfilerPort)` defaults to port 9999.

The `FinishAotProfiling` target attaches to the
`$(AndroidAotProfilerPort)` port, collects the AOT profiler data from
the target device, and writes the collected data into
`$(AndroidAotCustomProfilePath)`.

`$(AndroidAotCustomProfilePath)` defaults to `custom.aprof`.

The use of these two targets allows easily launching an Activity,
waiting for a period of time -- so that process startup can complete,
or so that some set of application behaviors can be included into the
profiled data -- and then collecting the profile.
  • Loading branch information
radekdoulik authored and jonpryor committed Dec 5, 2019
1 parent 83cd391 commit 853b367
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
23 changes: 23 additions & 0 deletions Documentation/guides/BuildProcess.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ The following build targets are defined for Xamarin.Android projects:
`Resource.designer.cs` file. This target is usually called by the
IDE when new resources are added to the project.

- **BuildAndStartAotProfiling** – Builds the package with
embedded AOT profiler, sets the AOT profiler socket port to
`$(AndroidAotProfilerPort)` and starts the *launch* activity.

Added in Xamarin.Android v10.3.

- **FinishAotProfiling** – Collects the AOT profiler data from
the device or the emulator through sockets port
`$(AndroidAotProfilerPort)` and writes them to
`$(AndroidAotCustomProfilePath)`.

The default values for port and custom profile are `9999` and
`custom.aprof`.

The `aprofutil` call may be extended with
`$(AProfUtilExtraOptions)`, to pass additional options.

This is equivalent to:

aprofutil $(AProfUtilExtraOptions) -s -v -f -p $(AndroidAotProfilerPort) -o "$(AndroidAotCustomProfilePath)"

Added in Xamarin.Android v10.3.

<a name="Build_Extension_Points" />

## Build Extension Points
Expand Down
21 changes: 21 additions & 0 deletions Documentation/release-notes/3964.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### Add new AOT profiling targets

The new `BuildAndStartAotProfiling` target builds the package with
embedded AOT profiler, sets AOT profiler socket port to
`$(AndroidAotProfilerPort)` and starts the *launch* activity.

The new `FinishAotProfiling` target collects the AOT profiler data
from the device or the emulator through sockets port
`$(AndroidAotProfilerPort)` and writes them to
`$(AndroidAotCustomProfilePath)`.

The default values for port and custom profile are `9999` and
`custom.aprof`.

The `aprofutil` call may be extended with
`$(AProfUtilExtraOptions)`, to pass additional options.

This is equivalent to:

aprofutil $(AProfUtilExtraOptions) -s -v -f -p $(AndroidAotProfilerPort) -o "$(AndroidAotCustomProfilePath)"

Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,30 @@ Copyright (C) 2019 Microsoft Corporation. All rights reserved.
</GetAndroidPackageName>
<Exec Command="&quot;$(AdbToolPath)adb&quot; $(AdbTarget) shell am force-stop &quot;$(_AndroidPackage)&quot;" />
</Target>
<PropertyGroup>
<AndroidAotCustomProfilePath Condition=" '$(AndroidAotCustomProfilePath)' == '' ">custom.aprof</AndroidAotCustomProfilePath>
<AndroidAotProfilerPort Condition=" '$(AndroidAotProfilerPort)' == '' ">9999</AndroidAotProfilerPort>
<_BeginAotProfilingDependsOnTargets>
_SetupAotProfiling;
Build;
Install;
_SetAotProfilingPropsOnDevice;
StartAndroidActivity;
</_BeginAotProfilingDependsOnTargets>
</PropertyGroup>
<Target Name="_SetupAotProfiling">
<PropertyGroup>
<AndroidEmbedProfilers>aot</AndroidEmbedProfilers>
</PropertyGroup>
</Target>
<Target Name="_SetAotProfilingPropsOnDevice">
<Exec Command="&quot;$(AdbToolPath)adb&quot; $(AdbTarget) shell setprop debug.mono.profile aot:port=$(AndroidAotProfilerPort)" />
</Target>
<Target Name="BuildAndStartAotProfiling"
DependsOnTargets="$(_BeginAotProfilingDependsOnTargets)">
</Target>
<Target Name="FinishAotProfiling"
DependsOnTargets="_ResolveSdks">
<Exec Command="&quot;$(MonoAndroidBinDirectory)aprofutil&quot; $(AProfUtilExtraOptions) -s -v -f -p $(AndroidAotProfilerPort) -o &quot;$(AndroidAotCustomProfilePath)&quot;" />
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,7 @@ because xbuild doesn't support framework reference assemblies.
<_PropertyCacheItems Include="BundleAssemblies=$(BundleAssemblies)" />
<_PropertyCacheItems Include="AotAssemblies=$(AotAssemblies)" />
<_PropertyCacheItems Include="AndroidAotMode=$(AndroidAotMode)" />
<_PropertyCacheItems Include="AndroidEmbedProfilers=$(AndroidEmbedProfilers)" />
<_PropertyCacheItems Include="AndroidEnableProfiledAot=$(AndroidEnableProfiledAot)" />
<_PropertyCacheItems Include="ExplicitCrunch=$(AndroidExplicitCrunch)" />
<_PropertyCacheItems Include="AndroidDexTool=$(AndroidDexTool)" />
Expand Down
29 changes: 29 additions & 0 deletions tests/MSBuildDeviceIntegration/Tests/AotProfileTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using NUnit.Framework;
using System.IO;
using Xamarin.ProjectTools;

namespace Xamarin.Android.Build.Tests
{
public class AotProfileTests : DeviceTest
{

[Test]
public void BuildBasicApplicationAndAotProfileIt ()
{
if (!HasDevices)
Assert.Ignore ("Skipping test. No devices available.");

var proj = new XamarinAndroidApplicationProject () { IsRelease = true };
proj.SetProperty (KnownProperties.AndroidSupportedAbis, "armeabi-v7a;x86");
var projDirectory = Path.Combine ("temp", TestName);
using (var b = CreateApkBuilder (projDirectory)) {
Assert.IsTrue (b.RunTarget (proj, "BuildAndStartAotProfiling"), "Run of BuildAndStartAotProfiling should have succeeded.");
System.Threading.Thread.Sleep (5000);
b.BuildLogFile = "build2.log";
Assert.IsTrue (b.RunTarget (proj, "FinishAotProfiling", doNotCleanupOnUpdate: true), "Run of FinishAotProfiling should have succeeded.");
var customProfile = Path.Combine (Root, projDirectory, "custom.aprof");
FileAssert.Exists (customProfile);
}
}
}
}

0 comments on commit 853b367

Please sign in to comment.