verification_results.cc revision 6c170c9e884e9dddf61d963d403042ee2a399e7d
1c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko/* 2c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Copyright (C) 2013 The Android Open Source Project 3c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * 4c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Licensed under the Apache License, Version 2.0 (the "License"); 5c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * you may not use this file except in compliance with the License. 6c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * You may obtain a copy of the License at 7c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * 8c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * http://www.apache.org/licenses/LICENSE-2.0 9c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * 10c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Unless required by applicable law or agreed to in writing, software 11c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * distributed under the License is distributed on an "AS IS" BASIS, 12c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * See the License for the specific language governing permissions and 14c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * limitations under the License. 15c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko */ 16c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 17c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "verification_results.h" 18c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 19c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "base/stl_util.h" 20c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "base/mutex.h" 21c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "base/mutex-inl.h" 226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#include "driver/compiler_driver.h" 236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#include "driver/compiler_options.h" 24c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "thread.h" 25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "thread-inl.h" 26c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "verified_method.h" 27c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "verifier/method_verifier.h" 28c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "verifier/method_verifier-inl.h" 29c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 30c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markonamespace art { 31c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 326449c62e40ef3a9bb75f664f922555affb532ee4Brian CarlstromVerificationResults::VerificationResults(const CompilerOptions* compiler_options) 331ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers : compiler_options_(compiler_options), 341ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers verified_methods_lock_("compiler verified methods lock"), 35c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_(), 36c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_lock_("compiler rejected classes lock"), 37c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_() { 38a03de6dbabbe857deae5b0f1e388fbd3a2420dc2Ian Rogers UNUSED(compiler_options); 39c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 40c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 41c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir MarkoVerificationResults::~VerificationResults() { 42c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko Thread* self = Thread::Current(); 43c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko { 44c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(self, verified_methods_lock_); 45c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko STLDeleteValues(&verified_methods_); 46c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 47c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 48c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 49c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markobool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { 506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom DCHECK(method_verifier != NULL); 51c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko MethodReference ref = method_verifier->GetMethodReference(); 52c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); 53c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // TODO: Check also for virtual/interface invokes when DEX-to-DEX supports devirtualization. 54c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (!compile && !method_verifier->HasCheckCasts()) { 55c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return true; 56c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 57c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 58c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); 59c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (verified_method == nullptr) { 606c170c9e884e9dddf61d963d403042ee2a399e7dAndreas Gampe // Do not report an error to the verifier. We'll just punt this later. 616c170c9e884e9dddf61d963d403042ee2a399e7dAndreas Gampe return true; 62c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 63c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 64c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(Thread::Current(), verified_methods_lock_); 65c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko auto it = verified_methods_.find(ref); 66c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (it != verified_methods_.end()) { 67c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // TODO: Investigate why are we doing the work again for this method and try to avoid it. 68c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko LOG(WARNING) << "Method processed more than once: " 69c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko << PrettyMethod(ref.dex_method_index, *ref.dex_file); 70c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK_EQ(it->second->GetDevirtMap().size(), verified_method->GetDevirtMap().size()); 71c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK_EQ(it->second->GetSafeCastSet().size(), verified_method->GetSafeCastSet().size()); 72c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK_EQ(it->second->GetDexGcMap().size(), verified_method->GetDexGcMap().size()); 73c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko delete it->second; 74c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_.erase(it); 75c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 76c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_.Put(ref, verified_method); 77c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK(verified_methods_.find(ref) != verified_methods_.end()); 78c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return true; 79c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 80c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 81c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markoconst VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) { 82c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko ReaderMutexLock mu(Thread::Current(), verified_methods_lock_); 83c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko auto it = verified_methods_.find(ref); 84c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return (it != verified_methods_.end()) ? it->second : nullptr; 85c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 86c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 87ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartiervoid VerificationResults::RemoveVerifiedMethod(MethodReference ref) { 88ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier WriterMutexLock mu(Thread::Current(), verified_methods_lock_); 89ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier auto it = verified_methods_.find(ref); 90ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier if (it != verified_methods_.end()) { 91ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier delete it->second; 92ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier verified_methods_.erase(it); 93ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier } 94ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier} 95ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier 96c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markovoid VerificationResults::AddRejectedClass(ClassReference ref) { 97c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko { 98c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(Thread::Current(), rejected_classes_lock_); 99c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_.insert(ref); 100c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 101c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK(IsClassRejected(ref)); 102c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 103c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 104c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markobool VerificationResults::IsClassRejected(ClassReference ref) { 105c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko ReaderMutexLock mu(Thread::Current(), rejected_classes_lock_); 106c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return (rejected_classes_.find(ref) != rejected_classes_.end()); 107c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 108c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 109956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughesbool VerificationResults::IsCandidateForCompilation(MethodReference&, 110c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const uint32_t access_flags) { 1111ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers if (!compiler_options_->IsCompilationEnabled()) { 1121ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers return false; 1131ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers } 114c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Don't compile class initializers, ever. 115c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { 116c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return false; 117c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 11839c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison return true; 119c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 120c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 121c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} // namespace art 122