Skip to content

Commit 772a812

Browse files
[GC Bridge] Split ManagedValueManager and SimpleValueManager (#10222)
Context: #10198 This PR contains bits from #10198 which don't depend on new APIs in dotnet/runtime. * Turn `ManagedValueManager` into singleton, for safety/correctness, as we don't want to be calling `JavaMarsha.Initialize()` more than once. * Create `SimpleValueManager` for NativeAOT, which is the "simple" implementation that just leaks... Eventually, `ManagedValueManager` will use the new `JavaMarshal` APIs and `SimpleValueManager` will be used temporarily for NativeAOT. `SimpleValueManager` can be removed in the future when `JavaMarshal` is implemented for NativeAOT.
1 parent 25516e7 commit 772a812

File tree

12 files changed

+355
-56
lines changed

12 files changed

+355
-56
lines changed

src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/JavaInteropRuntime.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void init (IntPtr jnienv, IntPtr klass, IntPtr classLoader)
4343
EnvironmentPointer = jnienv,
4444
ClassLoader = new JniObjectReference (classLoader),
4545
TypeManager = typeManager,
46-
ValueManager = new ManagedValueManager (),
46+
ValueManager = new SimpleValueManager (),
4747
UseMarshalMemberBuilder = false,
4848
JniGlobalReferenceLogWriter = settings.GrefLog,
4949
JniLocalReferenceLogWriter = settings.LrefLog,

src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static NativeAotRuntimeOptions CreateJreVM (NativeAotRuntimeOptions builder)
6161
builder.TypeManager ??= new ManagedTypeManager ();
6262
#endif // NET
6363

64-
builder.ValueManager ??= new ManagedValueManager ();
64+
builder.ValueManager ??= new SimpleValueManager ();
6565
builder.ObjectReferenceManager ??= new ManagedObjectReferenceManager (builder.JniGlobalReferenceLogWriter, builder.JniLocalReferenceLogWriter);
6666

6767
if (builder.InvocationPointer != IntPtr.Zero || builder.EnvironmentPointer != IntPtr.Zero)

src/Mono.Android/Android.Runtime/AndroidRuntime.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool f
5858
{
5959
if (!reference.IsValid)
6060
return null;
61-
var peeked = JNIEnvInit.ValueManager?.PeekPeer (reference);
61+
var peeked = JniEnvironment.Runtime.ValueManager.PeekPeer (reference);
6262
var peekedExc = peeked as Exception;
6363
if (peekedExc == null) {
6464
var throwable = Java.Lang.Object.GetObject<Java.Lang.Throwable> (reference.Handle, JniHandleOwnership.DoNotTransfer);
6565
JniObjectReference.Dispose (ref reference, options);
6666
return throwable;
6767
}
6868
JniObjectReference.Dispose (ref reference, options);
69-
var unwrapped = JNIEnvInit.ValueManager?.PeekValue (peeked!.PeerReference) as Exception;
69+
var unwrapped = JniEnvironment.Runtime.ValueManager.PeekValue (peeked!.PeerReference) as Exception;
7070
if (unwrapped != null) {
7171
return unwrapped;
7272
}

src/Mono.Android/Android.Runtime/JNIEnv.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ internal static void PropagateUncaughtException (IntPtr env, IntPtr javaThreadPt
118118

119119
public static void WaitForBridgeProcessing ()
120120
{
121-
JNIEnvInit.ValueManager?.WaitForGCBridgeProcessing ();
121+
JniEnvironment.Runtime.ValueManager.WaitForGCBridgeProcessing ();
122122
}
123123

124124
public static IntPtr AllocObject (string jniClassName)

src/Mono.Android/Android.Runtime/JNIEnvInit.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ internal struct JnienvInitializeArgs {
4040
}
4141
#pragma warning restore 0649
4242

43-
internal static JniRuntime.JniValueManager? ValueManager;
4443
internal static bool IsRunningOnDesktop;
4544
internal static bool jniRemappingInUse;
4645
internal static bool MarshalMethodsEnabled;
@@ -88,7 +87,6 @@ static Type TypeGetType (string typeName) =>
8887
internal static void InitializeJniRuntime (JniRuntime runtime)
8988
{
9089
androidRuntime = runtime;
91-
ValueManager = runtime.ValueManager;
9290
SetSynchronizationContext ();
9391
}
9492

@@ -115,11 +113,15 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
115113
JniRuntime.JniValueManager valueManager;
116114
if (RuntimeFeature.ManagedTypeMap) {
117115
typeManager = new ManagedTypeManager ();
118-
valueManager = new ManagedValueManager ();
119116
} else {
120117
typeManager = new AndroidTypeManager (args->jniAddNativeMethodRegistrationAttributePresent != 0);
121-
valueManager = RuntimeType == DotNetRuntimeType.MonoVM ? new AndroidValueManager () : new ManagedValueManager ();
122118
}
119+
valueManager = RuntimeType switch
120+
{
121+
DotNetRuntimeType.MonoVM => new AndroidValueManager(),
122+
DotNetRuntimeType.CoreCLR => ManagedValueManager.GetOrCreateInstance(),
123+
_ => throw new NotSupportedException ($"No value manager for runtime type: {RuntimeType}"),
124+
};
123125
androidRuntime = new AndroidRuntime (
124126
args->env,
125127
args->javaVm,
@@ -128,7 +130,6 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
128130
valueManager,
129131
args->jniAddNativeMethodRegistrationAttributePresent != 0
130132
);
131-
ValueManager = androidRuntime.ValueManager;
132133

133134
IsRunningOnDesktop = args->isRunningOnDesktop == 1;
134135

src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs

Lines changed: 40 additions & 40 deletions
Large diffs are not rendered by default.

src/Mono.Android/Android.Runtime/JNINativeWrapper.g.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ foreach (var info in delegateTypes) {
268268
#>
269269
internal static <#= info.Return #> Wrap<#= info.Type #> (this <#= info.Type #> callback, <#= info.Signature #>)
270270
{
271-
JNIEnvInit.ValueManager?.WaitForGCBridgeProcessing ();
271+
Java.Interop.JniEnvironment.Runtime.ValueManager.WaitForGCBridgeProcessing ();
272272
try {
273273
<#= info.Return != "void" ? "return " : "" #>callback (<#= info.Invoke #>);
274274
} catch (Exception e) when (_unhandled_exception (e)) {

src/Mono.Android/Java.Interop/Runtime.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class Runtime {
1111
[Obsolete ("Please use Java.Interop.JniEnvironment.Runtime.ValueManager.GetSurfacedPeers()")]
1212
public static List<WeakReference> GetSurfacedObjects ()
1313
{
14-
var peers = JNIEnvInit.ValueManager!.GetSurfacedPeers ();
14+
var peers = JniEnvironment.Runtime.ValueManager.GetSurfacedPeers ();
1515
var r = new List<WeakReference> (peers.Count);
1616
foreach (var p in peers) {
1717
if (p.SurfacedPeer.TryGetTarget (out var target))

src/Mono.Android/Java.Lang/Object.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ protected void SetHandle (IntPtr value, JniHandleOwnership transfer)
111111
{
112112
var reference = new JniObjectReference (value);
113113
var options = FromJniHandleOwnership (transfer);
114-
JNIEnvInit.ValueManager?.ConstructPeer (
114+
JniEnvironment.Runtime.ValueManager.ConstructPeer (
115115
this,
116116
ref reference,
117117
value == IntPtr.Zero ? JniObjectReferenceOptions.None : options);
@@ -128,7 +128,7 @@ static JniObjectReferenceOptions FromJniHandleOwnership (JniHandleOwnership tran
128128

129129
internal static IJavaPeerable? PeekObject (IntPtr handle, Type? requiredType = null)
130130
{
131-
var peeked = JNIEnvInit.ValueManager?.PeekPeer (new JniObjectReference (handle));
131+
var peeked = JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (handle));
132132
if (peeked == null)
133133
return null;
134134
if (requiredType != null && !requiredType.IsAssignableFrom (peeked.GetType ()))
@@ -180,7 +180,7 @@ internal static T? _GetObject<
180180
if (handle == IntPtr.Zero)
181181
return null;
182182

183-
var r = JNIEnvInit.ValueManager!.GetPeer (new JniObjectReference (handle), type);
183+
var r = JniEnvironment.Runtime.ValueManager.GetPeer (new JniObjectReference (handle), type);
184184
JNIEnv.DeleteRef (handle, transfer);
185185
return r;
186186
}

src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ class ManagedValueManager : JniRuntime.JniValueManager
2222

2323
Dictionary<int, List<IJavaPeerable>>? RegisteredInstances = new Dictionary<int, List<IJavaPeerable>>();
2424

25-
internal ManagedValueManager ()
25+
static Lazy<ManagedValueManager> s_instance = new (() => new ManagedValueManager ());
26+
public static ManagedValueManager GetOrCreateInstance () => s_instance.Value;
27+
28+
ManagedValueManager ()
2629
{
2730
}
2831

0 commit comments

Comments
 (0)