139 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2016 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #include "art_method-inl.h"
 | |
| #include "jit/jit.h"
 | |
| #include "jit/jit_code_cache.h"
 | |
| #include "jit/profiling_info.h"
 | |
| #include "nativehelper/ScopedUtfChars.h"
 | |
| #include "oat_quick_method_header.h"
 | |
| #include "scoped_thread_state_change-inl.h"
 | |
| #include "stack.h"
 | |
| #include "stack_map.h"
 | |
| #include "thread-current-inl.h"
 | |
| 
 | |
| namespace art {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| template <typename Handler>
 | |
| void ProcessMethodWithName(JNIEnv* env, jstring method_name, const Handler& handler) {
 | |
|   ScopedUtfChars chars(env, method_name);
 | |
|   CHECK(chars.c_str() != nullptr);
 | |
|   ScopedObjectAccess soa(Thread::Current());
 | |
|   StackVisitor::WalkStack(
 | |
|       [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|         std::string m_name(stack_visitor->GetMethod()->GetName());
 | |
| 
 | |
|         if (m_name.compare(chars.c_str()) == 0) {
 | |
|           handler(stack_visitor);
 | |
|           return false;
 | |
|         }
 | |
|         return true;
 | |
|       },
 | |
|       soa.Self(),
 | |
|       /* context= */ nullptr,
 | |
|       art::StackVisitor::StackWalkKind::kIncludeInlinedFrames);
 | |
| }
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInOsrCode(JNIEnv* env,
 | |
|                                                             jclass,
 | |
|                                                             jstring method_name) {
 | |
|   jit::Jit* jit = Runtime::Current()->GetJit();
 | |
|   if (jit == nullptr) {
 | |
|     // Just return true for non-jit configurations to stop the infinite loop.
 | |
|     return JNI_TRUE;
 | |
|   }
 | |
|   bool in_osr_code = false;
 | |
|   ProcessMethodWithName(
 | |
|       env,
 | |
|       method_name,
 | |
|       [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|         ArtMethod* m = stack_visitor->GetMethod();
 | |
|         const OatQuickMethodHeader* header =
 | |
|             Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m);
 | |
|         if (header != nullptr && header == stack_visitor->GetCurrentOatQuickMethodHeader()) {
 | |
|           in_osr_code = true;
 | |
|         }
 | |
|       });
 | |
|   return in_osr_code;
 | |
| }
 | |
| 
 | |
| extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInInterpreter(JNIEnv* env,
 | |
|                                                                 jclass,
 | |
|                                                                 jstring method_name) {
 | |
|   if (!Runtime::Current()->UseJitCompilation()) {
 | |
|     // The return value is irrelevant if we're not using JIT.
 | |
|     return false;
 | |
|   }
 | |
|   bool in_interpreter = false;
 | |
|   ProcessMethodWithName(
 | |
|       env,
 | |
|       method_name,
 | |
|       [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|         ArtMethod* m = stack_visitor->GetMethod();
 | |
|         const OatQuickMethodHeader* header =
 | |
|             Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m);
 | |
|         if ((header == nullptr || header != stack_visitor->GetCurrentOatQuickMethodHeader()) &&
 | |
|             (stack_visitor->IsShadowFrame() ||
 | |
|              stack_visitor->GetCurrentOatQuickMethodHeader()->IsNterpMethodHeader())) {
 | |
|           in_interpreter = true;
 | |
|         }
 | |
|       });
 | |
|   return in_interpreter;
 | |
| }
 | |
| 
 | |
| extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasProfilingInfo(JNIEnv* env,
 | |
|                                                                    jclass,
 | |
|                                                                    jstring method_name) {
 | |
|   if (!Runtime::Current()->UseJitCompilation()) {
 | |
|     return;
 | |
|   }
 | |
|   ProcessMethodWithName(
 | |
|       env,
 | |
|       method_name,
 | |
|       [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|         ArtMethod* m = stack_visitor->GetMethod();
 | |
|         ProfilingInfo::Create(Thread::Current(), m);
 | |
|       });
 | |
| }
 | |
| 
 | |
| extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv* env,
 | |
|                                                              jclass,
 | |
|                                                              jstring method_name) {
 | |
|   if (!Runtime::Current()->UseJitCompilation()) {
 | |
|     return;
 | |
|   }
 | |
|   ProcessMethodWithName(
 | |
|       env,
 | |
|       method_name,
 | |
|       [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|         ArtMethod* m = stack_visitor->GetMethod();
 | |
|         jit::Jit* jit = Runtime::Current()->GetJit();
 | |
|         while (jit->GetCodeCache()->LookupOsrMethodHeader(m) == nullptr) {
 | |
|           // Sleep to yield to the compiler thread.
 | |
|           usleep(1000);
 | |
|           // Will either ensure it's compiled or do the compilation itself.
 | |
|           jit->CompileMethod(
 | |
|               m, Thread::Current(), CompilationKind::kOsr, /*prejit=*/ false);
 | |
|         }
 | |
|       });
 | |
| }
 | |
| 
 | |
| }  // namespace art
 |