diff options
author | 2014-11-03 18:30:41 +0000 | |
---|---|---|
committer | 2014-11-03 18:30:41 +0000 | |
commit | a338da434433b180c33e043929ea79b18f4c093c (patch) | |
tree | e0b5a2ad83c86c96af8b10797bcccafeca4cb758 | |
parent | 4450721d3d396b392b1ec27bafbf3b6f956682f7 (diff) | |
parent | 2b0fa5ba4a8f07ee243452003bf93418d30e9448 (diff) |
Merge "ART: Add miranda checking"
-rw-r--r-- | runtime/mirror/class.cc | 5 | ||||
-rw-r--r-- | test/040-miranda/src/Main.java | 4 | ||||
-rw-r--r-- | test/040-miranda/src/MirandaAbstract.java | 2 | ||||
-rw-r--r-- | test/040-miranda/src/MirandaClass.java | 3 | ||||
-rw-r--r-- | test/040-miranda/src/MirandaClass2.java | 16 | ||||
-rw-r--r-- | test/126-miranda-multidex/build | 32 | ||||
-rw-r--r-- | test/126-miranda-multidex/expected.txt | 32 | ||||
-rw-r--r-- | test/126-miranda-multidex/info.txt | 2 | ||||
-rwxr-xr-x | test/126-miranda-multidex/run | 21 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/Main.java | 56 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/MirandaAbstract.java | 36 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/MirandaClass.java | 52 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/MirandaClass2.java | 42 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/MirandaInterface.java | 31 | ||||
-rw-r--r-- | test/126-miranda-multidex/src/MirandaInterface2.java | 26 | ||||
-rwxr-xr-x | test/etc/run-test-jar | 10 |
16 files changed, 361 insertions, 9 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 884aac1917..828d9861e1 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -490,8 +490,9 @@ ArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t 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; } } diff --git a/test/040-miranda/src/Main.java b/test/040-miranda/src/Main.java index ff5eba0a17..65f4fb4c4a 100644 --- a/test/040-miranda/src/Main.java +++ b/test/040-miranda/src/Main.java @@ -42,8 +42,8 @@ public class Main { 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"); diff --git a/test/040-miranda/src/MirandaAbstract.java b/test/040-miranda/src/MirandaAbstract.java index 309ecca764..c8cfa3465d 100644 --- a/test/040-miranda/src/MirandaAbstract.java +++ b/test/040-miranda/src/MirandaAbstract.java @@ -21,6 +21,8 @@ public abstract class MirandaAbstract implements MirandaInterface, MirandaInterf { 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(); diff --git a/test/040-miranda/src/MirandaClass.java b/test/040-miranda/src/MirandaClass.java index 0d942f0c98..4160992710 100644 --- a/test/040-miranda/src/MirandaClass.java +++ b/test/040-miranda/src/MirandaClass.java @@ -22,17 +22,14 @@ public class MirandaClass extends MirandaAbstract { 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; } } diff --git a/test/040-miranda/src/MirandaClass2.java b/test/040-miranda/src/MirandaClass2.java index e9bdf2b9ad..143eb371e6 100644 --- a/test/040-miranda/src/MirandaClass2.java +++ b/test/040-miranda/src/MirandaClass2.java @@ -1,3 +1,19 @@ +/* + * 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; diff --git a/test/126-miranda-multidex/build b/test/126-miranda-multidex/build new file mode 100644 index 0000000000..4c30f3f721 --- /dev/null +++ b/test/126-miranda-multidex/build @@ -0,0 +1,32 @@ +#!/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 diff --git a/test/126-miranda-multidex/expected.txt b/test/126-miranda-multidex/expected.txt new file mode 100644 index 0000000000..dbe37173a5 --- /dev/null +++ b/test/126-miranda-multidex/expected.txt @@ -0,0 +1,32 @@ +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 diff --git a/test/126-miranda-multidex/info.txt b/test/126-miranda-multidex/info.txt new file mode 100644 index 0000000000..ac50e2e8a4 --- /dev/null +++ b/test/126-miranda-multidex/info.txt @@ -0,0 +1,2 @@ +This test ensures that cross-dex-file Miranda methods are correctly resolved. +See b/18193682 for details. diff --git a/test/126-miranda-multidex/run b/test/126-miranda-multidex/run new file mode 100755 index 0000000000..23c9935c1c --- /dev/null +++ b/test/126-miranda-multidex/run @@ -0,0 +1,21 @@ +#!/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 ${@} diff --git a/test/126-miranda-multidex/src/Main.java b/test/126-miranda-multidex/src/Main.java new file mode 100644 index 0000000000..86243781ae --- /dev/null +++ b/test/126-miranda-multidex/src/Main.java @@ -0,0 +1,56 @@ +/* + * 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); + } + } +} diff --git a/test/126-miranda-multidex/src/MirandaAbstract.java b/test/126-miranda-multidex/src/MirandaAbstract.java new file mode 100644 index 0000000000..c09a61f3c6 --- /dev/null +++ b/test/126-miranda-multidex/src/MirandaAbstract.java @@ -0,0 +1,36 @@ +/* + * 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()); + } +} diff --git a/test/126-miranda-multidex/src/MirandaClass.java b/test/126-miranda-multidex/src/MirandaClass.java new file mode 100644 index 0000000000..7bb37e738e --- /dev/null +++ b/test/126-miranda-multidex/src/MirandaClass.java @@ -0,0 +1,52 @@ +/* + * 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"); + } +} diff --git a/test/126-miranda-multidex/src/MirandaClass2.java b/test/126-miranda-multidex/src/MirandaClass2.java new file mode 100644 index 0000000000..797ead23a5 --- /dev/null +++ b/test/126-miranda-multidex/src/MirandaClass2.java @@ -0,0 +1,42 @@ +/* + * 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"); + } +} diff --git a/test/126-miranda-multidex/src/MirandaInterface.java b/test/126-miranda-multidex/src/MirandaInterface.java new file mode 100644 index 0000000000..df12fcc475 --- /dev/null +++ b/test/126-miranda-multidex/src/MirandaInterface.java @@ -0,0 +1,31 @@ +/* + * 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(); + +} diff --git a/test/126-miranda-multidex/src/MirandaInterface2.java b/test/126-miranda-multidex/src/MirandaInterface2.java new file mode 100644 index 0000000000..7c93fd0634 --- /dev/null +++ b/test/126-miranda-multidex/src/MirandaInterface2.java @@ -0,0 +1,26 @@ +/* + * 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(); + +} diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 9ecc885a62..f1044e86b7 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -39,6 +39,7 @@ USE_GDB="n" USE_JVM="n" VERIFY="y" ZYGOTE="" +DEX_VERIFY="" while true; do if [ "x$1" = "x--quiet" ]; then @@ -176,7 +177,6 @@ if [ "$ZYGOTE" = "" ]; then fi if [ "$VERIFY" = "y" ]; then - DEX_VERIFY="" JVM_VERIFY_ARG="-Xverify:all" msg "Performing verification" else @@ -234,7 +234,12 @@ fi 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" @@ -279,6 +284,7 @@ fi dalvikvm_cmdline="$INVOKE_WITH $GDB $ANDROID_ROOT/bin/$DALVIKVM \ $GDB_ARGS \ $FLAGS \ + $DEX_VERIFY \ -XXlib:$LIB \ $PATCHOAT \ $DEX2OAT \ |