summaryrefslogtreecommitdiff
path: root/runtime/common_dex_operations.h
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2022-07-05 15:37:08 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2022-07-06 13:42:37 +0000
commit9f1a9bcfa320de7b4409cfd85cbe9b192c022f06 (patch)
tree83efde2a36a7c2e62fc21583ac0e1bd94f852eee /runtime/common_dex_operations.h
parent5eb7ad2aac1f0e1690c5f8213528a3cb8b820e16 (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.h47
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);
}
}