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 MethodReference; 48 class OatQuickMethodHeader; 49 class ScopedObjectAccessAlreadyRunnable; 50 class Thread; 51 52 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it 53 // cannot be resolved, throw an error. If it can, use it to create an instance. 54 template <bool kInstrumented = true> 55 ALWAYS_INLINE inline ObjPtr<mirror::Object> AllocObjectFromCode(ObjPtr<mirror::Class> klass, 56 Thread* self, 57 gc::AllocatorType allocator_type) 58 REQUIRES_SHARED(Locks::mutator_lock_) 59 REQUIRES(!Roles::uninterruptible_); 60 61 // Given the context of a calling Method and a resolved class, create an instance. 62 template <bool kInstrumented> 63 ALWAYS_INLINE 64 inline ObjPtr<mirror::Object> AllocObjectFromCodeResolved(ObjPtr<mirror::Class> klass, 65 Thread* self, 66 gc::AllocatorType allocator_type) 67 REQUIRES_SHARED(Locks::mutator_lock_) 68 REQUIRES(!Roles::uninterruptible_); 69 70 // Given the context of a calling Method and an initialized class, create an instance. 71 template <bool kInstrumented> 72 ALWAYS_INLINE 73 inline ObjPtr<mirror::Object> AllocObjectFromCodeInitialized(ObjPtr<mirror::Class> klass, 74 Thread* self, 75 gc::AllocatorType allocator_type) 76 REQUIRES_SHARED(Locks::mutator_lock_) 77 REQUIRES(!Roles::uninterruptible_); 78 79 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 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<bool access_check> 131 inline ArtMethod* FindSuperMethodToCall(uint32_t method_idx, 132 ArtMethod* resolved_method, 133 ArtMethod* referrer, 134 Thread* self) 135 REQUIRES_SHARED(Locks::mutator_lock_); 136 137 template<FindFieldType type, bool access_check> 138 inline ArtField* FindFieldFromCode(uint32_t field_idx, 139 ArtMethod* referrer, 140 Thread* self, 141 size_t expected_size) 142 REQUIRES_SHARED(Locks::mutator_lock_) 143 REQUIRES(!Roles::uninterruptible_); 144 145 template<InvokeType type> 146 inline ArtMethod* FindMethodToCall(Thread* self, 147 ArtMethod* referrer, 148 ObjPtr<mirror::Object>* this_object, 149 const Instruction& inst, 150 bool only_lookup_tls_cache, 151 /*out*/ bool* string_init) 152 REQUIRES_SHARED(Locks::mutator_lock_) 153 REQUIRES(!Roles::uninterruptible_); 154 155 inline ObjPtr<mirror::Class> ResolveVerifyAndClinit(dex::TypeIndex type_idx, 156 ArtMethod* referrer, 157 Thread* self, 158 bool can_run_clinit, 159 bool verify_access) 160 REQUIRES_SHARED(Locks::mutator_lock_) 161 REQUIRES(!Roles::uninterruptible_); 162 163 ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer, 164 uint32_t method_handle_idx) 165 REQUIRES_SHARED(Locks::mutator_lock_) 166 REQUIRES(!Roles::uninterruptible_); 167 168 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, dex::ProtoIndex proto_idx) 169 REQUIRES_SHARED(Locks::mutator_lock_) 170 REQUIRES(!Roles::uninterruptible_); 171 172 void CheckReferenceResult(Handle<mirror::Object> o, Thread* self) 173 REQUIRES_SHARED(Locks::mutator_lock_) 174 REQUIRES(!Roles::uninterruptible_); 175 176 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, 177 const char* shorty, 178 jobject rcvr_jobj, 179 jobject interface_art_method_jobj, 180 std::vector<jvalue>& args) 181 REQUIRES_SHARED(Locks::mutator_lock_) 182 REQUIRES(!Roles::uninterruptible_); 183 184 bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) 185 REQUIRES_SHARED(Locks::mutator_lock_) 186 REQUIRES(!Roles::uninterruptible_); 187 188 template <typename INT_TYPE, typename FLOAT_TYPE> 189 inline INT_TYPE art_float_to_integral(FLOAT_TYPE f); 190 191 ArtMethod* GetCalleeSaveMethodCallerAndDexPc(ArtMethod** sp, 192 CalleeSaveType type, 193 /* out */ uint32_t* dex_pc, 194 bool do_caller_check = false) 195 REQUIRES_SHARED(Locks::mutator_lock_); 196 197 struct CallerAndOuterMethod { 198 ArtMethod* caller; 199 ArtMethod* outer_method; 200 }; 201 202 CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, CalleeSaveType type) 203 REQUIRES_SHARED(Locks::mutator_lock_); 204 205 ArtMethod* GetCalleeSaveOuterMethod(Thread* self, CalleeSaveType type) 206 REQUIRES_SHARED(Locks::mutator_lock_); 207 208 // Returns the synchronization object for a native method for a GenericJni frame 209 // we have just created or are about to exit. The synchronization object is 210 // the class object for static methods and the `this` object otherwise. 211 ObjPtr<mirror::Object> GetGenericJniSynchronizationObject(Thread* self, ArtMethod* called) 212 REQUIRES_SHARED(Locks::mutator_lock_); 213 214 // Update .bss method entrypoint if the `outer_method` has a valid OatFile, and either 215 // A) the `callee_reference` has the same OatFile as `outer_method`, or 216 // B) the `callee_reference` comes from a BCP DexFile that was present during `outer_method`'s 217 // OatFile compilation. 218 // In both cases, we require that the oat file has a .bss entry for the `callee_reference`. 219 void MaybeUpdateBssMethodEntry(ArtMethod* callee, 220 MethodReference callee_reference, 221 ArtMethod* outer_method) REQUIRES_SHARED(Locks::mutator_lock_); 222 223 } // namespace art 224 225 #endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 226