1c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko/* 2c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Copyright (C) 2014 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#ifndef ART_COMPILER_DEX_VERIFIED_METHOD_H_ 18c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#define ART_COMPILER_DEX_VERIFIED_METHOD_H_ 19c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 20c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include <vector> 21c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 22719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h" 23c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "method_reference.h" 24c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "safe_map.h" 25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 26c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markonamespace art { 27c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 28c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markonamespace verifier { 29c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markoclass MethodVerifier; 30c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} // namespace verifier 31c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 32c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Markoclass VerifiedMethod { 33c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko public: 34c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Cast elision set type. 35c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Since we're adding the dex PCs to the set in increasing order, a sorted vector 36c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // is better for performance (not just memory usage), especially for large sets. 37c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko typedef std::vector<uint32_t> SafeCastSet; 38c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 39c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Devirtualization map type maps dex offset to concrete method reference. 40c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko typedef SafeMap<uint32_t, MethodReference> DevirtualizationMap; 41c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 42c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko static const VerifiedMethod* Create(verifier::MethodVerifier* method_verifier, bool compile) 43c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 44c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko ~VerifiedMethod() = default; 45c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 46c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const std::vector<uint8_t>& GetDexGcMap() const { 47c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return dex_gc_map_; 48c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 49c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 50c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const DevirtualizationMap& GetDevirtMap() const { 51c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return devirt_map_; 52c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 53c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 54c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const SafeCastSet& GetSafeCastSet() const { 55c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko return safe_cast_set_; 56c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko } 57c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 58c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Returns the devirtualization target method, or nullptr if none. 59c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const MethodReference* GetDevirtTarget(uint32_t dex_pc) const; 60c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 61c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Returns true if the cast can statically be verified to be redundant 62c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // by using the check-cast elision peephole optimization in the verifier. 63c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko bool IsSafeCast(uint32_t pc) const; 64c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 65c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko private: 66c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko VerifiedMethod() = default; 67c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 68c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko /* 69c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of 70c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * verification). For type-precise determination we have all the data we need, so we just need to 71c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * encode it in some clever fashion. 72c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko * Stores the data in dex_gc_map_, returns true on success and false on failure. 73c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko */ 74c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko bool GenerateGcMap(verifier::MethodVerifier* method_verifier); 75c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 76c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Verify that the GC map associated with method_ is well formed. 77c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko static void VerifyGcMap(verifier::MethodVerifier* method_verifier, 78c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko const std::vector<uint8_t>& data); 79c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 80c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Compute sizes for GC map data. 81c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko static void ComputeGcMapSizes(verifier::MethodVerifier* method_verifier, 82c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc); 83c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 84c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Generate devirtualizaion map into devirt_map_. 85c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko void GenerateDevirtMap(verifier::MethodVerifier* method_verifier) 86c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 87c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 88c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko // Generate safe case set into safe_cast_set_. 89c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko void GenerateSafeCastSet(verifier::MethodVerifier* method_verifier) 90c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 91c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 92c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko std::vector<uint8_t> dex_gc_map_; 93c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko DevirtualizationMap devirt_map_; 94c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko SafeCastSet safe_cast_set_; 95c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko}; 96c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 97c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko} // namespace art 98c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 99c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#endif // ART_COMPILER_DEX_VERIFIED_METHOD_H_ 100