1 /*
2 * Copyright (C) 2016 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_COMMON_DEX_OPERATIONS_H_
18 #define ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
19
20 #include "android-base/logging.h"
21 #include "art_field.h"
22 #include "art_method.h"
23 #include "base/locks.h"
24 #include "base/macros.h"
25 #include "class_linker.h"
26 #include "dex/code_item_accessors.h"
27 #include "dex/dex_file_structs.h"
28 #include "dex/primitive.h"
29 #include "entrypoints/entrypoint_utils.h"
30 #include "handle_scope-inl.h"
31 #include "instrumentation.h"
32 #include "interpreter/interpreter.h"
33 #include "interpreter/shadow_frame.h"
34 #include "interpreter/unstarted_runtime.h"
35 #include "jvalue-inl.h"
36 #include "mirror/class.h"
37 #include "mirror/object.h"
38 #include "obj_ptr-inl.h"
39 #include "reflective_handle.h"
40 #include "reflective_handle_scope.h"
41 #include "runtime.h"
42 #include "stack.h"
43 #include "thread.h"
44
45 namespace art {
46
47 namespace interpreter {
48 void ArtInterpreterToInterpreterBridge(Thread* self,
49 const dex::CodeItem* code_item,
50 ShadowFrame* shadow_frame,
51 JValue* result)
52 REQUIRES_SHARED(Locks::mutator_lock_);
53
54 void ArtInterpreterToCompiledCodeBridge(Thread* self,
55 ArtMethod* caller,
56 ShadowFrame* shadow_frame,
57 uint16_t arg_offset,
58 JValue* result);
59
60 } // namespace interpreter
61
EnsureInitialized(Thread * self,ShadowFrame * shadow_frame)62 inline bool EnsureInitialized(Thread* self, ShadowFrame* shadow_frame)
63 REQUIRES_SHARED(Locks::mutator_lock_) {
64 if (LIKELY(!shadow_frame->GetMethod()->StillNeedsClinitCheck())) {
65 return true;
66 }
67
68 // Save the shadow frame.
69 ScopedStackedShadowFramePusher pusher(self, shadow_frame);
70 StackHandleScope<1> hs(self);
71 Handle<mirror::Class> h_class = hs.NewHandle(shadow_frame->GetMethod()->GetDeclaringClass());
72 if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
73 self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
74 DCHECK(self->IsExceptionPending());
75 return false;
76 }
77 DCHECK(h_class->IsInitializing());
78 return true;
79 }
80
PerformCall(Thread * self,const CodeItemDataAccessor & accessor,ArtMethod * caller_method,const size_t first_dest_reg,ShadowFrame * callee_frame,JValue * result,bool use_interpreter_entrypoint)81 inline void PerformCall(Thread* self,
82 const CodeItemDataAccessor& accessor,
83 ArtMethod* caller_method,
84 const size_t first_dest_reg,
85 ShadowFrame* callee_frame,
86 JValue* result,
87 bool use_interpreter_entrypoint)
88 REQUIRES_SHARED(Locks::mutator_lock_) {
89 if (UNLIKELY(!Runtime::Current()->IsStarted())) {
90 interpreter::UnstartedRuntime::Invoke(self, accessor, callee_frame, result, first_dest_reg);
91 return;
92 }
93
94 if (!EnsureInitialized(self, callee_frame)) {
95 return;
96 }
97
98 if (use_interpreter_entrypoint) {
99 interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result);
100 } else {
101 interpreter::ArtInterpreterToCompiledCodeBridge(
102 self, caller_method, callee_frame, first_dest_reg, result);
103 }
104 }
105
106 template <typename T>
DCheckStaticState(Thread * self,T * entity)107 inline void DCheckStaticState(Thread* self, T* entity) REQUIRES_SHARED(Locks::mutator_lock_) {
108 if (kIsDebugBuild) {
109 ObjPtr<mirror::Class> klass = entity->GetDeclaringClass();
110 if (entity->IsStatic()) {
111 klass->AssertInitializedOrInitializingInThread(self);
112 } else {
113 CHECK(klass->IsInitializing() || klass->IsErroneousResolved());
114 }
115 }
116 }
117
118 template<Primitive::Type field_type>
DoFieldGetCommon(Thread * self,const ShadowFrame & shadow_frame,ObjPtr<mirror::Object> obj,ArtField * field,JValue * result)119 static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
120 const ShadowFrame& shadow_frame,
121 ObjPtr<mirror::Object> obj,
122 ArtField* field,
123 JValue* result)
124 REQUIRES_SHARED(Locks::mutator_lock_) {
125 DCheckStaticState(self, field);
126
127 // Report this field access to instrumentation if needed.
128 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
129 if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
130 StackHandleScope<1> hs(self);
131 StackArtFieldHandleScope<1> rhs(self);
132 // Wrap in handle wrapper in case the listener does thread suspension.
133 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
134 ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
135 ObjPtr<mirror::Object> this_object;
136 if (!field->IsStatic()) {
137 this_object = obj;
138 }
139 instrumentation->FieldReadEvent(self,
140 this_object,
141 shadow_frame.GetMethod(),
142 shadow_frame.GetDexPC(),
143 field);
144 if (UNLIKELY(self->IsExceptionPending())) {
145 return false;
146 }
147 }
148
149 switch (field_type) {
150 case Primitive::kPrimBoolean:
151 result->SetZ(field->GetBoolean(obj));
152 break;
153 case Primitive::kPrimByte:
154 result->SetB(field->GetByte(obj));
155 break;
156 case Primitive::kPrimChar:
157 result->SetC(field->GetChar(obj));
158 break;
159 case Primitive::kPrimShort:
160 result->SetS(field->GetShort(obj));
161 break;
162 case Primitive::kPrimInt:
163 result->SetI(field->GetInt(obj));
164 break;
165 case Primitive::kPrimLong:
166 result->SetJ(field->GetLong(obj));
167 break;
168 case Primitive::kPrimNot:
169 result->SetL(field->GetObject(obj));
170 break;
171 case Primitive::kPrimVoid:
172 LOG(FATAL) << "Unreachable " << field_type;
173 break;
174 }
175 return true;
176 }
177
178 template<Primitive::Type field_type, bool transaction_active>
DoFieldPutCommon(Thread * self,const ShadowFrame & shadow_frame,ObjPtr<mirror::Object> obj,ArtField * field,JValue & value)179 ALWAYS_INLINE bool DoFieldPutCommon(Thread* self,
180 const ShadowFrame& shadow_frame,
181 ObjPtr<mirror::Object> obj,
182 ArtField* field,
183 JValue& value)
184 REQUIRES_SHARED(Locks::mutator_lock_) {
185 DCheckStaticState(self, field);
186
187 // Report this field access to instrumentation if needed. Since we only have the offset of
188 // the field from the base of the object, we need to look for it first.
189 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
190 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
191 StackHandleScope<2> hs(self);
192 StackArtFieldHandleScope<1> rhs(self);
193 // Save this and return value (if needed) in case the instrumentation causes a suspend.
194 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
195 ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
196 ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
197 mirror::Object* fake_root = nullptr;
198 HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
199 field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root));
200 instrumentation->FieldWriteEvent(self,
201 this_object,
202 shadow_frame.GetMethod(),
203 shadow_frame.GetDexPC(),
204 field,
205 value);
206 if (UNLIKELY(self->IsExceptionPending())) {
207 return false;
208 }
209 if (shadow_frame.GetForcePopFrame()) {
210 // We need to check this here since we expect that the FieldWriteEvent happens before the
211 // actual field write. If one pops the stack we should not modify the field. The next
212 // instruction will force a pop. Return true.
213 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
214 return true;
215 }
216 }
217
218 switch (field_type) {
219 case Primitive::kPrimBoolean:
220 field->SetBoolean<transaction_active>(obj, value.GetZ());
221 break;
222 case Primitive::kPrimByte:
223 field->SetByte<transaction_active>(obj, value.GetB());
224 break;
225 case Primitive::kPrimChar:
226 field->SetChar<transaction_active>(obj, value.GetC());
227 break;
228 case Primitive::kPrimShort:
229 field->SetShort<transaction_active>(obj, value.GetS());
230 break;
231 case Primitive::kPrimInt:
232 field->SetInt<transaction_active>(obj, value.GetI());
233 break;
234 case Primitive::kPrimLong:
235 field->SetLong<transaction_active>(obj, value.GetJ());
236 break;
237 case Primitive::kPrimNot: {
238 ObjPtr<mirror::Object> reg = value.GetL();
239 if (reg != nullptr && !shadow_frame.GetMethod()->SkipAccessChecks()) {
240 // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
241 // object in the destructor.
242 ObjPtr<mirror::Class> field_class;
243 {
244 StackHandleScope<2> hs(self);
245 StackArtFieldHandleScope<1> rhs(self);
246 HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®));
247 HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
248 ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
249 field_class = field->ResolveType();
250 }
251 // ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577).
252 if (UNLIKELY(field_class.IsNull())) {
253 Thread::Current()->AssertPendingException();
254 return false;
255 }
256 if (UNLIKELY(!reg->VerifierInstanceOf(field_class))) {
257 // This should never happen.
258 std::string temp1, temp2, temp3;
259 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
260 "Put '%s' that is not instance of field '%s' in '%s'",
261 reg->GetClass()->GetDescriptor(&temp1),
262 field_class->GetDescriptor(&temp2),
263 field->GetDeclaringClass()->GetDescriptor(&temp3));
264 return false;
265 }
266 }
267 field->SetObj<transaction_active>(obj, reg);
268 break;
269 }
270 case Primitive::kPrimVoid: {
271 LOG(FATAL) << "Unreachable " << field_type;
272 break;
273 }
274 }
275 if (transaction_active) {
276 if (UNLIKELY(self->IsExceptionPending())) {
277 return false;
278 }
279 }
280 return true;
281 }
282
283 } // namespace art
284
285 #endif // ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
286