Fix the stack at the beginning of the Generic JNI trampoline.
Fix up a callee-save frame at the bottom of the stack while we
check for optimization annotations, thus allowing stack walking
until the completion of the JNI frame creation.
Test: art/test/testrunner/testrunner.py -t 656-annotation-lookup-generic-jni
Bug: 38454151
Bug: 34659969
Change-Id: I70dc3d40139198f29457dba5282b45a9d0d09e49
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index b7cd39f..4e54045 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2181,11 +2181,34 @@
REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* called = *sp;
DCHECK(called->IsNative()) << called->PrettyMethod(true);
+ // Fix up a callee-save frame at the bottom of the stack (at `*sp`,
+ // above the alloca region) while we check for optimization
+ // annotations, thus allowing stack walking until the completion of
+ // the JNI frame creation.
+ //
+ // Note however that the Generic JNI trampoline does not expect
+ // exception being thrown at that stage.
+ *sp = Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs);
+ self->SetTopOfStack(sp);
uint32_t shorty_len = 0;
const char* shorty = called->GetShorty(&shorty_len);
bool critical_native = called->IsAnnotatedWithCriticalNative();
+ // ArtMethod::IsAnnotatedWithCriticalNative should not throw
+ // an exception; clear it if it happened anyway.
+ // TODO: Revisit this code path and turn this into a CHECK(!self->IsExceptionPending()).
+ if (self->IsExceptionPending()) {
+ self->ClearException();
+ }
bool fast_native = called->IsAnnotatedWithFastNative();
+ // ArtMethod::IsAnnotatedWithFastNative should not throw
+ // an exception; clear it if it happened anyway.
+ // TODO: Revisit this code path and turn this into a CHECK(!self->IsExceptionPending()).
+ if (self->IsExceptionPending()) {
+ self->ClearException();
+ }
bool normal_native = !critical_native && !fast_native;
+ // Restore the initial ArtMethod pointer at `*sp`.
+ *sp = called;
// Run the visitor and update sp.
BuildGenericJniFrameVisitor visitor(self,