1 /* 2 * Copyright (C) 2014 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 #ifndef ART_COMPILER_DEX_MIR_METHOD_INFO_H_ 18 #define ART_COMPILER_DEX_MIR_METHOD_INFO_H_ 19 20 #include "base/logging.h" 21 #include "base/macros.h" 22 #include "base/mutex.h" 23 #include "invoke_type.h" 24 #include "method_reference.h" 25 26 namespace art { 27 28 class CompilerDriver; 29 class DexCompilationUnit; 30 class DexFile; 31 32 class MirMethodInfo { 33 public: 34 uint16_t MethodIndex() const { 35 return method_idx_; 36 } 37 38 bool IsStatic() const { 39 return (flags_ & kFlagIsStatic) != 0u; 40 } 41 42 bool IsResolved() const { 43 return declaring_dex_file_ != nullptr; 44 } 45 46 const DexFile* DeclaringDexFile() const { 47 return declaring_dex_file_; 48 } 49 50 uint16_t DeclaringClassIndex() const { 51 return declaring_class_idx_; 52 } 53 54 uint16_t DeclaringMethodIndex() const { 55 return declaring_method_idx_; 56 } 57 58 protected: 59 enum { 60 kBitIsStatic = 0, 61 kMethodInfoBitEnd 62 }; 63 COMPILE_ASSERT(kMethodInfoBitEnd <= 16, too_many_flags); 64 static constexpr uint16_t kFlagIsStatic = 1u << kBitIsStatic; 65 66 MirMethodInfo(uint16_t method_idx, uint16_t flags) 67 : method_idx_(method_idx), 68 flags_(flags), 69 declaring_method_idx_(0u), 70 declaring_class_idx_(0u), 71 declaring_dex_file_(nullptr) { 72 } 73 74 // Make copy-ctor/assign/dtor protected to avoid slicing. 75 MirMethodInfo(const MirMethodInfo& other) = default; 76 MirMethodInfo& operator=(const MirMethodInfo& other) = default; 77 ~MirMethodInfo() = default; 78 79 // The method index in the compiling method's dex file. 80 uint16_t method_idx_; 81 // Flags, for volatility and derived class data. 82 uint16_t flags_; 83 // The method index in the dex file that defines the method, 0 if unresolved. 84 uint16_t declaring_method_idx_; 85 // The type index of the class declaring the method, 0 if unresolved. 86 uint16_t declaring_class_idx_; 87 // The dex file that defines the class containing the method and the method, 88 // nullptr if unresolved. 89 const DexFile* declaring_dex_file_; 90 }; 91 92 class MirMethodLoweringInfo : public MirMethodInfo { 93 public: 94 // For each requested method retrieve the method's declaring location (dex file, class 95 // index and method index) and compute whether we can fast path the method call. For fast 96 // path methods, retrieve the method's vtable index and direct code and method when applicable. 97 static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit, 98 MirMethodLoweringInfo* method_infos, size_t count) 99 LOCKS_EXCLUDED(Locks::mutator_lock_); 100 101 MirMethodLoweringInfo(uint16_t method_idx, InvokeType type) 102 : MirMethodInfo(method_idx, 103 ((type == kStatic) ? kFlagIsStatic : 0u) | 104 (static_cast<uint16_t>(type) << kBitInvokeTypeBegin) | 105 (static_cast<uint16_t>(type) << kBitSharpTypeBegin)), 106 direct_code_(0u), 107 direct_method_(0u), 108 target_dex_file_(nullptr), 109 target_method_idx_(0u), 110 vtable_idx_(0u), 111 stats_flags_(0) { 112 } 113 114 void SetDevirtualizationTarget(const MethodReference& ref) { 115 DCHECK(target_dex_file_ == nullptr); 116 DCHECK_EQ(target_method_idx_, 0u); 117 DCHECK_LE(ref.dex_method_index, 0xffffu); 118 target_dex_file_ = ref.dex_file; 119 target_method_idx_ = ref.dex_method_index; 120 } 121 122 bool FastPath() const { 123 return (flags_ & kFlagFastPath) != 0u; 124 } 125 126 bool NeedsClassInitialization() const { 127 return (flags_ & kFlagNeedsClassInitialization) != 0u; 128 } 129 130 InvokeType GetInvokeType() const { 131 return static_cast<InvokeType>((flags_ >> kBitInvokeTypeBegin) & kInvokeTypeMask); 132 } 133 134 art::InvokeType GetSharpType() const { 135 return static_cast<InvokeType>((flags_ >> kBitSharpTypeBegin) & kInvokeTypeMask); 136 } 137 138 MethodReference GetTargetMethod() const { 139 return MethodReference(target_dex_file_, target_method_idx_); 140 } 141 142 uint16_t VTableIndex() const { 143 return vtable_idx_; 144 } 145 146 uintptr_t DirectCode() const { 147 return direct_code_; 148 } 149 150 uintptr_t DirectMethod() const { 151 return direct_method_; 152 } 153 154 int StatsFlags() const { 155 return stats_flags_; 156 } 157 158 private: 159 enum { 160 kBitFastPath = kMethodInfoBitEnd, 161 kBitInvokeTypeBegin, 162 kBitInvokeTypeEnd = kBitInvokeTypeBegin + 3, // 3 bits for invoke type. 163 kBitSharpTypeBegin, 164 kBitSharpTypeEnd = kBitSharpTypeBegin + 3, // 3 bits for sharp type. 165 kBitNeedsClassInitialization = kBitSharpTypeEnd, 166 kMethodLoweringInfoEnd 167 }; 168 COMPILE_ASSERT(kMethodLoweringInfoEnd <= 16, too_many_flags); 169 static constexpr uint16_t kFlagFastPath = 1u << kBitFastPath; 170 static constexpr uint16_t kFlagNeedsClassInitialization = 1u << kBitNeedsClassInitialization; 171 static constexpr uint16_t kInvokeTypeMask = 7u; 172 COMPILE_ASSERT((1u << (kBitInvokeTypeEnd - kBitInvokeTypeBegin)) - 1u == kInvokeTypeMask, 173 assert_invoke_type_bits_ok); 174 COMPILE_ASSERT((1u << (kBitSharpTypeEnd - kBitSharpTypeBegin)) - 1u == kInvokeTypeMask, 175 assert_sharp_type_bits_ok); 176 177 uintptr_t direct_code_; 178 uintptr_t direct_method_; 179 // Before Resolve(), target_dex_file_ and target_method_idx_ hold the verification-based 180 // devirtualized invoke target if available, nullptr and 0u otherwise. 181 // After Resolve() they hold the actual target method that will be called; it will be either 182 // a devirtualized target method or the compilation's unit's dex file and MethodIndex(). 183 const DexFile* target_dex_file_; 184 uint16_t target_method_idx_; 185 uint16_t vtable_idx_; 186 int stats_flags_; 187 188 friend class ClassInitCheckEliminationTest; 189 }; 190 191 } // namespace art 192 193 #endif // ART_COMPILER_DEX_MIR_METHOD_INFO_H_ 194