blob: efe92f39431d4ca5e7b84c7c6c8404c30c38f0c9 [file] [log] [blame]
Vladimir Markof096aad2014-01-23 15:51:58 +00001/*
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
26namespace art {
27
28class CompilerDriver;
29class DexCompilationUnit;
30class DexFile;
31
32class 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
92class 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
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000126 bool NeedsClassInitialization() const {
127 return (flags_ & kFlagNeedsClassInitialization) != 0u;
128 }
129
Vladimir Markof096aad2014-01-23 15:51:58 +0000130 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.
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000165 kBitNeedsClassInitialization = kBitSharpTypeEnd,
166 kMethodLoweringInfoEnd
Vladimir Markof096aad2014-01-23 15:51:58 +0000167 };
168 COMPILE_ASSERT(kMethodLoweringInfoEnd <= 16, too_many_flags);
169 static constexpr uint16_t kFlagFastPath = 1u << kBitFastPath;
Vladimir Marko9820b7c2014-01-02 16:40:37 +0000170 static constexpr uint16_t kFlagNeedsClassInitialization = 1u << kBitNeedsClassInitialization;
Vladimir Markof096aad2014-01-23 15:51:58 +0000171 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_;
Vladimir Markobfea9c22014-01-17 17:49:33 +0000187
188 friend class ClassInitCheckEliminationTest;
Vladimir Markof096aad2014-01-23 15:51:58 +0000189};
190
191} // namespace art
192
193#endif // ART_COMPILER_DEX_MIR_METHOD_INFO_H_