summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Jones <christopher.jones@arm.com> 2024-01-05 16:30:57 +0000
committer Ulya Trofimovich <skvadrik@google.com> 2024-09-25 18:50:21 +0000
commit9f3192455f075aea6538fa191b106f21ad6b789f (patch)
treeda4ced0a7a5c09cc758b64b6be4bc649eb01faa4
parentbb2fb09b7d4618e4e4319835e1a8e3c1eb1506ae (diff)
Refactor C++ entrypoints
Refactor all C++ entrypoint function (those that can be called from assembly entrypoints) declarations into a new header file. Now all C++ entrypoint functions have a single declaration, inside a header that can be included as needed. This removes the need for additional declarations to be made which, if not type checked, could be mismatched with the function definition. A macro is used to declare each entrypoint inside the header but also allows operations to be done on all C++ entrypoints similar to assembly entrypoints with its macro in quick_entrypoints_list.h. Note: linkers, unlike compilers, do not typically type check function declarations against defintions, e.g: when linking between two libraries. This can cause mismatches which are not caught when building and therefore become difficult to debug later. This patch aims to unify all C++ entrypoint function declarations, i.e: those C++ functions called from assembly entrypoints. By doing this any unnecessary and potentially conflicting declarations can be removed to ensure a single source of truth. Author: Chris Jones <christopher.jones@arm.com> Test: test.py --host --target Change-Id: I5b0de39eed96f666e7bb4205906c5d9369615aa8
-rw-r--r--runtime/arch/arm/entrypoints_init_arm.cc5
-rw-r--r--runtime/arch/arm64/entrypoints_init_arm64.cc5
-rw-r--r--runtime/arch/context.cc2
-rw-r--r--runtime/arch/context.h4
-rw-r--r--runtime/arch/riscv64/entrypoints_init_riscv64.cc4
-rw-r--r--runtime/arch/x86_64/entrypoints_init_x86_64.cc2
-rw-r--r--runtime/entrypoints/math_entrypoints.cc2
-rw-r--r--runtime/entrypoints/math_entrypoints.h29
-rw-r--r--runtime/entrypoints/math_entrypoints_test.cc2
-rw-r--r--runtime/entrypoints/quick/quick_entrypoints.h42
-rw-r--r--runtime/entrypoints/quick/quick_field_entrypoints.cc22
-rw-r--r--runtime/entrypoints/quick/quick_jni_entrypoints.cc20
-rw-r--r--runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc5
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc4
-rw-r--r--runtime/entrypoints/quick/runtime_entrypoints_list.h450
-rw-r--r--runtime/instrumentation.cc2
-rw-r--r--runtime/thread.cc1
17 files changed, 492 insertions, 109 deletions
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 156a107c99..551b4ba3cc 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -21,19 +21,16 @@
#include "base/bit_utils.h"
#include "entrypoints/entrypoint_utils.h"
#include "entrypoints/jni/jni_entrypoints.h"
-#include "entrypoints/math_entrypoints.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
#include "entrypoints/quick/quick_default_externs.h"
#include "entrypoints/quick/quick_default_init_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "interpreter/interpreter.h"
namespace art HIDDEN {
-// Cast entrypoints.
-extern "C" size_t artInstanceOfFromCode(mirror::Object* obj, mirror::Class* ref_class);
-
// Read barrier entrypoints.
// art_quick_read_barrier_mark_regX uses an non-standard calling
// convention: it expects its input in register X and returns its
diff --git a/runtime/arch/arm64/entrypoints_init_arm64.cc b/runtime/arch/arm64/entrypoints_init_arm64.cc
index 51cdacbb47..815a5c1ca3 100644
--- a/runtime/arch/arm64/entrypoints_init_arm64.cc
+++ b/runtime/arch/arm64/entrypoints_init_arm64.cc
@@ -22,11 +22,11 @@
#include "com_android_art_flags.h"
#include "entrypoints/entrypoint_utils.h"
#include "entrypoints/jni/jni_entrypoints.h"
-#include "entrypoints/math_entrypoints.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
#include "entrypoints/quick/quick_default_externs.h"
#include "entrypoints/quick/quick_default_init_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "interpreter/interpreter.h"
@@ -34,9 +34,6 @@ namespace art_flags = com::android::art::flags;
namespace art HIDDEN {
-// Cast entrypoints.
-extern "C" size_t artInstanceOfFromCode(mirror::Object* obj, mirror::Class* ref_class);
-
// Read barrier entrypoints.
// art_quick_read_barrier_mark_regX uses an non-standard calling
// convention: it expects its input in register X and returns its
diff --git a/runtime/arch/context.cc b/runtime/arch/context.cc
index 1d69691619..f09b8eff17 100644
--- a/runtime/arch/context.cc
+++ b/runtime/arch/context.cc
@@ -22,6 +22,8 @@ Context* Context::Create() {
return new RuntimeContextType;
}
+// Copy the GPRs and FPRs from the given thread's context to the given buffers. This function
+// expects that a long jump (art_quick_do_long_jump) is called afterwards.
extern "C" void artContextCopyForLongJump(Context* context, uintptr_t* gprs, uintptr_t* fprs) {
context->CopyContextTo(gprs, fprs);
// Once the context has been copied, it is no longer needed.
diff --git a/runtime/arch/context.h b/runtime/arch/context.h
index 1a82aa8553..d38726d619 100644
--- a/runtime/arch/context.h
+++ b/runtime/arch/context.h
@@ -21,6 +21,7 @@
#include <stdint.h>
#include "base/macros.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
namespace art HIDDEN {
@@ -102,9 +103,6 @@ class Context {
};
};
-// Copy the GPRs and FPRs from the context to the given buffers.
-extern "C" void artContextCopyForLongJump(Context* context, uintptr_t* gprs, uintptr_t* fprs);
-
} // namespace art
#endif // ART_RUNTIME_ARCH_CONTEXT_H_
diff --git a/runtime/arch/riscv64/entrypoints_init_riscv64.cc b/runtime/arch/riscv64/entrypoints_init_riscv64.cc
index d75a873c61..9f1bb7bb19 100644
--- a/runtime/arch/riscv64/entrypoints_init_riscv64.cc
+++ b/runtime/arch/riscv64/entrypoints_init_riscv64.cc
@@ -18,12 +18,10 @@
#include "entrypoints/quick/quick_default_init_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
namespace art HIDDEN {
-// Cast entrypoints.
-extern "C" size_t artInstanceOfFromCode(mirror::Object* obj, mirror::Class* ref_class);
-
// Read barrier entrypoints.
// art_quick_read_barrier_mark_regX uses an non-standard calling convention: it
// expects its input in register X and returns its result in that same register,
diff --git a/runtime/arch/x86_64/entrypoints_init_x86_64.cc b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
index 9652f43c7f..ebbcf84b96 100644
--- a/runtime/arch/x86_64/entrypoints_init_x86_64.cc
+++ b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
@@ -17,13 +17,13 @@
#include <math.h>
#include "entrypoints/jni/jni_entrypoints.h"
-#include "entrypoints/math_entrypoints.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
#include "entrypoints/quick/quick_default_externs.h"
#if !defined(__APPLE__)
#include "entrypoints/quick/quick_default_init_entrypoints.h"
#endif
#include "entrypoints/quick/quick_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "interpreter/interpreter.h"
diff --git a/runtime/entrypoints/math_entrypoints.cc b/runtime/entrypoints/math_entrypoints.cc
index 5db8dbfe9d..6d94ba5ef8 100644
--- a/runtime/entrypoints/math_entrypoints.cc
+++ b/runtime/entrypoints/math_entrypoints.cc
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include "math_entrypoints.h"
-
#include "entrypoint_utils-inl.h"
namespace art HIDDEN {
diff --git a/runtime/entrypoints/math_entrypoints.h b/runtime/entrypoints/math_entrypoints.h
deleted file mode 100644
index 717c7349bd..0000000000
--- a/runtime/entrypoints/math_entrypoints.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_ENTRYPOINTS_MATH_ENTRYPOINTS_H_
-#define ART_RUNTIME_ENTRYPOINTS_MATH_ENTRYPOINTS_H_
-
-#include <stdint.h>
-
-extern "C" double art_l2d(int64_t l);
-extern "C" float art_l2f(int64_t l);
-extern "C" int64_t art_d2l(double d);
-extern "C" int32_t art_d2i(double d);
-extern "C" int64_t art_f2l(float f);
-extern "C" int32_t art_f2i(float f);
-
-#endif // ART_RUNTIME_ENTRYPOINTS_MATH_ENTRYPOINTS_H_
diff --git a/runtime/entrypoints/math_entrypoints_test.cc b/runtime/entrypoints/math_entrypoints_test.cc
index 337f9f0925..82b4a52835 100644
--- a/runtime/entrypoints/math_entrypoints_test.cc
+++ b/runtime/entrypoints/math_entrypoints_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "math_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include <limits>
diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h
index fe01424c7c..cd6debea95 100644
--- a/runtime/entrypoints/quick/quick_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_entrypoints.h
@@ -53,51 +53,9 @@ struct QuickEntryPoints {
#undef ENTRYPOINT_ENUM
};
-
// JNI entrypoints.
-extern "C" void artJniMethodStart(Thread* self) UNLOCK_FUNCTION(Locks::mutator_lock_) HOT_ATTR;
-extern "C" void artJniMethodEnd(Thread* self) SHARED_LOCK_FUNCTION(Locks::mutator_lock_) HOT_ATTR;
extern mirror::Object* JniDecodeReferenceResult(jobject result, Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-extern "C" void artJniReadBarrier(ArtMethod* method)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-extern "C" void artJniUnlockObject(mirror::Object* locked, Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-
-// JNI entrypoints when monitoring entry/exit.
-extern "C" void artJniMonitoredMethodStart(Thread* self) UNLOCK_FUNCTION(Locks::mutator_lock_);
-extern "C" void artJniMonitoredMethodEnd(Thread* self) SHARED_LOCK_FUNCTION(Locks::mutator_lock_);
-extern "C" void artJniMethodEntryHook(Thread* self);
-
-// StringAppend pattern entrypoint.
-extern "C" mirror::String* artStringBuilderAppend(uint32_t format,
- const uint32_t* args,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-
-// Read barrier entrypoints.
-//
-// Compilers for ARM, ARM64 can insert a call to these
-// functions directly. For x86 and x86-64, compilers need a wrapper
-// assembly function, to handle mismatch in ABI.
-
-// Mark the heap reference `obj`. This entry point is used by read
-// barrier fast path implementations generated by the compiler to mark
-// an object that is referenced by a field of a gray object.
-extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-
-// Read barrier entrypoint for heap references.
-// This is the read barrier slow path for instance and static fields
-// and reference type arrays.
-extern "C" mirror::Object* artReadBarrierSlow(mirror::Object* ref,
- mirror::Object* obj,
- uint32_t offset)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
-
-// Read barrier entrypoint for GC roots.
-extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root)
- REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR;
} // namespace art
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 39b21ead02..1666e7d06b 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -425,14 +425,28 @@ extern "C" int artSet16InstanceFromCode(uint32_t field_idx,
return artSetCharInstanceFromCode(field_idx, obj, new_value, referrer, self);
}
-extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj) {
+// Read barrier entrypoints.
+//
+// Compilers for ARM, ARM64 can insert a call to these
+// functions directly. For x86 and x86-64, compilers need a wrapper
+// assembly function, to handle mismatch in ABI.
+
+// Mark the heap reference `obj`. This entry point is used by read
+// barrier fast path implementations generated by the compiler to mark
+// an object that is referenced by a field of a gray object.
+extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(gUseReadBarrier);
return ReadBarrier::Mark(obj);
}
+// Read barrier entrypoint for heap references.
+// This is the read barrier slow path for instance and static fields
+// and reference type arrays.
extern "C" mirror::Object* artReadBarrierSlow([[maybe_unused]] mirror::Object* ref,
mirror::Object* obj,
- uint32_t offset) {
+ uint32_t offset)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
// Used only in connection with non-volatile loads.
DCHECK(gUseReadBarrier);
uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
@@ -446,7 +460,9 @@ extern "C" mirror::Object* artReadBarrierSlow([[maybe_unused]] mirror::Object* r
return result;
}
-extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root) {
+// Read barrier entrypoint for GC roots.
+extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(gUseReadBarrier);
return root->Read();
}
diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
index 3c1dbffd7c..1359fef086 100644
--- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc
@@ -24,6 +24,7 @@
#include "palette/palette.h"
#include "thread-inl.h"
#include "verify_object.h"
+#include "runtime_entrypoints_list.h"
// For methods that monitor JNI invocations and report their begin/end to
// palette hooks.
@@ -38,15 +39,11 @@
namespace art HIDDEN {
-extern "C" int artMethodExitHook(Thread* self,
- ArtMethod* method,
- uint64_t* gpr_result,
- uint64_t* fpr_result);
-
static_assert(sizeof(jni::LRTSegmentState) == sizeof(uint32_t), "LRTSegmentState size unexpected");
static_assert(std::is_trivial<jni::LRTSegmentState>::value, "LRTSegmentState not trivial");
-extern "C" void artJniReadBarrier(ArtMethod* method) {
+extern "C" void artJniReadBarrier(ArtMethod* method)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(gUseReadBarrier);
mirror::CompressedReference<mirror::Object>* declaring_class =
method->GetDeclaringClassAddressWithoutBarrier();
@@ -64,7 +61,8 @@ extern "C" void artJniReadBarrier(ArtMethod* method) {
}
// Called on entry to JNI, transition out of Runnable and release share of mutator_lock_.
-extern "C" void artJniMethodStart(Thread* self) {
+extern "C" void artJniMethodStart(Thread* self)
+ UNLOCK_FUNCTION(Locks::mutator_lock_) {
if (kIsDebugBuild) {
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
CHECK(!native_method->IsFastNative()) << native_method->PrettyMethod();
@@ -88,7 +86,7 @@ static void PopLocalReferences(uint32_t saved_local_ref_cookie, Thread* self)
__attribute__((no_sanitize("memtag"))) // TODO(b/305919664)
extern "C" void
artJniUnlockObject(mirror::Object* locked, Thread* self) NO_THREAD_SAFETY_ANALYSIS
- REQUIRES(!Roles::uninterruptible_) {
+ REQUIRES(!Roles::uninterruptible_) REQUIRES_SHARED(Locks::mutator_lock_) {
// Note: No thread suspension is allowed for successful unlocking, otherwise plain
// `mirror::Object*` return value saved by the assembly stub would need to be updated.
uintptr_t old_poison_object_cookie = kIsDebugBuild ? self->GetPoisonObjectCookie() : 0u;
@@ -120,7 +118,7 @@ artJniUnlockObject(mirror::Object* locked, Thread* self) NO_THREAD_SAFETY_ANALYS
// TODO: These should probably be templatized or macro-ized.
// Otherwise there's just too much repetitive boilerplate.
-extern "C" void artJniMethodEnd(Thread* self) {
+extern "C" void artJniMethodEnd(Thread* self) SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
self->TransitionFromSuspendedToRunnable();
if (kIsDebugBuild) {
@@ -233,12 +231,12 @@ extern uint64_t GenericJniMethodEnd(Thread* self,
return ret;
}
-extern "C" void artJniMonitoredMethodStart(Thread* self) {
+extern "C" void artJniMonitoredMethodStart(Thread* self) UNLOCK_FUNCTION(Locks::mutator_lock_) {
artJniMethodStart(self);
MONITOR_JNI(PaletteNotifyBeginJniInvocation);
}
-extern "C" void artJniMonitoredMethodEnd(Thread* self) {
+extern "C" void artJniMonitoredMethodEnd(Thread* self) SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
MONITOR_JNI(PaletteNotifyEndJniInvocation);
artJniMethodEnd(self);
}
diff --git a/runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc b/runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc
index 9e5fe1c826..4db8094ff3 100644
--- a/runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "quick_entrypoints.h"
+#include "runtime_entrypoints_list.h"
#include "string_builder_append.h"
#include "obj_ptr-inl.h"
@@ -23,7 +23,8 @@ namespace art HIDDEN {
extern "C" mirror::String* artStringBuilderAppend(uint32_t format,
const uint32_t* args,
- Thread* self) {
+ Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
return StringBuilderAppend::AppendF(format, args, self).Ptr();
}
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 99390f1b3e..312af5441c 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -61,12 +61,10 @@
#include "thread-inl.h"
#include "var_handles.h"
#include "well_known_classes.h"
+#include "runtime_entrypoints_list.h"
namespace art HIDDEN {
-extern "C" Context* artDeoptimizeFromCompiledCode(DeoptimizationKind kind, Thread* self);
-extern "C" Context* artDeoptimize(Thread* self, bool skip_method_exit_callbacks);
-
// Visits the arguments as saved to the stack by a CalleeSaveType::kRefAndArgs callee save frame.
class QuickArgumentVisitor {
// Number of bytes for each out register in the caller method's frame.
diff --git a/runtime/entrypoints/quick/runtime_entrypoints_list.h b/runtime/entrypoints/quick/runtime_entrypoints_list.h
new file mode 100644
index 0000000000..dd13c742c2
--- /dev/null
+++ b/runtime/entrypoints/quick/runtime_entrypoints_list.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_ENTRYPOINTS_QUICK_RUNTIME_ENTRYPOINTS_LIST_H_
+#define ART_RUNTIME_ENTRYPOINTS_QUICK_RUNTIME_ENTRYPOINTS_LIST_H_
+
+
+#include "entrypoints/entrypoint_utils.h"
+#include "arch/instruction_set.h"
+#include <math.h>
+
+namespace art {
+
+namespace mirror {
+class Array;
+class Class;
+template<class MirrorType> class CompressedReference;
+class Object;
+class String;
+class Throwable;
+template<class T> class PrimitiveArray;
+using ByteArray = PrimitiveArray<int8_t>;
+using CharArray = PrimitiveArray<uint16_t>;
+} // namespace mirror
+
+class ArtMethod;
+template<class MirrorType> class GcRoot;
+template<class MirrorType> class StackReference;
+class Thread;
+class Context;
+enum class DeoptimizationKind;
+
+// All C++ quick entrypoints, i.e.: C++ entrypoint functions called from quick assembly code.
+// Format is name, attribute, return type, argument types.
+#define RUNTIME_ENTRYPOINT_LIST(V) \
+ V(artDeliverPendingExceptionFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artInvokeObsoleteMethod, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ ArtMethod* method, \
+ Thread* self) \
+ V(artDeliverExceptionFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ mirror::Throwable* exception, \
+ Thread* self) \
+ V(artThrowNullPointerExceptionFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artThrowNullPointerExceptionFromSignal, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ uintptr_t addr, \
+ Thread* self) \
+ V(artThrowDivZeroFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artThrowArrayBoundsFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ int index, \
+ int length, \
+ Thread* self) \
+ V(artThrowStringBoundsFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ int index, \
+ int length, \
+ Thread* self) \
+ V(artThrowStackOverflowFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artThrowClassCastExceptionForObject, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ mirror::Object* obj, \
+ mirror::Class* dest_type, \
+ Thread* self) \
+ V(artThrowArrayStoreException, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ mirror::Object* array, \
+ mirror::Object* value, \
+ Thread* self) \
+ \
+ V(artDeoptimizeIfNeeded, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self, \
+ uintptr_t result, \
+ bool is_ref) \
+ V(artTestSuspendFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artImplicitSuspendFromCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self) \
+ V(artCompileOptimized, REQUIRES_SHARED(Locks::mutator_lock_), void, \
+ ArtMethod* method, \
+ Thread* self) \
+ \
+ V(artQuickToInterpreterBridge, REQUIRES_SHARED(Locks::mutator_lock_), uint64_t, \
+ ArtMethod* method, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artQuickProxyInvokeHandler, REQUIRES_SHARED(Locks::mutator_lock_), uint64_t, \
+ ArtMethod* proxy_method, \
+ mirror::Object* receiver, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artQuickResolutionTrampoline, REQUIRES_SHARED(Locks::mutator_lock_), const void*, \
+ ArtMethod* called, \
+ mirror::Object* receiver, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artQuickGenericJniTrampoline, REQUIRES_SHARED(Locks::mutator_lock_) \
+ NO_THREAD_SAFETY_ANALYSIS, const void*, \
+ Thread* self, \
+ ArtMethod** managed_sp, \
+ uintptr_t* reserved_area) \
+ V(artQuickGenericJniEndTrampoline, , uint64_t, \
+ Thread* self, \
+ jvalue result, \
+ uint64_t result_fp) \
+ V(artInvokeInterfaceTrampolineWithAccessCheck, REQUIRES_SHARED(Locks::mutator_lock_), \
+ TwoWordReturn, \
+ uint32_t method_idx, \
+ mirror::Object* this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeDirectTrampolineWithAccessCheck, REQUIRES_SHARED(Locks::mutator_lock_), \
+ TwoWordReturn, \
+ uint32_t method_idx, \
+ mirror::Object* this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeStaticTrampolineWithAccessCheck, REQUIRES_SHARED(Locks::mutator_lock_), \
+ TwoWordReturn, \
+ uint32_t method_idx, \
+ [[maybe_unused]] mirror::Object* this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeSuperTrampolineWithAccessCheck, REQUIRES_SHARED(Locks::mutator_lock_), \
+ TwoWordReturn, \
+ uint32_t method_idx, \
+ mirror::Object* this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeVirtualTrampolineWithAccessCheck, REQUIRES_SHARED(Locks::mutator_lock_), \
+ TwoWordReturn, \
+ uint32_t method_idx, \
+ mirror::Object* this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeInterfaceTrampoline, REQUIRES_SHARED(Locks::mutator_lock_), TwoWordReturn, \
+ ArtMethod* interface_method, \
+ mirror::Object* raw_this_object, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokePolymorphic, REQUIRES_SHARED(Locks::mutator_lock_), uint64_t, \
+ mirror::Object* raw_receiver, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokePolymorphicWithHiddenReceiver, REQUIRES_SHARED(Locks::mutator_lock_), uint64_t, \
+ mirror::Object* raw_receiver, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artInvokeCustom, REQUIRES_SHARED(Locks::mutator_lock_), uint64_t, \
+ uint32_t call_site_idx, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artJniMethodEntryHook, REQUIRES_SHARED(Locks::mutator_lock_), void, \
+ Thread* self) \
+ V(artMethodEntryHook, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ ArtMethod* method, \
+ Thread* self, \
+ ArtMethod** sp) \
+ V(artMethodExitHook, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self, \
+ ArtMethod** sp, \
+ uint64_t* gpr_result, \
+ uint64_t* fpr_result, \
+ uint32_t frame_size) \
+ \
+ V(artIsAssignableFromCode, REQUIRES_SHARED(Locks::mutator_lock_), size_t, \
+ mirror::Class* klass, \
+ mirror::Class* ref_class) \
+ V(artInstanceOfFromCode, REQUIRES_SHARED(Locks::mutator_lock_), size_t, \
+ mirror::Object* obj, \
+ mirror::Class* ref_class) \
+ \
+ V(artInitializeStaticStorageFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::Class*, \
+ mirror::Class* klass, \
+ Thread* self) \
+ V(artResolveTypeFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::Class*, \
+ uint32_t type_idx, \
+ Thread* self) \
+ V(artResolveTypeAndVerifyAccessFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::Class*, \
+ uint32_t type_idx, \
+ Thread* self) \
+ V(artResolveMethodHandleFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::MethodHandle*, \
+ uint32_t method_handle_idx, \
+ Thread* self) \
+ V(artResolveMethodTypeFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::MethodType*, \
+ uint32_t proto_idx, \
+ Thread* self) \
+ V(artResolveStringFromCode, REQUIRES_SHARED(Locks::mutator_lock_), mirror::String*, \
+ int32_t string_idx, Thread* self) \
+ \
+ V(artDeoptimize, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ Thread* self, \
+ bool skip_method_exit_callbacks) \
+ V(artDeoptimizeFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), Context*, \
+ DeoptimizationKind kind, \
+ Thread* self) \
+ \
+ V(artHandleFillArrayDataFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ const Instruction::ArrayDataPayload* payload, \
+ mirror::Array* array, \
+ Thread* self) \
+ \
+ V(artJniReadBarrier, REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, void, \
+ ArtMethod* method) \
+ V(artJniMethodStart, UNLOCK_FUNCTION(Locks::mutator_lock_) HOT_ATTR, void, \
+ Thread* self) \
+ V(artJniUnlockObject, NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) \
+ REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, void, \
+ mirror::Object* locked, \
+ Thread* self) \
+ V(artJniMethodEnd, SHARED_LOCK_FUNCTION(Locks::mutator_lock_) HOT_ATTR, void, \
+ Thread* self) \
+ V(artJniMonitoredMethodStart, UNLOCK_FUNCTION(Locks::mutator_lock_), void, \
+ Thread* self) \
+ V(artJniMonitoredMethodEnd, SHARED_LOCK_FUNCTION(Locks::mutator_lock_), void, \
+ Thread* self) \
+ \
+ V(artStringBuilderAppend, REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, mirror::String*, \
+ uint32_t format, \
+ const uint32_t* args, \
+ Thread* self) \
+ \
+ V(artContextCopyForLongJump, , void, \
+ Context* context, \
+ uintptr_t* gprs, \
+ uintptr_t* fprs) \
+ \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, DlMalloc) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, RosAlloc) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, BumpPointer) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, TLAB) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, Region) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, RegionTLAB) \
+ \
+ ART_GET_FIELD_FROM_CODE_DECL(V, Byte, ssize_t, uint32_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, Boolean, size_t, uint32_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, Short, ssize_t, uint16_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, Char, size_t, uint16_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, 32, FIELD_RETURN_TYPE_32, uint32_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, 64, uint64_t, uint64_t) \
+ ART_GET_FIELD_FROM_CODE_DECL(V, Obj, mirror::Object*, mirror::Object*) \
+ V(artSet8StaticFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ uint32_t new_value, \
+ Thread* self) \
+ V(artSet16StaticFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ uint16_t new_value, \
+ Thread* self) \
+ V(artSet8InstanceFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ uint8_t new_value, \
+ Thread* self) \
+ V(artSet16InstanceFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ uint16_t new_value, \
+ Thread* self) \
+ V(artSet8StaticFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ uint32_t new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artSet16StaticFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ uint16_t new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artSet8InstanceFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ uint8_t new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artSet16InstanceFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ uint16_t new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artReadBarrierMark, REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, mirror::Object*, \
+ mirror::Object* obj) \
+ V(artReadBarrierSlow, REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, mirror::Object*, \
+ mirror::Object* ref, \
+ mirror::Object* obj, \
+ uint32_t offset) \
+ V(artReadBarrierForRootSlow, REQUIRES_SHARED(Locks::mutator_lock_) HOT_ATTR, mirror::Object*, \
+ GcRoot<mirror::Object>* root) \
+ \
+ V(artLockObjectFromCode, NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) \
+ REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ mirror::Object* obj, \
+ Thread* self) \
+ V(artUnlockObjectFromCode, NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) \
+ REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ mirror::Object* obj, \
+ Thread* self) \
+ \
+ V(artFindNativeMethodRunnable, REQUIRES_SHARED(Locks::mutator_lock_), const void*, \
+ Thread* self) \
+ V(artFindNativeMethod, , const void*, \
+ Thread* self) \
+ V(artCriticalNativeFrameSize, REQUIRES_SHARED(Locks::mutator_lock_), size_t, \
+ ArtMethod* method, \
+ uintptr_t caller_pc) \
+ \
+ V(artLmul, , int64_t, \
+ int64_t a, \
+ int64_t b) \
+ V(artLdiv, , int64_t, \
+ int64_t a, \
+ int64_t b) \
+ V(artLmod, , int64_t, \
+ int64_t a, \
+ int64_t b) \
+ \
+ V(art_l2d, , double, \
+ int64_t l) \
+ V(art_l2f, , float, \
+ int64_t l) \
+ V(art_d2l, , int64_t, \
+ double d) \
+ V(art_f2l, , int64_t, \
+ float f) \
+ V(art_d2i, , int32_t, \
+ double d) \
+ V(art_f2i, , int32_t, \
+ float f) \
+ V(fmodf, , float, \
+ float, \
+ float) \
+ V(fmod, , double, \
+ double, \
+ double)
+
+// Declarations from quick_alloc_entrypoints.cc
+#define GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR_INST(V, suffix, suffix2) \
+ V(artAllocObjectFromCodeWithChecks##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::Object*, \
+ mirror::Class* klass, \
+ Thread* self) \
+ V(artAllocObjectFromCodeResolved##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::Object*, \
+ mirror::Class* klass, \
+ Thread* self) \
+ V(artAllocObjectFromCodeInitialized##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::Object*, \
+ mirror::Class* klass, \
+ Thread* self) \
+ V(artAllocStringObject##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::String*, \
+ mirror::Class* klass, \
+ Thread* self) \
+ V(artAllocArrayFromCodeResolved##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::Array*, \
+ mirror::Class* klass, \
+ int32_t component_count, \
+ Thread* self) \
+ V(artAllocStringFromBytesFromCode##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::String*, \
+ mirror::ByteArray* byte_array, \
+ int32_t high, \
+ int32_t offset, \
+ int32_t byte_count, \
+ Thread* self) \
+ V(artAllocStringFromCharsFromCode##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::String*, \
+ int32_t offset, \
+ int32_t char_count, \
+ mirror::CharArray* char_array, \
+ Thread* self) \
+ V(artAllocStringFromStringFromCode##suffix##suffix2, REQUIRES_SHARED(Locks::mutator_lock_), \
+ mirror::String*, \
+ mirror::String* string, \
+ Thread* self)
+
+#define GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR(V, suffix) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR_INST(V, suffix, Instrumented) \
+ GENERATE_ENTRYPOINTS_DECL_FOR_ALLOCATOR_INST(V, suffix, )
+
+// Declarations from quick_field_entrypoints.cc
+#define ART_GET_FIELD_FROM_CODE_DECL(V, Kind, RetType, SetType) \
+ V(artGet ## Kind ## StaticFromCode, REQUIRES_SHARED(Locks::mutator_lock_), RetType, \
+ uint32_t field_idx, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artGet ## Kind ## InstanceFromCode, REQUIRES_SHARED(Locks::mutator_lock_), RetType, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artSet ## Kind ## StaticFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ SetType new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artSet ## Kind ## InstanceFromCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ SetType new_value, \
+ ArtMethod* referrer, \
+ Thread* self) \
+ V(artGet ## Kind ## StaticFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), RetType, \
+ uint32_t field_idx, \
+ Thread* self) \
+ V(artGet ## Kind ## InstanceFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), RetType, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ Thread* self) \
+ V(artSet ## Kind ## StaticFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ SetType new_value, \
+ Thread* self) \
+ V(artSet ## Kind ## InstanceFromCompiledCode, REQUIRES_SHARED(Locks::mutator_lock_), int, \
+ uint32_t field_idx, \
+ mirror::Object* obj, \
+ SetType new_value, \
+ Thread* self)
+
+#if defined(__riscv)
+#define FIELD_RETURN_TYPE_32 uint32_t
+#else
+#define FIELD_RETURN_TYPE_32 size_t
+#endif
+
+// Define a macro that will extract information from RUNTIME_ENTRYPOINT_LIST to create a function
+// declaration.
+#define ENTRYPOINT_ENUM(name, attr, rettype, ...) \
+ extern "C" rettype name(__VA_ARGS__) attr;
+
+// Declare all C++ quick entrypoints.
+RUNTIME_ENTRYPOINT_LIST(ENTRYPOINT_ENUM)
+#undef ENTRYPOINT_ENUM
+
+} // namespace art
+
+#endif // ART_RUNTIME_ENTRYPOINTS_QUICK_RUNTIME_ENTRYPOINTS_LIST_H_
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index ce8c35bfac..26aca42557 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -34,6 +34,7 @@
#include "dex/dex_instruction-inl.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
#include "entrypoints/quick/quick_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "gc_root-inl.h"
#include "interpreter/interpreter.h"
@@ -55,7 +56,6 @@
#include "thread_list.h"
namespace art HIDDEN {
-extern "C" void artDeliverPendingExceptionFromCode(Thread* self);
namespace instrumentation {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index dca08959f4..2e29e7970b 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -63,6 +63,7 @@
#include "dex/dex_file_types.h"
#include "entrypoints/entrypoint_utils.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
+#include "entrypoints/quick/runtime_entrypoints_list.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/heap_bitmap-inl.h"
#include "gc/allocator/rosalloc.h"