Number of reports matching the filters
Matching | Total | Match % | |
---|---|---|---|
All reports | 131 | 136,385 | 0.10% |
Android | 131 | 94,055 | 0.14% |
Desktop | 0 | 29,799 | 0.00% |
iOS | 0 | 12,531 | 0.00% |
Java tests
Note: iOS does not allow to load bytecode in runtime, both ReflectASM and ByteBuddy do not work there
Note: ByteBuddy and ReflectASM fieldAccess tests passed on all of the Android and Desktop devices, except one - so, technically, it has 100% support on these platforms
Note: ReflectASM methodAccess tests failed for some Android devices with exception: java.lang.ClassNotFoundException: com.prineside.tdi2.utils.PerformanceSurvey$TestClassMethodAccess
(MethodAccess is a suffix added to an existing class name by ReflectASM)
Test | Passed | Support percentage |
---|---|---|
ByteBuddy | 131 | 100.00% |
ReflectASM fieldAccess | 131 | 100.00% |
ReflectASM methodAccess | 131 | 100.00% |
Unsafe allocateMemory | 131 | 100.00% |
Unsafe allocateInstance | 131 | 100.00% |
Source code of tests
// Inner class (PerformanceSurvey$TestFieldAccess)
public static class TestClass {
public int intVal;
private int otherVal;
public TestFieldAccessClass() {
otherVal = 5;
}
public TestClass() {
}
public int getIntValPlus(int v) {
return intVal + v;
}
public int getMethodConstant() {
return 200;
}
}
// Static instance of Unsafe
public static final Unsafe unsafe;
static {
// This code worked on every platform and device
try {
Constructor unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
unsafe = unsafeConstructor.newInstance();
} catch (Exception e) {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe)f.get((Object) null);
} catch (Exception ignored) {}
}
}
ByteBuddy
// Subclass, override a method and test its intercepted return value
DynamicType.Unloaded> unloaded = new ByteBuddy().subclass(TestClass.class)
.method(ElementMatchers.named("getMethodConstant"))
.intercept(FixedValue.value(301))
.make();
Class> runtimeClass;
if (Gdx.app.getType() == ApplicationType.Android) {
ClassLoadingStrategy strategy = new AndroidClassLoadingStrategy.Wrapping(AndroidLauncher.this.getContext().getDir("generated", Context.MODE_PRIVATE));
unloaded.load(PerformanceSurvey.class.getClassLoader(), strategy).getLoaded();
} else {
runtimeClass = unloaded.load(PerformanceSurvey.class.getClassLoader()).getLoaded();
}
TestClass testObj = (TestClass) runtimeClass.getConstructor().newInstance();
assert testObj.getMethodConstant() == 301;
ReflectASM fieldAccess
TestClass asmTestObject = new TestClass();
asmTestObject.intVal = 9001;
FieldAccess intValFA = FieldAccess.get(TestClass.class);
intValFA.setInt(asmTestObject, intValFA.getIndex("intVal"), 12701);
assert intValFA.getInt(asmTestObject, intValFA.getIndex("intVal")) == 12701;
ReflectASM methodAccess
TestClass asmTestObject = new TestClass();
asmTestObject.intVal = 9001;
MethodAccess ma = MethodAccess.get(TestClass.class);
int mIdx = ma.getIndex("getIntValPlus", int.class);
assert (int) ma.invoke(asmTestObject, mIdx, 500) == 9001 + 500;
Unsafe allocateMemory
long addr = unsafe.allocateMemory(64);
unsafe.putByte(addr + 7, 121);
assert unsafe.getByte(addr + 7) == 121;
unsafe.freeMemory(addr);
Unsafe allocateInstance
TestClass testObj = (TestClass) unsafe.allocateInstance(TestClass.class);
assert testObj.otherVal == 0;