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