diff options
Diffstat (limited to 'runtime/interpreter/interpreter.cc')
-rw-r--r-- | runtime/interpreter/interpreter.cc | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 0ffc38beeb..5aa2fb6eed 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -389,6 +389,7 @@ void EnterInterpreterFromInvoke(Thread* self, ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0); ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get(); + self->PushShadowFrame(shadow_frame); size_t cur_reg = num_regs - num_ins; if (!method->IsStatic()) { @@ -420,10 +421,21 @@ void EnterInterpreterFromInvoke(Thread* self, } } self->EndAssertNoThreadSuspension(old_cause); - if (!EnsureInitialized(self, shadow_frame)) { - return; + // Do this after populating the shadow frame in case EnsureInitialized causes a GC. + if (method->IsStatic()) { + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); + if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) { + StackHandleScope<1> hs(self); + Handle<mirror::Class> h_class(hs.NewHandle(declaring_class)); + if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( + self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) { + CHECK(self->IsExceptionPending()); + self->PopShadowFrame(); + return; + } + DCHECK(h_class->IsInitializing()); + } } - self->PushShadowFrame(shadow_frame); if (LIKELY(!method->IsNative())) { JValue r = Execute(self, accessor, *shadow_frame, JValue(), stay_in_interpreter); if (result != nullptr) { @@ -595,6 +607,23 @@ void ArtInterpreterToInterpreterBridge(Thread* self, } self->PushShadowFrame(shadow_frame); + ArtMethod* method = shadow_frame->GetMethod(); + // Ensure static methods are initialized. + const bool is_static = method->IsStatic(); + if (is_static) { + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); + if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) { + StackHandleScope<1> hs(self); + Handle<mirror::Class> h_class(hs.NewHandle(declaring_class)); + if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( + self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) { + DCHECK(self->IsExceptionPending()); + self->PopShadowFrame(); + return; + } + DCHECK(h_class->IsInitializing()); + } + } if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { result->SetJ(Execute(self, accessor, *shadow_frame, JValue()).GetJ()); @@ -602,7 +631,6 @@ void ArtInterpreterToInterpreterBridge(Thread* self, // We don't expect to be asked to interpret native code (which is entered via a JNI compiler // generated stub) except during testing and image writing. CHECK(!Runtime::Current()->IsStarted()); - bool is_static = shadow_frame->GetMethod()->IsStatic(); ObjPtr<mirror::Object> receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver.Ptr(), args, result); |