blob: dd13c742c298b57afa8db9dbefb369a285581c53 [file] [log] [blame]
/*
* 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_