private static unsafe void TryExplicitlyCallJni() { Console.WriteLine("Part2: Check JNI Calls..."); var vm = JniRuntime.CurrentRuntime; Console.WriteLine("# JniEnvironment.EnvironmentPointer={0}", JniEnvironment.EnvironmentPointer); Console.WriteLine("vm.SafeHandle={0}", vm.InvocationPointer); var t = new JniType("java/lang/Object"); var c = t.GetConstructor("()V"); var o = t.NewObject(c, null); var m = t.GetInstanceMethod("hashCode", "()I"); int i = JniEnvironment.InstanceMethods.CallIntMethod(o, m); Console.WriteLine("java.lang.Object={0}", o); Console.WriteLine("hashcode={0}", i); JniObjectReference.Dispose(ref o); t.Dispose(); // var o = JniTypes.FindClass ("java/lang/Object"); /* * var waitForCreation = new CountdownEvent (1); * var exitThread = new CountdownEvent (1); * var t = new Thread (() => { * var vm2 = new JavaVMBuilder ().CreateJavaVM (); * waitForCreation.Signal (); * exitThread.Wait (); * }); * t.Start (); * waitForCreation.Wait (); */ }
public unsafe void Name() { using (var Object_class = new JniType("java/lang/Object")) using (var Class_class = new JniType("java/lang/Class")) using (var Method_class = new JniType("java/lang/reflect/Method")) { var Class_getMethod = Class_class.GetInstanceMethod("getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); var Method_getReturnType = Method_class.GetInstanceMethod("getReturnType", "()Ljava/lang/Class;"); var hashCode_str = JniEnvironment.Strings.NewString("hashCode"); var emptyArray = JniEnvironment.Arrays.NewObjectArray(0, Class_class.PeerReference, new JniObjectReference()); var getHashcodeMethodArgs = stackalloc JniArgumentValue [2]; getHashcodeMethodArgs [0] = new JniArgumentValue(hashCode_str); getHashcodeMethodArgs [1] = new JniArgumentValue(emptyArray); var Object_hashCode = JniEnvironment.InstanceMethods.CallObjectMethod(Object_class.PeerReference, Class_getMethod, getHashcodeMethodArgs); var Object_hashCode_rt = JniEnvironment.InstanceMethods.CallObjectMethod(Object_hashCode, Method_getReturnType); try { Assert.AreEqual("java/lang/Object", Object_class.Name); using (var t = new JniType(ref Object_hashCode_rt, JniObjectReferenceOptions.Copy)) Assert.AreEqual("I", t.Name); } finally { JniObjectReference.Dispose(ref hashCode_str); JniObjectReference.Dispose(ref Object_hashCode); JniObjectReference.Dispose(ref Object_hashCode_rt); JniObjectReference.Dispose(ref emptyArray); } } }
List <JavaConstructorInfo> LookupConstructors() { if (Members == null) { return(null); } lock (Members) { if (constructors != null || Disposed) { return(constructors); } constructors = new List <JavaConstructorInfo> (); var ctors = JniEnvironment.InstanceMethods.CallObjectMethod(Members.JniPeerType.PeerReference, Class_getConstructors); try { int len = JniEnvironment.Arrays.GetArrayLength(ctors); for (int i = 0; i < len; ++i) { var ctor = JniEnvironment.Arrays.GetObjectArrayElement(ctors, i); var m = new JavaConstructorInfo(Members, ctor); constructors.Add(m); JniObjectReference.Dispose(ref ctor); } } finally { JniObjectReference.Dispose(ref ctors); } return(constructors); } }
public unsafe void CallNonvirtualVoidMethod_WithBaseMethodIDAndDerivedType() { using (var b = new JniType("com/xamarin/interop/CallNonvirtualBase")) using (var d = new JniType("com/xamarin/interop/CallNonvirtualDerived")) { var m = b.GetInstanceMethod("method", "()V"); var f = b.GetInstanceField("methodInvoked", "Z"); var c = d.GetConstructor("()V"); var g = d.GetInstanceField("methodInvoked", "Z"); var o = d.NewObject(c, null); try { if (JavaVMFixture.CallNonvirtualVoidMethodSupportsDeclaringClassMismatch) { JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(o, d.PeerReference, m); Assert.IsFalse(JniEnvironment.InstanceFields.GetBooleanField(o, f)); Assert.IsTrue(JniEnvironment.InstanceFields.GetBooleanField(o, g)); } else { JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod(o, d.PeerReference, m); Assert.IsTrue(JniEnvironment.InstanceFields.GetBooleanField(o, f)); Assert.IsFalse(JniEnvironment.InstanceFields.GetBooleanField(o, g)); } } finally { JniObjectReference.Dispose(ref o); } } }
static void SetThrowableCause(JniType type, JniObjectReference outer, string message) { var cause = CreateThrowable(type, message); SetThrowableCause(type, outer, cause); JniObjectReference.Dispose(ref cause); }
public void References_CreatedReference_LocalRef() { var NewLocalRef = GetNewRefFunc("java_interop_jnienv_new_local_ref"); if (NewLocalRef == null) { Assert.Ignore("This version of Java.Interop.dll doesn't use P/Invoke-based JNI invokes."); return; } using (var t = new JniType("java/lang/Object")) { var c = JniEnvironment.LocalReferenceCount; var r = NewLocalRef(JniEnvironment.EnvironmentPointer, t.PeerReference.Handle); // This is the "problem": direct use of JNI functions don't contribute to // our reference count accounting Assert.AreEqual(c, JniEnvironment.LocalReferenceCount); var o = new JniObjectReference(r, JniObjectReferenceType.Local); JniEnvironment.References.CreatedReference(o); Assert.AreEqual(c + 1, JniEnvironment.LocalReferenceCount); JniObjectReference.Dispose(ref o); Assert.AreEqual(c, JniEnvironment.LocalReferenceCount); } }
protected override void Dispose(bool disposing) { if (!disposing || !PeerReference.IsValid) { return; } var pr = PeerReference; JniObjectReference.Dispose(ref pr); PeerReference = pr; members = null; if (arguments == null) { return; } for (int i = 0; i < arguments.Count; ++i) { var a = arguments [i]; JniObjectReference.Dispose(ref a); arguments [i] = a; } arguments = null; }
static unsafe void SetThrowableCause(JniType type, JniObjectReference outer, JniObjectReference inner) { var a = stackalloc JniArgumentValue [1]; a [0] = new JniArgumentValue(inner); var i = type.GetInstanceMethod("initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); var l = JniEnvironment.InstanceMethods.CallObjectMethod(outer, i, a); JniObjectReference.Dispose(ref l); }
public override IJavaPeerable?CreatePeer(ref JniObjectReference reference, JniObjectReferenceOptions options, Type?targetType) { if (!reference.IsValid) { return(null); } var peer = Java.Interop.TypeManager.CreateInstance(reference.Handle, JniHandleOwnership.DoNotTransfer, targetType) as IJavaPeerable; JniObjectReference.Dispose(ref reference, options); return(peer); }
public override Exception GetExceptionForThrowable(ref JniObjectReference value, JniObjectReferenceOptions transfer) { var throwable = Java.Lang.Object.GetObject <Java.Lang.Throwable>(value.Handle, JniHandleOwnership.DoNotTransfer); JniObjectReference.Dispose(ref value, transfer); var p = throwable as JavaProxyThrowable; if (p != null) { return(p.InnerException); } return(throwable); }
public unsafe void IsInstanceOfType() { using (var Object_class = new JniType("java/lang/Object")) using (var String_class = new JniType("java/lang/String")) { var String_ctor = String_class.GetConstructor("()V"); var s = String_class.NewObject(String_ctor, null); try { Assert.IsTrue(Object_class.IsInstanceOfType(s), "java.lang.String IS-NOT-A java.lang.Object?!"); } finally { JniObjectReference.Dispose(ref s); } } }
static unsafe JniObjectReference CreateThrowable(JniType type, string message) { var c = type.GetConstructor("(Ljava/lang/String;)V"); var s = JniEnvironment.Strings.NewString(message); try { var args = stackalloc JniArgumentValue [1]; args [0] = new JniArgumentValue(s); return(type.NewObject(c, args)); } finally { JniObjectReference.Dispose(ref s); } }
public unsafe void Types_IsSameObject() { using (var t = new JniType("java/lang/Object")) { var c = t.GetConstructor("()V"); var o = t.NewObject(c, null); try { using (var ot = JniEnvironment.Types.GetTypeFromInstance(o)) { Assert.IsTrue(JniEnvironment.Types.IsSameObject(t.PeerReference, ot.PeerReference)); } } finally { JniObjectReference.Dispose(ref o); } } }
public void PeekValue() { JniObjectReference lref; using (var o = new JavaObject()) { lref = o.PeerReference.NewLocalRef(); Assert.AreSame(o, JniRuntime.CurrentRuntime.ValueManager.PeekValue(lref)); } // At this point, the Java-side object is kept alive by `lref`, // but the wrapper instance has been disposed, and thus should // be unregistered, and thus unfindable. Assert.IsNull(JniRuntime.CurrentRuntime.ValueManager.PeekValue(lref)); JniObjectReference.Dispose(ref lref); }
public static unsafe void Main(string[] args) { Console.WriteLine("Hello World!"); try { var ignore = JniRuntime.CurrentRuntime; } catch (InvalidOperationException e) { Console.WriteLine(e); } foreach (var h in JniRuntime.GetAvailableInvocationPointers()) { Console.WriteLine("PRE: GetCreatedJavaVMHandles: {0}", h); } Console.WriteLine("Part 2!"); using (var vm = new JreRuntimeOptions().CreateJreVM()) { Console.WriteLine("# JniEnvironment.EnvironmentPointer={0}", JniEnvironment.EnvironmentPointer); Console.WriteLine("vm.SafeHandle={0}", vm.InvocationPointer); var t = new JniType("java/lang/Object"); var c = t.GetConstructor("()V"); var o = t.NewObject(c, null); var m = t.GetInstanceMethod("hashCode", "()I"); int i = JniEnvironment.InstanceMethods.CallIntMethod(o, m); Console.WriteLine("java.lang.Object={0}", o); Console.WriteLine("hashcode={0}", i); JniObjectReference.Dispose(ref o); t.Dispose(); // var o = JniTypes.FindClass ("java/lang/Object"); /* * var waitForCreation = new CountdownEvent (1); * var exitThread = new CountdownEvent (1); * var t = new Thread (() => { * var vm2 = new JavaVMBuilder ().CreateJavaVM (); * waitForCreation.Signal (); * exitThread.Wait (); * }); * t.Start (); * waitForCreation.Wait (); */ foreach (var h in JniRuntime.GetAvailableInvocationPointers()) { Console.WriteLine("WITHIN: GetCreatedJavaVMs: {0}", h); } // exitThread.Signal (); } foreach (var h in JniRuntime.GetAvailableInvocationPointers()) { Console.WriteLine("POST: GetCreatedJavaVMs: {0}", h); } }
Dictionary <string, List <JavaMethodInfo> > LookupMethods() { if (Members == null) { return(null); } lock (Members) { if (this.methods != null || Disposed) { return(this.methods); } this.methods = new Dictionary <string, List <JavaMethodInfo> > (); var methods = JniEnvironment.InstanceMethods.CallObjectMethod(Members.JniPeerType.PeerReference, Class_getMethods); try { int len = JniEnvironment.Arrays.GetArrayLength(methods); for (int i = 0; i < len; ++i) { var method = JniEnvironment.Arrays.GetObjectArrayElement(methods, i); var n_name = JniEnvironment.InstanceMethods.CallObjectMethod(method, Method_getName); var name = JniEnvironment.Strings.ToString(ref n_name, JniObjectReferenceOptions.CopyAndDispose); var isStatic = IsStatic(method); List <JavaMethodInfo> overloads; if (!Methods.TryGetValue(name, out overloads)) { Methods.Add(name, overloads = new List <JavaMethodInfo> ()); } var nrt = JniEnvironment.InstanceMethods.CallObjectMethod(method, Method_getReturnType); var rt = new JniType(ref nrt, JniObjectReferenceOptions.CopyAndDispose); var m = new JavaMethodInfo(Members, method, name, isStatic) { ReturnType = rt, }; overloads.Add(m); JniObjectReference.Dispose(ref method); } } finally { JniObjectReference.Dispose(ref methods); } return(this.methods); } }
Dictionary <string, List <JavaFieldInfo> > LookupFields() { if (Members == null) { return(null); } lock (Members) { if (this.fields != null || Disposed) { return(this.fields); } this.fields = new Dictionary <string, List <JavaFieldInfo> > (); var fields = JniEnvironment.InstanceMethods.CallObjectMethod(Members.JniPeerType.PeerReference, Class_getFields); try { int len = JniEnvironment.Arrays.GetArrayLength(fields); for (int i = 0; i < len; ++i) { var field = JniEnvironment.Arrays.GetObjectArrayElement(fields, i); var n_name = JniEnvironment.InstanceMethods.CallObjectMethod(field, Field_getName); var name = JniEnvironment.Strings.ToString(ref n_name, JniObjectReferenceOptions.CopyAndDispose); var isStatic = IsStatic(field); List <JavaFieldInfo> overloads; if (!Fields.TryGetValue(name, out overloads)) { Fields.Add(name, overloads = new List <JavaFieldInfo> ()); } var n_type = JniEnvironment.InstanceMethods.CallObjectMethod(field, Field_getType); using (var type = new JniType(ref n_type, JniObjectReferenceOptions.CopyAndDispose)) { var sig = JniTypeSignature.Parse(type.Name); overloads.Add(new JavaFieldInfo(Members, name + "." + sig.QualifiedReference, isStatic)); } JniObjectReference.Dispose(ref field); } } finally { JniObjectReference.Dispose(ref fields); } return(this.fields); } }
public unsafe void Handles_NewReturnToJniRef() { using (var t = new JniType("java/lang/Object")) { var c = t.GetConstructor("()V"); var o = t.NewObject(c, null); try { var n = o.NewLocalRef(); JniObjectReference.Dispose(ref n); // warning: lref 'leak' var r = JniEnvironment.References.NewReturnToJniRef(o); var h = new JniObjectReference(r); Assert.AreEqual(JniEnvironment.References.GetIdentityHashCode(o), JniEnvironment.References.GetIdentityHashCode(h)); } finally { JniObjectReference.Dispose(ref o); } } }
static IntPtr GetStringValueHandler(IntPtr jnienv, IntPtr n_self, int value) { var r_self = new JniObjectReference(n_self); var self = JniEnvironment.Runtime.ValueManager.GetValue <TestType>(ref r_self, JniObjectReferenceOptions.CopyAndDoNotRegister); try { var s = self.GetStringValue(value); var r = JniEnvironment.Strings.NewString(s); try { return(JniEnvironment.References.NewReturnToJniRef(r)); } finally { JniObjectReference.Dispose(ref r); } } finally { self.DisposeUnlessReferenced(); } }
public void UnreferencedInstanceIsCollected() { JniObjectReference oldHandle = new JniObjectReference(); WeakReference r = null; FinalizerHelpers.PerformNoPinAction(() => { var v = new JavaObject(); oldHandle = v.PeerReference.NewWeakGlobalRef(); r = new WeakReference(v); }); JniEnvironment.Runtime.ValueManager.CollectPeers(); GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers(); Assert.IsFalse(r.IsAlive); Assert.IsNull(r.Target); Assert.IsNull(JniRuntime.CurrentRuntime.ValueManager.PeekValue(oldHandle)); JniObjectReference.Dispose(ref oldHandle); }
private void Dispose(bool disposing) { if (!_javaRef.IsValid) { return; } unsafe { // tell Java that we're done with this array JniEnvironment.Arrays.ReleaseByteArrayElements(_javaRef, (sbyte *)Raw, JniReleaseArrayElementsMode.Default); } if (disposing) { JniObjectReference.Dispose(ref _javaRef); } }
public void UnregisterFromRuntime() { int registeredCount = JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers().Count; JniObjectReference l; JavaObject o; using (o = new JavaObject()) { l = o.PeerReference.NewLocalRef(); Assert.AreEqual(JniObjectReferenceType.Global, o.PeerReference.Type); Assert.AreEqual(registeredCount + 1, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers().Count); Assert.IsNotNull(JniRuntime.CurrentRuntime.ValueManager.PeekValue(l)); Assert.AreNotSame(l, o.PeerReference); Assert.AreSame(o, JniRuntime.CurrentRuntime.ValueManager.PeekValue(l)); } Assert.AreEqual(registeredCount, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers().Count); Assert.IsNull(JniRuntime.CurrentRuntime.ValueManager.PeekValue(l)); JniObjectReference.Dispose(ref l); Assert.Throws <ObjectDisposedException> (() => o.UnregisterFromRuntime()); }
unsafe TimeSpan GetJIMethodCallTiming() { using (var k = new JniType("java/lang/Object")) { var c = k.GetConstructor("()V"); var o = k.NewObject(c, null); var t = k.GetInstanceMethod("toString", "()Ljava/lang/String;"); var sw = Stopwatch.StartNew(); for (int i = 0; i < Unified_ToString_Iterations; ++i) { var r = JniEnvironment.InstanceMethods.CallObjectMethod(o, t); JniObjectReference.Dispose(ref r); } sw.Stop(); JniObjectReference.Dispose(ref o); return(sw.Elapsed); } }
public unsafe void Sanity() { using (var Integer_class = new JniType("java/lang/Integer")) { Assert.AreEqual("java/lang/Integer", Integer_class.Name); var ctor_args = stackalloc JniArgumentValue [1]; ctor_args [0] = new JniArgumentValue(42); var Integer_ctor = Integer_class.GetConstructor("(I)V"); var Integer_intValue = Integer_class.GetInstanceMethod("intValue", "()I"); var o = Integer_class.NewObject(Integer_ctor, ctor_args); try { int v = JniEnvironment.InstanceMethods.CallIntMethod(o, Integer_intValue); Assert.AreEqual(42, v); } finally { JniObjectReference.Dispose(ref o); } } }
public void LookupArguments() { if (arguments != null) { return; } var vm = JniEnvironment.Runtime; var sb = new StringBuilder(); var mgr = vm.TypeManager; if (!IsConstructor) { sb.Append(Name).Append("."); } sb.Append("("); var parameters = IsConstructor ? JavaClassInfo.GetConstructorParameters(PeerReference) : JavaClassInfo.GetMethodParameters(PeerReference); try { int len = JniEnvironment.Arrays.GetArrayLength(parameters); arguments = new List <JniObjectReference> (len); for (int i = 0; i < len; ++i) { var p = JniEnvironment.Arrays.GetObjectArrayElement(parameters, i); try { var sig = JniTypeSignature.Parse(JniEnvironment.Types.GetJniTypeNameFromClass(p)); sb.Append(sig.QualifiedReference); arguments.Add(p.NewGlobalRef()); } finally { JniObjectReference.Dispose(ref p); } } } finally { JniObjectReference.Dispose(ref parameters); } sb.Append(")").Append(JniReturnType); JniSignature = sb.ToString(); }
static unsafe Bitmap RenderUsingCreateSnapshot(View view, bool skipChildren) { if (view.Width <= 0 || view.Height <= 0) { Log.Debug(TAG, $"Skipping createSnapshot rendering on view {view}, width or height are <= 0."); return(null); } JniObjectReference o = default(JniObjectReference); try { // Invoke the createSnapshot package-private method. JniArgumentValue *args = stackalloc JniArgumentValue [3]; args [0] = new JniArgumentValue(Bitmap.Config.Argb8888.PeerReference); args [1] = new JniArgumentValue(0); args [2] = new JniArgumentValue(skipChildren); o = JniEnvironment.InstanceMethods.CallObjectMethod( view.PeerReference, viewCreateSnapshot.Value, args); if (o.IsValid) { return(Java.Lang.Object.GetObject <Bitmap> ( o.Handle, JniHandleOwnership.DoNotTransfer)); } return(null); } catch (Exception e) { Log.Debug(TAG, $"CreateSnapshot failed: {e.Message}."); return(null); } finally { JniObjectReference.Dispose(ref o); } }
public override Exception?GetExceptionForThrowable(ref JniObjectReference reference, JniObjectReferenceOptions options) { if (!reference.IsValid) { return(null); } var peeked = JNIEnv.AndroidValueManager?.PeekPeer(reference); var peekedExc = peeked as Exception; if (peekedExc == null) { var throwable = Java.Lang.Object.GetObject <Java.Lang.Throwable> (reference.Handle, JniHandleOwnership.DoNotTransfer); JniObjectReference.Dispose(ref reference, options); return(throwable); } JniObjectReference.Dispose(ref reference, options); var unwrapped = JNIEnv.AndroidValueManager?.UnboxException(peeked !); if (unwrapped != null) { return(unwrapped); } return(peekedExc); }
public void MethodLookupTiming() { #if __ANDROID__ const int count = 100; #else // __ANDROID__ const int count = 100; #endif // __ANDROID__ var total = Stopwatch.StartNew(); using (var o = new JavaTiming()) { var tt = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { var s = o.Timing_ToString_Traditional(); JniObjectReference.Dispose(ref s); } tt.Stop(); var ta = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { var s = o.Timing_ToString_NoCache(); JniObjectReference.Dispose(ref s); } ta.Stop(); var td = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { var s = o.Timing_ToString_DictWithLock();; JniObjectReference.Dispose(ref s); } td.Stop(); var tc = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { var s = o.Timing_ToString_DictWithNoLock(); JniObjectReference.Dispose(ref s); } tc.Stop(); var tp = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { var s = o.Timing_ToString_JniPeerMembers(); JniObjectReference.Dispose(ref s); } tp.Stop(); var vtt = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { o.VirtualIntMethod1Args(i); } vtt.Stop(); var vti = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { o.Timing_VirtualIntMethod_Marshal1Args(i); } vti.Stop(); Console.WriteLine("Method Lookup + Invoke Timing:"); Console.WriteLine("\t Traditional: {0}", tt.Elapsed); Console.WriteLine("\t No caching: {0}", ta.Elapsed); Console.WriteLine("\t Dict w/ lock: {0}", td.Elapsed); Console.WriteLine("\tConcurrentDict: {0}", tc.Elapsed); Console.WriteLine("\tJniPeerMembers: {0}", tp.Elapsed); Console.WriteLine(); Console.WriteLine("\t (I)I virtual+traditional: {0}", vtt.Elapsed); Console.WriteLine("\t (I)I virtual+JniPeerMembers: {0}", vti.Elapsed); } using (var o = new DerivedJavaTiming()) { var ntt = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { o.VirtualIntMethod1Args(i); } ntt.Stop(); var nti = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) { o.Timing_VirtualIntMethod_Marshal1Args(i); } nti.Stop(); Console.WriteLine("\t (I)I nonvirtual+traditional: {0}", ntt.Elapsed); Console.WriteLine("\t(I)I nonvirtual+JniPeerMembers: {0}", nti.Elapsed); } total.Stop(); Console.WriteLine("## {0} Timing: {1}", nameof(MethodLookupTiming), total.Elapsed); }
public void ObjectArrayEnumerationTiming() { const int C = 100; var total = Stopwatch.StartNew(); JniMethodInfo Class_getMethods; using (var t = new JniType("java/lang/Class")) { Class_getMethods = t.GetInstanceMethod("getMethods", "()[Ljava/lang/reflect/Method;"); } JniMethodInfo Method_getName; JniMethodInfo Method_getParameterTypes; JniMethodInfo Method_getReturnType; using (var t = new JniType("java/lang/reflect/Method")) { Method_getName = t.GetInstanceMethod("getName", "()Ljava/lang/String;"); Method_getParameterTypes = t.GetInstanceMethod("getParameterTypes", "()[Ljava/lang/Class;"); Method_getReturnType = t.GetInstanceMethod("getReturnType", "()Ljava/lang/Class;"); } Console.WriteLine("# {0}: Method Lookups Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); var methodHandles = new List <JavaObject> (); using (var Arrays_class = new JniType("java/util/Arrays")) { var lrefMethods = JniEnvironment.InstanceMethods.CallObjectMethod(Arrays_class.PeerReference, Class_getMethods); Console.WriteLine("# {0}: java.util.Arrays.class.getMethods() Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); var methodsTiming = Stopwatch.StartNew(); using (var methods = new JavaObjectArray <JavaObject> (ref lrefMethods, JniObjectReferenceOptions.Copy)) { foreach (var method in methods) { methodHandles.Add(method); } } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaObjectArray<JavaObject>) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); methodsTiming = Stopwatch.StartNew(); var methodHandlesGO = new List <JavaObject> (); var vm = JniEnvironment.Runtime; int len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesGO.Add(vm.ValueManager.GetValue <JavaObject> (ref v, JniObjectReferenceOptions.CopyAndDoNotRegister)); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaVM.GetObject) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); foreach (var h in methodHandlesGO) { h.DisposeUnlessReferenced(); } methodsTiming = Stopwatch.StartNew(); var methodHandlesAr = new List <JavaObject> (); len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesAr.Add(new JavaObject(ref v, JniObjectReferenceOptions.CopyAndDoNotRegister)); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaObject[]) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); foreach (var h in methodHandlesAr) { h.Dispose(); } methodsTiming = Stopwatch.StartNew(); var methodHandlesGR = new List <JniObjectReference> (); len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesGR.Add(v.NewGlobalRef()); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JniGlobalReference) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); for (int i = 0; i < methodHandlesGR.Count; ++i) { var h = methodHandlesGR [i]; JniObjectReference.Dispose(ref h); methodHandlesGR [i] = h; } JniObjectReference.Dispose(ref lrefMethods); } // HACK HACK HACK // This is to workaround an error wherein constructing `pt` (below) // throws an exception because `h` is NULL, when it really can't be. // I believe that this is due to the finalizer, which likewise makes // NO SENSE AT ALL, since `p` should be keeping the handle valid! // GC.Collect (); // GC.WaitForPendingFinalizers (); foreach (var method in methodHandles) { var lookupTiming = Stopwatch.StartNew(); var n_name = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getName); var name = JniEnvironment.Strings.ToString(ref n_name, JniObjectReferenceOptions.CopyAndDispose); var n_rt = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getReturnType); using (var rt = new JniType(ref n_rt, JniObjectReferenceOptions.CopyAndDispose)) { } var parameterTiming = Stopwatch.StartNew(); var enumTime = new TimeSpan(); var lrefPs = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getParameterTypes); int len = JniEnvironment.Arrays.GetArrayLength(lrefPs); var enumSw = Stopwatch.StartNew(); for (int i = 0; i < len; ++i) { var p = JniEnvironment.Arrays.GetObjectArrayElement(lrefPs, i); using (var pt = new JniType(ref p, JniObjectReferenceOptions.Copy)) { } JniObjectReference.Dispose(ref p); } JniObjectReference.Dispose(ref lrefPs); enumSw.Stop(); enumTime = enumSw.Elapsed; parameterTiming.Stop(); Console.WriteLine("## method '{0}' timing: Total={1}; Parameters={2} Parameters.Dispose={3}", name, lookupTiming.Elapsed, enumTime, parameterTiming.Elapsed); } var mhDisposeTiming = Stopwatch.StartNew(); foreach (var method in methodHandles) { method.Dispose(); } mhDisposeTiming.Stop(); Console.WriteLine("# methodHandles -> Dispose() Timing: {0}", mhDisposeTiming.Elapsed); total.Stop(); Console.WriteLine("## {0} Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); }
public unsafe void ObjectCreationTiming() { const int C = 100; var total = Stopwatch.StartNew(); Stopwatch allocTime, newObjectTime, newTime, getObjectTime; using (var Object_class = new JniType("java/lang/Object")) { var Object_init = Object_class.GetConstructor("()V"); allocTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = Object_class.AllocObject(); JniObjectReference.Dispose(ref h); } allocTime.Stop(); newObjectTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = Object_class.NewObject(Object_init, null); JniObjectReference.Dispose(ref h); } newObjectTime.Stop(); newTime = Stopwatch.StartNew(); var olist = new List <JavaObject> (C); for (int i = 0; i < C; ++i) { olist.Add(new JavaObject()); } newTime.Stop(); foreach (var o in olist) { o.Dispose(); } var strings = new JavaObjectArray <string> (100); for (int i = 0; i < 100; ++i) { strings [i] = i.ToString(); } using (strings) { var vm = JniEnvironment.Runtime; var rlist = new List <JavaObject> (C); getObjectTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = JniEnvironment.Arrays.GetObjectArrayElement(strings.PeerReference, i); var o = vm.ValueManager.GetValue <JavaObject> (ref h, JniObjectReferenceOptions.CopyAndDispose); rlist.Add(o); } getObjectTime.Stop(); foreach (var o in rlist) { o.DisposeUnlessReferenced(); } } } total.Stop(); Console.WriteLine("## {0} Timing: Total={1} AllocObject={2} NewObject={3} `new JavaObject()`={4} JavaVM.GetObject()={5}", nameof(ObjectCreationTiming), total.Elapsed, allocTime.Elapsed, newObjectTime.Elapsed, newTime.Elapsed, getObjectTime.Elapsed); }