diff options
Diffstat (limited to 'runtime/interpreter/interpreter_common.cc')
| -rw-r--r-- | runtime/interpreter/interpreter_common.cc | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index da8915e32a..937a3b0f97 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -67,25 +67,36 @@ bool CheckStackOverflow(Thread* self, size_t frame_size) return true; } -bool UseFastInterpreterToInterpreterInvoke(ArtMethod* method) { - Runtime* runtime = Runtime::Current(); - const void* quick_code = method->GetEntryPointFromQuickCompiledCode(); - if (!runtime->GetClassLinker()->IsQuickToInterpreterBridge(quick_code)) { - return false; +bool ShouldStayInSwitchInterpreter(ArtMethod* method) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (!Runtime::Current()->IsStarted()) { + // For unstarted runtimes, always use the interpreter entrypoint. This fixes the case where + // we are doing cross compilation. Note that GetEntryPointFromQuickCompiledCode doesn't use + // the image pointer size here and this may case an overflow if it is called from the + // compiler. b/62402160 + return true; } - if (!method->SkipAccessChecks() || method->IsNative() || method->IsProxyMethod()) { + + if (UNLIKELY(method->IsNative() || method->IsProxyMethod())) { return false; } - if (method->IsIntrinsic()) { - return false; + + if (Thread::Current()->IsForceInterpreter()) { + // Force the use of interpreter when it is required by the debugger. + return true; } - if (method->GetDeclaringClass()->IsStringClass() && method->IsConstructor()) { - return false; + + if (Thread::Current()->IsAsyncExceptionPending()) { + // Force use of interpreter to handle async-exceptions + return true; } - if (method->IsStatic() && !method->GetDeclaringClass()->IsVisiblyInitialized()) { - return false; + + const void* code = method->GetEntryPointFromQuickCompiledCode(); + if (code == GetQuickInstrumentationEntryPoint()) { + code = Runtime::Current()->GetInstrumentation()->GetCodeForInvoke(method); } - return true; + + return Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(code); } template <typename T> @@ -1216,13 +1227,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, // PerformCall. A deoptimization could occur at any time, and we shouldn't change which // entrypoint to use once we start building the shadow frame. - // For unstarted runtimes, always use the interpreter entrypoint. This fixes the case where we are - // doing cross compilation. Note that GetEntryPointFromQuickCompiledCode doesn't use the image - // pointer size here and this may case an overflow if it is called from the compiler. b/62402160 - const bool use_interpreter_entrypoint = !Runtime::Current()->IsStarted() || - ClassLinker::ShouldUseInterpreterEntrypoint( - called_method, - called_method->GetEntryPointFromQuickCompiledCode()); + const bool use_interpreter_entrypoint = ShouldStayInSwitchInterpreter(called_method); if (LIKELY(accessor.HasCodeItem())) { // When transitioning to compiled code, space only needs to be reserved for the input registers. // The rest of the frame gets discarded. This also prevents accessing the called method's code |