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