summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter.cc')
-rw-r--r--runtime/interpreter/interpreter.cc36
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);