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