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