From 4509e29abb448edc998a42facc72075f9631efa9 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 12 Jan 2015 09:54:11 -0700 Subject: [PATCH] fix method interception bug When we intercept a method (i.e. when the VM wants to run its own code instead of whatever the classpath provides for that method), we make a clone of the original method so we can later call it from the intercepting code if appropriate. We also set the ACC_NATIVE flag on the original method to ensure that our intercepting code is always used in preference to the classpath version. However, we need to set that flag *after* we make the clone, or else the clone will also have the ACC_NATIVE flag set, which is not what we want. We never noticed this before because classpath versions of all the methods we intercept as of Java 7 are either native or are never called from their VM-specified replacements. However, some of those native methods are non-native in later versions of Java, so the bug has become apparent. --- src/avian/classpath-common.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index afc699383a..a45b4f01f3 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -611,11 +611,11 @@ void intercept(Thread* t, if (m) { PROTECT(t, m); - m->flags() |= ACC_NATIVE; - if (updateRuntimeData) { GcMethod* clone = methodClone(t, m); + m->flags() |= ACC_NATIVE; + // make clone private to prevent vtable updates at compilation // time. Otherwise, our interception might be bypassed by calls // through the vtable. @@ -628,6 +628,8 @@ void intercept(Thread* t, GcMethodRuntimeData* runtimeData = getMethodRuntimeData(t, m); runtimeData->setNative(t, native->as(t)); + } else { + m->flags() |= ACC_NATIVE; } } else { // If we can't find the method, just ignore it, since ProGuard may