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-inl.h" 18 #include "jit/jit.h" 19 #include "jit/jit_code_cache.h" 20 #include "jit/profiling_info.h" 21 #include "nativehelper/ScopedUtfChars.h" 22 #include "oat_quick_method_header.h" 23 #include "scoped_thread_state_change-inl.h" 24 #include "stack.h" 25 #include "stack_map.h" 26 #include "thread-current-inl.h" 27 28 namespace art { 29 30 namespace { 31 32 template <typename Handler> ProcessMethodWithName(JNIEnv * env,jstring method_name,const Handler & handler)33 void ProcessMethodWithName(JNIEnv* env, jstring method_name, const Handler& handler) { 34 ScopedUtfChars chars(env, method_name); 35 CHECK(chars.c_str() != nullptr); 36 ScopedObjectAccess soa(Thread::Current()); 37 StackVisitor::WalkStack( 38 [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { 39 std::string m_name(stack_visitor->GetMethod()->GetName()); 40 41 if (m_name.compare(chars.c_str()) == 0) { 42 handler(stack_visitor); 43 return false; 44 } 45 return true; 46 }, 47 soa.Self(), 48 /* context= */ nullptr, 49 art::StackVisitor::StackWalkKind::kIncludeInlinedFrames); 50 } 51 52 } // namespace 53 Java_Main_isInOsrCode(JNIEnv * env,jclass,jstring method_name)54 extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInOsrCode(JNIEnv* env, 55 jclass, 56 jstring method_name) { 57 jit::Jit* jit = Runtime::Current()->GetJit(); 58 if (jit == nullptr) { 59 // Just return true for non-jit configurations to stop the infinite loop. 60 return JNI_TRUE; 61 } 62 bool in_osr_code = false; 63 ProcessMethodWithName( 64 env, 65 method_name, 66 [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { 67 ArtMethod* m = stack_visitor->GetMethod(); 68 const OatQuickMethodHeader* header = 69 Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m); 70 if (header != nullptr && header == stack_visitor->GetCurrentOatQuickMethodHeader()) { 71 in_osr_code = true; 72 } 73 }); 74 return in_osr_code; 75 } 76 Java_Main_isInInterpreter(JNIEnv * env,jclass,jstring method_name)77 extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInInterpreter(JNIEnv* env, 78 jclass, 79 jstring method_name) { 80 if (!Runtime::Current()->UseJitCompilation()) { 81 // The return value is irrelevant if we're not using JIT. 82 return false; 83 } 84 bool in_interpreter = false; 85 ProcessMethodWithName( 86 env, 87 method_name, 88 [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { 89 ArtMethod* m = stack_visitor->GetMethod(); 90 const OatQuickMethodHeader* header = 91 Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m); 92 if ((header == nullptr || header != stack_visitor->GetCurrentOatQuickMethodHeader()) && 93 stack_visitor->IsShadowFrame()) { 94 in_interpreter = true; 95 } 96 }); 97 return in_interpreter; 98 } 99 Java_Main_ensureHasProfilingInfo(JNIEnv * env,jclass,jstring method_name)100 extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasProfilingInfo(JNIEnv* env, 101 jclass, 102 jstring method_name) { 103 if (!Runtime::Current()->UseJitCompilation()) { 104 return; 105 } 106 ProcessMethodWithName( 107 env, 108 method_name, 109 [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { 110 ArtMethod* m = stack_visitor->GetMethod(); 111 ProfilingInfo::Create(Thread::Current(), m, /* retry_allocation */ true); 112 }); 113 } 114 Java_Main_ensureHasOsrCode(JNIEnv * env,jclass,jstring method_name)115 extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv* env, 116 jclass, 117 jstring method_name) { 118 if (!Runtime::Current()->UseJitCompilation()) { 119 return; 120 } 121 ProcessMethodWithName( 122 env, 123 method_name, 124 [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { 125 ArtMethod* m = stack_visitor->GetMethod(); 126 jit::Jit* jit = Runtime::Current()->GetJit(); 127 while (jit->GetCodeCache()->LookupOsrMethodHeader(m) == nullptr) { 128 // Sleep to yield to the compiler thread. 129 usleep(1000); 130 // Will either ensure it's compiled or do the compilation itself. 131 jit->CompileMethod(m, Thread::Current(), /*baseline=*/ false, /*osr=*/ true); 132 } 133 }); 134 } 135 136 } // namespace art 137