diff options
| -rw-r--r-- | runtime/class_linker.cc | 183 | ||||
| -rwxr-xr-x | test/131-structural-change/build | 39 | ||||
| -rw-r--r-- | test/131-structural-change/expected.txt | 3 | ||||
| -rw-r--r-- | test/131-structural-change/info.txt | 1 | ||||
| -rwxr-xr-x | test/131-structural-change/run | 18 | ||||
| -rw-r--r-- | test/131-structural-change/src-ex/A.java | 20 | ||||
| -rw-r--r-- | test/131-structural-change/src-ex/B.java | 21 | ||||
| -rw-r--r-- | test/131-structural-change/src/A.java | 26 | ||||
| -rw-r--r-- | test/131-structural-change/src/Main.java | 54 | ||||
| -rw-r--r-- | test/knownfailures.json | 9 |
10 files changed, 0 insertions, 374 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 71558e1820..141df1ec1a 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -5440,184 +5440,6 @@ bool ClassLinker::LinkClass(Thread* self, return true; } -static void CountMethodsAndFields(ClassDataItemIterator& dex_data, - size_t* virtual_methods, - size_t* direct_methods, - size_t* static_fields, - size_t* instance_fields) { - *static_fields = dex_data.NumStaticFields(); - *instance_fields = dex_data.NumInstanceFields(); - *direct_methods = dex_data.NumDirectMethods(); - *virtual_methods = dex_data.NumVirtualMethods(); -} - -static void DumpClass(std::ostream& os, - const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, - const char* suffix) { - ClassDataItemIterator dex_data(dex_file, dex_file.GetClassData(dex_class_def)); - os << dex_file.GetClassDescriptor(dex_class_def) << suffix << ":\n"; - os << " Static fields:\n"; - while (dex_data.HasNextStaticField()) { - const DexFile::FieldId& id = dex_file.GetFieldId(dex_data.GetMemberIndex()); - os << " " << dex_file.GetFieldTypeDescriptor(id) << " " << dex_file.GetFieldName(id) << "\n"; - dex_data.Next(); - } - os << " Instance fields:\n"; - while (dex_data.HasNextInstanceField()) { - const DexFile::FieldId& id = dex_file.GetFieldId(dex_data.GetMemberIndex()); - os << " " << dex_file.GetFieldTypeDescriptor(id) << " " << dex_file.GetFieldName(id) << "\n"; - dex_data.Next(); - } - os << " Direct methods:\n"; - while (dex_data.HasNextDirectMethod()) { - const DexFile::MethodId& id = dex_file.GetMethodId(dex_data.GetMemberIndex()); - os << " " << dex_file.GetMethodName(id) << dex_file.GetMethodSignature(id).ToString() << "\n"; - dex_data.Next(); - } - os << " Virtual methods:\n"; - while (dex_data.HasNextVirtualMethod()) { - const DexFile::MethodId& id = dex_file.GetMethodId(dex_data.GetMemberIndex()); - os << " " << dex_file.GetMethodName(id) << dex_file.GetMethodSignature(id).ToString() << "\n"; - dex_data.Next(); - } -} - -static std::string DumpClasses(const DexFile& dex_file1, - const DexFile::ClassDef& dex_class_def1, - const DexFile& dex_file2, - const DexFile::ClassDef& dex_class_def2) { - std::ostringstream os; - DumpClass(os, dex_file1, dex_class_def1, " (Compile time)"); - DumpClass(os, dex_file2, dex_class_def2, " (Runtime)"); - return os.str(); -} - - -// Very simple structural check on whether the classes match. Only compares the number of -// methods and fields. -static bool SimpleStructuralCheck(const DexFile& dex_file1, - const DexFile::ClassDef& dex_class_def1, - const DexFile& dex_file2, - const DexFile::ClassDef& dex_class_def2, - std::string* error_msg) { - ClassDataItemIterator dex_data1(dex_file1, dex_file1.GetClassData(dex_class_def1)); - ClassDataItemIterator dex_data2(dex_file2, dex_file2.GetClassData(dex_class_def2)); - - // Counters for current dex file. - size_t dex_virtual_methods1, dex_direct_methods1, dex_static_fields1, dex_instance_fields1; - CountMethodsAndFields(dex_data1, - &dex_virtual_methods1, - &dex_direct_methods1, - &dex_static_fields1, - &dex_instance_fields1); - // Counters for compile-time dex file. - size_t dex_virtual_methods2, dex_direct_methods2, dex_static_fields2, dex_instance_fields2; - CountMethodsAndFields(dex_data2, - &dex_virtual_methods2, - &dex_direct_methods2, - &dex_static_fields2, - &dex_instance_fields2); - - if (dex_virtual_methods1 != dex_virtual_methods2) { - std::string class_dump = DumpClasses(dex_file1, dex_class_def1, dex_file2, dex_class_def2); - *error_msg = StringPrintf("Virtual method count off: %zu vs %zu\n%s", - dex_virtual_methods1, - dex_virtual_methods2, - class_dump.c_str()); - return false; - } - if (dex_direct_methods1 != dex_direct_methods2) { - std::string class_dump = DumpClasses(dex_file1, dex_class_def1, dex_file2, dex_class_def2); - *error_msg = StringPrintf("Direct method count off: %zu vs %zu\n%s", - dex_direct_methods1, - dex_direct_methods2, - class_dump.c_str()); - return false; - } - if (dex_static_fields1 != dex_static_fields2) { - std::string class_dump = DumpClasses(dex_file1, dex_class_def1, dex_file2, dex_class_def2); - *error_msg = StringPrintf("Static field count off: %zu vs %zu\n%s", - dex_static_fields1, - dex_static_fields2, - class_dump.c_str()); - return false; - } - if (dex_instance_fields1 != dex_instance_fields2) { - std::string class_dump = DumpClasses(dex_file1, dex_class_def1, dex_file2, dex_class_def2); - *error_msg = StringPrintf("Instance field count off: %zu vs %zu\n%s", - dex_instance_fields1, - dex_instance_fields2, - class_dump.c_str()); - return false; - } - - return true; -} - -// Checks whether a the super-class changed from what we had at compile-time. This would -// invalidate quickening. -static bool CheckSuperClassChange(Handle<mirror::Class> klass, - const DexFile& dex_file, - const DexFile::ClassDef& class_def, - ObjPtr<mirror::Class> super_class) - REQUIRES_SHARED(Locks::mutator_lock_) { - // Check for unexpected changes in the superclass. - // Quick check 1) is the super_class class-loader the boot class loader? This always has - // precedence. - if (super_class->GetClassLoader() != nullptr && - // Quick check 2) different dex cache? Breaks can only occur for different dex files, - // which is implied by different dex cache. - klass->GetDexCache() != super_class->GetDexCache()) { - // Now comes the expensive part: things can be broken if (a) the klass' dex file has a - // definition for the super-class, and (b) the files are in separate oat files. The oat files - // are referenced from the dex file, so do (b) first. Only relevant if we have oat files. - const OatDexFile* class_oat_dex_file = dex_file.GetOatDexFile(); - const OatFile* class_oat_file = nullptr; - if (class_oat_dex_file != nullptr) { - class_oat_file = class_oat_dex_file->GetOatFile(); - } - - if (class_oat_file != nullptr) { - const OatDexFile* loaded_super_oat_dex_file = super_class->GetDexFile().GetOatDexFile(); - const OatFile* loaded_super_oat_file = nullptr; - if (loaded_super_oat_dex_file != nullptr) { - loaded_super_oat_file = loaded_super_oat_dex_file->GetOatFile(); - } - - if (loaded_super_oat_file != nullptr && class_oat_file != loaded_super_oat_file) { - // Now check (a). - const DexFile::ClassDef* super_class_def = dex_file.FindClassDef(class_def.superclass_idx_); - if (super_class_def != nullptr) { - // Uh-oh, we found something. Do our check. - std::string error_msg; - if (!SimpleStructuralCheck(dex_file, *super_class_def, - super_class->GetDexFile(), *super_class->GetClassDef(), - &error_msg)) { - // Print a warning to the log. This exception might be caught, e.g., as common in test - // drivers. When the class is later tried to be used, we re-throw a new instance, as we - // only save the type of the exception. - LOG(WARNING) << "Incompatible structural change detected: " << - StringPrintf( - "Structural change of %s is hazardous (%s at compile time, %s at runtime): %s", - dex_file.PrettyType(super_class_def->class_idx_).c_str(), - class_oat_file->GetLocation().c_str(), - loaded_super_oat_file->GetLocation().c_str(), - error_msg.c_str()); - ThrowIncompatibleClassChangeError(klass.Get(), - "Structural change of %s is hazardous (%s at compile time, %s at runtime): %s", - dex_file.PrettyType(super_class_def->class_idx_).c_str(), - class_oat_file->GetLocation().c_str(), - loaded_super_oat_file->GetLocation().c_str(), - error_msg.c_str()); - return false; - } - } - } - } - } - return true; -} - bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) { CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus()); const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex()); @@ -5650,11 +5472,6 @@ bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexF } CHECK(super_class->IsResolved()); klass->SetSuperClass(super_class); - - if (!CheckSuperClassChange(klass, dex_file, class_def, super_class)) { - DCHECK(Thread::Current()->IsExceptionPending()); - return false; - } } const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def); if (interfaces != nullptr) { diff --git a/test/131-structural-change/build b/test/131-structural-change/build deleted file mode 100755 index ff0da2098d..0000000000 --- a/test/131-structural-change/build +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2015 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 - -if [ ${USE_JACK} = "true" ]; then - ${JACK} --output-dex . src - zip $TEST_NAME.jar classes.dex - - ${JACK} --output-dex . src-ex - zip ${TEST_NAME}-ex.jar classes.dex -else - mkdir classes - ${JAVAC} -d classes `find src -name '*.java'` - - mkdir classes-ex - ${JAVAC} -d classes-ex `find src-ex -name '*.java'` - - if [ ${NEED_DEX} = "true" ]; then - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes - zip $TEST_NAME.jar classes.dex - ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex - zip ${TEST_NAME}-ex.jar classes.dex - fi -fi diff --git a/test/131-structural-change/expected.txt b/test/131-structural-change/expected.txt deleted file mode 100644 index 1d19278f1e..0000000000 --- a/test/131-structural-change/expected.txt +++ /dev/null @@ -1,3 +0,0 @@ -JNI_OnLoad called -Should really reach here. -Done. diff --git a/test/131-structural-change/info.txt b/test/131-structural-change/info.txt deleted file mode 100644 index 6d5817bcea..0000000000 --- a/test/131-structural-change/info.txt +++ /dev/null @@ -1 +0,0 @@ -Check whether a structural change in a (non-native) multi-dex scenario is detected. diff --git a/test/131-structural-change/run b/test/131-structural-change/run deleted file mode 100755 index 63fdb8c749..0000000000 --- a/test/131-structural-change/run +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2015 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. - -# Use secondary switch to add secondary dex file to class path. -exec ${RUN} "${@}" --secondary diff --git a/test/131-structural-change/src-ex/A.java b/test/131-structural-change/src-ex/A.java deleted file mode 100644 index 800347b716..0000000000 --- a/test/131-structural-change/src-ex/A.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 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. - */ - -public class A { - public void bar() { - } -} diff --git a/test/131-structural-change/src-ex/B.java b/test/131-structural-change/src-ex/B.java deleted file mode 100644 index 61369db32d..0000000000 --- a/test/131-structural-change/src-ex/B.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2015 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. - */ - -public class B extends A { - public void test() { - System.out.println("Should not reach this!"); - } -} diff --git a/test/131-structural-change/src/A.java b/test/131-structural-change/src/A.java deleted file mode 100644 index b07de581d8..0000000000 --- a/test/131-structural-change/src/A.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2015 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. - */ - -public class A { - public void foo() { - } - - public void bar() { - } - - public void baz() { - } -} diff --git a/test/131-structural-change/src/Main.java b/test/131-structural-change/src/Main.java deleted file mode 100644 index c7488992df..0000000000 --- a/test/131-structural-change/src/Main.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015 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.io.File; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; - -/** - * Structural hazard test. - */ -public class Main { - public static void main(String[] args) { - System.loadLibrary(args[0]); - new Main().run(); - } - - private void run() { - try { - Class<?> bClass = getClass().getClassLoader().loadClass("A"); - System.out.println("Should really reach here."); - } catch (Exception e) { - e.printStackTrace(System.out); - } - - boolean haveOatFile = hasOatFile(); - boolean gotError = false; - try { - Class<?> bClass = getClass().getClassLoader().loadClass("B"); - } catch (IncompatibleClassChangeError icce) { - gotError = true; - } catch (Exception e) { - e.printStackTrace(System.out); - } - if (haveOatFile ^ gotError) { - System.out.println("Did not get expected error. " + haveOatFile + " " + gotError); - } - System.out.println("Done."); - } - - private native static boolean hasOatFile(); -} diff --git a/test/knownfailures.json b/test/knownfailures.json index 8bdaeaaf5a..7bfa417691 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -143,15 +143,6 @@ "complete test) JDWP must be set up."] }, { - "tests": "131-structural-change", - "variant": "debug", - "description": ["131 is an old test. The functionality has been", - "implemented at an earlier stage and is checked", - "in tests 138. Blacklisted for debug builds since", - "these builds have duplicate classes checks which", - "punt to interpreter"] - }, - { "tests": "138-duplicate-classes-check", "variant": "ndebug", "description": ["Turned on for debug builds since debug builds have", |