entrypoint_utils.h revision 1fd00287bedce99cd602aec00d421bddb7a9a107
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 31namespace art { 32 33namespace mirror { 34 class Array; 35 class Class; 36 class Object; 37 class String; 38} // namespace mirror 39 40class ArtField; 41class ArtMethod; 42class OatQuickMethodHeader; 43class ScopedObjectAccessAlreadyRunnable; 44class Thread; 45 46template <const bool kAccessCheck> 47ALWAYS_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 52ALWAYS_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. 61template <bool kAccessCheck, bool kInstrumented> 62ALWAYS_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. 69template <bool kInstrumented> 70ALWAYS_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. 76template <bool kInstrumented> 77ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass, 78 Thread* self, 79 gc::AllocatorType allocator_type) 80 SHARED_REQUIRES(Locks::mutator_lock_); 81 82 83template <bool kAccessCheck> 84ALWAYS_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. 94template <bool kAccessCheck, bool kInstrumented> 95ALWAYS_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 102template <bool kAccessCheck, bool kInstrumented> 103ALWAYS_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 110extern 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 116extern 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. 125enum FindFieldType { 126 InstanceObjectRead, 127 InstanceObjectWrite, 128 InstancePrimitiveRead, 129 InstancePrimitiveWrite, 130 StaticObjectRead, 131 StaticObjectWrite, 132 StaticPrimitiveRead, 133 StaticPrimitiveWrite, 134}; 135 136inline constexpr bool FindFieldTypeIsRead(FindFieldType type) { 137 return type == InstanceObjectRead || 138 type == InstancePrimitiveRead || 139 type == StaticObjectRead || 140 type == StaticPrimitiveRead; 141} 142 143template<FindFieldType type, bool access_check> 144inline ArtField* FindFieldFromCode( 145 uint32_t field_idx, ArtMethod* referrer, Thread* self, size_t expected_size) 146 SHARED_REQUIRES(Locks::mutator_lock_); 147 148template<InvokeType type, bool access_check> 149inline ArtMethod* FindMethodFromCode( 150 uint32_t method_idx, mirror::Object** this_object, ArtMethod* referrer, Thread* self) 151 SHARED_REQUIRES(Locks::mutator_lock_); 152 153// Fast path field resolution that can't initialize classes or throw exceptions. 154inline ArtField* FindFieldFast( 155 uint32_t field_idx, ArtMethod* referrer, FindFieldType type, size_t expected_size) 156 SHARED_REQUIRES(Locks::mutator_lock_); 157 158// Fast path method resolution that can't throw exceptions. 159inline ArtMethod* FindMethodFast( 160 uint32_t method_idx, mirror::Object* this_object, ArtMethod* referrer, bool access_check, 161 InvokeType type) 162 SHARED_REQUIRES(Locks::mutator_lock_); 163 164inline mirror::Class* ResolveVerifyAndClinit( 165 uint32_t type_idx, ArtMethod* referrer, Thread* self, bool can_run_clinit, bool verify_access) 166 SHARED_REQUIRES(Locks::mutator_lock_); 167 168inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx) 169 SHARED_REQUIRES(Locks::mutator_lock_); 170 171// TODO: annotalysis disabled as monitor semantics are maintained in Java code. 172inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self) 173 NO_THREAD_SAFETY_ANALYSIS; 174 175void CheckReferenceResult(mirror::Object* o, Thread* self) 176 SHARED_REQUIRES(Locks::mutator_lock_); 177 178JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty, 179 jobject rcvr_jobj, jobject interface_art_method_jobj, 180 std::vector<jvalue>& args) 181 SHARED_REQUIRES(Locks::mutator_lock_); 182 183bool FillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload) 184 SHARED_REQUIRES(Locks::mutator_lock_); 185 186template <typename INT_TYPE, typename FLOAT_TYPE> 187inline INT_TYPE art_float_to_integral(FLOAT_TYPE f); 188 189ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp, 190 Runtime::CalleeSaveType type, 191 bool do_caller_check = false); 192 193} // namespace art 194 195#endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ 196