diff options
author | 2024-01-05 16:30:57 +0000 | |
---|---|---|
committer | 2024-09-25 18:50:21 +0000 | |
commit | 9f3192455f075aea6538fa191b106f21ad6b789f (patch) | |
tree | da4ced0a7a5c09cc758b64b6be4bc649eb01faa4 | |
parent | bb2fb09b7d4618e4e4319835e1a8e3c1eb1506ae (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.cc | 5 | ||||
-rw-r--r-- | runtime/arch/arm64/entrypoints_init_arm64.cc | 5 | ||||
-rw-r--r-- | runtime/arch/context.cc | 2 | ||||
-rw-r--r-- | runtime/arch/context.h | 4 | ||||
-rw-r--r-- | runtime/arch/riscv64/entrypoints_init_riscv64.cc | 4 | ||||
-rw-r--r-- | runtime/arch/x86_64/entrypoints_init_x86_64.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/math_entrypoints.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/math_entrypoints.h | 29 | ||||
-rw-r--r-- | runtime/entrypoints/math_entrypoints_test.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_entrypoints.h | 42 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_field_entrypoints.cc | 22 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_jni_entrypoints.cc | 20 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_string_builder_append_entrypoints.cc | 5 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 4 | ||||
-rw-r--r-- | runtime/entrypoints/quick/runtime_entrypoints_list.h | 450 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 2 | ||||
-rw-r--r-- | runtime/thread.cc | 1 |
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" |