verification_results.cc revision e5f13e57ff8fa36342beb33830b3ec5942a61cca
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 190b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h" 20c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "base/stl_util.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-inl.h" 28c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 29c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markonamespace art { 30c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 316449c62e40ef3a9bb75f664f922555affb532ee4Brian CarlstromVerificationResults::VerificationResults(const CompilerOptions* compiler_options) 321ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers : compiler_options_(compiler_options), 331ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers verified_methods_lock_("compiler verified methods lock"), 34c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_(), 35c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_lock_("compiler rejected classes lock"), 36c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_() { 37a03de6dbabbe857deae5b0f1e388fbd3a2420dc2Ian Rogers UNUSED(compiler_options); 38c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 39c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 40c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir MarkoVerificationResults::~VerificationResults() { 41c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko Thread* self = Thread::Current(); 42c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko { 43c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(self, verified_methods_lock_); 44c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko STLDeleteValues(&verified_methods_); 45c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 46c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 47c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 48c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markobool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { 496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom DCHECK(method_verifier != NULL); 50c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko MethodReference ref = method_verifier->GetMethodReference(); 51c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); 52c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // TODO: Check also for virtual/interface invokes when DEX-to-DEX supports devirtualization. 53c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (!compile && !method_verifier->HasCheckCasts()) { 54c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return true; 55c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 56c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 57c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); 58c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (verified_method == nullptr) { 596c170c9e884e9dddf61d963d403042ee2a399e7dAndreas Gampe // Do not report an error to the verifier. We'll just punt this later. 606c170c9e884e9dddf61d963d403042ee2a399e7dAndreas Gampe return true; 61c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 62c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 63c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(Thread::Current(), verified_methods_lock_); 64c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko auto it = verified_methods_.find(ref); 65c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (it != verified_methods_.end()) { 66c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // TODO: Investigate why are we doing the work again for this method and try to avoid it. 67c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko LOG(WARNING) << "Method processed more than once: " 68c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko << PrettyMethod(ref.dex_method_index, *ref.dex_file); 69e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (!Runtime::Current()->UseJit()) { 70e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DCHECK_EQ(it->second->GetDevirtMap().size(), verified_method->GetDevirtMap().size()); 71e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DCHECK_EQ(it->second->GetSafeCastSet().size(), verified_method->GetSafeCastSet().size()); 72e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 73c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK_EQ(it->second->GetDexGcMap().size(), verified_method->GetDexGcMap().size()); 74c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko delete it->second; 75c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_.erase(it); 76c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 77c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko verified_methods_.Put(ref, verified_method); 78c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK(verified_methods_.find(ref) != verified_methods_.end()); 79c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return true; 80c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 81c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 82c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markoconst VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) { 83c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko ReaderMutexLock mu(Thread::Current(), verified_methods_lock_); 84c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko auto it = verified_methods_.find(ref); 85c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return (it != verified_methods_.end()) ? it->second : nullptr; 86c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 87c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 88ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartiervoid VerificationResults::RemoveVerifiedMethod(MethodReference ref) { 89ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier WriterMutexLock mu(Thread::Current(), verified_methods_lock_); 90ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier auto it = verified_methods_.find(ref); 91ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier if (it != verified_methods_.end()) { 92ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier delete it->second; 93ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier verified_methods_.erase(it); 94ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier } 95ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier} 96ab972ef472001fa113d54486d7592979e33480b3Mathieu Chartier 97c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markovoid VerificationResults::AddRejectedClass(ClassReference ref) { 98c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko { 99c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko WriterMutexLock mu(Thread::Current(), rejected_classes_lock_); 100c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko rejected_classes_.insert(ref); 101c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 102c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DCHECK(IsClassRejected(ref)); 103c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 104c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 105c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markobool VerificationResults::IsClassRejected(ClassReference ref) { 106c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko ReaderMutexLock mu(Thread::Current(), rejected_classes_lock_); 107c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return (rejected_classes_.find(ref) != rejected_classes_.end()); 108c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 109c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 110956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughesbool VerificationResults::IsCandidateForCompilation(MethodReference&, 111c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const uint32_t access_flags) { 1121ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers if (!compiler_options_->IsCompilationEnabled()) { 1131ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers return false; 1141ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers } 115c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Don't compile class initializers, ever. 116c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { 117c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return false; 118c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 11939c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison return true; 120c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} 121c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 122c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} // namespace art 123