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 #include "art_method.h"
18 
19 #include <cstddef>
20 
21 #include "android-base/stringprintf.h"
22 
23 #include "arch/context.h"
24 #include "art_method-inl.h"
25 #include "base/stringpiece.h"
26 #include "class_linker-inl.h"
27 #include "debugger.h"
28 #include "dex_file-inl.h"
29 #include "dex_file_annotations.h"
30 #include "dex_instruction.h"
31 #include "entrypoints/runtime_asm_entrypoints.h"
32 #include "gc/accounting/card_table-inl.h"
33 #include "interpreter/interpreter.h"
34 #include "jit/jit.h"
35 #include "jit/jit_code_cache.h"
36 #include "jit/profiling_info.h"
37 #include "jni_internal.h"
38 #include "mirror/class-inl.h"
39 #include "mirror/class_ext.h"
40 #include "mirror/executable.h"
41 #include "mirror/object_array-inl.h"
42 #include "mirror/object-inl.h"
43 #include "mirror/string.h"
44 #include "oat_file-inl.h"
45 #include "runtime_callbacks.h"
46 #include "scoped_thread_state_change-inl.h"
47 #include "well_known_classes.h"
48 
49 namespace art {
50 
51 using android::base::StringPrintf;
52 
53 extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
54                                       const char*);
55 extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
56                                              const char*);
57 
58 // Enforce that we he have the right index for runtime methods.
59 static_assert(ArtMethod::kRuntimeMethodDexMethodIndex == DexFile::kDexNoIndex,
60               "Wrong runtime-method dex method index");
61 
GetNonObsoleteMethod()62 ArtMethod* ArtMethod::GetNonObsoleteMethod() {
63   DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
64   if (LIKELY(!IsObsolete())) {
65     return this;
66   } else if (IsDirect()) {
67     return &GetDeclaringClass()->GetDirectMethodsSlice(kRuntimePointerSize)[GetMethodIndex()];
68   } else {
69     return GetDeclaringClass()->GetVTableEntry(GetMethodIndex(), kRuntimePointerSize);
70   }
71 }
72 
GetSingleImplementation(PointerSize pointer_size)73 ArtMethod* ArtMethod::GetSingleImplementation(PointerSize pointer_size) {
74   if (!IsAbstract()) {
75     // A non-abstract's single implementation is itself.
76     return this;
77   }
78   return reinterpret_cast<ArtMethod*>(GetDataPtrSize(pointer_size));
79 }
80 
FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable & soa,jobject jlr_method)81 ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
82                                           jobject jlr_method) {
83   ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(jlr_method);
84   DCHECK(executable != nullptr);
85   return executable->GetArtMethod();
86 }
87 
GetObsoleteDexCache()88 mirror::DexCache* ArtMethod::GetObsoleteDexCache() {
89   DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
90   DCHECK(IsObsolete());
91   ObjPtr<mirror::ClassExt> ext(GetDeclaringClass()->GetExtData());
92   CHECK(!ext.IsNull());
93   ObjPtr<mirror::PointerArray> obsolete_methods(ext->GetObsoleteMethods());
94   CHECK(!obsolete_methods.IsNull());
95   DCHECK(ext->GetObsoleteDexCaches() != nullptr);
96   int32_t len = obsolete_methods->GetLength();
97   DCHECK_EQ(len, ext->GetObsoleteDexCaches()->GetLength());
98   // Using kRuntimePointerSize (instead of using the image's pointer size) is fine since images
99   // should never have obsolete methods in them so they should always be the same.
100   PointerSize pointer_size = kRuntimePointerSize;
101   DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
102   for (int32_t i = 0; i < len; i++) {
103     if (this == obsolete_methods->GetElementPtrSize<ArtMethod*>(i, pointer_size)) {
104       return ext->GetObsoleteDexCaches()->Get(i);
105     }
106   }
107   LOG(FATAL) << "This method does not appear in the obsolete map of its class!";
108   UNREACHABLE();
109 }
110 
FindObsoleteDexClassDefIndex()111 uint16_t ArtMethod::FindObsoleteDexClassDefIndex() {
112   DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
113   DCHECK(IsObsolete());
114   const DexFile* dex_file = GetDexFile();
115   const dex::TypeIndex declaring_class_type = dex_file->GetMethodId(GetDexMethodIndex()).class_idx_;
116   const DexFile::ClassDef* class_def = dex_file->FindClassDef(declaring_class_type);
117   CHECK(class_def != nullptr);
118   return dex_file->GetIndexForClassDef(*class_def);
119 }
120 
GetNameAsString(Thread * self)121 mirror::String* ArtMethod::GetNameAsString(Thread* self) {
122   CHECK(!IsProxyMethod());
123   StackHandleScope<1> hs(self);
124   Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
125   auto* dex_file = dex_cache->GetDexFile();
126   uint32_t dex_method_idx = GetDexMethodIndex();
127   const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
128   return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
129                                                              dex_cache);
130 }
131 
ThrowInvocationTimeError()132 void ArtMethod::ThrowInvocationTimeError() {
133   DCHECK(!IsInvokable());
134   // NOTE: IsDefaultConflicting must be first since the actual method might or might not be abstract
135   //       due to the way we select it.
136   if (IsDefaultConflicting()) {
137     ThrowIncompatibleClassChangeErrorForMethodConflict(this);
138   } else {
139     DCHECK(IsAbstract());
140     ThrowAbstractMethodError(this);
141   }
142 }
143 
GetInvokeType()144 InvokeType ArtMethod::GetInvokeType() {
145   // TODO: kSuper?
146   if (IsStatic()) {
147     return kStatic;
148   } else if (GetDeclaringClass()->IsInterface()) {
149     return kInterface;
150   } else if (IsDirect()) {
151     return kDirect;
152   } else {
153     return kVirtual;
154   }
155 }
156 
NumArgRegisters(const StringPiece & shorty)157 size_t ArtMethod::NumArgRegisters(const StringPiece& shorty) {
158   CHECK_LE(1U, shorty.length());
159   uint32_t num_registers = 0;
160   for (size_t i = 1; i < shorty.length(); ++i) {
161     char ch = shorty[i];
162     if (ch == 'D' || ch == 'J') {
163       num_registers += 2;
164     } else {
165       num_registers += 1;
166     }
167   }
168   return num_registers;
169 }
170 
HasSameNameAndSignature(ArtMethod * other)171 bool ArtMethod::HasSameNameAndSignature(ArtMethod* other) {
172   ScopedAssertNoThreadSuspension ants("HasSameNameAndSignature");
173   const DexFile* dex_file = GetDexFile();
174   const DexFile::MethodId& mid = dex_file->GetMethodId(GetDexMethodIndex());
175   if (GetDexCache() == other->GetDexCache()) {
176     const DexFile::MethodId& mid2 = dex_file->GetMethodId(other->GetDexMethodIndex());
177     return mid.name_idx_ == mid2.name_idx_ && mid.proto_idx_ == mid2.proto_idx_;
178   }
179   const DexFile* dex_file2 = other->GetDexFile();
180   const DexFile::MethodId& mid2 = dex_file2->GetMethodId(other->GetDexMethodIndex());
181   if (!DexFileStringEquals(dex_file, mid.name_idx_, dex_file2, mid2.name_idx_)) {
182     return false;  // Name mismatch.
183   }
184   return dex_file->GetMethodSignature(mid) == dex_file2->GetMethodSignature(mid2);
185 }
186 
FindOverriddenMethod(PointerSize pointer_size)187 ArtMethod* ArtMethod::FindOverriddenMethod(PointerSize pointer_size) {
188   if (IsStatic()) {
189     return nullptr;
190   }
191   mirror::Class* declaring_class = GetDeclaringClass();
192   mirror::Class* super_class = declaring_class->GetSuperClass();
193   uint16_t method_index = GetMethodIndex();
194   ArtMethod* result = nullptr;
195   // Did this method override a super class method? If so load the result from the super class'
196   // vtable
197   if (super_class->HasVTable() && method_index < super_class->GetVTableLength()) {
198     result = super_class->GetVTableEntry(method_index, pointer_size);
199   } else {
200     // Method didn't override superclass method so search interfaces
201     if (IsProxyMethod()) {
202       result = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
203                                                    GetDexMethodIndex(),
204                                                    pointer_size);
205       CHECK_EQ(result,
206                Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
207     } else {
208       mirror::IfTable* iftable = GetDeclaringClass()->GetIfTable();
209       for (size_t i = 0; i < iftable->Count() && result == nullptr; i++) {
210         mirror::Class* interface = iftable->GetInterface(i);
211         for (ArtMethod& interface_method : interface->GetVirtualMethods(pointer_size)) {
212           if (HasSameNameAndSignature(interface_method.GetInterfaceMethodIfProxy(pointer_size))) {
213             result = &interface_method;
214             break;
215           }
216         }
217       }
218     }
219   }
220   DCHECK(result == nullptr ||
221          GetInterfaceMethodIfProxy(pointer_size)->HasSameNameAndSignature(
222              result->GetInterfaceMethodIfProxy(pointer_size)));
223   return result;
224 }
225 
FindDexMethodIndexInOtherDexFile(const DexFile & other_dexfile,uint32_t name_and_signature_idx)226 uint32_t ArtMethod::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
227                                                      uint32_t name_and_signature_idx) {
228   const DexFile* dexfile = GetDexFile();
229   const uint32_t dex_method_idx = GetDexMethodIndex();
230   const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
231   const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
232   DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
233   DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
234   if (dexfile == &other_dexfile) {
235     return dex_method_idx;
236   }
237   const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
238   const DexFile::TypeId* other_type_id = other_dexfile.FindTypeId(mid_declaring_class_descriptor);
239   if (other_type_id != nullptr) {
240     const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
241         *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
242         other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
243     if (other_mid != nullptr) {
244       return other_dexfile.GetIndexForMethodId(*other_mid);
245     }
246   }
247   return DexFile::kDexNoIndex;
248 }
249 
FindCatchBlock(Handle<mirror::Class> exception_type,uint32_t dex_pc,bool * has_no_move_exception)250 uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type,
251                                    uint32_t dex_pc, bool* has_no_move_exception) {
252   const DexFile::CodeItem* code_item = GetCodeItem();
253   // Set aside the exception while we resolve its type.
254   Thread* self = Thread::Current();
255   StackHandleScope<1> hs(self);
256   Handle<mirror::Throwable> exception(hs.NewHandle(self->GetException()));
257   self->ClearException();
258   // Default to handler not found.
259   uint32_t found_dex_pc = DexFile::kDexNoIndex;
260   // Iterate over the catch handlers associated with dex_pc.
261   for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
262     dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex();
263     // Catch all case
264     if (!iter_type_idx.IsValid()) {
265       found_dex_pc = it.GetHandlerAddress();
266       break;
267     }
268     // Does this catch exception type apply?
269     mirror::Class* iter_exception_type = GetClassFromTypeIndex(iter_type_idx, true /* resolve */);
270     if (UNLIKELY(iter_exception_type == nullptr)) {
271       // Now have a NoClassDefFoundError as exception. Ignore in case the exception class was
272       // removed by a pro-guard like tool.
273       // Note: this is not RI behavior. RI would have failed when loading the class.
274       self->ClearException();
275       // Delete any long jump context as this routine is called during a stack walk which will
276       // release its in use context at the end.
277       delete self->GetLongJumpContext();
278       LOG(WARNING) << "Unresolved exception class when finding catch block: "
279         << DescriptorToDot(GetTypeDescriptorFromTypeIdx(iter_type_idx));
280     } else if (iter_exception_type->IsAssignableFrom(exception_type.Get())) {
281       found_dex_pc = it.GetHandlerAddress();
282       break;
283     }
284   }
285   if (found_dex_pc != DexFile::kDexNoIndex) {
286     const Instruction* first_catch_instr =
287         Instruction::At(&code_item->insns_[found_dex_pc]);
288     *has_no_move_exception = (first_catch_instr->Opcode() != Instruction::MOVE_EXCEPTION);
289   }
290   // Put the exception back.
291   if (exception != nullptr) {
292     self->SetException(exception.Get());
293   }
294   return found_dex_pc;
295 }
296 
Invoke(Thread * self,uint32_t * args,uint32_t args_size,JValue * result,const char * shorty)297 void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
298                        const char* shorty) {
299   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
300     ThrowStackOverflowError(self);
301     return;
302   }
303 
304   if (kIsDebugBuild) {
305     self->AssertThreadSuspensionIsAllowable();
306     CHECK_EQ(kRunnable, self->GetState());
307     CHECK_STREQ(GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(), shorty);
308   }
309 
310   // Push a transition back into managed code onto the linked list in thread.
311   ManagedStack fragment;
312   self->PushManagedStackFragment(&fragment);
313 
314   Runtime* runtime = Runtime::Current();
315   // Call the invoke stub, passing everything as arguments.
316   // If the runtime is not yet started or it is required by the debugger, then perform the
317   // Invocation by the interpreter, explicitly forcing interpretation over JIT to prevent
318   // cycling around the various JIT/Interpreter methods that handle method invocation.
319   if (UNLIKELY(!runtime->IsStarted() || Dbg::IsForcedInterpreterNeededForCalling(self, this))) {
320     if (IsStatic()) {
321       art::interpreter::EnterInterpreterFromInvoke(
322           self, this, nullptr, args, result, /*stay_in_interpreter*/ true);
323     } else {
324       mirror::Object* receiver =
325           reinterpret_cast<StackReference<mirror::Object>*>(&args[0])->AsMirrorPtr();
326       art::interpreter::EnterInterpreterFromInvoke(
327           self, this, receiver, args + 1, result, /*stay_in_interpreter*/ true);
328     }
329   } else {
330     DCHECK_EQ(runtime->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
331 
332     constexpr bool kLogInvocationStartAndReturn = false;
333     bool have_quick_code = GetEntryPointFromQuickCompiledCode() != nullptr;
334     if (LIKELY(have_quick_code)) {
335       if (kLogInvocationStartAndReturn) {
336         LOG(INFO) << StringPrintf(
337             "Invoking '%s' quick code=%p static=%d", PrettyMethod().c_str(),
338             GetEntryPointFromQuickCompiledCode(), static_cast<int>(IsStatic() ? 1 : 0));
339       }
340 
341       // Ensure that we won't be accidentally calling quick compiled code when -Xint.
342       if (kIsDebugBuild && runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
343         CHECK(!runtime->UseJitCompilation());
344         const void* oat_quick_code =
345             (IsNative() || !IsInvokable() || IsProxyMethod() || IsObsolete())
346             ? nullptr
347             : GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize());
348         CHECK(oat_quick_code == nullptr || oat_quick_code != GetEntryPointFromQuickCompiledCode())
349             << "Don't call compiled code when -Xint " << PrettyMethod();
350       }
351 
352       if (!IsStatic()) {
353         (*art_quick_invoke_stub)(this, args, args_size, self, result, shorty);
354       } else {
355         (*art_quick_invoke_static_stub)(this, args, args_size, self, result, shorty);
356       }
357       if (UNLIKELY(self->GetException() == Thread::GetDeoptimizationException())) {
358         // Unusual case where we were running generated code and an
359         // exception was thrown to force the activations to be removed from the
360         // stack. Continue execution in the interpreter.
361         self->DeoptimizeWithDeoptimizationException(result);
362       }
363       if (kLogInvocationStartAndReturn) {
364         LOG(INFO) << StringPrintf("Returned '%s' quick code=%p", PrettyMethod().c_str(),
365                                   GetEntryPointFromQuickCompiledCode());
366       }
367     } else {
368       LOG(INFO) << "Not invoking '" << PrettyMethod() << "' code=null";
369       if (result != nullptr) {
370         result->SetJ(0);
371       }
372     }
373   }
374 
375   // Pop transition.
376   self->PopManagedStackFragment(fragment);
377 }
378 
RegisterNative(const void * native_method,bool is_fast)379 const void* ArtMethod::RegisterNative(const void* native_method, bool is_fast) {
380   CHECK(IsNative()) << PrettyMethod();
381   CHECK(!IsFastNative()) << PrettyMethod();
382   CHECK(native_method != nullptr) << PrettyMethod();
383   if (is_fast) {
384     AddAccessFlags(kAccFastNative);
385   }
386   void* new_native_method = nullptr;
387   Runtime::Current()->GetRuntimeCallbacks()->RegisterNativeMethod(this,
388                                                                   native_method,
389                                                                   /*out*/&new_native_method);
390   SetEntryPointFromJni(new_native_method);
391   return new_native_method;
392 }
393 
UnregisterNative()394 void ArtMethod::UnregisterNative() {
395   CHECK(IsNative() && !IsFastNative()) << PrettyMethod();
396   // restore stub to lookup native pointer via dlsym
397   SetEntryPointFromJni(GetJniDlsymLookupStub());
398 }
399 
IsOverridableByDefaultMethod()400 bool ArtMethod::IsOverridableByDefaultMethod() {
401   return GetDeclaringClass()->IsInterface();
402 }
403 
IsAnnotatedWithFastNative()404 bool ArtMethod::IsAnnotatedWithFastNative() {
405   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_FastNative,
406                          DexFile::kDexVisibilityBuild,
407                          /* lookup_in_resolved_boot_classes */ true);
408 }
409 
IsAnnotatedWithCriticalNative()410 bool ArtMethod::IsAnnotatedWithCriticalNative() {
411   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_CriticalNative,
412                          DexFile::kDexVisibilityBuild,
413                          /* lookup_in_resolved_boot_classes */ true);
414 }
415 
IsAnnotatedWith(jclass klass,uint32_t visibility,bool lookup_in_resolved_boot_classes)416 bool ArtMethod::IsAnnotatedWith(jclass klass,
417                                 uint32_t visibility,
418                                 bool lookup_in_resolved_boot_classes) {
419   Thread* self = Thread::Current();
420   ScopedObjectAccess soa(self);
421   StackHandleScope<1> shs(self);
422 
423   ObjPtr<mirror::Class> annotation = soa.Decode<mirror::Class>(klass);
424   DCHECK(annotation->IsAnnotation());
425   Handle<mirror::Class> annotation_handle(shs.NewHandle(annotation));
426 
427   return annotations::IsMethodAnnotationPresent(
428       this, annotation_handle, visibility, lookup_in_resolved_boot_classes);
429 }
430 
GetOatMethodIndexFromMethodIndex(const DexFile & dex_file,uint16_t class_def_idx,uint32_t method_idx)431 static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
432                                                  uint16_t class_def_idx,
433                                                  uint32_t method_idx) {
434   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
435   const uint8_t* class_data = dex_file.GetClassData(class_def);
436   CHECK(class_data != nullptr);
437   ClassDataItemIterator it(dex_file, class_data);
438   // Skip fields
439   while (it.HasNextStaticField()) {
440     it.Next();
441   }
442   while (it.HasNextInstanceField()) {
443     it.Next();
444   }
445   // Process methods
446   size_t class_def_method_index = 0;
447   while (it.HasNextDirectMethod()) {
448     if (it.GetMemberIndex() == method_idx) {
449       return class_def_method_index;
450     }
451     class_def_method_index++;
452     it.Next();
453   }
454   while (it.HasNextVirtualMethod()) {
455     if (it.GetMemberIndex() == method_idx) {
456       return class_def_method_index;
457     }
458     class_def_method_index++;
459     it.Next();
460   }
461   DCHECK(!it.HasNext());
462   LOG(FATAL) << "Failed to find method index " << method_idx << " in " << dex_file.GetLocation();
463   UNREACHABLE();
464 }
465 
466 // We use the method's DexFile and declaring class name to find the OatMethod for an obsolete
467 // method.  This is extremely slow but we need it if we want to be able to have obsolete native
468 // methods since we need this to find the size of its stack frames.
469 //
470 // NB We could (potentially) do this differently and rely on the way the transformation is applied
471 // in order to use the entrypoint to find this information. However, for debugging reasons (most
472 // notably making sure that new invokes of obsolete methods fail) we choose to instead get the data
473 // directly from the dex file.
FindOatMethodFromDexFileFor(ArtMethod * method,bool * found)474 static const OatFile::OatMethod FindOatMethodFromDexFileFor(ArtMethod* method, bool* found)
475     REQUIRES_SHARED(Locks::mutator_lock_) {
476   DCHECK(method->IsObsolete() && method->IsNative());
477   const DexFile* dex_file = method->GetDexFile();
478 
479   // recreate the class_def_index from the descriptor.
480   std::string descriptor_storage;
481   const DexFile::TypeId* declaring_class_type_id =
482       dex_file->FindTypeId(method->GetDeclaringClass()->GetDescriptor(&descriptor_storage));
483   CHECK(declaring_class_type_id != nullptr);
484   dex::TypeIndex declaring_class_type_index = dex_file->GetIndexForTypeId(*declaring_class_type_id);
485   const DexFile::ClassDef* declaring_class_type_def =
486       dex_file->FindClassDef(declaring_class_type_index);
487   CHECK(declaring_class_type_def != nullptr);
488   uint16_t declaring_class_def_index = dex_file->GetIndexForClassDef(*declaring_class_type_def);
489 
490   size_t oat_method_index = GetOatMethodIndexFromMethodIndex(*dex_file,
491                                                              declaring_class_def_index,
492                                                              method->GetDexMethodIndex());
493 
494   OatFile::OatClass oat_class = OatFile::FindOatClass(*dex_file,
495                                                       declaring_class_def_index,
496                                                       found);
497   if (!(*found)) {
498     return OatFile::OatMethod::Invalid();
499   }
500   return oat_class.GetOatMethod(oat_method_index);
501 }
502 
FindOatMethodFor(ArtMethod * method,PointerSize pointer_size,bool * found)503 static const OatFile::OatMethod FindOatMethodFor(ArtMethod* method,
504                                                  PointerSize pointer_size,
505                                                  bool* found)
506     REQUIRES_SHARED(Locks::mutator_lock_) {
507   if (UNLIKELY(method->IsObsolete())) {
508     // We shouldn't be calling this with obsolete methods except for native obsolete methods for
509     // which we need to use the oat method to figure out how large the quick frame is.
510     DCHECK(method->IsNative()) << "We should only be finding the OatMethod of obsolete methods in "
511                                << "order to allow stack walking. Other obsolete methods should "
512                                << "never need to access this information.";
513     DCHECK_EQ(pointer_size, kRuntimePointerSize) << "Obsolete method in compiler!";
514     return FindOatMethodFromDexFileFor(method, found);
515   }
516   // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
517   // method for direct methods (or virtual methods made direct).
518   mirror::Class* declaring_class = method->GetDeclaringClass();
519   size_t oat_method_index;
520   if (method->IsStatic() || method->IsDirect()) {
521     // Simple case where the oat method index was stashed at load time.
522     oat_method_index = method->GetMethodIndex();
523   } else {
524     // Compute the oat_method_index by search for its position in the declared virtual methods.
525     oat_method_index = declaring_class->NumDirectMethods();
526     bool found_virtual = false;
527     for (ArtMethod& art_method : declaring_class->GetVirtualMethods(pointer_size)) {
528       // Check method index instead of identity in case of duplicate method definitions.
529       if (method->GetDexMethodIndex() == art_method.GetDexMethodIndex()) {
530         found_virtual = true;
531         break;
532       }
533       oat_method_index++;
534     }
535     CHECK(found_virtual) << "Didn't find oat method index for virtual method: "
536                          << method->PrettyMethod();
537   }
538   DCHECK_EQ(oat_method_index,
539             GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
540                                              method->GetDeclaringClass()->GetDexClassDefIndex(),
541                                              method->GetDexMethodIndex()));
542   OatFile::OatClass oat_class = OatFile::FindOatClass(*declaring_class->GetDexCache()->GetDexFile(),
543                                                       declaring_class->GetDexClassDefIndex(),
544                                                       found);
545   if (!(*found)) {
546     return OatFile::OatMethod::Invalid();
547   }
548   return oat_class.GetOatMethod(oat_method_index);
549 }
550 
EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params)551 bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params) {
552   auto* dex_cache = GetDexCache();
553   auto* dex_file = dex_cache->GetDexFile();
554   const auto& method_id = dex_file->GetMethodId(GetDexMethodIndex());
555   const auto& proto_id = dex_file->GetMethodPrototype(method_id);
556   const DexFile::TypeList* proto_params = dex_file->GetProtoParameters(proto_id);
557   auto count = proto_params != nullptr ? proto_params->Size() : 0u;
558   auto param_len = params != nullptr ? params->GetLength() : 0u;
559   if (param_len != count) {
560     return false;
561   }
562   auto* cl = Runtime::Current()->GetClassLinker();
563   for (size_t i = 0; i < count; ++i) {
564     auto type_idx = proto_params->GetTypeItem(i).type_idx_;
565     auto* type = cl->ResolveType(type_idx, this);
566     if (type == nullptr) {
567       Thread::Current()->AssertPendingException();
568       return false;
569     }
570     if (type != params->GetWithoutChecks(i)) {
571       return false;
572     }
573   }
574   return true;
575 }
576 
GetQuickenedInfo(PointerSize pointer_size)577 const uint8_t* ArtMethod::GetQuickenedInfo(PointerSize pointer_size) {
578   bool found = false;
579   OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
580   if (!found || (oat_method.GetQuickCode() != nullptr)) {
581     return nullptr;
582   }
583   if (kIsVdexEnabled) {
584     const OatQuickMethodHeader* header = oat_method.GetOatQuickMethodHeader();
585     // OatMethod without a header: no quickening table.
586     if (header == nullptr) {
587       return nullptr;
588     }
589     // The table is in the .vdex file.
590     const OatFile::OatDexFile* oat_dex_file = GetDexCache()->GetDexFile()->GetOatDexFile();
591     const OatFile* oat_file = oat_dex_file->GetOatFile();
592     if (oat_file == nullptr) {
593       return nullptr;
594     }
595     return oat_file->DexBegin() + header->GetVmapTableOffset();
596   } else {
597     return oat_method.GetVmapTable();
598   }
599 }
600 
GetOatQuickMethodHeader(uintptr_t pc)601 const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
602   // Our callers should make sure they don't pass the instrumentation exit pc,
603   // as this method does not look at the side instrumentation stack.
604   DCHECK_NE(pc, reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()));
605 
606   if (IsRuntimeMethod()) {
607     return nullptr;
608   }
609 
610   Runtime* runtime = Runtime::Current();
611   const void* existing_entry_point = GetEntryPointFromQuickCompiledCode();
612   CHECK(existing_entry_point != nullptr) << PrettyMethod() << "@" << this;
613   ClassLinker* class_linker = runtime->GetClassLinker();
614 
615   if (class_linker->IsQuickGenericJniStub(existing_entry_point)) {
616     // The generic JNI does not have any method header.
617     return nullptr;
618   }
619 
620   if (existing_entry_point == GetQuickProxyInvokeHandler()) {
621     DCHECK(IsProxyMethod() && !IsConstructor());
622     // The proxy entry point does not have any method header.
623     return nullptr;
624   }
625 
626   // Check whether the current entry point contains this pc.
627   if (!class_linker->IsQuickResolutionStub(existing_entry_point) &&
628       !class_linker->IsQuickToInterpreterBridge(existing_entry_point)) {
629     OatQuickMethodHeader* method_header =
630         OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
631 
632     if (method_header->Contains(pc)) {
633       return method_header;
634     }
635   }
636 
637   // Check whether the pc is in the JIT code cache.
638   jit::Jit* jit = runtime->GetJit();
639   if (jit != nullptr) {
640     jit::JitCodeCache* code_cache = jit->GetCodeCache();
641     OatQuickMethodHeader* method_header = code_cache->LookupMethodHeader(pc, this);
642     if (method_header != nullptr) {
643       DCHECK(method_header->Contains(pc));
644       return method_header;
645     } else {
646       DCHECK(!code_cache->ContainsPc(reinterpret_cast<const void*>(pc)))
647           << PrettyMethod()
648           << ", pc=" << std::hex << pc
649           << ", entry_point=" << std::hex << reinterpret_cast<uintptr_t>(existing_entry_point)
650           << ", copy=" << std::boolalpha << IsCopied()
651           << ", proxy=" << std::boolalpha << IsProxyMethod();
652     }
653   }
654 
655   // The code has to be in an oat file.
656   bool found;
657   OatFile::OatMethod oat_method =
658       FindOatMethodFor(this, class_linker->GetImagePointerSize(), &found);
659   if (!found) {
660     if (class_linker->IsQuickResolutionStub(existing_entry_point)) {
661       // We are running the generic jni stub, but the entry point of the method has not
662       // been updated yet.
663       DCHECK_EQ(pc, 0u) << "Should be a downcall";
664       DCHECK(IsNative());
665       return nullptr;
666     }
667     if (existing_entry_point == GetQuickInstrumentationEntryPoint()) {
668       // We are running the generic jni stub, but the method is being instrumented.
669       DCHECK_EQ(pc, 0u) << "Should be a downcall";
670       DCHECK(IsNative());
671       return nullptr;
672     }
673     // Only for unit tests.
674     // TODO(ngeoffray): Update these tests to pass the right pc?
675     return OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
676   }
677   const void* oat_entry_point = oat_method.GetQuickCode();
678   if (oat_entry_point == nullptr || class_linker->IsQuickGenericJniStub(oat_entry_point)) {
679     DCHECK(IsNative()) << PrettyMethod();
680     return nullptr;
681   }
682 
683   OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromEntryPoint(oat_entry_point);
684   if (pc == 0) {
685     // This is a downcall, it can only happen for a native method.
686     DCHECK(IsNative());
687     return method_header;
688   }
689 
690   DCHECK(method_header->Contains(pc))
691       << PrettyMethod()
692       << " " << std::hex << pc << " " << oat_entry_point
693       << " " << (uintptr_t)(method_header->GetCode() + method_header->GetCodeSize());
694   return method_header;
695 }
696 
GetOatMethodQuickCode(PointerSize pointer_size)697 const void* ArtMethod::GetOatMethodQuickCode(PointerSize pointer_size) {
698   bool found;
699   OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
700   if (found) {
701     return oat_method.GetQuickCode();
702   }
703   return nullptr;
704 }
705 
HasAnyCompiledCode()706 bool ArtMethod::HasAnyCompiledCode() {
707   if (IsNative() || !IsInvokable() || IsProxyMethod()) {
708     return false;
709   }
710 
711   // Check whether the JIT has compiled it.
712   Runtime* runtime = Runtime::Current();
713   jit::Jit* jit = runtime->GetJit();
714   if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(this)) {
715     return true;
716   }
717 
718   // Check whether we have AOT code.
719   return GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize()) != nullptr;
720 }
721 
CopyFrom(ArtMethod * src,PointerSize image_pointer_size)722 void ArtMethod::CopyFrom(ArtMethod* src, PointerSize image_pointer_size) {
723   memcpy(reinterpret_cast<void*>(this), reinterpret_cast<const void*>(src),
724          Size(image_pointer_size));
725   declaring_class_ = GcRoot<mirror::Class>(const_cast<ArtMethod*>(src)->GetDeclaringClass());
726 
727   // If the entry point of the method we are copying from is from JIT code, we just
728   // put the entry point of the new method to interpreter. We could set the entry point
729   // to the JIT code, but this would require taking the JIT code cache lock to notify
730   // it, which we do not want at this level.
731   Runtime* runtime = Runtime::Current();
732   if (runtime->UseJitCompilation()) {
733     if (runtime->GetJit()->GetCodeCache()->ContainsPc(GetEntryPointFromQuickCompiledCode())) {
734       SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), image_pointer_size);
735     }
736   }
737   // Clear the profiling info for the same reasons as the JIT code.
738   if (!src->IsNative()) {
739     SetProfilingInfoPtrSize(nullptr, image_pointer_size);
740   }
741   // Clear hotness to let the JIT properly decide when to compile this method.
742   hotness_count_ = 0;
743 }
744 
IsImagePointerSize(PointerSize pointer_size)745 bool ArtMethod::IsImagePointerSize(PointerSize pointer_size) {
746   // Hijack this function to get access to PtrSizedFieldsOffset.
747   //
748   // Ensure that PrtSizedFieldsOffset is correct. We rely here on usually having both 32-bit and
749   // 64-bit builds.
750   static_assert(std::is_standard_layout<ArtMethod>::value, "ArtMethod is not standard layout.");
751   static_assert(
752       (sizeof(void*) != 4) ||
753           (offsetof(ArtMethod, ptr_sized_fields_) == PtrSizedFieldsOffset(PointerSize::k32)),
754       "Unexpected 32-bit class layout.");
755   static_assert(
756       (sizeof(void*) != 8) ||
757           (offsetof(ArtMethod, ptr_sized_fields_) == PtrSizedFieldsOffset(PointerSize::k64)),
758       "Unexpected 64-bit class layout.");
759 
760   Runtime* runtime = Runtime::Current();
761   if (runtime == nullptr) {
762     return true;
763   }
764   return runtime->GetClassLinker()->GetImagePointerSize() == pointer_size;
765 }
766 
PrettyMethod(ArtMethod * m,bool with_signature)767 std::string ArtMethod::PrettyMethod(ArtMethod* m, bool with_signature) {
768   if (m == nullptr) {
769     return "null";
770   }
771   return m->PrettyMethod(with_signature);
772 }
773 
PrettyMethod(bool with_signature)774 std::string ArtMethod::PrettyMethod(bool with_signature) {
775   ArtMethod* m = this;
776   if (!m->IsRuntimeMethod()) {
777     m = m->GetInterfaceMethodIfProxy(Runtime::Current()->GetClassLinker()->GetImagePointerSize());
778   }
779   std::string result(PrettyDescriptor(m->GetDeclaringClassDescriptor()));
780   result += '.';
781   result += m->GetName();
782   if (UNLIKELY(m->IsFastNative())) {
783     result += "!";
784   }
785   if (with_signature) {
786     const Signature signature = m->GetSignature();
787     std::string sig_as_string(signature.ToString());
788     if (signature == Signature::NoSignature()) {
789       return result + sig_as_string;
790     }
791     result = PrettyReturnType(sig_as_string.c_str()) + " " + result +
792         PrettyArguments(sig_as_string.c_str());
793   }
794   return result;
795 }
796 
JniShortName()797 std::string ArtMethod::JniShortName() {
798   return GetJniShortName(GetDeclaringClassDescriptor(), GetName());
799 }
800 
JniLongName()801 std::string ArtMethod::JniLongName() {
802   std::string long_name;
803   long_name += JniShortName();
804   long_name += "__";
805 
806   std::string signature(GetSignature().ToString());
807   signature.erase(0, 1);
808   signature.erase(signature.begin() + signature.find(')'), signature.end());
809 
810   long_name += MangleForJni(signature);
811 
812   return long_name;
813 }
814 
815 // AssertSharedHeld doesn't work in GetAccessFlags, so use a NO_THREAD_SAFETY_ANALYSIS helper.
816 // TODO: Figure out why ASSERT_SHARED_CAPABILITY doesn't work.
817 template <ReadBarrierOption kReadBarrierOption>
DoGetAccessFlagsHelper(ArtMethod * method)818 ALWAYS_INLINE static inline void DoGetAccessFlagsHelper(ArtMethod* method)
819     NO_THREAD_SAFETY_ANALYSIS {
820   CHECK(method->IsRuntimeMethod() ||
821         method->GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
822         method->GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
823 }
824 
GetAccessFlagsDCheck()825 template <ReadBarrierOption kReadBarrierOption> void ArtMethod::GetAccessFlagsDCheck() {
826   if (kCheckDeclaringClassState) {
827     Thread* self = Thread::Current();
828     if (!Locks::mutator_lock_->IsSharedHeld(self)) {
829       if (self->IsThreadSuspensionAllowable()) {
830         ScopedObjectAccess soa(self);
831         CHECK(IsRuntimeMethod() ||
832               GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
833               GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
834       }
835     } else {
836       // We cannot use SOA in this case. We might be holding the lock, but may not be in the
837       // runnable state (e.g., during GC).
838       Locks::mutator_lock_->AssertSharedHeld(self);
839       DoGetAccessFlagsHelper<kReadBarrierOption>(this);
840     }
841   }
842 }
843 template void ArtMethod::GetAccessFlagsDCheck<ReadBarrierOption::kWithReadBarrier>();
844 template void ArtMethod::GetAccessFlagsDCheck<ReadBarrierOption::kWithoutReadBarrier>();
845 
846 }  // namespace art
847