for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
if (method->GetDexMethodIndex() == dex_method_idx &&
- // A miranda method may have a different DexCache.
- method->GetDexCache() == dex_cache) {
+ // A miranda method may have a different DexCache and is always created by linking,
+ // never *declared* in the class.
+ !method->IsMiranda()) {
return method;
}
}
System.out.println("Test getting miranda method via reflection:");
try {
- Class mirandaClass = Class.forName("MirandaAbstract");
- Method mirandaMethod = mirandaClass.getDeclaredMethod("inInterface", (Class[]) null);
+ Class<?> mirandaClass = Class.forName("MirandaAbstract");
+ Method mirandaMethod = mirandaClass.getDeclaredMethod("inInterface");
System.out.println(" did not expect to find miranda method");
} catch (NoSuchMethodException nsme) {
System.out.println(" caught expected NoSuchMethodException");
{
protected MirandaAbstract() { }
+ // These will be miranda methods, as the interfaces define them, but they are not
+ // implemented in this abstract class:
//public abstract boolean inInterface();
//public abstract int inInterface2();
public MirandaClass() {}
public boolean inInterface() {
- //System.out.println(" MirandaClass inInterface");
return true;
}
public int inInterface2() {
- //System.out.println(" MirandaClass inInterface2");
return 27;
}
public boolean inAbstract() {
- //System.out.println(" MirandaClass inAbstract");
return false;
}
}
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
class MirandaClass2 extends MirandaAbstract {
public boolean inInterface() {
return true;
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Stop if something fails.
+set -e
+
+mkdir classes
+
+# All except Main
+${JAVAC} -d classes `find src -name '*.java'`
+rm classes/MirandaInterface.class
+${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes
+
+# Only Main
+${JAVAC} -d classes `find src -name '*.java'`
+rm classes/Main.class classes/MirandaAbstract.class classes/MirandaClass*.class classes/MirandaInterface2*.class
+${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex classes
+
+zip $TEST_NAME.jar classes.dex classes2.dex
--- /dev/null
+MirandaClass:
+ inInterface: true
+ inInterface2: 27
+ inAbstract: false
+MirandaAbstract / MirandaClass:
+ inInterface: true
+ inInterface2: 27
+ inAbstract: false
+true 27
+MirandaAbstract / MirandaClass2:
+ inInterface: true
+ inInterface2: 28
+ inAbstract: true
+true 28
+Test getting miranda method via reflection:
+ caught expected NoSuchMethodException
+MirandaClass:
+ inInterface: true
+ inInterface2: 27
+ inAbstract: false
+MirandaAbstract / MirandaClass:
+ inInterface: true
+ inInterface2: 27
+ inAbstract: false
+true 27
+MirandaAbstract / MirandaClass2:
+ inInterface: true
+ inInterface2: 28
+ inAbstract: true
+true 28
+Test getting miranda method via reflection:
+ caught expected NoSuchMethodException
--- /dev/null
+This test ensures that cross-dex-file Miranda methods are correctly resolved.
+See b/18193682 for details.
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+${RUN} $@
+
+# The problem was first exposed in a no-verify setting, as that changes the resolution path
+# taken. Make sure we also test in that environment.
+${RUN} --no-verify ${@}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Method;
+
+/**
+ * Miranda testing.
+ */
+public class Main {
+ public static void main(String[] args) {
+ MirandaClass mir = new MirandaClass();
+ System.out.println("MirandaClass:");
+ System.out.println(" inInterface: " + mir.inInterface());
+ System.out.println(" inInterface2: " + mir.inInterface2());
+ System.out.println(" inAbstract: " + mir.inAbstract());
+
+ /* try again through abstract class; results should be identical */
+ MirandaAbstract mira = mir;
+ System.out.println("MirandaAbstract / MirandaClass:");
+ System.out.println(" inInterface: " + mira.inInterface());
+ System.out.println(" inInterface2: " + mira.inInterface2());
+ System.out.println(" inAbstract: " + mira.inAbstract());
+ mira.callMiranda();
+
+ MirandaAbstract mira2 = new MirandaClass2();
+ System.out.println("MirandaAbstract / MirandaClass2:");
+ System.out.println(" inInterface: " + mira2.inInterface());
+ System.out.println(" inInterface2: " + mira2.inInterface2());
+ System.out.println(" inAbstract: " + mira2.inAbstract());
+ mira2.callMiranda();
+
+ System.out.println("Test getting miranda method via reflection:");
+ try {
+ Class<?> mirandaClass = Class.forName("MirandaAbstract");
+ Method mirandaMethod = mirandaClass.getDeclaredMethod("inInterface");
+ System.out.println(" did not expect to find miranda method");
+ } catch (NoSuchMethodException nsme) {
+ System.out.println(" caught expected NoSuchMethodException");
+ } catch (Exception e) {
+ System.out.println(" caught unexpected exception " + e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Miranda testing.
+ */
+public abstract class MirandaAbstract implements MirandaInterface, MirandaInterface2
+{
+ protected MirandaAbstract() { }
+
+ // These will be miranda methods, as the interfaces define them, but they are not
+ // implemented in this abstract class:
+ //public abstract boolean inInterface();
+ //public abstract int inInterface2();
+
+ public boolean inAbstract() {
+ return true;
+ }
+
+ public void callMiranda() {
+ System.out.println(inInterface() + " " + inInterface2());
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Miranda testing.
+ */
+public class MirandaClass extends MirandaAbstract {
+
+ public MirandaClass() {}
+
+ public boolean inInterface() {
+ return true;
+ }
+
+ public int inInterface2() {
+ return 27;
+ }
+
+ public boolean inAbstract() {
+ return false;
+ }
+
+ // Better not hit any of these...
+ public void inInterfaceDummy1() {
+ System.out.println("inInterfaceDummy1");
+ }
+ public void inInterfaceDummy2() {
+ System.out.println("inInterfaceDummy2");
+ }
+ public void inInterfaceDummy3() {
+ System.out.println("inInterfaceDummy3");
+ }
+ public void inInterfaceDummy4() {
+ System.out.println("inInterfaceDummy4");
+ }
+ public void inInterfaceDummy5() {
+ System.out.println("inInterfaceDummy5");
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class MirandaClass2 extends MirandaAbstract {
+ public boolean inInterface() {
+ return true;
+ }
+
+ public int inInterface2() {
+ return 28;
+ }
+
+ // Better not hit any of these...
+ public void inInterfaceDummy1() {
+ System.out.println("inInterfaceDummy1");
+ }
+ public void inInterfaceDummy2() {
+ System.out.println("inInterfaceDummy2");
+ }
+ public void inInterfaceDummy3() {
+ System.out.println("inInterfaceDummy3");
+ }
+ public void inInterfaceDummy4() {
+ System.out.println("inInterfaceDummy4");
+ }
+ public void inInterfaceDummy5() {
+ System.out.println("inInterfaceDummy5");
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Miranda testing.
+ */
+public interface MirandaInterface {
+
+ public boolean inInterface();
+
+ // A couple of dummy methods to fill the method table.
+ public void inInterfaceDummy1();
+ public void inInterfaceDummy2();
+ public void inInterfaceDummy3();
+ public void inInterfaceDummy4();
+ public void inInterfaceDummy5();
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Miranda testing.
+ */
+public interface MirandaInterface2 {
+
+ public boolean inInterface();
+
+ public int inInterface2();
+
+}
SECONDARY_DEX=""
exe="${ANDROID_HOST_OUT}/bin/dalvikvm32"
main="Main"
+DEX_VERIFY=""
while true; do
if [ "x$1" = "x--quiet" ]; then
if [ "$INTERPRETER" = "y" ]; then
INT_OPTS="-Xint"
- COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=interpret-only"
+ if [ "$VERIFY" = "y" ] ; then
+ COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=interpret-only"
+ else
+ COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=verify-none"
+ DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
+ fi
fi
if [ "$RELOCATE" = "y" ]; then
fi
JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
-cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX $main"
+cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $DEX_VERIFY $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX $main"
if [ "$DEV_MODE" = "y" ]; then
if [ "$PREBUILD" = "y" ]; then
echo "$mkdir_cmd && $prebuild_cmd && $cmdline"
GDB_TARGET_SUFFIX=""
COMPILE_FLAGS=""
SECONDARY_DEX=""
+DEX_VERIFY=""
while true; do
if [ "x$1" = "x--quiet" ]; then
fi
if [ "$VERIFY" = "y" ]; then
- DEX_VERIFY=""
msg "Performing verification"
else
DEX_VERIFY="-Xverify:none"
if [ "$INTERPRETER" = "y" ]; then
INT_OPTS="-Xint"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
+ if [ "$VERIFY" = "y" ] ; then
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
+ else
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
+ DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
+ fi
fi
JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
TARGET_SUFFIX="32"
GDB_TARGET_SUFFIX=""
SECONDARY_DEX=""
+DEX_VERIFY=""
while true; do
if [ "x$1" = "x--quiet" ]; then
fi
if [ "$VERIFY" = "y" ]; then
- DEX_VERIFY=""
msg "Performing verification"
else
DEX_VERIFY="-Xverify:none"
if [ "$INTERPRETER" = "y" ]; then
INT_OPTS="-Xint"
+ if [ "$VERIFY" = "y" ] ; then
+ COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=interpret-only"
+ else
+ COMPILER_FLAGS="${COMPILER_FLAGS} --compiler-filter=verify-none"
+ DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
+ fi
fi
JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
fi
cmdline="cd $DEX_LOCATION && export ANDROID_DATA=$DEX_LOCATION && export DEX_LOCATION=$DEX_LOCATION && \
- $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX Main"
+ $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $DEX_VERIFY $gdbargs -XXlib:$LIB $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX Main"
if [ "$DEV_MODE" = "y" ]; then
echo $cmdline "$@"
fi