blob: 8712bdbbf54f17fc10682f09f8574a97a076a6a1 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
2 * Copyright (C) 2011 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
Mathieu Chartiere401d142015-04-22 13:56:20 -070017#ifndef ART_RUNTIME_ART_METHOD_INL_H_
18#define ART_RUNTIME_ART_METHOD_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Brian Carlstromea46f952013-07-30 01:26:50 -070020#include "art_method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021
Andreas Gampe58a5af82014-07-31 16:23:49 -070022#include "art_field.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080023#include "dex_file.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080024#include "dex_file-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070025#include "gc_root-inl.h"
26#include "mirror/class-inl.h"
27#include "mirror/dex_cache.h"
28#include "mirror/object-inl.h"
29#include "mirror/object_array.h"
Vladimir Marko96c6ab92014-04-08 14:00:50 +010030#include "oat.h"
Vladimir Marko7624d252014-05-02 14:40:15 +010031#include "quick/quick_method_frame_info.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070032#include "read_barrier-inl.h"
Vladimir Marko7624d252014-05-02 14:40:15 +010033#include "runtime-inl.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010034#include "utils.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035
36namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037
Mathieu Chartiere401d142015-04-22 13:56:20 -070038inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070039 GcRootSource gc_root_source(this);
40 return declaring_class_.Read(&gc_root_source);
Mingyao Yang98d1cc82014-05-15 17:02:16 -070041}
42
Mathieu Chartiere401d142015-04-22 13:56:20 -070043inline mirror::Class* ArtMethod::GetDeclaringClassNoBarrier() {
44 return declaring_class_.Read<kWithoutReadBarrier>();
Mingyao Yang98d1cc82014-05-15 17:02:16 -070045}
46
Mathieu Chartiere401d142015-04-22 13:56:20 -070047inline mirror::Class* ArtMethod::GetDeclaringClass() {
48 mirror::Class* result = GetDeclaringClassUnchecked();
49 if (kIsDebugBuild) {
50 if (!IsRuntimeMethod()) {
51 CHECK(result != nullptr) << this;
52 CHECK(result->IsIdxLoaded() || result->IsErroneous())
53 << result->GetStatus() << " " << PrettyClass(result);
54 } else {
55 CHECK(result == nullptr) << this;
56 }
57 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058 return result;
59}
60
Mathieu Chartiere401d142015-04-22 13:56:20 -070061inline void ArtMethod::SetDeclaringClass(mirror::Class* new_declaring_class) {
62 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080063}
64
Ian Rogersef7d42f2014-01-06 12:55:46 -080065inline uint32_t ArtMethod::GetAccessFlags() {
Mathieu Chartiere401d142015-04-22 13:56:20 -070066 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() ||
67 GetDeclaringClass()->IsErroneous());
68 return access_flags_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080069}
70
Ian Rogersef7d42f2014-01-06 12:55:46 -080071inline uint16_t ArtMethod::GetMethodIndex() {
Mathieu Chartiere401d142015-04-22 13:56:20 -070072 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved() ||
73 GetDeclaringClass()->IsErroneous());
74 return method_index_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080075}
76
Mathieu Chartier9f3629d2014-10-28 18:23:02 -070077inline uint16_t ArtMethod::GetMethodIndexDuringLinking() {
Mathieu Chartiere401d142015-04-22 13:56:20 -070078 return method_index_;
Mathieu Chartier9f3629d2014-10-28 18:23:02 -070079}
80
Ian Rogersef7d42f2014-01-06 12:55:46 -080081inline uint32_t ArtMethod::GetDexMethodIndex() {
Mathieu Chartiere401d142015-04-22 13:56:20 -070082 DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() ||
83 GetDeclaringClass()->IsErroneous());
84 return dex_method_index_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080085}
86
Mathieu Chartiere401d142015-04-22 13:56:20 -070087inline mirror::PointerArray* ArtMethod::GetDexCacheResolvedMethods() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070088 GcRootSource gc_root_source(this);
89 return dex_cache_resolved_methods_.Read(&gc_root_source);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070090}
91
Mathieu Chartiere401d142015-04-22 13:56:20 -070092inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index, size_t ptr_size) {
93 auto* method = GetDexCacheResolvedMethods()->GetElementPtrSize<ArtMethod*>(
94 method_index, ptr_size);
95 if (LIKELY(method != nullptr)) {
96 auto* declaring_class = method->GetDeclaringClass();
97 if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) {
98 return method;
99 }
Andreas Gampe58a5af82014-07-31 16:23:49 -0700100 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700101 return nullptr;
Andreas Gampe58a5af82014-07-31 16:23:49 -0700102}
103
Mathieu Chartiere401d142015-04-22 13:56:20 -0700104inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method,
105 size_t ptr_size) {
106 DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr);
107 GetDexCacheResolvedMethods()->SetElementPtrSize(method_idx, new_method, ptr_size);
Andreas Gampe58a5af82014-07-31 16:23:49 -0700108}
109
110inline bool ArtMethod::HasDexCacheResolvedMethods() {
111 return GetDexCacheResolvedMethods() != nullptr;
112}
113
Mathieu Chartiere401d142015-04-22 13:56:20 -0700114inline bool ArtMethod::HasSameDexCacheResolvedMethods(mirror::PointerArray* other_cache) {
Andreas Gampe58a5af82014-07-31 16:23:49 -0700115 return GetDexCacheResolvedMethods() == other_cache;
116}
117
118inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other) {
119 return GetDexCacheResolvedMethods() == other->GetDexCacheResolvedMethods();
120}
121
Mathieu Chartiere401d142015-04-22 13:56:20 -0700122inline mirror::ObjectArray<mirror::Class>* ArtMethod::GetDexCacheResolvedTypes() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -0700123 GcRootSource gc_root_source(this);
124 return dex_cache_resolved_types_.Read(&gc_root_source);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700125}
126
Andreas Gampe58a5af82014-07-31 16:23:49 -0700127template <bool kWithCheck>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700128inline mirror::Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index) {
129 mirror::Class* klass = kWithCheck ?
130 GetDexCacheResolvedTypes()->Get(type_index) :
131 GetDexCacheResolvedTypes()->GetWithoutChecks(type_index);
Andreas Gampe58a5af82014-07-31 16:23:49 -0700132 return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr;
133}
134
135inline bool ArtMethod::HasDexCacheResolvedTypes() {
136 return GetDexCacheResolvedTypes() != nullptr;
137}
138
Mathieu Chartiere401d142015-04-22 13:56:20 -0700139inline bool ArtMethod::HasSameDexCacheResolvedTypes(
140 mirror::ObjectArray<mirror::Class>* other_cache) {
Andreas Gampe58a5af82014-07-31 16:23:49 -0700141 return GetDexCacheResolvedTypes() == other_cache;
142}
143
144inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other) {
145 return GetDexCacheResolvedTypes() == other->GetDexCacheResolvedTypes();
146}
147
Ian Rogersa0485602014-12-02 15:48:04 -0800148inline mirror::Class* ArtMethod::GetClassFromTypeIndex(uint16_t type_idx, bool resolve) {
149 mirror::Class* type = GetDexCacheResolvedType(type_idx);
150 if (type == nullptr && resolve) {
151 type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this);
152 CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
153 }
154 return type;
155}
156
Ian Rogersef7d42f2014-01-06 12:55:46 -0800157inline uint32_t ArtMethod::GetCodeSize() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158 DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800159 return GetCodeSize(EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode()));
160}
161
162inline uint32_t ArtMethod::GetCodeSize(const void* code) {
Vladimir Marko8a630572014-04-09 18:45:35 +0100163 if (code == nullptr) {
164 return 0u;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165 }
Vladimir Marko7624d252014-05-02 14:40:15 +0100166 return reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].code_size_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800167}
168
Brian Carlstromea46f952013-07-30 01:26:50 -0700169inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800170 switch (type) {
171 case kStatic:
172 return !IsStatic();
173 case kDirect:
174 return !IsDirect() || IsStatic();
175 case kVirtual: {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700176 mirror::Class* methods_class = GetDeclaringClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800177 return IsDirect() || (methods_class->IsInterface() && !IsMiranda());
178 }
179 case kSuper:
Andreas Gampe8f252e62014-08-25 20:46:31 -0700180 // Constructors and static methods are called with invoke-direct.
181 // Interface methods cannot be invoked with invoke-super.
182 return IsConstructor() || IsStatic() || GetDeclaringClass()->IsInterface();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800183 case kInterface: {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700184 mirror::Class* methods_class = GetDeclaringClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
186 }
187 default:
188 LOG(FATAL) << "Unreachable - invocation type: " << type;
Ian Rogers2c4257b2014-10-24 14:20:06 -0700189 UNREACHABLE();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800190 }
191}
192
Ian Rogersef7d42f2014-01-06 12:55:46 -0800193inline uint32_t ArtMethod::GetQuickOatCodeOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800194 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800195 return PointerToLowMemUInt32(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800196}
197
Ian Rogersef7d42f2014-01-06 12:55:46 -0800198inline void ArtMethod::SetQuickOatCodeOffset(uint32_t code_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800199 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800200 SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(code_offset));
201}
202
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800203inline const uint8_t* ArtMethod::GetMappingTable(size_t pointer_size) {
204 const void* code_pointer = GetQuickOatCodePointer(pointer_size);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100205 if (code_pointer == nullptr) {
206 return nullptr;
207 }
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800208 return GetMappingTable(code_pointer, pointer_size);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100209}
210
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800211inline const uint8_t* ArtMethod::GetMappingTable(const void* code_pointer, size_t pointer_size) {
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100212 DCHECK(code_pointer != nullptr);
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800213 DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size));
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100214 uint32_t offset =
215 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].mapping_table_offset_;
216 if (UNLIKELY(offset == 0u)) {
217 return nullptr;
218 }
219 return reinterpret_cast<const uint8_t*>(code_pointer) - offset;
220}
221
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800222inline const uint8_t* ArtMethod::GetVmapTable(size_t pointer_size) {
223 const void* code_pointer = GetQuickOatCodePointer(pointer_size);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100224 if (code_pointer == nullptr) {
225 return nullptr;
226 }
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800227 return GetVmapTable(code_pointer, pointer_size);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100228}
229
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800230inline const uint8_t* ArtMethod::GetVmapTable(const void* code_pointer, size_t pointer_size) {
231 CHECK(!IsOptimized(pointer_size)) << "Unimplemented vmap table for optimized compiler";
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100232 DCHECK(code_pointer != nullptr);
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800233 DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size));
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100234 uint32_t offset =
235 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].vmap_table_offset_;
236 if (UNLIKELY(offset == 0u)) {
237 return nullptr;
238 }
239 return reinterpret_cast<const uint8_t*>(code_pointer) - offset;
240}
241
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +0100242inline CodeInfo ArtMethod::GetOptimizedCodeInfo() {
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800243 DCHECK(IsOptimized(sizeof(void*)));
244 const void* code_pointer = GetQuickOatCodePointer(sizeof(void*));
Nicolas Geoffray39468442014-09-02 15:17:15 +0100245 DCHECK(code_pointer != nullptr);
246 uint32_t offset =
247 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].vmap_table_offset_;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700248 const void* data =
249 reinterpret_cast<const void*>(reinterpret_cast<const uint8_t*>(code_pointer) - offset);
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +0100250 return CodeInfo(data);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100251}
252
Mathieu Chartier957ca1c2014-11-21 16:51:29 -0800253inline const uint8_t* ArtMethod::GetNativeGcMap(size_t pointer_size) {
254 const void* code_pointer = GetQuickOatCodePointer(pointer_size);
255 if (code_pointer == nullptr) {
256 return nullptr;
257 }
258 return GetNativeGcMap(code_pointer, pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800259}
260
Mathieu Chartier957ca1c2014-11-21 16:51:29 -0800261inline const uint8_t* ArtMethod::GetNativeGcMap(const void* code_pointer, size_t pointer_size) {
262 DCHECK(code_pointer != nullptr);
263 DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size));
264 uint32_t offset =
265 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].gc_map_offset_;
266 if (UNLIKELY(offset == 0u)) {
267 return nullptr;
268 }
269 return reinterpret_cast<const uint8_t*>(code_pointer) - offset;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800270}
271
Ian Rogersef7d42f2014-01-06 12:55:46 -0800272inline bool ArtMethod::IsRuntimeMethod() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700273 return dex_method_index_ == DexFile::kDexNoIndex;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800274}
275
Ian Rogersef7d42f2014-01-06 12:55:46 -0800276inline bool ArtMethod::IsCalleeSaveMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800277 if (!IsRuntimeMethod()) {
278 return false;
279 }
280 Runtime* runtime = Runtime::Current();
281 bool result = false;
282 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
283 if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
284 result = true;
285 break;
286 }
287 }
288 return result;
289}
290
Ian Rogersef7d42f2014-01-06 12:55:46 -0800291inline bool ArtMethod::IsResolutionMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800292 bool result = this == Runtime::Current()->GetResolutionMethod();
293 // Check that if we do think it is phony it looks like the resolution method.
294 DCHECK(!result || IsRuntimeMethod());
295 return result;
296}
Jeff Hao88474b42013-10-23 16:24:40 -0700297
Ian Rogersef7d42f2014-01-06 12:55:46 -0800298inline bool ArtMethod::IsImtConflictMethod() {
Jeff Hao88474b42013-10-23 16:24:40 -0700299 bool result = this == Runtime::Current()->GetImtConflictMethod();
300 // Check that if we do think it is phony it looks like the imt conflict method.
301 DCHECK(!result || IsRuntimeMethod());
302 return result;
303}
Mathieu Chartier4e305412014-02-19 10:54:44 -0800304
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700305inline bool ArtMethod::IsImtUnimplementedMethod() {
306 bool result = this == Runtime::Current()->GetImtUnimplementedMethod();
307 // Check that if we do think it is phony it looks like the imt unimplemented method.
308 DCHECK(!result || IsRuntimeMethod());
309 return result;
310}
311
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700312inline uintptr_t ArtMethod::NativeQuickPcOffset(const uintptr_t pc) {
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800313 const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(
314 this, sizeof(void*));
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100315 return pc - reinterpret_cast<uintptr_t>(code);
316}
317
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100318inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo(const void* code_pointer) {
319 DCHECK(code_pointer != nullptr);
Mathieu Chartiera7dd0382014-11-20 17:08:58 -0800320 DCHECK_EQ(code_pointer, GetQuickOatCodePointer(sizeof(void*)));
Vladimir Marko7624d252014-05-02 14:40:15 +0100321 return reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].frame_info_;
322}
323
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700324inline const DexFile* ArtMethod::GetDexFile() {
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700325 return GetDexCache()->GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700326}
327
328inline const char* ArtMethod::GetDeclaringClassDescriptor() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700329 uint32_t dex_method_idx = GetDexMethodIndex();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700330 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
331 return "<runtime method>";
332 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700333 DCHECK(!IsProxyMethod());
334 const DexFile* dex_file = GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700335 return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx));
336}
337
338inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700339 DCHECK(!IsProxyMethod());
340 const DexFile* dex_file = GetDexFile();
341 return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700342}
343
344inline const Signature ArtMethod::GetSignature() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700345 uint32_t dex_method_idx = GetDexMethodIndex();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700346 if (dex_method_idx != DexFile::kDexNoIndex) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700347 DCHECK(!IsProxyMethod());
348 const DexFile* dex_file = GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700349 return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx));
350 }
351 return Signature::NoSignature();
352}
353
Ian Rogers1ff3c982014-08-12 02:30:58 -0700354inline const char* ArtMethod::GetName() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700355 uint32_t dex_method_idx = GetDexMethodIndex();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700356 if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700357 DCHECK(!IsProxyMethod());
358 const DexFile* dex_file = GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700359 return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx));
360 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700361 Runtime* const runtime = Runtime::Current();
362 if (this == runtime->GetResolutionMethod()) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700363 return "<runtime internal resolution method>";
Mathieu Chartiere401d142015-04-22 13:56:20 -0700364 } else if (this == runtime->GetImtConflictMethod()) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700365 return "<runtime internal imt conflict method>";
Mathieu Chartiere401d142015-04-22 13:56:20 -0700366 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700367 return "<runtime internal callee-save all registers method>";
Mathieu Chartiere401d142015-04-22 13:56:20 -0700368 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700369 return "<runtime internal callee-save reference registers method>";
Mathieu Chartiere401d142015-04-22 13:56:20 -0700370 } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700371 return "<runtime internal callee-save reference and argument registers method>";
372 } else {
373 return "<unknown runtime internal method>";
374 }
375}
376
377inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
Mathieu Chartier12b3dd72014-12-11 13:25:33 -0800378 return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset());
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700379}
380
381inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700382 DCHECK(!IsProxyMethod());
383 return GetDexCacheResolvedType(type_idx) != nullptr;
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700384}
385
386inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700387 DCHECK(!IsProxyMethod());
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700388 if (dex_pc == DexFile::kDexNoIndex) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700389 return IsNative() ? -2 : -1;
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700390 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700391 return GetDexFile()->GetLineNumFromPC(this, dex_pc);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700392}
393
394inline const DexFile::ProtoId& ArtMethod::GetPrototype() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700395 DCHECK(!IsProxyMethod());
396 const DexFile* dex_file = GetDexFile();
397 return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex()));
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700398}
399
400inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700401 DCHECK(!IsProxyMethod());
402 const DexFile* dex_file = GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700403 const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700404 dex_file->GetMethodId(GetDexMethodIndex()));
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700405 return dex_file->GetProtoParameters(proto);
406}
407
408inline const char* ArtMethod::GetDeclaringClassSourceFile() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700409 DCHECK(!IsProxyMethod());
410 return GetDeclaringClass()->GetSourceFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700411}
412
413inline uint16_t ArtMethod::GetClassDefIndex() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700414 DCHECK(!IsProxyMethod());
415 return GetDeclaringClass()->GetDexClassDefIndex();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700416}
417
418inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700419 DCHECK(!IsProxyMethod());
420 return GetDexFile()->GetClassDef(GetClassDefIndex());
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700421}
422
423inline const char* ArtMethod::GetReturnTypeDescriptor() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700424 DCHECK(!IsProxyMethod());
425 const DexFile* dex_file = GetDexFile();
426 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700427 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
428 uint16_t return_type_idx = proto_id.return_type_idx_;
429 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx));
430}
431
432inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700433 DCHECK(!IsProxyMethod());
434 const DexFile* dex_file = GetDexFile();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700435 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx));
436}
437
438inline mirror::ClassLoader* ArtMethod::GetClassLoader() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700439 DCHECK(!IsProxyMethod());
440 return GetDeclaringClass()->GetClassLoader();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700441}
442
443inline mirror::DexCache* ArtMethod::GetDexCache() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700444 DCHECK(!IsProxyMethod());
445 return GetDeclaringClass()->GetDexCache();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700446}
447
Ian Rogers03b6eaf2014-10-28 09:34:57 -0700448inline bool ArtMethod::IsProxyMethod() {
449 return GetDeclaringClass()->IsProxyClass();
450}
451
Mathieu Chartiere401d142015-04-22 13:56:20 -0700452inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) {
Ian Rogers03b6eaf2014-10-28 09:34:57 -0700453 if (LIKELY(!IsProxyMethod())) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700454 return this;
455 }
Ian Rogers03b6eaf2014-10-28 09:34:57 -0700456 mirror::Class* klass = GetDeclaringClass();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700457 auto interface_method = GetDexCacheResolvedMethods()->GetElementPtrSize<ArtMethod*>(
458 GetDexMethodIndex(), pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700459 DCHECK(interface_method != nullptr);
460 DCHECK_EQ(interface_method,
461 Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this));
462 return interface_method;
463}
464
Mathieu Chartiere401d142015-04-22 13:56:20 -0700465inline void ArtMethod::SetDexCacheResolvedMethods(mirror::PointerArray* new_dex_cache_methods) {
466 dex_cache_resolved_methods_ = GcRoot<mirror::PointerArray>(new_dex_cache_methods);
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700467}
468
Mathieu Chartiere401d142015-04-22 13:56:20 -0700469inline void ArtMethod::SetDexCacheResolvedTypes(
470 mirror::ObjectArray<mirror::Class>* new_dex_cache_types) {
471 dex_cache_resolved_types_ = GcRoot<mirror::ObjectArray<mirror::Class>>(new_dex_cache_types);
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700472}
473
Ian Rogersded66a02014-10-28 18:12:55 -0700474inline mirror::Class* ArtMethod::GetReturnType(bool resolve) {
475 DCHECK(!IsProxyMethod());
476 const DexFile* dex_file = GetDexFile();
477 const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
478 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
479 uint16_t return_type_idx = proto_id.return_type_idx_;
480 mirror::Class* type = GetDexCacheResolvedType(return_type_idx);
481 if (type == nullptr && resolve) {
482 type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this);
483 CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
484 }
485 return type;
486}
487
Mathieu Chartiere401d142015-04-22 13:56:20 -0700488template<typename RootVisitorType>
489void ArtMethod::VisitRoots(RootVisitorType& visitor) {
Mathieu Chartiere3b034a2015-05-31 14:29:23 -0700490 visitor.VisitRootIfNonNull(declaring_class_.AddressWithoutBarrier());
491 visitor.VisitRootIfNonNull(dex_cache_resolved_methods_.AddressWithoutBarrier());
492 visitor.VisitRootIfNonNull(dex_cache_resolved_types_.AddressWithoutBarrier());
Mathieu Chartier2d721012014-11-10 11:08:06 -0800493}
494
Mathieu Chartiere401d142015-04-22 13:56:20 -0700495inline void ArtMethod::CopyFrom(const ArtMethod* src, size_t image_pointer_size) {
496 memcpy(reinterpret_cast<void*>(this), reinterpret_cast<const void*>(src),
497 ObjectSize(image_pointer_size));
498 declaring_class_ = GcRoot<mirror::Class>(const_cast<ArtMethod*>(src)->GetDeclaringClass());
499 dex_cache_resolved_methods_ = GcRoot<mirror::PointerArray>(
500 const_cast<ArtMethod*>(src)->GetDexCacheResolvedMethods());
501 dex_cache_resolved_types_ = GcRoot<mirror::ObjectArray<mirror::Class>>(
502 const_cast<ArtMethod*>(src)->GetDexCacheResolvedTypes());
503}
504
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800505} // namespace art
506
Mathieu Chartiere401d142015-04-22 13:56:20 -0700507#endif // ART_RUNTIME_ART_METHOD_INL_H_