Skip to content
Closed
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
74 changes: 48 additions & 26 deletions src/Mono.Android/Android.Runtime/AndroidRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,15 @@ public AndroidRuntimeOptions (IntPtr jnienv,
}

internal class AndroidObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
static int _grefc;
static int _weak_grefc;

public override int GlobalReferenceCount {
get {return RuntimeNativeMethods._monodroid_gref_get ();}
get {return Volatile.Read (ref _grefc);}
}

public override int WeakGlobalReferenceCount {
get {return RuntimeNativeMethods._monodroid_weak_gref_get ();}
get {return Volatile.Read (ref _weak_grefc);}
}

public override JniObjectReference CreateLocalReference (JniObjectReference value, ref int localReferenceCount)
Expand Down Expand Up @@ -176,20 +179,24 @@ public override void WriteGlobalReferenceLine (string format, params object?[] a

public override JniObjectReference CreateGlobalReference (JniObjectReference value)
{
var r = base.CreateGlobalReference (value);
var r = base.CreateGlobalReference (value);
int gc = Interlocked.Increment (ref _grefc);

var log = Logger.LogGlobalRef;
var ctype = log ? GetObjectRefType (value.Type) : (byte) '*';
var ntype = log ? GetObjectRefType (r.Type) : (byte) '*';
var tname = log ? Thread.CurrentThread.Name : null;
var tid = log ? Thread.CurrentThread.ManagedThreadId : 0;
var from = log ? new StringBuilder (new StackTrace (true).ToString ()) : null;
int gc = RuntimeNativeMethods._monodroid_gref_log_new (value.Handle, ctype, r.Handle, ntype, tname, tid, from, 1);
if (gc >= JNIEnvInit.gref_gc_threshold) {
Logger.Log (LogLevel.Warn, "monodroid-gc", gc + " outstanding GREFs. Performing a full GC!");
System.GC.Collect ();
}

if (!Logger.LogGlobalRef)
return r;

var ctype = GetObjectRefType (value.Type);
var ntype = GetObjectRefType (r.Type);
var tname = Thread.CurrentThread.Name;
var tid = Thread.CurrentThread.ManagedThreadId;
var from = new StringBuilder (new StackTrace (true).ToString ());
RuntimeNativeMethods._monodroid_gref_log_new (value.Handle, ctype, r.Handle, ntype, tname, tid, from, 1);

return r;
}

Expand All @@ -206,11 +213,17 @@ static byte GetObjectRefType (JniObjectReferenceType type)

public override void DeleteGlobalReference (ref JniObjectReference value)
{
var log = Logger.LogGlobalRef;
var ctype = log ? GetObjectRefType (value.Type) : (byte) '*';
var tname = log ? Thread.CurrentThread.Name : null;
var tid = log ? Thread.CurrentThread.ManagedThreadId : 0;
var from = log ? new StringBuilder (new StackTrace (true).ToString ()) : null;
Interlocked.Decrement (ref _grefc);

if (!Logger.LogGlobalRef) {
base.DeleteGlobalReference (ref value);
return;
}

var ctype = GetObjectRefType (value.Type);
var tname = Thread.CurrentThread.Name;
var tid = Thread.CurrentThread.ManagedThreadId;
var from = new StringBuilder (new StackTrace (true).ToString ());
RuntimeNativeMethods._monodroid_gref_log_delete (value.Handle, ctype, tname, tid, from, 1);

base.DeleteGlobalReference (ref value);
Expand All @@ -219,25 +232,34 @@ public override void DeleteGlobalReference (ref JniObjectReference value)
public override JniObjectReference CreateWeakGlobalReference (JniObjectReference value)
{
var r = base.CreateWeakGlobalReference (value);
Interlocked.Increment (ref _weak_grefc);

if (!Logger.LogGlobalRef)
return r;

var log = Logger.LogGlobalRef;
var ctype = log ? GetObjectRefType (value.Type) : (byte) '*';
var ntype = log ? GetObjectRefType (r.Type) : (byte) '*';
var tname = log ? Thread.CurrentThread.Name : null;
var tid = log ? Thread.CurrentThread.ManagedThreadId : 0;
var from = log ? new StringBuilder (new StackTrace (true).ToString ()) : null;
var ctype = GetObjectRefType (value.Type);
var ntype = GetObjectRefType (r.Type);
var tname = Thread.CurrentThread.Name;
var tid = Thread.CurrentThread.ManagedThreadId;
var from = new StringBuilder (new StackTrace (true).ToString ());
RuntimeNativeMethods._monodroid_weak_gref_new (value.Handle, ctype, r.Handle, ntype, tname, tid, from, 1);

return r;
}

public override void DeleteWeakGlobalReference (ref JniObjectReference value)
{
var log = Logger.LogGlobalRef;
var ctype = log ? GetObjectRefType (value.Type) : (byte) '*';
var tname = log ? Thread.CurrentThread.Name : null;
var tid = log ? Thread.CurrentThread.ManagedThreadId : 0;
var from = log ? new StringBuilder (new StackTrace (true).ToString ()) : null;
Interlocked.Decrement (ref _weak_grefc);

if (!Logger.LogGlobalRef) {
base.DeleteWeakGlobalReference (ref value);
return;
}

var ctype = GetObjectRefType (value.Type);
var tname = Thread.CurrentThread.Name;
var tid = Thread.CurrentThread.ManagedThreadId;
var from = new StringBuilder (new StackTrace (true).ToString ());
RuntimeNativeMethods._monodroid_weak_gref_delete (value.Handle, ctype, tname, tid, from, 1);

base.DeleteWeakGlobalReference (ref value);
Expand Down
Loading