summaryrefslogtreecommitdiff
path: root/runtime/common_dex_operations.h
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2022-09-12 13:15:36 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2022-09-13 08:34:15 +0000
commit509c6c544a3e16b4686932d45427b2a96fa27440 (patch)
treef8e655863a58cb8ca3daf35c651cd841d8fdeddf /runtime/common_dex_operations.h
parent51ee7dcedb254542e4359c72e36295f48d3b331a (diff)
Reland "Ensure we initialize before pushing the method invoked."
This reverts commit b96054f6f3704dcb039af56532b2ce10896e2b81. Reason for revert: Works now that https://android-review.googlesource.com/c/platform/art/+/2209538 is submitted. Change-Id: I0df2407ecac74df736f9ab23a7b519fcce82192f
Diffstat (limited to 'runtime/common_dex_operations.h')
-rw-r--r--runtime/common_dex_operations.h46
1 files changed, 38 insertions, 8 deletions
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h
index 882e3ce4c7..b8d9cbe141 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,32 @@ 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);
+ 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 +90,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);
}
}