1/*
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
17#ifndef ART_RUNTIME_ART_METHOD_INL_H_
18#define ART_RUNTIME_ART_METHOD_INL_H_
19
20#include "art_method.h"
21
22#include "art_field.h"
23#include "base/logging.h"
24#include "class_linker-inl.h"
25#include "common_throws.h"
26#include "dex_file.h"
27#include "dex_file_annotations.h"
28#include "dex_file-inl.h"
29#include "gc_root-inl.h"
30#include "jit/profiling_info.h"
31#include "mirror/class-inl.h"
32#include "mirror/dex_cache-inl.h"
33#include "mirror/object-inl.h"
34#include "mirror/object_array.h"
35#include "mirror/string.h"
36#include "oat.h"
37#include "obj_ptr-inl.h"
38#include "quick/quick_method_frame_info.h"
39#include "read_barrier-inl.h"
40#include "runtime-inl.h"
41#include "scoped_thread_state_change-inl.h"
42#include "thread-inl.h"
43#include "utils.h"
44
45namespace art {
46
47template <ReadBarrierOption kReadBarrierOption>
48inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() {
49  GcRootSource gc_root_source(this);
50  return declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
51}
52
53template <ReadBarrierOption kReadBarrierOption>
54inline mirror::Class* ArtMethod::GetDeclaringClass() {
55  mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>();
56  if (kIsDebugBuild) {
57    if (!IsRuntimeMethod()) {
58      CHECK(result != nullptr) << this;
59      if (kCheckDeclaringClassState) {
60        if (!(result->IsIdxLoaded() || result->IsErroneous())) {
61          LOG(FATAL_WITHOUT_ABORT) << "Class status: " << result->GetStatus();
62          LOG(FATAL) << result->PrettyClass();
63        }
64      }
65    } else {
66      CHECK(result == nullptr) << this;
67    }
68  }
69  return result;
70}
71
72inline void ArtMethod::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
73  declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
74}
75
76inline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class,
77                                         mirror::Class* desired_class) {
78  GcRoot<mirror::Class> expected_root(expected_class);
79  GcRoot<mirror::Class> desired_root(desired_class);
80  return reinterpret_cast<Atomic<GcRoot<mirror::Class>>*>(&declaring_class_)->
81      CompareExchangeStrongSequentiallyConsistent(
82          expected_root, desired_root);
83}
84
85inline uint16_t ArtMethod::GetMethodIndex() {
86  DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved());
87  return method_index_;
88}
89
90inline uint16_t ArtMethod::GetMethodIndexDuringLinking() {
91  return method_index_;
92}
93
94inline uint32_t ArtMethod::GetDexMethodIndex() {
95  if (kCheckDeclaringClassState) {
96    CHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() ||
97          GetDeclaringClass()->IsErroneous());
98  }
99  return GetDexMethodIndexUnchecked();
100}
101
102inline ArtMethod** ArtMethod::GetDexCacheResolvedMethods(PointerSize pointer_size) {
103  return GetNativePointer<ArtMethod**>(DexCacheResolvedMethodsOffset(pointer_size),
104                                       pointer_size);
105}
106
107inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index,
108                                                       PointerSize pointer_size) {
109  // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
110  // without accessing the DexCache and we don't want to do that in release build.
111  DCHECK_LT(method_index,
112            GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
113  ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
114                                                          method_index,
115                                                          pointer_size);
116  if (LIKELY(method != nullptr)) {
117    auto* declaring_class = method->GetDeclaringClass();
118    if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) {
119      return method;
120    }
121  }
122  return nullptr;
123}
124
125inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index,
126                                                 ArtMethod* new_method,
127                                                 PointerSize pointer_size) {
128  // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
129  // without accessing the DexCache and we don't want to do that in release build.
130  DCHECK_LT(method_index,
131            GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
132  DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr);
133  mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
134                                      method_index,
135                                      new_method,
136                                      pointer_size);
137}
138
139inline bool ArtMethod::HasDexCacheResolvedMethods(PointerSize pointer_size) {
140  return GetDexCacheResolvedMethods(pointer_size) != nullptr;
141}
142
143inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod** other_cache,
144                                                      PointerSize pointer_size) {
145  return GetDexCacheResolvedMethods(pointer_size) == other_cache;
146}
147
148inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, PointerSize pointer_size) {
149  return GetDexCacheResolvedMethods(pointer_size) ==
150      other->GetDexCacheResolvedMethods(pointer_size);
151}
152
153inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve) {
154  // TODO: Refactor this function into two functions, Resolve...() and Lookup...()
155  // so that we can properly annotate it with no-suspension possible / suspension possible.
156  ObjPtr<mirror::DexCache> dex_cache = GetDexCache();
157  ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
158  if (UNLIKELY(type == nullptr)) {
159    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
160    if (resolve) {
161      type = class_linker->ResolveType(type_idx, this);
162      CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
163    } else {
164      type = class_linker->LookupResolvedType(
165          *dex_cache->GetDexFile(), type_idx, dex_cache, GetClassLoader());
166    }
167  }
168  return type.Ptr();
169}
170
171inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
172  switch (type) {
173    case kStatic:
174      return !IsStatic();
175    case kDirect:
176      return !IsDirect() || IsStatic();
177    case kVirtual: {
178      // We have an error if we are direct or a non-copied (i.e. not part of a real class) interface
179      // method.
180      mirror::Class* methods_class = GetDeclaringClass();
181      return IsDirect() || (methods_class->IsInterface() && !IsCopied());
182    }
183    case kSuper:
184      // Constructors and static methods are called with invoke-direct.
185      return IsConstructor() || IsStatic();
186    case kInterface: {
187      mirror::Class* methods_class = GetDeclaringClass();
188      return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
189    }
190    default:
191      LOG(FATAL) << "Unreachable - invocation type: " << type;
192      UNREACHABLE();
193  }
194}
195
196inline bool ArtMethod::IsCalleeSaveMethod() {
197  if (!IsRuntimeMethod()) {
198    return false;
199  }
200  Runtime* runtime = Runtime::Current();
201  bool result = false;
202  for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
203    if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
204      result = true;
205      break;
206    }
207  }
208  return result;
209}
210
211inline bool ArtMethod::IsResolutionMethod() {
212  bool result = this == Runtime::Current()->GetResolutionMethod();
213  // Check that if we do think it is phony it looks like the resolution method.
214  DCHECK(!result || IsRuntimeMethod());
215  return result;
216}
217
218inline bool ArtMethod::IsImtUnimplementedMethod() {
219  bool result = this == Runtime::Current()->GetImtUnimplementedMethod();
220  // Check that if we do think it is phony it looks like the imt unimplemented method.
221  DCHECK(!result || IsRuntimeMethod());
222  return result;
223}
224
225inline const DexFile* ArtMethod::GetDexFile() {
226  // It is safe to avoid the read barrier here since the dex file is constant, so if we read the
227  // from-space dex file pointer it will be equal to the to-space copy.
228  return GetDexCache<kWithoutReadBarrier>()->GetDexFile();
229}
230
231inline const char* ArtMethod::GetDeclaringClassDescriptor() {
232  uint32_t dex_method_idx = GetDexMethodIndex();
233  if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
234    return "<runtime method>";
235  }
236  DCHECK(!IsProxyMethod());
237  const DexFile* dex_file = GetDexFile();
238  return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx));
239}
240
241inline const char* ArtMethod::GetShorty() {
242  uint32_t unused_length;
243  return GetShorty(&unused_length);
244}
245
246inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
247  DCHECK(!IsProxyMethod());
248  const DexFile* dex_file = GetDexFile();
249  return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length);
250}
251
252inline const Signature ArtMethod::GetSignature() {
253  uint32_t dex_method_idx = GetDexMethodIndex();
254  if (dex_method_idx != DexFile::kDexNoIndex) {
255    DCHECK(!IsProxyMethod());
256    const DexFile* dex_file = GetDexFile();
257    return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx));
258  }
259  return Signature::NoSignature();
260}
261
262inline const char* ArtMethod::GetName() {
263  uint32_t dex_method_idx = GetDexMethodIndex();
264  if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
265    DCHECK(!IsProxyMethod());
266    const DexFile* dex_file = GetDexFile();
267    return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx));
268  }
269  Runtime* const runtime = Runtime::Current();
270  if (this == runtime->GetResolutionMethod()) {
271    return "<runtime internal resolution method>";
272  } else if (this == runtime->GetImtConflictMethod()) {
273    return "<runtime internal imt conflict method>";
274  } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveAllCalleeSaves)) {
275    return "<runtime internal callee-save all registers method>";
276  } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveRefsOnly)) {
277    return "<runtime internal callee-save reference registers method>";
278  } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs)) {
279    return "<runtime internal callee-save reference and argument registers method>";
280  } else {
281    return "<unknown runtime internal method>";
282  }
283}
284
285inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
286  return GetDexFile()->GetCodeItem(GetCodeItemOffset());
287}
288
289inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx) {
290  DCHECK(!IsProxyMethod());
291  return GetClassFromTypeIndex(type_idx, /* resolve */ false) != nullptr;
292}
293
294inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {
295  DCHECK(!IsProxyMethod());
296  if (dex_pc == DexFile::kDexNoIndex) {
297    return IsNative() ? -2 : -1;
298  }
299  return annotations::GetLineNumFromPC(GetDexFile(), this, dex_pc);
300}
301
302inline const DexFile::ProtoId& ArtMethod::GetPrototype() {
303  DCHECK(!IsProxyMethod());
304  const DexFile* dex_file = GetDexFile();
305  return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex()));
306}
307
308inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
309  DCHECK(!IsProxyMethod());
310  const DexFile* dex_file = GetDexFile();
311  const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
312      dex_file->GetMethodId(GetDexMethodIndex()));
313  return dex_file->GetProtoParameters(proto);
314}
315
316inline const char* ArtMethod::GetDeclaringClassSourceFile() {
317  DCHECK(!IsProxyMethod());
318  return GetDeclaringClass()->GetSourceFile();
319}
320
321inline uint16_t ArtMethod::GetClassDefIndex() {
322  DCHECK(!IsProxyMethod());
323  if (LIKELY(!IsObsolete())) {
324    return GetDeclaringClass()->GetDexClassDefIndex();
325  } else {
326    return FindObsoleteDexClassDefIndex();
327  }
328}
329
330inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
331  DCHECK(!IsProxyMethod());
332  return GetDexFile()->GetClassDef(GetClassDefIndex());
333}
334
335inline const char* ArtMethod::GetReturnTypeDescriptor() {
336  DCHECK(!IsProxyMethod());
337  const DexFile* dex_file = GetDexFile();
338  const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
339  const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
340  return dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_));
341}
342
343inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) {
344  DCHECK(!IsProxyMethod());
345  const DexFile* dex_file = GetDexFile();
346  return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx));
347}
348
349inline mirror::ClassLoader* ArtMethod::GetClassLoader() {
350  DCHECK(!IsProxyMethod());
351  return GetDeclaringClass()->GetClassLoader();
352}
353
354template <ReadBarrierOption kReadBarrierOption>
355inline mirror::DexCache* ArtMethod::GetDexCache() {
356  if (LIKELY(!IsObsolete())) {
357    mirror::Class* klass = GetDeclaringClass<kReadBarrierOption>();
358    return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>();
359  } else {
360    DCHECK(!IsProxyMethod());
361    return GetObsoleteDexCache();
362  }
363}
364
365inline bool ArtMethod::IsProxyMethod() {
366  // Avoid read barrier since the from-space version of the class will have the correct proxy class
367  // flags since they are constant for the lifetime of the class.
368  return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass();
369}
370
371inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(PointerSize pointer_size) {
372  if (LIKELY(!IsProxyMethod())) {
373    return this;
374  }
375  ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
376      GetDexCacheResolvedMethods(pointer_size),
377      GetDexMethodIndex(),
378      pointer_size);
379  DCHECK(interface_method != nullptr);
380  DCHECK_EQ(interface_method,
381            Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
382  return interface_method;
383}
384
385inline void ArtMethod::SetDexCacheResolvedMethods(ArtMethod** new_dex_cache_methods,
386                                                  PointerSize pointer_size) {
387  SetNativePointer(DexCacheResolvedMethodsOffset(pointer_size),
388                   new_dex_cache_methods,
389                   pointer_size);
390}
391
392inline mirror::Class* ArtMethod::GetReturnType(bool resolve) {
393  DCHECK(!IsProxyMethod());
394  const DexFile* dex_file = GetDexFile();
395  const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
396  const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
397  dex::TypeIndex return_type_idx = proto_id.return_type_idx_;
398  return GetClassFromTypeIndex(return_type_idx, resolve);
399}
400
401inline bool ArtMethod::HasSingleImplementation() {
402  if (IsFinal() || GetDeclaringClass()->IsFinal()) {
403    // We don't set kAccSingleImplementation for these cases since intrinsic
404    // can use the flag also.
405    return true;
406  }
407  return (GetAccessFlags() & kAccSingleImplementation) != 0;
408}
409
410inline void ArtMethod::SetIntrinsic(uint32_t intrinsic) {
411  DCHECK(IsUint<8>(intrinsic));
412  // Currently we only do intrinsics for static/final methods or methods of final
413  // classes. We don't set kHasSingleImplementation for those methods.
414  DCHECK(IsStatic() || IsFinal() || GetDeclaringClass()->IsFinal()) <<
415      "Potential conflict with kAccSingleImplementation";
416  uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) |
417      kAccIntrinsic |
418      (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic));
419  if (kIsDebugBuild) {
420    uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask);
421    bool is_constructor = IsConstructor();
422    bool is_synchronized = IsSynchronized();
423    bool skip_access_checks = SkipAccessChecks();
424    bool is_fast_native = IsFastNative();
425    bool is_copied = IsCopied();
426    bool is_miranda = IsMiranda();
427    bool is_default = IsDefault();
428    bool is_default_conflict = IsDefaultConflicting();
429    bool is_compilable = IsCompilable();
430    bool must_count_locks = MustCountLocks();
431    SetAccessFlags(new_value);
432    DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask));
433    DCHECK_EQ(is_constructor, IsConstructor());
434    DCHECK_EQ(is_synchronized, IsSynchronized());
435    DCHECK_EQ(skip_access_checks, SkipAccessChecks());
436    DCHECK_EQ(is_fast_native, IsFastNative());
437    DCHECK_EQ(is_copied, IsCopied());
438    DCHECK_EQ(is_miranda, IsMiranda());
439    DCHECK_EQ(is_default, IsDefault());
440    DCHECK_EQ(is_default_conflict, IsDefaultConflicting());
441    DCHECK_EQ(is_compilable, IsCompilable());
442    DCHECK_EQ(must_count_locks, MustCountLocks());
443  } else {
444    SetAccessFlags(new_value);
445  }
446}
447
448template<ReadBarrierOption kReadBarrierOption, typename RootVisitorType>
449void ArtMethod::VisitRoots(RootVisitorType& visitor, PointerSize pointer_size) {
450  if (LIKELY(!declaring_class_.IsNull())) {
451    visitor.VisitRoot(declaring_class_.AddressWithoutBarrier());
452    mirror::Class* klass = declaring_class_.Read<kReadBarrierOption>();
453    if (UNLIKELY(klass->IsProxyClass())) {
454      // For normal methods, dex cache shortcuts will be visited through the declaring class.
455      // However, for proxies we need to keep the interface method alive, so we visit its roots.
456      ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
457          GetDexCacheResolvedMethods(pointer_size),
458          GetDexMethodIndex(),
459          pointer_size);
460      DCHECK(interface_method != nullptr);
461      DCHECK_EQ(interface_method,
462                Runtime::Current()->GetClassLinker()->FindMethodForProxy<kReadBarrierOption>(
463                    klass, this));
464      interface_method->VisitRoots(visitor, pointer_size);
465    }
466  }
467}
468
469template <typename Visitor>
470inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor,
471                                                       PointerSize pointer_size) {
472  mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>();
473  mirror::Class* new_class = visitor(old_class);
474  if (old_class != new_class) {
475    SetDeclaringClass(new_class);
476  }
477  ArtMethod** old_methods = GetDexCacheResolvedMethods(pointer_size);
478  ArtMethod** new_methods = visitor(old_methods);
479  if (old_methods != new_methods) {
480    SetDexCacheResolvedMethods(new_methods, pointer_size);
481  }
482}
483
484template <ReadBarrierOption kReadBarrierOption, typename Visitor>
485inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize pointer_size) {
486  if (IsNative<kReadBarrierOption>()) {
487    const void* old_native_code = GetEntryPointFromJniPtrSize(pointer_size);
488    const void* new_native_code = visitor(old_native_code);
489    if (old_native_code != new_native_code) {
490      SetEntryPointFromJniPtrSize(new_native_code, pointer_size);
491    }
492  } else {
493    DCHECK(GetDataPtrSize(pointer_size) == nullptr);
494  }
495  const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
496  const void* new_code = visitor(old_code);
497  if (old_code != new_code) {
498    SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size);
499  }
500}
501
502}  // namespace art
503
504#endif  // ART_RUNTIME_ART_METHOD_INL_H_
505