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