-
Notifications
You must be signed in to change notification settings - Fork 533
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New code to perform managed <-> java lookups (typemap)
Xamarin.Assembly needs to "translate" managed types to Java types and vice versa in order to provide a bridge between the two world. So far it has been done using a straightforward (and fast) method of performing the lookups - all the type pairs were stored in two tables of the same size, with all type names padded to the width of the longest name so that the `bsearch` C function can be used to quickly perform a binary search over the data set. This approach works very well at the expense of data size (shorter strings are 0-padded to the maximum width) and a slightly degraded performace because of the requirement to perform string comparisons. Furthermore, the lookup required that reflection is used to obtain full managed type name (when translating from managed to Java) or to get a `Type` instance from type name (when translating from Java to managed). For Release builds all the above data is placed in the `libxamarin-app.so` library, for Debug builds it is also placed in two files - one for each direction of lookup, described above. This commit is a slight improvement over the above scheme. It eliminates reflection from the process by using managed type tokens (which are integers) and using UUID/Guid of the module in which the type is found. This allows us to perform the binary search over the set of 20 bytes (16 bytes for the UUID and 4 bytes for the token ID) for managed to Java lookups and a single string comparison + binary search over a set of integers for the Java to managed lookup. Java type names must still be used because Java doesn't provide any equivalent to the .NET's type token and module UUID. Those names are still 0-padded to the width of the longest name but there are no longer duplicated. Managed type names are eliminated completely. If Xamarin.Android Instant Run is not used (which is the case for OSS code) for Debug builds, the operation is performed in the same way for both Release and Debug builds. If, however, Instant Run is in effect, the type maps are stored in several files with the .typemap extension - one per **module**. The files contain both the Java to managed maps as well as managed to Java maps (which use indexes into the Java to managed maps). All of those files are loaded during Debug app startup and used to construct a dataset which is the searched during all the lookups. TODO: - Performance changes - Size changes: - monodroid PR
- Loading branch information
Showing
30 changed files
with
1,563 additions
and
644 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
xamarin/monodroid:master@0f6725edfa09559afad58233d43f385122e31e8d | ||
grendello/monodroid:new-typemap@efe3956ce2e557b5f8286f984731e43c6ee402f7 | ||
mono/mono:2019-10@18920a83f423fb864a2263948737681968f5b2c8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
using Microsoft.Build.Framework; | ||
|
||
using Java.Interop.Tools.Cecil; | ||
using Java.Interop.Tools.Diagnostics; | ||
using Xamarin.Android.Tools; | ||
|
||
namespace Xamarin.Android.Tasks | ||
{ | ||
public class GenerateTypeMaps : AndroidTask | ||
{ | ||
public override string TaskPrefix => "GTM"; | ||
|
||
[Required] | ||
public ITaskItem[] ResolvedAssemblies { get; set; } | ||
|
||
[Required] | ||
public ITaskItem[] ResolvedUserAssemblies { get; set; } | ||
|
||
[Required] | ||
public ITaskItem [] FrameworkDirectories { get; set; } | ||
|
||
[Required] | ||
public string[] SupportedAbis { get; set; } | ||
|
||
[Required] | ||
public string OutputDirectory { get; set; } | ||
|
||
[Required] | ||
public bool GenerateNativeAssembly { get; set; } | ||
|
||
[Output] | ||
public string[] GeneratedBinaryTypeMaps { get; set; } | ||
|
||
public bool ErrorOnCustomJavaObject { get; set; } | ||
|
||
public override bool RunTask () | ||
{ | ||
try { | ||
Run (); | ||
} catch (XamarinAndroidException e) { | ||
Log.LogCodedError (string.Format ("XA{0:0000}", e.Code), e.MessageWithoutCode); | ||
if (MonoAndroidHelper.LogInternalExceptions) | ||
Log.LogMessage (e.ToString ()); | ||
} | ||
|
||
if (Log.HasLoggedErrors) { | ||
// Ensure that on a rebuild, we don't *skip* the `_GenerateJavaStubs` target, | ||
// by ensuring that the target outputs have been deleted. | ||
Files.DeleteFile (Path.Combine (OutputDirectory, "typemap.index"), Log); | ||
foreach (string file in Directory.EnumerateFiles (OutputDirectory, "*.typemap")) { | ||
Files.DeleteFile (file, Log); | ||
} | ||
} | ||
|
||
return !Log.HasLoggedErrors; | ||
} | ||
|
||
void Run () | ||
{ | ||
var interestingAssemblies = new HashSet<string> (StringComparer.OrdinalIgnoreCase); | ||
|
||
var res = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: true); | ||
foreach (var dir in FrameworkDirectories) { | ||
if (Directory.Exists (dir.ItemSpec)) | ||
res.SearchDirectories.Add (dir.ItemSpec); | ||
} | ||
|
||
foreach (ITaskItem assembly in ResolvedAssemblies) { | ||
res.Load (assembly.ItemSpec); | ||
if (String.Compare ("MonoAndroid", assembly.GetMetadata ("TargetFrameworkIdentifier"), StringComparison.Ordinal) != 0) | ||
continue; | ||
if (interestingAssemblies.Contains (assembly.ItemSpec)) | ||
continue; | ||
interestingAssemblies.Add (assembly.ItemSpec); | ||
} | ||
|
||
var tmg = new TypeMapGenerator ((string message) => Log.LogDebugMessage (message), SupportedAbis); | ||
if (!tmg.Generate (res, interestingAssemblies, OutputDirectory, GenerateNativeAssembly)) | ||
throw new XamarinAndroidException (99999, "Failed to generate type maps"); | ||
GeneratedBinaryTypeMaps = tmg.GeneratedBinaryTypeMaps.ToArray (); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.