art_method-inl.h revision 4ef12f5b0e26c6016c87866f6a33da5ed8e98d74
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_MIRROR_ART_METHOD_INL_H_ 18#define ART_RUNTIME_MIRROR_ART_METHOD_INL_H_ 19 20#include "art_method.h" 21 22#include "art_field.h" 23#include "class.h" 24#include "class_linker.h" 25#include "dex_cache.h" 26#include "dex_file.h" 27#include "entrypoints/entrypoint_utils.h" 28#include "method_helper.h" 29#include "object-inl.h" 30#include "object_array.h" 31#include "oat.h" 32#include "quick/quick_method_frame_info.h" 33#include "read_barrier-inl.h" 34#include "runtime-inl.h" 35 36namespace art { 37namespace mirror { 38 39inline uint32_t ArtMethod::ClassSize() { 40 uint32_t vtable_entries = Object::kVTableLength + 8; 41 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0); 42} 43 44template<ReadBarrierOption kReadBarrierOption> 45inline Class* ArtMethod::GetJavaLangReflectArtMethod() { 46 DCHECK(!java_lang_reflect_ArtMethod_.IsNull()); 47 return java_lang_reflect_ArtMethod_.Read<kReadBarrierOption>(); 48} 49 50inline Class* ArtMethod::GetDeclaringClass() { 51 Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_)); 52 DCHECK(result != NULL) << this; 53 DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this; 54 return result; 55} 56 57inline void ArtMethod::SetDeclaringClass(Class *new_declaring_class) { 58 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_), 59 new_declaring_class); 60} 61 62inline uint32_t ArtMethod::GetAccessFlags() { 63 DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous()); 64 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_)); 65} 66 67inline uint16_t ArtMethod::GetMethodIndex() { 68 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous()); 69 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_)); 70} 71 72inline uint32_t ArtMethod::GetDexMethodIndex() { 73#ifdef ART_SEA_IR_MODE 74 // TODO: Re-add this check for (PORTABLE + SMALL + ) SEA IR when PORTABLE IS fixed! 75 // DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous()); 76#else 77 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous()); 78#endif 79 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_)); 80} 81 82inline ObjectArray<String>* ArtMethod::GetDexCacheStrings() { 83 return GetFieldObject<ObjectArray<String>>( 84 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_)); 85} 86 87inline ObjectArray<ArtMethod>* ArtMethod::GetDexCacheResolvedMethods() { 88 return GetFieldObject<ObjectArray<ArtMethod>>( 89 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_)); 90} 91 92inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index) { 93 ArtMethod* method = GetDexCacheResolvedMethods()->Get(method_index); 94 if (method != nullptr && !method->GetDeclaringClass()->IsErroneous()) { 95 return method; 96 } else { 97 return nullptr; 98 } 99} 100 101inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method) { 102 GetDexCacheResolvedMethods()->Set<false>(method_idx, new_method); 103} 104 105inline bool ArtMethod::HasDexCacheResolvedMethods() { 106 return GetDexCacheResolvedMethods() != nullptr; 107} 108 109inline bool ArtMethod::HasSameDexCacheResolvedMethods(ObjectArray<ArtMethod>* other_cache) { 110 return GetDexCacheResolvedMethods() == other_cache; 111} 112 113inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other) { 114 return GetDexCacheResolvedMethods() == other->GetDexCacheResolvedMethods(); 115} 116 117 118inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() { 119 return GetFieldObject<ObjectArray<Class>>( 120 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_)); 121} 122 123template <bool kWithCheck> 124inline Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index) { 125 Class* klass; 126 if (kWithCheck) { 127 klass = GetDexCacheResolvedTypes()->Get(type_index); 128 } else { 129 klass = GetDexCacheResolvedTypes()->GetWithoutChecks(type_index); 130 } 131 return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; 132} 133 134inline bool ArtMethod::HasDexCacheResolvedTypes() { 135 return GetDexCacheResolvedTypes() != nullptr; 136} 137 138inline bool ArtMethod::HasSameDexCacheResolvedTypes(ObjectArray<Class>* other_cache) { 139 return GetDexCacheResolvedTypes() == other_cache; 140} 141 142inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other) { 143 return GetDexCacheResolvedTypes() == other->GetDexCacheResolvedTypes(); 144} 145 146inline uint32_t ArtMethod::GetCodeSize() { 147 DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this); 148 const void* code = EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode()); 149 if (code == nullptr) { 150 return 0u; 151 } 152 return reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].code_size_; 153} 154 155inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) { 156 switch (type) { 157 case kStatic: 158 return !IsStatic(); 159 case kDirect: 160 return !IsDirect() || IsStatic(); 161 case kVirtual: { 162 Class* methods_class = GetDeclaringClass(); 163 return IsDirect() || (methods_class->IsInterface() && !IsMiranda()); 164 } 165 case kSuper: 166 return false; // TODO: appropriate checks for call to super class. 167 case kInterface: { 168 Class* methods_class = GetDeclaringClass(); 169 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass()); 170 } 171 default: 172 LOG(FATAL) << "Unreachable - invocation type: " << type; 173 return true; 174 } 175} 176 177inline void ArtMethod::AssertPcIsWithinQuickCode(uintptr_t pc) { 178 if (!kIsDebugBuild) { 179 return; 180 } 181 if (IsNative() || IsRuntimeMethod() || IsProxyMethod()) { 182 return; 183 } 184 if (pc == GetQuickInstrumentationExitPc()) { 185 return; 186 } 187 const void* code = GetEntryPointFromQuickCompiledCode(); 188 if (code == GetQuickToInterpreterBridge() || code == GetQuickInstrumentationEntryPoint()) { 189 return; 190 } 191 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 192 if (code == class_linker->GetQuickResolutionTrampoline() || 193 code == class_linker->GetQuickToInterpreterBridgeTrampoline()) { 194 return; 195 } 196 DCHECK(IsWithinQuickCode(pc)) 197 << PrettyMethod(this) 198 << " pc=" << std::hex << pc 199 << " code=" << code 200 << " size=" << GetCodeSize(); 201} 202 203inline uint32_t ArtMethod::GetQuickOatCodeOffset() { 204 DCHECK(!Runtime::Current()->IsStarted()); 205 return PointerToLowMemUInt32(GetEntryPointFromQuickCompiledCode()); 206} 207 208inline uint32_t ArtMethod::GetPortableOatCodeOffset() { 209 DCHECK(!Runtime::Current()->IsStarted()); 210 return PointerToLowMemUInt32(GetEntryPointFromPortableCompiledCode()); 211} 212 213inline void ArtMethod::SetQuickOatCodeOffset(uint32_t code_offset) { 214 DCHECK(!Runtime::Current()->IsStarted()); 215 SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(code_offset)); 216} 217 218inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) { 219 DCHECK(!Runtime::Current()->IsStarted()); 220 SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset)); 221} 222 223inline const void* ArtMethod::GetQuickOatEntryPoint() { 224 if (IsPortableCompiled() || IsAbstract() || IsRuntimeMethod() || IsProxyMethod()) { 225 return nullptr; 226 } 227 Runtime* runtime = Runtime::Current(); 228 const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this); 229 // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method 230 // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline) 231 // for non-native methods. 232 DCHECK(entry_point != runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline()); 233 if (UNLIKELY(entry_point == GetQuickToInterpreterBridge()) || 234 UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) { 235 return nullptr; 236 } 237 return entry_point; 238} 239 240inline const void* ArtMethod::GetQuickOatCodePointer() { 241 return EntryPointToCodePointer(GetQuickOatEntryPoint()); 242} 243 244inline const uint8_t* ArtMethod::GetMappingTable() { 245 const void* code_pointer = GetQuickOatCodePointer(); 246 if (code_pointer == nullptr) { 247 return nullptr; 248 } 249 return GetMappingTable(code_pointer); 250} 251 252inline const uint8_t* ArtMethod::GetMappingTable(const void* code_pointer) { 253 DCHECK(code_pointer != nullptr); 254 DCHECK(code_pointer == GetQuickOatCodePointer()); 255 uint32_t offset = 256 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].mapping_table_offset_; 257 if (UNLIKELY(offset == 0u)) { 258 return nullptr; 259 } 260 return reinterpret_cast<const uint8_t*>(code_pointer) - offset; 261} 262 263inline const uint8_t* ArtMethod::GetVmapTable() { 264 const void* code_pointer = GetQuickOatCodePointer(); 265 if (code_pointer == nullptr) { 266 return nullptr; 267 } 268 return GetVmapTable(code_pointer); 269} 270 271inline const uint8_t* ArtMethod::GetVmapTable(const void* code_pointer) { 272 DCHECK(code_pointer != nullptr); 273 DCHECK(code_pointer == GetQuickOatCodePointer()); 274 uint32_t offset = 275 reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].vmap_table_offset_; 276 if (UNLIKELY(offset == 0u)) { 277 return nullptr; 278 } 279 return reinterpret_cast<const uint8_t*>(code_pointer) - offset; 280} 281 282inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) { 283 DCHECK(!Runtime::Current()->IsStarted()); 284 SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset)); 285} 286 287inline uint32_t ArtMethod::GetOatNativeGcMapOffset() { 288 DCHECK(!Runtime::Current()->IsStarted()); 289 return PointerToLowMemUInt32(GetNativeGcMap()); 290} 291 292inline bool ArtMethod::IsRuntimeMethod() { 293 return GetDexMethodIndex() == DexFile::kDexNoIndex; 294} 295 296inline bool ArtMethod::IsCalleeSaveMethod() { 297 if (!IsRuntimeMethod()) { 298 return false; 299 } 300 Runtime* runtime = Runtime::Current(); 301 bool result = false; 302 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 303 if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) { 304 result = true; 305 break; 306 } 307 } 308 return result; 309} 310 311inline bool ArtMethod::IsResolutionMethod() { 312 bool result = this == Runtime::Current()->GetResolutionMethod(); 313 // Check that if we do think it is phony it looks like the resolution method. 314 DCHECK(!result || IsRuntimeMethod()); 315 return result; 316} 317 318inline bool ArtMethod::IsImtConflictMethod() { 319 bool result = this == Runtime::Current()->GetImtConflictMethod(); 320 // Check that if we do think it is phony it looks like the imt conflict method. 321 DCHECK(!result || IsRuntimeMethod()); 322 return result; 323} 324 325inline uintptr_t ArtMethod::NativePcOffset(const uintptr_t pc) { 326 const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this); 327 return pc - reinterpret_cast<uintptr_t>(code); 328} 329 330inline uintptr_t ArtMethod::NativePcOffset(const uintptr_t pc, const void* quick_entry_point) { 331 DCHECK(quick_entry_point != GetQuickToInterpreterBridge()); 332 DCHECK(quick_entry_point == Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this)); 333 return pc - reinterpret_cast<uintptr_t>(quick_entry_point); 334} 335 336template<VerifyObjectFlags kVerifyFlags> 337inline void ArtMethod::SetNativeMethod(const void* native_method) { 338 SetFieldPtr<false, true, kVerifyFlags>( 339 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_), native_method); 340} 341 342inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo() { 343 if (UNLIKELY(IsPortableCompiled())) { 344 // Portable compiled dex bytecode or jni stub. 345 return QuickMethodFrameInfo(kStackAlignment, 0u, 0u); 346 } 347 Runtime* runtime = Runtime::Current(); 348 if (UNLIKELY(IsAbstract()) || UNLIKELY(IsProxyMethod())) { 349 return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); 350 } 351 if (UNLIKELY(IsRuntimeMethod())) { 352 return runtime->GetRuntimeMethodFrameInfo(this); 353 } 354 355 const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this); 356 // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method 357 // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline) 358 // for non-native methods. And we really shouldn't see a failure for non-native methods here. 359 DCHECK(entry_point != runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline()); 360 CHECK(entry_point != GetQuickToInterpreterBridge()); 361 362 if (UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) { 363 // Generic JNI frame. 364 DCHECK(IsNative()); 365 StackHandleScope<1> hs(Thread::Current()); 366 uint32_t handle_refs = 367 MethodHelper(hs.NewHandle(this)).GetNumberOfReferenceArgsWithoutReceiver() + 1; 368 size_t scope_size = HandleScope::SizeOf(handle_refs); 369 QuickMethodFrameInfo callee_info = runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); 370 371 // Callee saves + handle scope + method ref + alignment 372 size_t frame_size = RoundUp(callee_info.FrameSizeInBytes() + scope_size 373 - kPointerSize // callee-save frame stores a whole method pointer 374 + sizeof(StackReference<mirror::ArtMethod>), 375 kStackAlignment); 376 377 return QuickMethodFrameInfo(frame_size, callee_info.CoreSpillMask(), callee_info.FpSpillMask()); 378 } 379 380 const void* code_pointer = EntryPointToCodePointer(entry_point); 381 return GetQuickFrameInfo(code_pointer); 382} 383 384inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo(const void* code_pointer) { 385 DCHECK(code_pointer != nullptr); 386 DCHECK_EQ(code_pointer, GetQuickOatCodePointer()); 387 return reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].frame_info_; 388} 389 390inline const DexFile* ArtMethod::GetDexFile() { 391 return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache()->GetDexFile(); 392} 393 394inline const char* ArtMethod::GetDeclaringClassDescriptor() { 395 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 396 uint32_t dex_method_idx = method->GetDexMethodIndex(); 397 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) { 398 return "<runtime method>"; 399 } 400 const DexFile* dex_file = method->GetDexFile(); 401 return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx)); 402} 403 404inline const char* ArtMethod::GetShorty(uint32_t* out_length) { 405 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 406 const DexFile* dex_file = method->GetDexFile(); 407 return dex_file->GetMethodShorty(dex_file->GetMethodId(method->GetDexMethodIndex()), out_length); 408} 409 410inline const Signature ArtMethod::GetSignature() { 411 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 412 uint32_t dex_method_idx = method->GetDexMethodIndex(); 413 if (dex_method_idx != DexFile::kDexNoIndex) { 414 const DexFile* dex_file = method->GetDexFile(); 415 return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx)); 416 } 417 return Signature::NoSignature(); 418} 419 420inline const char* ArtMethod::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 421 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 422 uint32_t dex_method_idx = method->GetDexMethodIndex(); 423 if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) { 424 const DexFile* dex_file = method->GetDexFile(); 425 return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx)); 426 } 427 Runtime* runtime = Runtime::Current(); 428 if (method == runtime->GetResolutionMethod()) { 429 return "<runtime internal resolution method>"; 430 } else if (method == runtime->GetImtConflictMethod()) { 431 return "<runtime internal imt conflict method>"; 432 } else if (method == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) { 433 return "<runtime internal callee-save all registers method>"; 434 } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) { 435 return "<runtime internal callee-save reference registers method>"; 436 } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) { 437 return "<runtime internal callee-save reference and argument registers method>"; 438 } else { 439 return "<unknown runtime internal method>"; 440 } 441} 442 443inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { 444 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 445 return method->GetDexFile()->GetCodeItem(method->GetCodeItemOffset()); 446} 447 448inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) { 449 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 450 return method->GetDexCacheResolvedType(type_idx) != nullptr; 451} 452 453inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) { 454 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 455 if (dex_pc == DexFile::kDexNoIndex) { 456 return method->IsNative() ? -2 : -1; 457 } 458 return method->GetDexFile()->GetLineNumFromPC(method, dex_pc); 459} 460 461inline const DexFile::ProtoId& ArtMethod::GetPrototype() { 462 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 463 const DexFile* dex_file = method->GetDexFile(); 464 return dex_file->GetMethodPrototype(dex_file->GetMethodId(method->GetDexMethodIndex())); 465} 466 467inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() { 468 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 469 const DexFile* dex_file = method->GetDexFile(); 470 const DexFile::ProtoId& proto = dex_file->GetMethodPrototype( 471 dex_file->GetMethodId(method->GetDexMethodIndex())); 472 return dex_file->GetProtoParameters(proto); 473} 474 475inline const char* ArtMethod::GetDeclaringClassSourceFile() { 476 return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetSourceFile(); 477} 478 479inline uint16_t ArtMethod::GetClassDefIndex() { 480 return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexClassDefIndex(); 481} 482 483inline const DexFile::ClassDef& ArtMethod::GetClassDef() { 484 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 485 return method->GetDexFile()->GetClassDef(GetClassDefIndex()); 486} 487 488inline const char* ArtMethod::GetReturnTypeDescriptor() { 489 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 490 const DexFile* dex_file = method->GetDexFile(); 491 const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex()); 492 const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 493 uint16_t return_type_idx = proto_id.return_type_idx_; 494 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx)); 495} 496 497inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) { 498 mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); 499 const DexFile* dex_file = method->GetDexFile(); 500 return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); 501} 502 503inline mirror::ClassLoader* ArtMethod::GetClassLoader() { 504 return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetClassLoader(); 505} 506 507inline mirror::DexCache* ArtMethod::GetDexCache() { 508 return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache(); 509} 510 511inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy() { 512 mirror::Class* klass = GetDeclaringClass(); 513 if (LIKELY(!klass->IsProxyClass())) { 514 return this; 515 } 516 mirror::ArtMethod* interface_method = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex()); 517 DCHECK(interface_method != nullptr); 518 DCHECK_EQ(interface_method, 519 Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this)); 520 return interface_method; 521} 522 523} // namespace mirror 524} // namespace art 525 526#endif // ART_RUNTIME_MIRROR_ART_METHOD_INL_H_ 527