• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 class HandleScope;
46 enum InvokeType : uint32_t;
47 class MethodReference;
48 class OatQuickMethodHeader;
49 class ScopedObjectAccessAlreadyRunnable;
50 class Thread;
51 
52 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
53 // cannot be resolved, throw an error. If it can, use it to create an instance.
54 template <bool kInstrumented = true>
55 ALWAYS_INLINE inline ObjPtr<mirror::Object> AllocObjectFromCode(ObjPtr<mirror::Class> klass,
56                                                                 Thread* self,
57                                                                 gc::AllocatorType allocator_type)
58     REQUIRES_SHARED(Locks::mutator_lock_)
59     REQUIRES(!Roles::uninterruptible_);
60 
61 // Given the context of a calling Method and a resolved class, create an instance.
62 template <bool kInstrumented>
63 ALWAYS_INLINE
64 inline ObjPtr<mirror::Object> AllocObjectFromCodeResolved(ObjPtr<mirror::Class> klass,
65                                                           Thread* self,
66                                                           gc::AllocatorType allocator_type)
67     REQUIRES_SHARED(Locks::mutator_lock_)
68     REQUIRES(!Roles::uninterruptible_);
69 
70 // Given the context of a calling Method and an initialized class, create an instance.
71 template <bool kInstrumented>
72 ALWAYS_INLINE
73 inline ObjPtr<mirror::Object> AllocObjectFromCodeInitialized(ObjPtr<mirror::Class> klass,
74                                                              Thread* self,
75                                                              gc::AllocatorType allocator_type)
76     REQUIRES_SHARED(Locks::mutator_lock_)
77     REQUIRES(!Roles::uninterruptible_);
78 
79 
80 template <bool kAccessCheck>
81 ALWAYS_INLINE inline ObjPtr<mirror::Class> CheckArrayAlloc(dex::TypeIndex type_idx,
82                                                            int32_t component_count,
83                                                            ArtMethod* method,
84                                                            bool* slow_path)
85     REQUIRES_SHARED(Locks::mutator_lock_)
86     REQUIRES(!Roles::uninterruptible_);
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 = true>
93 ALWAYS_INLINE inline ObjPtr<mirror::Array> AllocArrayFromCode(dex::TypeIndex type_idx,
94                                                               int32_t component_count,
95                                                               ArtMethod* method,
96                                                               Thread* self,
97                                                               gc::AllocatorType allocator_type)
98     REQUIRES_SHARED(Locks::mutator_lock_)
99     REQUIRES(!Roles::uninterruptible_);
100 
101 template <bool kInstrumented>
102 ALWAYS_INLINE
103 inline ObjPtr<mirror::Array> AllocArrayFromCodeResolved(ObjPtr<mirror::Class> klass,
104                                                         int32_t component_count,
105                                                         Thread* self,
106                                                         gc::AllocatorType allocator_type)
107     REQUIRES_SHARED(Locks::mutator_lock_)
108     REQUIRES(!Roles::uninterruptible_);
109 
110 enum FindFieldFlags {
111   InstanceBit = 1 << 0,
112   StaticBit = 1 << 1,
113   ObjectBit = 1 << 2,
114   PrimitiveBit = 1 << 3,
115   ReadBit = 1 << 4,
116   WriteBit = 1 << 5,
117 };
118 
119 // Type of find field operation for fast and slow case.
120 enum FindFieldType {
121   InstanceObjectRead = InstanceBit | ObjectBit | ReadBit,
122   InstanceObjectWrite = InstanceBit | ObjectBit | WriteBit,
123   InstancePrimitiveRead = InstanceBit | PrimitiveBit | ReadBit,
124   InstancePrimitiveWrite = InstanceBit | PrimitiveBit | WriteBit,
125   StaticObjectRead = StaticBit | ObjectBit | ReadBit,
126   StaticObjectWrite = StaticBit | ObjectBit | WriteBit,
127   StaticPrimitiveRead = StaticBit | PrimitiveBit | ReadBit,
128   StaticPrimitiveWrite = StaticBit | PrimitiveBit | WriteBit,
129 };
130 
131 template<bool access_check>
132 inline ArtMethod* FindSuperMethodToCall(uint32_t method_idx,
133                                         ArtMethod* resolved_method,
134                                         ArtMethod* referrer,
135                                         Thread* self)
136     REQUIRES_SHARED(Locks::mutator_lock_);
137 
138 template<FindFieldType type, bool access_check>
139 inline ArtField* FindFieldFromCode(uint32_t field_idx,
140                                    ArtMethod* referrer,
141                                    Thread* self,
142                                    size_t expected_size)
143     REQUIRES_SHARED(Locks::mutator_lock_)
144     REQUIRES(!Roles::uninterruptible_);
145 
146 template<InvokeType type, bool access_check>
147 inline ArtMethod* FindMethodFromCode(uint32_t method_idx,
148                                      ObjPtr<mirror::Object>* this_object,
149                                      ArtMethod* referrer,
150                                      Thread* self)
151     REQUIRES_SHARED(Locks::mutator_lock_)
152     REQUIRES(!Roles::uninterruptible_);
153 
154 inline ObjPtr<mirror::Class> ResolveVerifyAndClinit(dex::TypeIndex type_idx,
155                                                     ArtMethod* referrer,
156                                                     Thread* self,
157                                                     bool can_run_clinit,
158                                                     bool verify_access)
159     REQUIRES_SHARED(Locks::mutator_lock_)
160     REQUIRES(!Roles::uninterruptible_);
161 
162 ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer,
163                                                          uint32_t method_handle_idx)
164     REQUIRES_SHARED(Locks::mutator_lock_)
165     REQUIRES(!Roles::uninterruptible_);
166 
167 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, dex::ProtoIndex proto_idx)
168     REQUIRES_SHARED(Locks::mutator_lock_)
169     REQUIRES(!Roles::uninterruptible_);
170 
171 void CheckReferenceResult(Handle<mirror::Object> o, Thread* self)
172     REQUIRES_SHARED(Locks::mutator_lock_)
173     REQUIRES(!Roles::uninterruptible_);
174 
175 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa,
176                                     const char* shorty,
177                                     jobject rcvr_jobj,
178                                     jobject interface_art_method_jobj,
179                                     std::vector<jvalue>& args)
180     REQUIRES_SHARED(Locks::mutator_lock_)
181     REQUIRES(!Roles::uninterruptible_);
182 
183 bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload)
184     REQUIRES_SHARED(Locks::mutator_lock_)
185     REQUIRES(!Roles::uninterruptible_);
186 
187 template <typename INT_TYPE, typename FLOAT_TYPE>
188 inline INT_TYPE art_float_to_integral(FLOAT_TYPE f);
189 
190 ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp,
191                                      CalleeSaveType type,
192                                      bool do_caller_check = false)
193     REQUIRES_SHARED(Locks::mutator_lock_);
194 
195 struct CallerAndOuterMethod {
196   ArtMethod* caller;
197   ArtMethod* outer_method;
198 };
199 
200 CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, CalleeSaveType type)
201     REQUIRES_SHARED(Locks::mutator_lock_);
202 
203 ArtMethod* GetCalleeSaveOuterMethod(Thread* self, CalleeSaveType type)
204     REQUIRES_SHARED(Locks::mutator_lock_);
205 
206 // Returns whether we need to do class initialization check before invoking the method.
207 // The caller is responsible for performing that check.
208 bool NeedsClinitCheckBeforeCall(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
209 
210 // Returns the synchronization object for a native method for a GenericJni frame
211 // we have just created or are about to exit. The synchronization object is
212 // the class object for static methods and the `this` object otherwise.
213 ObjPtr<mirror::Object> GetGenericJniSynchronizationObject(Thread* self, ArtMethod* called)
214     REQUIRES_SHARED(Locks::mutator_lock_);
215 
216 // Update .bss method entrypoint if the `outer_method` has a valid OatFile, and either
217 //   A) the `callee_reference` has the same OatFile as `outer_method`, or
218 //   B) the `callee_reference` comes from a BCP DexFile that was present during `outer_method`'s
219 //      OatFile compilation.
220 // In both cases, we require that the oat file has a .bss entry for the `callee_reference`.
221 void MaybeUpdateBssMethodEntry(ArtMethod* callee,
222                                MethodReference callee_reference,
223                                ArtMethod* outer_method) REQUIRES_SHARED(Locks::mutator_lock_);
224 
225 }  // namespace art
226 
227 #endif  // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
228