Home | History | Annotate | Download | only in 570-checker-osr
      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:
     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 
     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 
     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 
     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:
     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 
     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 
    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:
    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 
    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 
    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