imtable_test.cc revision b486a98aadc95d80548953410cf23edba62259fa
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "imtable-inl.h" 18 19#include <memory> 20#include <string> 21 22#include "jni.h" 23 24#include "base/mutex.h" 25#include "class_linker.h" 26#include "common_runtime_test.h" 27#include "mirror/accessible_object.h" 28#include "mirror/class.h" 29#include "mirror/class_loader.h" 30#include "handle_scope-inl.h" 31#include "scoped_thread_state_change-inl.h" 32#include "thread-current-inl.h" 33 34namespace art { 35 36class ImTableTest : public CommonRuntimeTest { 37 public: 38 std::pair<mirror::Class*, mirror::Class*> LoadClasses(const std::string& class_name) 39 REQUIRES_SHARED(Locks::mutator_lock_) { 40 jobject jclass_loader_a = LoadDex("IMTA"); 41 CHECK(jclass_loader_a != nullptr); 42 jobject jclass_loader_b = LoadDex("IMTB"); 43 CHECK(jclass_loader_b != nullptr); 44 45 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 46 Thread* self = Thread::Current(); 47 48 StackHandleScope<3> hs(self); 49 MutableHandle<mirror::ClassLoader> h_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); 50 51 // A. 52 h_class_loader.Assign( 53 ObjPtr<mirror::ClassLoader>::DownCast(self->DecodeJObject(jclass_loader_a))); 54 Handle<mirror::Class> h_class_a( 55 hs.NewHandle(class_linker->FindClass(self, class_name.c_str(), h_class_loader))); 56 if (h_class_a == nullptr) { 57 LOG(ERROR) << self->GetException()->Dump(); 58 CHECK(false) << "h_class_a == nullptr"; 59 } 60 61 // B. 62 h_class_loader.Assign( 63 ObjPtr<mirror::ClassLoader>::DownCast(self->DecodeJObject(jclass_loader_b))); 64 Handle<mirror::Class> h_class_b( 65 hs.NewHandle(class_linker->FindClass(self, class_name.c_str(), h_class_loader))); 66 if (h_class_b == nullptr) { 67 LOG(ERROR) << self->GetException()->Dump(); 68 CHECK(false) << "h_class_b == nullptr"; 69 } 70 71 return std::make_pair(h_class_a.Get(), h_class_b.Get()); 72 } 73 74 std::pair<ArtMethod*, ArtMethod*> LoadMethods(const std::string& class_name, 75 const std::string& method_name) 76 REQUIRES_SHARED(Locks::mutator_lock_) { 77 std::pair<mirror::Class*, mirror::Class*> classes = LoadClasses(class_name); 78 79 const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 80 81 ArtMethod* method_a = 82 classes.first->FindDeclaredVirtualMethodByName(method_name, pointer_size); 83 ArtMethod* method_b = 84 classes.second->FindDeclaredVirtualMethodByName(method_name, pointer_size); 85 86 return std::make_pair(method_a, method_b); 87 } 88}; 89 90TEST_F(ImTableTest, NewMethodBefore) { 91 ScopedObjectAccess soa(Thread::Current()); 92 93 std::pair<ArtMethod*, ArtMethod*> methods = LoadMethods("LInterfaces$A;", "foo"); 94 CHECK_EQ(ImTable::GetImtIndex(methods.first), ImTable::GetImtIndex(methods.second)); 95} 96 97TEST_F(ImTableTest, NewClassBefore) { 98 ScopedObjectAccess soa(Thread::Current()); 99 100 std::pair<ArtMethod*, ArtMethod*> methods = LoadMethods("LInterfaces$Z;", "foo"); 101 CHECK_EQ(ImTable::GetImtIndex(methods.first), ImTable::GetImtIndex(methods.second)); 102} 103 104} // namespace art 105