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