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/callee_save_type.h" 24 #include "base/locks.h" 25 #include "base/macros.h" 26 #include "dex/dex_file_types.h" 27 #include "dex/dex_instruction.h" 28 #include "gc/allocator_type.h" 29 #include "handle.h" 30 #include "jvalue.h" 31 32 namespace art { 33 34 namespace mirror { 35 class Array; 36 class Class; 37 class MethodHandle; 38 class MethodType; 39 class Object; 40 class String; 41 } // namespace mirror 42 43 class ArtField; 44 class ArtMethod; 45 class HandleScope; 46 enum InvokeType : uint32_t; 47 class OatQuickMethodHeader; 48 class ScopedObjectAccessAlreadyRunnable; 49 class Thread; 50 51 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it 52 // cannot be resolved, throw an error. If it can, use it to create an instance. 53 template <bool kInstrumented = true> 54 ALWAYS_INLINE inline ObjPtr<mirror::Object> AllocObjectFromCode(ObjPtr<mirror::Class> klass, 55 Thread* self, 56 gc::AllocatorType allocator_type) 57 REQUIRES_SHARED(Locks::mutator_lock_) 58 REQUIRES(!Roles::uninterruptible_); 59 60 // Given the context of a calling Method and a resolved class, create an instance. 61 template <bool kInstrumented> 62 ALWAYS_INLINE 63 inline ObjPtr<mirror::Object> AllocObjectFromCodeResolved(ObjPtr<mirror::Class> klass, 64 Thread* self, 65 gc::AllocatorType allocator_type) 66 REQUIRES_SHARED(Locks::mutator_lock_) 67 REQUIRES(!Roles::uninterruptible_); 68 69 // Given the context of a calling Method and an initialized class, create an instance. 70 template <bool kInstrumented> 71 ALWAYS_INLINE 72 inline ObjPtr<mirror::Object> AllocObjectFromCodeInitialized(ObjPtr<mirror::Class> klass, 73 Thread* self, 74 gc::AllocatorType allocator_type) 75 REQUIRES_SHARED(Locks::mutator_lock_) 76 REQUIRES(!Roles::uninterruptible_); 77 78 79 template <bool kAccessCheck> 80 ALWAYS_INLINE inline ObjPtr<mirror::Class> CheckArrayAlloc(dex::TypeIndex type_idx, 81 int32_t component_count, 82 ArtMethod* method, 83 bool* slow_path) 84 REQUIRES_SHARED(Locks::mutator_lock_) 85 REQUIRES(!Roles::uninterruptible_); 86 87 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If 88 // it cannot be resolved, throw an error. If it can, use it to create an array. 89 // When verification/compiler hasn't been able to verify access, optionally perform an access 90 // check. 91 template <bool kAccessCheck, bool kInstrumented = true> 92 ALWAYS_INLINE inline ObjPtr<mirror::Array> AllocArrayFromCode(dex::TypeIndex type_idx, 93 int32_t component_count, 94 ArtMethod* method, 95 Thread* self, 96 gc::AllocatorType allocator_type) 97 REQUIRES_SHARED(Locks::mutator_lock_) 98 REQUIRES(!Roles::uninterruptible_); 99 100 template <bool kInstrumented> 101 ALWAYS_INLINE 102 inline ObjPtr<mirror::Array> AllocArrayFromCodeResolved(ObjPtr<mirror::Class> klass, 103 int32_t component_count, 104 Thread* self, 105 gc::AllocatorType allocator_type) 106 REQUIRES_SHARED(Locks::mutator_lock_) 107 REQUIRES(!Roles::uninterruptible_); 108 109 enum FindFieldFlags { 110 InstanceBit = 1 << 0, 111 StaticBit = 1 << 1, 112 ObjectBit = 1 << 2, 113 PrimitiveBit = 1 << 3, 114 ReadBit = 1 << 4, 115 WriteBit = 1 << 5, 116 }; 117 118 // Type of find field operation for fast and slow case. 119 enum FindFieldType { 120 InstanceObjectRead = InstanceBit | ObjectBit | ReadBit, 121 InstanceObjectWrite = InstanceBit | ObjectBit | WriteBit, 122 InstancePrimitiveRead = InstanceBit | PrimitiveBit | ReadBit, 123 InstancePrimitiveWrite = InstanceBit | PrimitiveBit | WriteBit, 124 StaticObjectRead = StaticBit | ObjectBit | ReadBit, 125 StaticObjectWrite = StaticBit | ObjectBit | WriteBit, 126 StaticPrimitiveRead = StaticBit | PrimitiveBit | ReadBit, 127 StaticPrimitiveWrite = StaticBit | PrimitiveBit | WriteBit, 128 }; 129 130 template<FindFieldType type, bool access_check> 131 inline ArtField* FindFieldFromCode(uint32_t field_idx, 132 ArtMethod* referrer, 133 Thread* self, 134 size_t expected_size) 135 REQUIRES_SHARED(Locks::mutator_lock_) 136 REQUIRES(!Roles::uninterruptible_); 137 138 template<InvokeType type, bool access_check> 139 inline ArtMethod* FindMethodFromCode(uint32_t method_idx, 140 ObjPtr<mirror::Object>* this_object, 141 ArtMethod* referrer, 142 Thread* self) 143 REQUIRES_SHARED(Locks::mutator_lock_) 144 REQUIRES(!Roles::uninterruptible_); 145 146 // Fast path field resolution that can't initialize classes or throw exceptions. 147 inline ArtField* FindFieldFast(uint32_t field_idx, 148 ArtMethod* referrer, 149 FindFieldType type, 150 size_t expected_size) 151 REQUIRES_SHARED(Locks::mutator_lock_); 152 153 // Fast path method resolution that can't throw exceptions. 154 template <InvokeType type, bool access_check> 155 inline ArtMethod* FindMethodFast(uint32_t method_idx, 156 ObjPtr<mirror::Object> this_object, 157 ArtMethod* referrer) 158 REQUIRES_SHARED(Locks::mutator_lock_); 159 160 inline ObjPtr<mirror::Class> ResolveVerifyAndClinit(dex::TypeIndex type_idx, 161 ArtMethod* referrer, 162 Thread* self, 163 bool can_run_clinit, 164 bool verify_access) 165 REQUIRES_SHARED(Locks::mutator_lock_) 166 REQUIRES(!Roles::uninterruptible_); 167 168 ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer, 169 uint32_t method_handle_idx) 170 REQUIRES_SHARED(Locks::mutator_lock_) 171 REQUIRES(!Roles::uninterruptible_); 172 173 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, dex::ProtoIndex proto_idx) 174 REQUIRES_SHARED(Locks::mutator_lock_) 175 REQUIRES(!Roles::uninterruptible_); 176 177 void CheckReferenceResult(Handle<mirror::Object> o, Thread* self) 178 REQUIRES_SHARED(Locks::mutator_lock_) 179 REQUIRES(!Roles::uninterruptible_); 180 181 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, 182 const char* shorty, 183 jobject rcvr_jobj, 184 jobject interface_art_method_jobj, 185 std::vector<jvalue>& args) 186 REQUIRES_SHARED(Locks::mutator_lock_) 187 REQUIRES(!Roles::uninterruptible_); 188 189 bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) 190 REQUIRES_SHARED(Locks::mutator_lock_) 191 REQUIRES(!Roles::uninterruptible_); 192 193 template <typename INT_TYPE, typename FLOAT_TYPE> 194 inline INT_TYPE art_float_to_integral(FLOAT_TYPE f); 195 196 ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp, 197 CalleeSaveType type, 198 bool do_caller_check = false) 199 REQUIRES_SHARED(Locks::mutator_lock_); 200 201 struct CallerAndOuterMethod { 202 ArtMethod* caller; 203 ArtMethod* outer_method; 204 }; 205 206 CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, CalleeSaveType type) 207 REQUIRES_SHARED(Locks::mutator_lock_); 208 209 ArtMethod* GetCalleeSaveOuterMethod(Thread* self, CalleeSaveType type) 210 REQUIRES_SHARED(Locks::mutator_lock_); 211 212 // Returns whether we need to do class initialization check before invoking the method. 213 // The caller is responsible for performing that check. 214 bool NeedsClinitCheckBeforeCall(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 215 216 constexpr size_t kJniCookieSize = sizeof(uint32_t); 217 218 inline HandleScope* GetGenericJniHandleScope(ArtMethod** managed_sp, 219 size_t num_handle_scope_references); 220 221 } // namespace art 222 223 #endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 224