blob: c29043e7c6835fa3a891dcef2b4a8172bd40959c [file] [log] [blame]
Orion Hodson811bd5f2016-12-07 11:35:37 +00001/*
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
Andreas Gampe0a0935f2017-10-23 11:59:49 -070020#include "android-base/logging.h"
Orion Hodson811bd5f2016-12-07 11:35:37 +000021#include "art_field.h"
22#include "art_method.h"
Andreas Gampe0a0935f2017-10-23 11:59:49 -070023#include "base/macros.h"
24#include "base/mutex.h"
Orion Hodson811bd5f2016-12-07 11:35:37 +000025#include "class_linker.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/code_item_accessors.h"
David Sehr67bf42e2018-02-26 16:43:04 -080027#include "dex/primitive.h"
Andreas Gampe0a0935f2017-10-23 11:59:49 -070028#include "handle_scope-inl.h"
29#include "instrumentation.h"
30#include "interpreter/shadow_frame.h"
Orion Hodson811bd5f2016-12-07 11:35:37 +000031#include "interpreter/unstarted_runtime.h"
Andreas Gampec5b75642018-05-16 15:12:11 -070032#include "jvalue-inl.h"
Andreas Gampe0a0935f2017-10-23 11:59:49 -070033#include "mirror/class.h"
34#include "mirror/object.h"
35#include "obj_ptr-inl.h"
Orion Hodson811bd5f2016-12-07 11:35:37 +000036#include "runtime.h"
37#include "stack.h"
38#include "thread.h"
39
40namespace art {
41
42namespace interpreter {
43 void ArtInterpreterToInterpreterBridge(Thread* self,
44 const DexFile::CodeItem* code_item,
45 ShadowFrame* shadow_frame,
46 JValue* result)
47 REQUIRES_SHARED(Locks::mutator_lock_);
48
49 void ArtInterpreterToCompiledCodeBridge(Thread* self,
50 ArtMethod* caller,
Orion Hodson811bd5f2016-12-07 11:35:37 +000051 ShadowFrame* shadow_frame,
Jeff Hao5ea84132017-05-05 16:59:29 -070052 uint16_t arg_offset,
Orion Hodson811bd5f2016-12-07 11:35:37 +000053 JValue* result);
54} // namespace interpreter
55
56inline void PerformCall(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -080057 const CodeItemDataAccessor& accessor,
Orion Hodson811bd5f2016-12-07 11:35:37 +000058 ArtMethod* caller_method,
59 const size_t first_dest_reg,
60 ShadowFrame* callee_frame,
Jeff Hao5ea84132017-05-05 16:59:29 -070061 JValue* result,
62 bool use_interpreter_entrypoint)
Orion Hodson811bd5f2016-12-07 11:35:37 +000063 REQUIRES_SHARED(Locks::mutator_lock_) {
64 if (LIKELY(Runtime::Current()->IsStarted())) {
Jeff Hao5ea84132017-05-05 16:59:29 -070065 if (use_interpreter_entrypoint) {
Mathieu Chartier808c7a52017-12-15 11:19:33 -080066 interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result);
Orion Hodson811bd5f2016-12-07 11:35:37 +000067 } else {
68 interpreter::ArtInterpreterToCompiledCodeBridge(
Jeff Hao5ea84132017-05-05 16:59:29 -070069 self, caller_method, callee_frame, first_dest_reg, result);
Orion Hodson811bd5f2016-12-07 11:35:37 +000070 }
71 } else {
Mathieu Chartier808c7a52017-12-15 11:19:33 -080072 interpreter::UnstartedRuntime::Invoke(self, accessor, callee_frame, result, first_dest_reg);
Orion Hodson811bd5f2016-12-07 11:35:37 +000073 }
74}
75
Andreas Gampe580667b2017-10-23 11:20:39 -070076template <typename T>
77inline void DCheckStaticState(Thread* self, T* entity) REQUIRES_SHARED(Locks::mutator_lock_) {
78 if (kIsDebugBuild) {
79 ObjPtr<mirror::Class> klass = entity->GetDeclaringClass();
80 if (entity->IsStatic()) {
81 klass->AssertInitializedOrInitializingInThread(self);
82 } else {
83 CHECK(klass->IsInitializing() || klass->IsErroneousResolved());
84 }
85 }
86}
87
Orion Hodson811bd5f2016-12-07 11:35:37 +000088template<Primitive::Type field_type>
Alex Light084fa372017-06-16 08:58:34 -070089static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
Orion Hodson811bd5f2016-12-07 11:35:37 +000090 const ShadowFrame& shadow_frame,
91 ObjPtr<mirror::Object> obj,
92 ArtField* field,
93 JValue* result)
94 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe580667b2017-10-23 11:20:39 -070095 DCheckStaticState(self, field);
Orion Hodson811bd5f2016-12-07 11:35:37 +000096
97 // Report this field access to instrumentation if needed.
98 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
99 if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
100 StackHandleScope<1> hs(self);
101 // Wrap in handle wrapper in case the listener does thread suspension.
102 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
103 ObjPtr<mirror::Object> this_object;
104 if (!field->IsStatic()) {
105 this_object = obj;
106 }
107 instrumentation->FieldReadEvent(self,
108 this_object.Ptr(),
109 shadow_frame.GetMethod(),
110 shadow_frame.GetDexPC(),
111 field);
Alex Light084fa372017-06-16 08:58:34 -0700112 if (UNLIKELY(self->IsExceptionPending())) {
113 return false;
114 }
Orion Hodson811bd5f2016-12-07 11:35:37 +0000115 }
116
117 switch (field_type) {
118 case Primitive::kPrimBoolean:
119 result->SetZ(field->GetBoolean(obj));
120 break;
121 case Primitive::kPrimByte:
122 result->SetB(field->GetByte(obj));
123 break;
124 case Primitive::kPrimChar:
125 result->SetC(field->GetChar(obj));
126 break;
127 case Primitive::kPrimShort:
128 result->SetS(field->GetShort(obj));
129 break;
130 case Primitive::kPrimInt:
131 result->SetI(field->GetInt(obj));
132 break;
133 case Primitive::kPrimLong:
134 result->SetJ(field->GetLong(obj));
135 break;
136 case Primitive::kPrimNot:
137 result->SetL(field->GetObject(obj));
138 break;
139 case Primitive::kPrimVoid:
140 LOG(FATAL) << "Unreachable " << field_type;
141 break;
142 }
Alex Light084fa372017-06-16 08:58:34 -0700143 return true;
Orion Hodson811bd5f2016-12-07 11:35:37 +0000144}
145
146template<Primitive::Type field_type, bool do_assignability_check, bool transaction_active>
147ALWAYS_INLINE bool DoFieldPutCommon(Thread* self,
148 const ShadowFrame& shadow_frame,
149 ObjPtr<mirror::Object> obj,
150 ArtField* field,
Alex Light084fa372017-06-16 08:58:34 -0700151 JValue& value)
Orion Hodson811bd5f2016-12-07 11:35:37 +0000152 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe580667b2017-10-23 11:20:39 -0700153 DCheckStaticState(self, field);
Orion Hodson811bd5f2016-12-07 11:35:37 +0000154
155 // Report this field access to instrumentation if needed. Since we only have the offset of
156 // the field from the base of the object, we need to look for it first.
157 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
158 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
Alex Light084fa372017-06-16 08:58:34 -0700159 StackHandleScope<2> hs(self);
160 // Save this and return value (if needed) in case the instrumentation causes a suspend.
Orion Hodson811bd5f2016-12-07 11:35:37 +0000161 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
162 ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
Alex Light084fa372017-06-16 08:58:34 -0700163 mirror::Object* fake_root = nullptr;
164 HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
165 field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root));
166 instrumentation->FieldWriteEvent(self,
167 this_object.Ptr(),
Orion Hodson811bd5f2016-12-07 11:35:37 +0000168 shadow_frame.GetMethod(),
169 shadow_frame.GetDexPC(),
170 field,
171 value);
Alex Light084fa372017-06-16 08:58:34 -0700172 if (UNLIKELY(self->IsExceptionPending())) {
173 return false;
174 }
Orion Hodson811bd5f2016-12-07 11:35:37 +0000175 }
176
177 switch (field_type) {
178 case Primitive::kPrimBoolean:
179 field->SetBoolean<transaction_active>(obj, value.GetZ());
180 break;
181 case Primitive::kPrimByte:
182 field->SetByte<transaction_active>(obj, value.GetB());
183 break;
184 case Primitive::kPrimChar:
185 field->SetChar<transaction_active>(obj, value.GetC());
186 break;
187 case Primitive::kPrimShort:
188 field->SetShort<transaction_active>(obj, value.GetS());
189 break;
190 case Primitive::kPrimInt:
191 field->SetInt<transaction_active>(obj, value.GetI());
192 break;
193 case Primitive::kPrimLong:
194 field->SetLong<transaction_active>(obj, value.GetJ());
195 break;
196 case Primitive::kPrimNot: {
197 ObjPtr<mirror::Object> reg = value.GetL();
198 if (do_assignability_check && reg != nullptr) {
199 // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
200 // object in the destructor.
201 ObjPtr<mirror::Class> field_class;
202 {
203 StackHandleScope<2> hs(self);
204 HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(&reg));
205 HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000206 field_class = field->ResolveType();
Orion Hodson811bd5f2016-12-07 11:35:37 +0000207 }
Orion Hodson9fa1bab2018-05-23 15:21:35 +0100208 // ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577).
209 if (UNLIKELY(field_class.IsNull())) {
210 Thread::Current()->AssertPendingException();
211 return false;
212 }
213 if (UNLIKELY(!reg->VerifierInstanceOf(field_class.Ptr()))) {
Orion Hodson811bd5f2016-12-07 11:35:37 +0000214 // This should never happen.
215 std::string temp1, temp2, temp3;
216 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
217 "Put '%s' that is not instance of field '%s' in '%s'",
218 reg->GetClass()->GetDescriptor(&temp1),
219 field_class->GetDescriptor(&temp2),
220 field->GetDeclaringClass()->GetDescriptor(&temp3));
221 return false;
222 }
223 }
224 field->SetObj<transaction_active>(obj, reg);
225 break;
226 }
227 case Primitive::kPrimVoid: {
228 LOG(FATAL) << "Unreachable " << field_type;
229 break;
230 }
231 }
Chang Xingbd208d82017-07-12 14:53:17 -0700232 if (transaction_active) {
233 if (UNLIKELY(self->IsExceptionPending())) {
234 return false;
235 }
236 }
Orion Hodson811bd5f2016-12-07 11:35:37 +0000237 return true;
238}
239
240} // namespace art
241
242#endif // ART_RUNTIME_COMMON_DEX_OPERATIONS_H_