entrypoint_utils.h revision 63bc11efaac0c041e849ab401f9fc368631a00f5
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 18#define ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 19 20#include <jni.h> 21#include <stdint.h> 22 23#include "base/macros.h" 24#include "base/mutex.h" 25#include "gc/allocator_type.h" 26#include "invoke_type.h" 27#include "jvalue.h" 28 29namespace art { 30 31namespace mirror { 32 class Class; 33 class Array; 34 class ArtField; 35 class ArtMethod; 36 class Object; 37 class String; 38} // namespace mirror 39 40class ScopedObjectAccessAlreadyRunnable; 41class Thread; 42 43template <const bool kAccessCheck> 44ALWAYS_INLINE static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, 45 mirror::ArtMethod* method, 46 Thread* self, bool* slow_path) 47 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 48 49// TODO: Fix no thread safety analysis when annotalysis is smarter. 50ALWAYS_INLINE static inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass, 51 Thread* self, bool* slow_path) 52 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 53 54// Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it 55// cannot be resolved, throw an error. If it can, use it to create an instance. 56// When verification/compiler hasn't been able to verify access, optionally perform an access 57// check. 58template <bool kAccessCheck, bool kInstrumented> 59ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, 60 mirror::ArtMethod* method, 61 Thread* self, 62 gc::AllocatorType allocator_type) 63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64 65// Given the context of a calling Method and a resolved class, create an instance. 66template <bool kInstrumented> 67ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass, 68 mirror::ArtMethod* method, 69 Thread* self, 70 gc::AllocatorType allocator_type) 71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 72 73// Given the context of a calling Method and an initialized class, create an instance. 74template <bool kInstrumented> 75ALWAYS_INLINE static inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, 76 mirror::ArtMethod* method, 77 Thread* self, 78 gc::AllocatorType allocator_type) 79 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 80 81 82template <bool kAccessCheck> 83ALWAYS_INLINE static inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, 84 mirror::ArtMethod* method, 85 int32_t component_count, 86 bool* slow_path) 87 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 88 89// Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If 90// it cannot be resolved, throw an error. If it can, use it to create an array. 91// When verification/compiler hasn't been able to verify access, optionally perform an access 92// check. 93template <bool kAccessCheck, bool kInstrumented> 94ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, 95 mirror::ArtMethod* method, 96 int32_t component_count, 97 Thread* self, 98 gc::AllocatorType allocator_type) 99 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 100 101template <bool kAccessCheck, bool kInstrumented> 102ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass, 103 mirror::ArtMethod* method, 104 int32_t component_count, 105 Thread* self, 106 gc::AllocatorType allocator_type) 107 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 108 109extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::ArtMethod* method, 110 int32_t component_count, Thread* self, 111 bool access_check, 112 gc::AllocatorType allocator_type) 113 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 114 115extern mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, 116 mirror::ArtMethod* method, 117 int32_t component_count, Thread* self, 118 bool access_check, 119 gc::AllocatorType allocator_type) 120 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 121 122// Type of find field operation for fast and slow case. 123enum FindFieldType { 124 InstanceObjectRead, 125 InstanceObjectWrite, 126 InstancePrimitiveRead, 127 InstancePrimitiveWrite, 128 StaticObjectRead, 129 StaticObjectWrite, 130 StaticPrimitiveRead, 131 StaticPrimitiveWrite, 132}; 133 134template<FindFieldType type, bool access_check> 135static inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod* referrer, 136 Thread* self, size_t expected_size) 137 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 138 139template<InvokeType type, bool access_check> 140static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, 141 mirror::Object** this_object, 142 mirror::ArtMethod** referrer, Thread* self) 143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 144 145// Fast path field resolution that can't initialize classes or throw exceptions. 146static inline mirror::ArtField* FindFieldFast(uint32_t field_idx, 147 mirror::ArtMethod* referrer, 148 FindFieldType type, size_t expected_size) 149 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 150 151// Fast path method resolution that can't throw exceptions. 152static inline mirror::ArtMethod* FindMethodFast(uint32_t method_idx, 153 mirror::Object* this_object, 154 mirror::ArtMethod* referrer, 155 bool access_check, InvokeType type) 156 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 157 158static inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, 159 mirror::ArtMethod* referrer, 160 Thread* self, bool can_run_clinit, 161 bool verify_access) 162 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 163 164extern void ThrowStackOverflowError(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 165 166static inline mirror::String* ResolveStringFromCode(mirror::ArtMethod* referrer, 167 uint32_t string_idx) 168 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 169 170// TODO: annotalysis disabled as monitor semantics are maintained in Java code. 171static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self) 172 NO_THREAD_SAFETY_ANALYSIS; 173 174void CheckReferenceResult(mirror::Object* o, Thread* self) 175 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 176 177static inline void CheckSuspend(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 178 179JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty, 180 jobject rcvr_jobj, jobject interface_art_method_jobj, 181 std::vector<jvalue>& args) 182 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 183 184// Entry point for deoptimization. 185extern "C" void art_quick_deoptimize(); 186static inline uintptr_t GetQuickDeoptimizationEntryPoint() { 187 return reinterpret_cast<uintptr_t>(art_quick_deoptimize); 188} 189 190// Return address of instrumentation stub. 191extern "C" void art_quick_instrumentation_entry(void*); 192static inline void* GetQuickInstrumentationEntryPoint() { 193 return reinterpret_cast<void*>(art_quick_instrumentation_entry); 194} 195 196// The return_pc of instrumentation exit stub. 197extern "C" void art_quick_instrumentation_exit(); 198static inline uintptr_t GetQuickInstrumentationExitPc() { 199 return reinterpret_cast<uintptr_t>(art_quick_instrumentation_exit); 200} 201 202#if defined(ART_USE_PORTABLE_COMPILER) 203extern "C" void art_portable_to_interpreter_bridge(mirror::ArtMethod*); 204static inline const void* GetPortableToInterpreterBridge() { 205 return reinterpret_cast<void*>(art_portable_to_interpreter_bridge); 206} 207 208static inline const void* GetPortableToQuickBridge() { 209 // TODO: portable to quick bridge. Bug: 8196384 210 return GetPortableToInterpreterBridge(); 211} 212#endif 213 214extern "C" void art_quick_to_interpreter_bridge(mirror::ArtMethod*); 215static inline const void* GetQuickToInterpreterBridge() { 216 return reinterpret_cast<void*>(art_quick_to_interpreter_bridge); 217} 218 219#if defined(ART_USE_PORTABLE_COMPILER) 220static inline const void* GetQuickToPortableBridge() { 221 // TODO: quick to portable bridge. Bug: 8196384 222 return GetQuickToInterpreterBridge(); 223} 224 225extern "C" void art_portable_proxy_invoke_handler(); 226static inline const void* GetPortableProxyInvokeHandler() { 227 return reinterpret_cast<void*>(art_portable_proxy_invoke_handler); 228} 229#endif 230 231extern "C" void art_quick_proxy_invoke_handler(); 232static inline const void* GetQuickProxyInvokeHandler() { 233 return reinterpret_cast<void*>(art_quick_proxy_invoke_handler); 234} 235 236extern "C" void* art_jni_dlsym_lookup_stub(JNIEnv*, jobject); 237static inline void* GetJniDlsymLookupStub() { 238 return reinterpret_cast<void*>(art_jni_dlsym_lookup_stub); 239} 240 241template <typename INT_TYPE, typename FLOAT_TYPE> 242static inline INT_TYPE art_float_to_integral(FLOAT_TYPE f); 243 244} // namespace art 245 246#endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 247