[Ikvm-developers] Avoiding hidden reflection
Brought to you by:
jfrijters
From: Michael B. <md...@sa...> - 2013-10-18 17:43:39
|
One of the things we do when using IKVM to build apps that run on Xamarin iOS is use the linker to strip all unused code from the final app. This yields massive reduction in app size, as you might expect, because the whole JVM is huge and an app often only uses a small part of it. There's one place that reflection is used "under the hood" which is causing the generation of stack traces to fail in AOT compiled and linked applications. Basically it's a use of ConditionalWeakTable.GetOrCreate, which calls the default constructor via reflection if a value is not found. Miraculously, that seems to be the only place where IKVM internals are using reflection in such a way that it undermines linking. The following patch eliminates this use of reflection: diff --git i/runtime/openjdk.cs w/runtime/openjdk.cs index dd7d21e6e8..a925a3110a 100644 --- i/runtime/openjdk.cs +++ w/runtime/openjdk.cs @@ -5788,6 +5788,9 @@ namespace IKVM.NativeCode.sun.reflect public sealed class State { internal int Value; + public State(int Value) { + this.Value = Value; + } } static class Reflection @@ -5797,10 +5800,11 @@ namespace IKVM.NativeCode.sun.reflect internal static bool IsHideFromJava(MethodBase mb) { - State state = isHideFromJavaCache.GetOrCreateValue(mb); - if (state.Value == 0) + State state; + isHideFromJavaCache.TryGetValue(mb, out state); + if (state == null) { - state.Value = IsHideFromJavaImpl(mb); + isHideFromJavaCache.Add(mb, state = new State(IsHideFromJavaImpl(mb))); } return state.Value == 1; } I believe this code to be no worse, from a thread-safety standpoint, than the previous code. Two threads can now race on TryGetValue whereas before two threads could race on state.Value == 0. In either case, the worst that happens is that IsHideFromJavaImpl might be called once or twice more than needed. -- md...@sa... |