Skip to content
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: 2 additions & 0 deletions dotnet/targets/Xamarin.Shared.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@
<_UseDynamicDependenciesForGeneratedCodeOptimizations Condition="'$(_UseDynamicDependenciesForGeneratedCodeOptimizations)' == ''">$(_UseDynamicDependenciesInsteadOfMarking)</_UseDynamicDependenciesForGeneratedCodeOptimizations>
<_UseLinkDescriptionForApplyPreserveAttribute Condition="'$(_UseLinkDescriptionForApplyPreserveAttribute)' == '' And '$(_XamarinRuntime)' == 'NativeAOT'">true</_UseLinkDescriptionForApplyPreserveAttribute>
<_UseLinkDescriptionForApplyPreserveAttribute Condition="'$(_UseLinkDescriptionForApplyPreserveAttribute)' == ''">$(_UseDynamicDependenciesInsteadOfMarking)</_UseLinkDescriptionForApplyPreserveAttribute>
<_UseDynamicDependenciesForMarkStaticRegistrar Condition="'$(_UseDynamicDependenciesForMarkStaticRegistrar)' == ''">$(_UseDynamicDependenciesInsteadOfMarking)</_UseDynamicDependenciesForMarkStaticRegistrar>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -759,6 +760,7 @@
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" BeforeStep="MarkStep" Type="Xamarin.Linker.Steps.PreserveBlockCodeStep" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(_UseDynamicDependenciesForBlockCodePreservation)' == 'true'" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" BeforeStep="MarkStep" Type="Xamarin.Linker.Steps.OptimizeGeneratedCodeStep" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(_UseDynamicDependenciesForGeneratedCodeOptimizations)' == 'true'" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" BeforeStep="MarkStep" Type="Xamarin.Linker.Steps.ApplyPreserveAttributeStep" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(_UseLinkDescriptionForApplyPreserveAttribute)' == 'true'" />
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" BeforeStep="MarkStep" Type="Xamarin.Linker.Steps.MarkForStaticRegistrarStep" Condition="'$(_AreAnyAssembliesTrimmed)' == 'true' And '$(_UseDynamicDependenciesForMarkStaticRegistrar)' == 'true'" />
<!-- The final decision to remove/keep the dynamic registrar must be done before the linking step -->
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)" BeforeStep="MarkStep" Type="MonoTouch.Tuner.RegistrarRemovalTrackingStep" />
<!-- TODO: these steps should probably run after mark. -->
Expand Down
1 change: 1 addition & 0 deletions tools/common/DerivedLinkContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class DerivedLinkContext : LinkContext {
Dictionary<TypeDefinition, LinkedAwayTypeReference> LinkedAwayTypeMap = new Dictionary<TypeDefinition, LinkedAwayTypeReference> ();

public bool DidRunApplyPreserveAttributeStep { get; set; }
public bool DidRunMarkForStaticRegistrarStep { get; set; }

public DerivedLinkContext (LinkerConfiguration configuration, Application app)
#if !LEGACY_TOOLS
Expand Down
4 changes: 4 additions & 0 deletions tools/dotnet-linker/MarkForStaticRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public class MarkForStaticRegistrar : ConfigurationAwareSubStep {

public override bool IsActiveFor (AssemblyDefinition assembly)
{
// It's either this step, or MarkForStaticRegistrarStep. If MarkForStaticRegistrarStep already ran, then we shouldn't run this step.
if (Configuration.DerivedLinkContext.DidRunMarkForStaticRegistrarStep)
return false;

if (Configuration.Application.Optimizations.OptimizeBlockLiteralSetupBlock != true)
return false;

Expand Down
66 changes: 66 additions & 0 deletions tools/dotnet-linker/MarkForStaticRegistrarStep.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Linq;

using Mono.Cecil;
using Mono.Linker;
using Registrar;
using Xamarin.Bundler;

#nullable enable

namespace Xamarin.Linker.Steps {

// This class marks APIs referenced by the native code generated by the static registrar.
public class MarkForStaticRegistrarStep : AssemblyModifierStep {
protected override string Name { get => "Mark For Static Registrar"; }

protected override int ErrorCode { get => 2460; }

protected override bool IsActiveFor (AssemblyDefinition assembly)
{
if (Configuration.Application.Optimizations.OptimizeBlockLiteralSetupBlock != true)
return false;

if (Configuration.Application.Registrar != RegistrarMode.Static)
return false;

return Annotations.GetAction (assembly) == AssemblyAction.Link;
}

protected override void TryProcess ()
{
DerivedLinkContext.DidRunMarkForStaticRegistrarStep = true;
base.TryProcess ();
}

protected override bool ProcessType (TypeDefinition type)
{
return base.ProcessMethods (type);
}

protected override bool ProcessMethod (MethodDefinition method)
{
return ProcessDelegateProxyAttribute (method);
}

// Mark the Invoke method in the type pointed to by the DelegateProxy attribute,
// because it may only be referenced from native code when using the static registrar.
bool ProcessDelegateProxyAttribute (MethodDefinition method)
{
if (!StaticRegistrar.IsDelegate (method.ReturnType.Resolve ()))
return false;

var getDelegateProxyType = DerivedLinkContext.StaticRegistrar.GetDelegateProxyType (method);
if (getDelegateProxyType is null)
return false;

Comment thread
rolfbjarne marked this conversation as resolved.
var invokeMethod = getDelegateProxyType.Methods.SingleOrDefault (m => m.Name == "Invoke");
Comment thread
rolfbjarne marked this conversation as resolved.
if (invokeMethod is null)
return false;

return abr.AddDynamicDependencyAttribute (method, invokeMethod);
}
}
}