1 /* 2 * Copyright (C) 2016 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 #include "base/enums.h" 19 #include "jit/jit.h" 20 #include "jit/jit_code_cache.h" 21 #include "jit/profiling_info.h" 22 #include "mirror/class.h" 23 #include "oat_quick_method_header.h" 24 #include "scoped_thread_state_change-inl.h" 25 #include "stack_map.h" 26 27 namespace art { 28 29 static void do_checks(jclass cls, const char* method_name) { 30 ScopedObjectAccess soa(Thread::Current()); 31 ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); 32 jit::Jit* jit = Runtime::Current()->GetJit(); 33 jit::JitCodeCache* code_cache = jit->GetCodeCache(); 34 ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); 35 36 OatQuickMethodHeader* header = nullptr; 37 // Infinite loop... Test harness will have its own timeout. 38 while (true) { 39 const void* pc = method->GetEntryPointFromQuickCompiledCode(); 40 if (code_cache->ContainsPc(pc)) { 41 header = OatQuickMethodHeader::FromEntryPoint(pc); 42 break; 43 } else { 44 // Sleep to yield to the compiler thread. 45 usleep(1000); 46 // Will either ensure it's compiled or do the compilation itself. 47 jit->CompileMethod(method, soa.Self(), /* osr */ false); 48 } 49 } 50 51 CodeInfo info = header->GetOptimizedCodeInfo(); 52 CodeInfoEncoding encoding = info.ExtractEncoding(); 53 CHECK(info.HasInlineInfo(encoding)); 54 } 55 56 static void allocate_profiling_info(jclass cls, const char* method_name) { 57 ScopedObjectAccess soa(Thread::Current()); 58 ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); 59 ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); 60 ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); 61 } 62 63 extern "C" JNIEXPORT void JNICALL Java_Main_ensureProfilingInfo566(JNIEnv*, jclass cls) { 64 jit::Jit* jit = Runtime::Current()->GetJit(); 65 if (jit == nullptr) { 66 return; 67 } 68 69 allocate_profiling_info(cls, "testInvokeVirtual"); 70 allocate_profiling_info(cls, "testInvokeInterface"); 71 allocate_profiling_info(cls, "$noinline$testInlineToSameTarget"); 72 } 73 74 extern "C" JNIEXPORT void JNICALL Java_Main_ensureJittedAndPolymorphicInline566(JNIEnv*, jclass cls) { 75 jit::Jit* jit = Runtime::Current()->GetJit(); 76 if (jit == nullptr) { 77 return; 78 } 79 80 if (kIsDebugBuild) { 81 // A debug build might often compile the methods without profiling informations filled. 82 return; 83 } 84 85 do_checks(cls, "testInvokeVirtual"); 86 do_checks(cls, "testInvokeInterface"); 87 do_checks(cls, "testInvokeInterface2"); 88 do_checks(cls, "$noinline$testInlineToSameTarget"); 89 } 90 91 } // namespace art 92