diff options
author | 2022-07-05 15:37:08 +0100 | |
---|---|---|
committer | 2022-07-06 13:42:37 +0000 | |
commit | 9f1a9bcfa320de7b4409cfd85cbe9b192c022f06 (patch) | |
tree | 83efde2a36a7c2e62fc21583ac0e1bd94f852eee /runtime/common_dex_operations.h | |
parent | 5eb7ad2aac1f0e1690c5f8213528a3cb8b820e16 (diff) |
Ensure we initialize before pushing the method invoked.
Test: 839-clinit-throw
Change-Id: I4571d2445bc3f3a35fe27757208cfc7bcee4a801
Diffstat (limited to 'runtime/common_dex_operations.h')
-rw-r--r-- | runtime/common_dex_operations.h | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h index 882e3ce4c7..22057c91b8 100644 --- a/runtime/common_dex_operations.h +++ b/runtime/common_dex_operations.h @@ -26,6 +26,7 @@ #include "dex/code_item_accessors.h" #include "dex/dex_file_structs.h" #include "dex/primitive.h" +#include "entrypoints/entrypoint_utils.h" #include "handle_scope-inl.h" #include "instrumentation.h" #include "interpreter/interpreter.h" @@ -55,8 +56,33 @@ namespace interpreter { ShadowFrame* shadow_frame, uint16_t arg_offset, JValue* result); + } // namespace interpreter +inline bool EnsureInitialized(Thread* self, ShadowFrame* shadow_frame) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (!NeedsClinitCheckBeforeCall(shadow_frame->GetMethod())) { + return true; + } + ObjPtr<mirror::Class> declaring_class = shadow_frame->GetMethod()->GetDeclaringClass(); + if (LIKELY(declaring_class->IsVisiblyInitialized())) { + return true; + } + + // Save the shadow frame. + ScopedStackedShadowFramePusher pusher( + self, shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction); + 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()); + return false; + } + DCHECK(h_class->IsInitializing()); + return true; +} + inline void PerformCall(Thread* self, const CodeItemDataAccessor& accessor, ArtMethod* caller_method, @@ -65,15 +91,20 @@ inline void PerformCall(Thread* self, JValue* result, bool use_interpreter_entrypoint) REQUIRES_SHARED(Locks::mutator_lock_) { - if (LIKELY(Runtime::Current()->IsStarted())) { - if (use_interpreter_entrypoint) { - interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result); - } else { - interpreter::ArtInterpreterToCompiledCodeBridge( - self, caller_method, callee_frame, first_dest_reg, result); - } - } else { + if (UNLIKELY(!Runtime::Current()->IsStarted())) { interpreter::UnstartedRuntime::Invoke(self, accessor, callee_frame, result, first_dest_reg); + return; + } + + if (!EnsureInitialized(self, callee_frame)) { + return; + } + + if (use_interpreter_entrypoint) { + interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result); + } else { + interpreter::ArtInterpreterToCompiledCodeBridge( + self, caller_method, callee_frame, first_dest_reg, result); } } |