• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "oat_quick_method_header.h"
22 #include "scoped_thread_state_change.h"
23 #include "ScopedUtfChars.h"
24 #include "stack_map.h"
25 
26 namespace art {
27 
28 class OsrVisitor : public StackVisitor {
29  public:
OsrVisitor(Thread * thread,const char * method_name)30   explicit OsrVisitor(Thread* thread, const char* method_name)
31       SHARED_REQUIRES(Locks::mutator_lock_)
32       : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
33         method_name_(method_name),
34         in_osr_method_(false),
35         in_interpreter_(false) {}
36 
VisitFrame()37   bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
38     ArtMethod* m = GetMethod();
39     std::string m_name(m->GetName());
40 
41     if (m_name.compare(method_name_) == 0) {
42       const OatQuickMethodHeader* header =
43           Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m);
44       if (header != nullptr && header == GetCurrentOatQuickMethodHeader()) {
45         in_osr_method_ = true;
46       } else if (IsCurrentFrameInInterpreter()) {
47         in_interpreter_ = true;
48       }
49       return false;
50     }
51     return true;
52   }
53 
54   const char* const method_name_;
55   bool in_osr_method_;
56   bool in_interpreter_;
57 };
58 
Java_Main_isInOsrCode(JNIEnv * env,jclass,jstring method_name)59 extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInOsrCode(JNIEnv* env,
60                                                             jclass,
61                                                             jstring method_name) {
62   jit::Jit* jit = Runtime::Current()->GetJit();
63   if (jit == nullptr) {
64     // Just return true for non-jit configurations to stop the infinite loop.
65     return JNI_TRUE;
66   }
67   ScopedUtfChars chars(env, method_name);
68   CHECK(chars.c_str() != nullptr);
69   ScopedObjectAccess soa(Thread::Current());
70   OsrVisitor visitor(soa.Self(), chars.c_str());
71   visitor.WalkStack();
72   return visitor.in_osr_method_;
73 }
74 
Java_Main_isInInterpreter(JNIEnv * env,jclass,jstring method_name)75 extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInInterpreter(JNIEnv* env,
76                                                                 jclass,
77                                                                 jstring method_name) {
78   if (!Runtime::Current()->UseJitCompilation()) {
79     // The return value is irrelevant if we're not using JIT.
80     return false;
81   }
82   ScopedUtfChars chars(env, method_name);
83   CHECK(chars.c_str() != nullptr);
84   ScopedObjectAccess soa(Thread::Current());
85   OsrVisitor visitor(soa.Self(), chars.c_str());
86   visitor.WalkStack();
87   return visitor.in_interpreter_;
88 }
89 
90 class ProfilingInfoVisitor : public StackVisitor {
91  public:
ProfilingInfoVisitor(Thread * thread,const char * method_name)92   explicit ProfilingInfoVisitor(Thread* thread, const char* method_name)
93       SHARED_REQUIRES(Locks::mutator_lock_)
94       : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
95         method_name_(method_name) {}
96 
VisitFrame()97   bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
98     ArtMethod* m = GetMethod();
99     std::string m_name(m->GetName());
100 
101     if (m_name.compare(method_name_) == 0) {
102       ProfilingInfo::Create(Thread::Current(), m, /* retry_allocation */ true);
103       return false;
104     }
105     return true;
106   }
107 
108   const char* const method_name_;
109 };
110 
Java_Main_ensureHasProfilingInfo(JNIEnv * env,jclass,jstring method_name)111 extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasProfilingInfo(JNIEnv* env,
112                                                                    jclass,
113                                                                    jstring method_name) {
114   if (!Runtime::Current()->UseJitCompilation()) {
115     return;
116   }
117   ScopedUtfChars chars(env, method_name);
118   CHECK(chars.c_str() != nullptr);
119   ScopedObjectAccess soa(Thread::Current());
120   ProfilingInfoVisitor visitor(soa.Self(), chars.c_str());
121   visitor.WalkStack();
122 }
123 
124 class OsrCheckVisitor : public StackVisitor {
125  public:
OsrCheckVisitor(Thread * thread,const char * method_name)126   OsrCheckVisitor(Thread* thread, const char* method_name)
127       SHARED_REQUIRES(Locks::mutator_lock_)
128       : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
129         method_name_(method_name) {}
130 
VisitFrame()131   bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
132     ArtMethod* m = GetMethod();
133     std::string m_name(m->GetName());
134 
135     jit::Jit* jit = Runtime::Current()->GetJit();
136     if (m_name.compare(method_name_) == 0) {
137       while (jit->GetCodeCache()->LookupOsrMethodHeader(m) == nullptr) {
138         // Sleep to yield to the compiler thread.
139         sleep(0);
140         // Will either ensure it's compiled or do the compilation itself.
141         jit->CompileMethod(m, Thread::Current(), /* osr */ true);
142       }
143       return false;
144     }
145     return true;
146   }
147 
148   const char* const method_name_;
149 };
150 
Java_Main_ensureHasOsrCode(JNIEnv * env,jclass,jstring method_name)151 extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv* env,
152                                                              jclass,
153                                                              jstring method_name) {
154   if (!Runtime::Current()->UseJitCompilation()) {
155     return;
156   }
157   ScopedUtfChars chars(env, method_name);
158   CHECK(chars.c_str() != nullptr);
159   ScopedObjectAccess soa(Thread::Current());
160   OsrCheckVisitor visitor(soa.Self(), chars.c_str());
161   visitor.WalkStack();
162 }
163 
164 }  // namespace art
165