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 30 namespace art { 31 32 namespace mirror { 33 class Array; 34 class Class; 35 class Object; 36 class String; 37 } // namespace mirror 38 39 class ArtField; 40 class ArtMethod; 41 class ScopedObjectAccessAlreadyRunnable; 42 class Thread; 43 44 template <const bool kAccessCheck> 45 ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, 46 ArtMethod* method, 47 Thread* self, bool* slow_path) 48 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 49 50 ALWAYS_INLINE inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass, 51 Thread* self, 52 bool* slow_path) 53 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 54 55 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it 56 // cannot be resolved, throw an error. If it can, use it to create an instance. 57 // When verification/compiler hasn't been able to verify access, optionally perform an access 58 // check. 59 template <bool kAccessCheck, bool kInstrumented> 60 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, 61 ArtMethod* method, 62 Thread* self, 63 gc::AllocatorType allocator_type) 64 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 65 66 // Given the context of a calling Method and a resolved class, create an instance. 67 template <bool kInstrumented> 68 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass, 69 Thread* self, 70 gc::AllocatorType allocator_type) 71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 72 73 // Given the context of a calling Method and an initialized class, create an instance. 74 template <bool kInstrumented> 75 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, 76 Thread* self, 77 gc::AllocatorType allocator_type) 78 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 79 80 81 template <bool kAccessCheck> 82 ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, 83 int32_t component_count, 84 ArtMethod* method, 85 bool* slow_path) 86 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 87 88 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If 89 // it cannot be resolved, throw an error. If it can, use it to create an array. 90 // When verification/compiler hasn't been able to verify access, optionally perform an access 91 // check. 92 template <bool kAccessCheck, bool kInstrumented> 93 ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, 94 int32_t component_count, 95 ArtMethod* method, 96 Thread* self, 97 gc::AllocatorType allocator_type) 98 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 99 100 template <bool kAccessCheck, bool kInstrumented> 101 ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass, 102 int32_t component_count, 103 ArtMethod* method, 104 Thread* self, 105 gc::AllocatorType allocator_type) 106 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 107 108 extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count, 109 ArtMethod* method, Thread* self, 110 bool access_check, 111 gc::AllocatorType allocator_type) 112 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 113 114 extern mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, 115 int32_t component_count, 116 ArtMethod* method, 117 Thread* self, 118 bool access_check, 119 gc::AllocatorType allocator_type) 120 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 121 122 // Type of find field operation for fast and slow case. 123 enum FindFieldType { 124 InstanceObjectRead, 125 InstanceObjectWrite, 126 InstancePrimitiveRead, 127 InstancePrimitiveWrite, 128 StaticObjectRead, 129 StaticObjectWrite, 130 StaticPrimitiveRead, 131 StaticPrimitiveWrite, 132 }; 133 134 template<FindFieldType type, bool access_check> 135 inline ArtField* FindFieldFromCode( 136 uint32_t field_idx, ArtMethod* referrer, Thread* self, size_t expected_size) 137 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 138 139 template<InvokeType type, bool access_check> 140 inline ArtMethod* FindMethodFromCode( 141 uint32_t method_idx, mirror::Object** this_object, ArtMethod** referrer, Thread* self) 142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 143 144 // Fast path field resolution that can't initialize classes or throw exceptions. 145 inline ArtField* FindFieldFast( 146 uint32_t field_idx, ArtMethod* referrer, FindFieldType type, size_t expected_size) 147 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 148 149 // Fast path method resolution that can't throw exceptions. 150 inline ArtMethod* FindMethodFast( 151 uint32_t method_idx, mirror::Object* this_object, ArtMethod* referrer, bool access_check, 152 InvokeType type) 153 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 154 155 inline mirror::Class* ResolveVerifyAndClinit( 156 uint32_t type_idx, ArtMethod* referrer, Thread* self, bool can_run_clinit, bool verify_access) 157 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 158 159 extern void ThrowStackOverflowError(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 160 161 inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx) 162 SHARED_LOCKS_REQUIRED(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_LOCKS_REQUIRED(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_LOCKS_REQUIRED(Locks::mutator_lock_); 175 176 bool FillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload) 177 SHARED_LOCKS_REQUIRED(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 } // namespace art 183 184 #endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 185