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