• 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 #include "interpreter_common.h"
18 
19 #include <cmath>
20 
21 #include "base/enums.h"
22 #include "debugger.h"
23 #include "entrypoints/runtime_asm_entrypoints.h"
24 #include "jit/jit.h"
25 #include "jvalue.h"
26 #include "method_handles.h"
27 #include "method_handles-inl.h"
28 #include "mirror/array-inl.h"
29 #include "mirror/class.h"
30 #include "mirror/emulated_stack_frame.h"
31 #include "mirror/method_handle_impl-inl.h"
32 #include "reflection.h"
33 #include "reflection-inl.h"
34 #include "stack.h"
35 #include "thread-inl.h"
36 #include "well_known_classes.h"
37 
38 namespace art {
39 namespace interpreter {
40 
ThrowNullPointerExceptionFromInterpreter()41 void ThrowNullPointerExceptionFromInterpreter() {
42   ThrowNullPointerExceptionFromDexPC();
43 }
44 
45 template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check>
DoFieldGet(Thread * self,ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data)46 bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
47                 uint16_t inst_data) {
48   const bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
49   const uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
50   ArtField* f =
51       FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self,
52                                                     Primitive::ComponentSize(field_type));
53   if (UNLIKELY(f == nullptr)) {
54     CHECK(self->IsExceptionPending());
55     return false;
56   }
57   ObjPtr<mirror::Object> obj;
58   if (is_static) {
59     obj = f->GetDeclaringClass();
60   } else {
61     obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
62     if (UNLIKELY(obj == nullptr)) {
63       ThrowNullPointerExceptionForFieldAccess(f, true);
64       return false;
65     }
66   }
67 
68   JValue result;
69   if (UNLIKELY(!DoFieldGetCommon<field_type>(self, shadow_frame, obj, f, &result))) {
70     // Instrumentation threw an error!
71     CHECK(self->IsExceptionPending());
72     return false;
73   }
74   uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
75   switch (field_type) {
76     case Primitive::kPrimBoolean:
77       shadow_frame.SetVReg(vregA, result.GetZ());
78       break;
79     case Primitive::kPrimByte:
80       shadow_frame.SetVReg(vregA, result.GetB());
81       break;
82     case Primitive::kPrimChar:
83       shadow_frame.SetVReg(vregA, result.GetC());
84       break;
85     case Primitive::kPrimShort:
86       shadow_frame.SetVReg(vregA, result.GetS());
87       break;
88     case Primitive::kPrimInt:
89       shadow_frame.SetVReg(vregA, result.GetI());
90       break;
91     case Primitive::kPrimLong:
92       shadow_frame.SetVRegLong(vregA, result.GetJ());
93       break;
94     case Primitive::kPrimNot:
95       shadow_frame.SetVRegReference(vregA, result.GetL());
96       break;
97     default:
98       LOG(FATAL) << "Unreachable: " << field_type;
99       UNREACHABLE();
100   }
101   return true;
102 }
103 
104 // Explicitly instantiate all DoFieldGet functions.
105 #define EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, _do_check) \
106   template bool DoFieldGet<_find_type, _field_type, _do_check>(Thread* self, \
107                                                                ShadowFrame& shadow_frame, \
108                                                                const Instruction* inst, \
109                                                                uint16_t inst_data)
110 
111 #define EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(_find_type, _field_type)  \
112     EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, false);  \
113     EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, true);
114 
115 // iget-XXX
EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead,Primitive::kPrimBoolean)116 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimBoolean)
117 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimByte)
118 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimChar)
119 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimShort)
120 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimInt)
121 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimLong)
122 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstanceObjectRead, Primitive::kPrimNot)
123 
124 // sget-XXX
125 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimBoolean)
126 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimByte)
127 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimChar)
128 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimShort)
129 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimInt)
130 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimLong)
131 EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticObjectRead, Primitive::kPrimNot)
132 
133 #undef EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL
134 #undef EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL
135 
136 // Handles iget-quick, iget-wide-quick and iget-object-quick instructions.
137 // Returns true on success, otherwise throws an exception and returns false.
138 template<Primitive::Type field_type>
139 bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) {
140   ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
141   if (UNLIKELY(obj == nullptr)) {
142     // We lost the reference to the field index so we cannot get a more
143     // precised exception message.
144     ThrowNullPointerExceptionFromDexPC();
145     return false;
146   }
147   MemberOffset field_offset(inst->VRegC_22c());
148   // Report this field access to instrumentation if needed. Since we only have the offset of
149   // the field from the base of the object, we need to look for it first.
150   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
151   if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
152     ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(),
153                                                         field_offset.Uint32Value());
154     DCHECK(f != nullptr);
155     DCHECK(!f->IsStatic());
156     Thread* self = Thread::Current();
157     StackHandleScope<1> hs(self);
158     // Save obj in case the instrumentation event has thread suspension.
159     HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&obj);
160     instrumentation->FieldReadEvent(self,
161                                     obj.Ptr(),
162                                     shadow_frame.GetMethod(),
163                                     shadow_frame.GetDexPC(),
164                                     f);
165     if (UNLIKELY(self->IsExceptionPending())) {
166       return false;
167     }
168   }
169   // Note: iget-x-quick instructions are only for non-volatile fields.
170   const uint32_t vregA = inst->VRegA_22c(inst_data);
171   switch (field_type) {
172     case Primitive::kPrimInt:
173       shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetField32(field_offset)));
174       break;
175     case Primitive::kPrimBoolean:
176       shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldBoolean(field_offset)));
177       break;
178     case Primitive::kPrimByte:
179       shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldByte(field_offset)));
180       break;
181     case Primitive::kPrimChar:
182       shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldChar(field_offset)));
183       break;
184     case Primitive::kPrimShort:
185       shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldShort(field_offset)));
186       break;
187     case Primitive::kPrimLong:
188       shadow_frame.SetVRegLong(vregA, static_cast<int64_t>(obj->GetField64(field_offset)));
189       break;
190     case Primitive::kPrimNot:
191       shadow_frame.SetVRegReference(vregA, obj->GetFieldObject<mirror::Object>(field_offset));
192       break;
193     default:
194       LOG(FATAL) << "Unreachable: " << field_type;
195       UNREACHABLE();
196   }
197   return true;
198 }
199 
200 // Explicitly instantiate all DoIGetQuick functions.
201 #define EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(_field_type) \
202   template bool DoIGetQuick<_field_type>(ShadowFrame& shadow_frame, const Instruction* inst, \
203                                          uint16_t inst_data)
204 
205 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimInt);      // iget-quick.
206 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimBoolean);  // iget-boolean-quick.
207 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimByte);     // iget-byte-quick.
208 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimChar);     // iget-char-quick.
209 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimShort);    // iget-short-quick.
210 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimLong);     // iget-wide-quick.
211 EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimNot);      // iget-object-quick.
212 #undef EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL
213 
214 template<Primitive::Type field_type>
GetFieldValue(const ShadowFrame & shadow_frame,uint32_t vreg)215 static JValue GetFieldValue(const ShadowFrame& shadow_frame, uint32_t vreg)
216     REQUIRES_SHARED(Locks::mutator_lock_) {
217   JValue field_value;
218   switch (field_type) {
219     case Primitive::kPrimBoolean:
220       field_value.SetZ(static_cast<uint8_t>(shadow_frame.GetVReg(vreg)));
221       break;
222     case Primitive::kPrimByte:
223       field_value.SetB(static_cast<int8_t>(shadow_frame.GetVReg(vreg)));
224       break;
225     case Primitive::kPrimChar:
226       field_value.SetC(static_cast<uint16_t>(shadow_frame.GetVReg(vreg)));
227       break;
228     case Primitive::kPrimShort:
229       field_value.SetS(static_cast<int16_t>(shadow_frame.GetVReg(vreg)));
230       break;
231     case Primitive::kPrimInt:
232       field_value.SetI(shadow_frame.GetVReg(vreg));
233       break;
234     case Primitive::kPrimLong:
235       field_value.SetJ(shadow_frame.GetVRegLong(vreg));
236       break;
237     case Primitive::kPrimNot:
238       field_value.SetL(shadow_frame.GetVRegReference(vreg));
239       break;
240     default:
241       LOG(FATAL) << "Unreachable: " << field_type;
242       UNREACHABLE();
243   }
244   return field_value;
245 }
246 
247 template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check,
248          bool transaction_active>
DoFieldPut(Thread * self,const ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data)249 bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction* inst,
250                 uint16_t inst_data) {
251   const bool do_assignability_check = do_access_check;
252   bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
253   uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
254   ArtField* f =
255       FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self,
256                                                     Primitive::ComponentSize(field_type));
257   if (UNLIKELY(f == nullptr)) {
258     CHECK(self->IsExceptionPending());
259     return false;
260   }
261   ObjPtr<mirror::Object> obj;
262   if (is_static) {
263     obj = f->GetDeclaringClass();
264   } else {
265     obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
266     if (UNLIKELY(obj == nullptr)) {
267       ThrowNullPointerExceptionForFieldAccess(f, false);
268       return false;
269     }
270   }
271 
272   uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
273   JValue value = GetFieldValue<field_type>(shadow_frame, vregA);
274   return DoFieldPutCommon<field_type, do_assignability_check, transaction_active>(self,
275                                                                                   shadow_frame,
276                                                                                   obj,
277                                                                                   f,
278                                                                                   value);
279 }
280 
281 // Explicitly instantiate all DoFieldPut functions.
282 #define EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, _do_check, _transaction_active) \
283   template bool DoFieldPut<_find_type, _field_type, _do_check, _transaction_active>(Thread* self, \
284       const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data)
285 
286 #define EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(_find_type, _field_type)  \
287     EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, false, false);  \
288     EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, true, false);  \
289     EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, false, true);  \
290     EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, true, true);
291 
292 // iput-XXX
EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite,Primitive::kPrimBoolean)293 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimBoolean)
294 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimByte)
295 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimChar)
296 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimShort)
297 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimInt)
298 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimLong)
299 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstanceObjectWrite, Primitive::kPrimNot)
300 
301 // sput-XXX
302 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimBoolean)
303 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimByte)
304 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimChar)
305 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimShort)
306 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimInt)
307 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimLong)
308 EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticObjectWrite, Primitive::kPrimNot)
309 
310 #undef EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL
311 #undef EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL
312 
313 template<Primitive::Type field_type, bool transaction_active>
314 bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) {
315   ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
316   if (UNLIKELY(obj == nullptr)) {
317     // We lost the reference to the field index so we cannot get a more
318     // precised exception message.
319     ThrowNullPointerExceptionFromDexPC();
320     return false;
321   }
322   MemberOffset field_offset(inst->VRegC_22c());
323   const uint32_t vregA = inst->VRegA_22c(inst_data);
324   // Report this field modification to instrumentation if needed. Since we only have the offset of
325   // the field from the base of the object, we need to look for it first.
326   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
327   if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
328     ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(),
329                                                         field_offset.Uint32Value());
330     DCHECK(f != nullptr);
331     DCHECK(!f->IsStatic());
332     JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA);
333     Thread* self = Thread::Current();
334     StackHandleScope<2> hs(self);
335     // Save obj in case the instrumentation event has thread suspension.
336     HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&obj);
337     mirror::Object* fake_root = nullptr;
338     HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
339         field_type == Primitive::kPrimNot ? field_value.GetGCRoot() : &fake_root));
340     instrumentation->FieldWriteEvent(self,
341                                      obj.Ptr(),
342                                      shadow_frame.GetMethod(),
343                                      shadow_frame.GetDexPC(),
344                                      f,
345                                      field_value);
346     if (UNLIKELY(self->IsExceptionPending())) {
347       return false;
348     }
349   }
350   // Note: iput-x-quick instructions are only for non-volatile fields.
351   switch (field_type) {
352     case Primitive::kPrimBoolean:
353       obj->SetFieldBoolean<transaction_active>(field_offset, shadow_frame.GetVReg(vregA));
354       break;
355     case Primitive::kPrimByte:
356       obj->SetFieldByte<transaction_active>(field_offset, shadow_frame.GetVReg(vregA));
357       break;
358     case Primitive::kPrimChar:
359       obj->SetFieldChar<transaction_active>(field_offset, shadow_frame.GetVReg(vregA));
360       break;
361     case Primitive::kPrimShort:
362       obj->SetFieldShort<transaction_active>(field_offset, shadow_frame.GetVReg(vregA));
363       break;
364     case Primitive::kPrimInt:
365       obj->SetField32<transaction_active>(field_offset, shadow_frame.GetVReg(vregA));
366       break;
367     case Primitive::kPrimLong:
368       obj->SetField64<transaction_active>(field_offset, shadow_frame.GetVRegLong(vregA));
369       break;
370     case Primitive::kPrimNot:
371       obj->SetFieldObject<transaction_active>(field_offset, shadow_frame.GetVRegReference(vregA));
372       break;
373     default:
374       LOG(FATAL) << "Unreachable: " << field_type;
375       UNREACHABLE();
376   }
377   return true;
378 }
379 
380 // Explicitly instantiate all DoIPutQuick functions.
381 #define EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, _transaction_active) \
382   template bool DoIPutQuick<_field_type, _transaction_active>(const ShadowFrame& shadow_frame, \
383                                                               const Instruction* inst, \
384                                                               uint16_t inst_data)
385 
386 #define EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(_field_type)   \
387   EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, false);     \
388   EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, true);
389 
390 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimInt)      // iput-quick.
EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimBoolean)391 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimBoolean)  // iput-boolean-quick.
392 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimByte)     // iput-byte-quick.
393 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimChar)     // iput-char-quick.
394 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimShort)    // iput-short-quick.
395 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimLong)     // iput-wide-quick.
396 EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimNot)      // iput-object-quick.
397 #undef EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL
398 #undef EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL
399 
400 // We accept a null Instrumentation* meaning we must not report anything to the instrumentation.
401 uint32_t FindNextInstructionFollowingException(
402     Thread* self, ShadowFrame& shadow_frame, uint32_t dex_pc,
403     const instrumentation::Instrumentation* instrumentation) {
404   self->VerifyStack();
405   StackHandleScope<2> hs(self);
406   Handle<mirror::Throwable> exception(hs.NewHandle(self->GetException()));
407   if (instrumentation != nullptr && instrumentation->HasExceptionCaughtListeners()
408       && self->IsExceptionThrownByCurrentMethod(exception.Get())) {
409     instrumentation->ExceptionCaughtEvent(self, exception.Get());
410   }
411   bool clear_exception = false;
412   uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock(
413       hs.NewHandle(exception->GetClass()), dex_pc, &clear_exception);
414   if (found_dex_pc == DexFile::kDexNoIndex && instrumentation != nullptr) {
415     // Exception is not caught by the current method. We will unwind to the
416     // caller. Notify any instrumentation listener.
417     instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(),
418                                        shadow_frame.GetMethod(), dex_pc);
419   } else {
420     // Exception is caught in the current method. We will jump to the found_dex_pc.
421     if (clear_exception) {
422       self->ClearException();
423     }
424   }
425   return found_dex_pc;
426 }
427 
UnexpectedOpcode(const Instruction * inst,const ShadowFrame & shadow_frame)428 void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame) {
429   LOG(FATAL) << "Unexpected instruction: "
430              << inst->DumpString(shadow_frame.GetMethod()->GetDexFile());
431   UNREACHABLE();
432 }
433 
AbortTransactionF(Thread * self,const char * fmt,...)434 void AbortTransactionF(Thread* self, const char* fmt, ...) {
435   va_list args;
436   va_start(args, fmt);
437   AbortTransactionV(self, fmt, args);
438   va_end(args);
439 }
440 
AbortTransactionV(Thread * self,const char * fmt,va_list args)441 void AbortTransactionV(Thread* self, const char* fmt, va_list args) {
442   CHECK(Runtime::Current()->IsActiveTransaction());
443   // Constructs abort message.
444   std::string abort_msg;
445   android::base::StringAppendV(&abort_msg, fmt, args);
446   // Throws an exception so we can abort the transaction and rollback every change.
447   Runtime::Current()->AbortTransactionAndThrowAbortError(self, abort_msg);
448 }
449 
450 // START DECLARATIONS :
451 //
452 // These additional declarations are required because clang complains
453 // about ALWAYS_INLINE (-Werror, -Wgcc-compat) in definitions.
454 //
455 
456 template <bool is_range, bool do_assignability_check>
457 static ALWAYS_INLINE bool DoCallCommon(ArtMethod* called_method,
458                                        Thread* self,
459                                        ShadowFrame& shadow_frame,
460                                        JValue* result,
461                                        uint16_t number_of_inputs,
462                                        uint32_t (&arg)[Instruction::kMaxVarArgRegs],
463                                        uint32_t vregC) REQUIRES_SHARED(Locks::mutator_lock_);
464 
465 template <bool is_range>
466 ALWAYS_INLINE void CopyRegisters(ShadowFrame& caller_frame,
467                                  ShadowFrame* callee_frame,
468                                  const uint32_t (&arg)[Instruction::kMaxVarArgRegs],
469                                  const size_t first_src_reg,
470                                  const size_t first_dest_reg,
471                                  const size_t num_regs) REQUIRES_SHARED(Locks::mutator_lock_);
472 
473 // END DECLARATIONS.
474 
ArtInterpreterToCompiledCodeBridge(Thread * self,ArtMethod * caller,ShadowFrame * shadow_frame,uint16_t arg_offset,JValue * result)475 void ArtInterpreterToCompiledCodeBridge(Thread* self,
476                                         ArtMethod* caller,
477                                         ShadowFrame* shadow_frame,
478                                         uint16_t arg_offset,
479                                         JValue* result)
480     REQUIRES_SHARED(Locks::mutator_lock_) {
481   ArtMethod* method = shadow_frame->GetMethod();
482   // Ensure static methods are initialized.
483   if (method->IsStatic()) {
484     ObjPtr<mirror::Class> declaringClass = method->GetDeclaringClass();
485     if (UNLIKELY(!declaringClass->IsInitialized())) {
486       self->PushShadowFrame(shadow_frame);
487       StackHandleScope<1> hs(self);
488       Handle<mirror::Class> h_class(hs.NewHandle(declaringClass));
489       if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_class, true,
490                                                                             true))) {
491         self->PopShadowFrame();
492         DCHECK(self->IsExceptionPending());
493         return;
494       }
495       self->PopShadowFrame();
496       CHECK(h_class->IsInitializing());
497       // Reload from shadow frame in case the method moved, this is faster than adding a handle.
498       method = shadow_frame->GetMethod();
499     }
500   }
501   // Basic checks for the arg_offset. If there's no code item, the arg_offset must be 0. Otherwise,
502   // check that the arg_offset isn't greater than the number of registers. A stronger check is
503   // difficult since the frame may contain space for all the registers in the method, or only enough
504   // space for the arguments.
505   if (kIsDebugBuild) {
506     if (method->GetCodeItem() == nullptr) {
507       DCHECK_EQ(0u, arg_offset) << method->PrettyMethod();
508     } else {
509       DCHECK_LE(arg_offset, shadow_frame->NumberOfVRegs());
510     }
511   }
512   jit::Jit* jit = Runtime::Current()->GetJit();
513   if (jit != nullptr && caller != nullptr) {
514     jit->NotifyInterpreterToCompiledCodeTransition(self, caller);
515   }
516   method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset),
517                  (shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t),
518                  result, method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty());
519 }
520 
SetStringInitValueToAllAliases(ShadowFrame * shadow_frame,uint16_t this_obj_vreg,JValue result)521 void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame,
522                                     uint16_t this_obj_vreg,
523                                     JValue result)
524     REQUIRES_SHARED(Locks::mutator_lock_) {
525   ObjPtr<mirror::Object> existing = shadow_frame->GetVRegReference(this_obj_vreg);
526   if (existing == nullptr) {
527     // If it's null, we come from compiled code that was deoptimized. Nothing to do,
528     // as the compiler verified there was no alias.
529     // Set the new string result of the StringFactory.
530     shadow_frame->SetVRegReference(this_obj_vreg, result.GetL());
531     return;
532   }
533   // Set the string init result into all aliases.
534   for (uint32_t i = 0, e = shadow_frame->NumberOfVRegs(); i < e; ++i) {
535     if (shadow_frame->GetVRegReference(i) == existing) {
536       DCHECK_EQ(shadow_frame->GetVRegReference(i),
537                 reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
538       shadow_frame->SetVRegReference(i, result.GetL());
539       DCHECK_EQ(shadow_frame->GetVRegReference(i),
540                 reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
541     }
542   }
543 }
544 
545 template<bool is_range>
DoInvokePolymorphic(Thread * self,ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result)546 bool DoInvokePolymorphic(Thread* self,
547                          ShadowFrame& shadow_frame,
548                          const Instruction* inst,
549                          uint16_t inst_data,
550                          JValue* result)
551     REQUIRES_SHARED(Locks::mutator_lock_) {
552   // Invoke-polymorphic instructions always take a receiver. i.e, they are never static.
553   const uint32_t vRegC = (is_range) ? inst->VRegC_4rcc() : inst->VRegC_45cc();
554   const int invoke_method_idx = (is_range) ? inst->VRegB_4rcc() : inst->VRegB_45cc();
555 
556   // Initialize |result| to 0 as this is the default return value for
557   // polymorphic invocations of method handle types with void return
558   // and provides sane return result in error cases.
559   result->SetJ(0);
560 
561   // The invoke_method_idx here is the name of the signature polymorphic method that
562   // was symbolically invoked in bytecode (say MethodHandle.invoke or MethodHandle.invokeExact)
563   // and not the method that we'll dispatch to in the end.
564   StackHandleScope<5> hs(self);
565   Handle<mirror::MethodHandle> method_handle(hs.NewHandle(
566       ObjPtr<mirror::MethodHandle>::DownCast(
567           MakeObjPtr(shadow_frame.GetVRegReference(vRegC)))));
568   if (UNLIKELY(method_handle == nullptr)) {
569     // Note that the invoke type is kVirtual here because a call to a signature
570     // polymorphic method is shaped like a virtual call at the bytecode level.
571     ThrowNullPointerExceptionForMethodAccess(invoke_method_idx, InvokeType::kVirtual);
572     return false;
573   }
574 
575   // The vRegH value gives the index of the proto_id associated with this
576   // signature polymorphic call site.
577   const uint32_t callsite_proto_id = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc();
578 
579   // Call through to the classlinker and ask it to resolve the static type associated
580   // with the callsite. This information is stored in the dex cache so it's
581   // guaranteed to be fast after the first resolution.
582   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
583   Handle<mirror::Class> caller_class(hs.NewHandle(shadow_frame.GetMethod()->GetDeclaringClass()));
584   Handle<mirror::MethodType> callsite_type(hs.NewHandle(class_linker->ResolveMethodType(
585       caller_class->GetDexFile(), callsite_proto_id,
586       hs.NewHandle<mirror::DexCache>(caller_class->GetDexCache()),
587       hs.NewHandle<mirror::ClassLoader>(caller_class->GetClassLoader()))));
588 
589   // This implies we couldn't resolve one or more types in this method handle.
590   if (UNLIKELY(callsite_type == nullptr)) {
591     CHECK(self->IsExceptionPending());
592     return false;
593   }
594 
595   ArtMethod* invoke_method =
596       class_linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
597           self, invoke_method_idx, shadow_frame.GetMethod(), kVirtual);
598 
599   // There is a common dispatch method for method handles that takes
600   // arguments either from a range or an array of arguments depending
601   // on whether the DEX instruction is invoke-polymorphic/range or
602   // invoke-polymorphic. The array here is for the latter.
603   uint32_t args[Instruction::kMaxVarArgRegs] = {};
604   if (is_range) {
605     // VRegC is the register holding the method handle. Arguments passed
606     // to the method handle's target do not include the method handle.
607     uint32_t first_arg = inst->VRegC_4rcc() + 1;
608     return DoInvokePolymorphic<is_range>(self,
609                                          invoke_method,
610                                          shadow_frame,
611                                          method_handle,
612                                          callsite_type,
613                                          args /* unused */,
614                                          first_arg,
615                                          result);
616   } else {
617     // Get the register arguments for the invoke.
618     inst->GetVarArgs(args, inst_data);
619     // Drop the first register which is the method handle performing the invoke.
620     memmove(args, args + 1, sizeof(args[0]) * (Instruction::kMaxVarArgRegs - 1));
621     args[Instruction::kMaxVarArgRegs - 1] = 0;
622     return DoInvokePolymorphic<is_range>(self,
623                                          invoke_method,
624                                          shadow_frame,
625                                          method_handle,
626                                          callsite_type,
627                                          args,
628                                          args[0],
629                                          result);
630   }
631 }
632 
InvokeBootstrapMethod(Thread * self,ShadowFrame & shadow_frame,uint32_t call_site_idx)633 static ObjPtr<mirror::CallSite> InvokeBootstrapMethod(Thread* self,
634                                                       ShadowFrame& shadow_frame,
635                                                       uint32_t call_site_idx)
636     REQUIRES_SHARED(Locks::mutator_lock_) {
637   ArtMethod* referrer = shadow_frame.GetMethod();
638   const DexFile* dex_file = referrer->GetDexFile();
639   const DexFile::CallSiteIdItem& csi = dex_file->GetCallSiteId(call_site_idx);
640 
641   StackHandleScope<10> hs(self);
642   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader()));
643   Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
644 
645   CallSiteArrayValueIterator it(*dex_file, csi);
646   uint32_t method_handle_idx = static_cast<uint32_t>(it.GetJavaValue().i);
647   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
648   Handle<mirror::MethodHandle>
649       bootstrap(hs.NewHandle(class_linker->ResolveMethodHandle(method_handle_idx, referrer)));
650   if (bootstrap.IsNull()) {
651     DCHECK(self->IsExceptionPending());
652     return nullptr;
653   }
654   Handle<mirror::MethodType> bootstrap_method_type = hs.NewHandle(bootstrap->GetMethodType());
655   it.Next();
656 
657   DCHECK_EQ(static_cast<size_t>(bootstrap->GetMethodType()->GetPTypes()->GetLength()), it.Size());
658   const size_t num_bootstrap_vregs = bootstrap->GetMethodType()->NumberOfVRegs();
659 
660   // Set-up a shadow frame for invoking the bootstrap method handle.
661   ShadowFrameAllocaUniquePtr bootstrap_frame =
662       CREATE_SHADOW_FRAME(num_bootstrap_vregs, nullptr, referrer, shadow_frame.GetDexPC());
663   ScopedStackedShadowFramePusher pusher(
664       self, bootstrap_frame.get(), StackedShadowFrameType::kShadowFrameUnderConstruction);
665   size_t vreg = 0;
666 
667   // The first parameter is a MethodHandles lookup instance.
668   {
669     Handle<mirror::Class> lookup_class(hs.NewHandle(bootstrap->GetTargetClass()));
670     ObjPtr<mirror::MethodHandlesLookup> lookup =
671         mirror::MethodHandlesLookup::Create(self, lookup_class);
672     if (lookup.IsNull()) {
673       DCHECK(self->IsExceptionPending());
674       return nullptr;
675     }
676     bootstrap_frame->SetVRegReference(vreg++, lookup.Ptr());
677   }
678 
679   // The second parameter is the name to lookup.
680   {
681     dex::StringIndex name_idx(static_cast<uint32_t>(it.GetJavaValue().i));
682     ObjPtr<mirror::String> name = class_linker->ResolveString(*dex_file, name_idx, dex_cache);
683     if (name.IsNull()) {
684       DCHECK(self->IsExceptionPending());
685       return nullptr;
686     }
687     bootstrap_frame->SetVRegReference(vreg++, name.Ptr());
688   }
689   it.Next();
690 
691   // The third parameter is the method type associated with the name.
692   uint32_t method_type_idx = static_cast<uint32_t>(it.GetJavaValue().i);
693   Handle<mirror::MethodType>
694       method_type(hs.NewHandle(class_linker->ResolveMethodType(*dex_file,
695                                                                method_type_idx,
696                                                                dex_cache,
697                                                                class_loader)));
698   if (method_type.IsNull()) {
699     DCHECK(self->IsExceptionPending());
700     return nullptr;
701   }
702   bootstrap_frame->SetVRegReference(vreg++, method_type.Get());
703   it.Next();
704 
705   // Append remaining arguments (if any).
706   while (it.HasNext()) {
707     const jvalue& jvalue = it.GetJavaValue();
708     switch (it.GetValueType()) {
709       case EncodedArrayValueIterator::ValueType::kBoolean:
710       case EncodedArrayValueIterator::ValueType::kByte:
711       case EncodedArrayValueIterator::ValueType::kChar:
712       case EncodedArrayValueIterator::ValueType::kShort:
713       case EncodedArrayValueIterator::ValueType::kInt:
714         bootstrap_frame->SetVReg(vreg, jvalue.i);
715         vreg += 1;
716         break;
717       case EncodedArrayValueIterator::ValueType::kLong:
718         bootstrap_frame->SetVRegLong(vreg, jvalue.j);
719         vreg += 2;
720         break;
721       case EncodedArrayValueIterator::ValueType::kFloat:
722         bootstrap_frame->SetVRegFloat(vreg, jvalue.f);
723         vreg += 1;
724         break;
725       case EncodedArrayValueIterator::ValueType::kDouble:
726         bootstrap_frame->SetVRegDouble(vreg, jvalue.d);
727         vreg += 2;
728         break;
729       case EncodedArrayValueIterator::ValueType::kMethodType: {
730         uint32_t idx = static_cast<uint32_t>(jvalue.i);
731         ObjPtr<mirror::MethodType> ref =
732             class_linker->ResolveMethodType(*dex_file, idx, dex_cache, class_loader);
733         if (ref.IsNull()) {
734           DCHECK(self->IsExceptionPending());
735           return nullptr;
736         }
737         bootstrap_frame->SetVRegReference(vreg, ref.Ptr());
738         vreg += 1;
739         break;
740       }
741       case EncodedArrayValueIterator::ValueType::kMethodHandle: {
742         uint32_t idx = static_cast<uint32_t>(jvalue.i);
743         ObjPtr<mirror::MethodHandle> ref =
744             class_linker->ResolveMethodHandle(idx, referrer);
745         if (ref.IsNull()) {
746           DCHECK(self->IsExceptionPending());
747           return nullptr;
748         }
749         bootstrap_frame->SetVRegReference(vreg, ref.Ptr());
750         vreg += 1;
751         break;
752       }
753       case EncodedArrayValueIterator::ValueType::kString: {
754         dex::StringIndex idx(static_cast<uint32_t>(jvalue.i));
755         ObjPtr<mirror::String> ref = class_linker->ResolveString(*dex_file, idx, dex_cache);
756         if (ref.IsNull()) {
757           DCHECK(self->IsExceptionPending());
758           return nullptr;
759         }
760         bootstrap_frame->SetVRegReference(vreg, ref.Ptr());
761         vreg += 1;
762         break;
763       }
764       case EncodedArrayValueIterator::ValueType::kType: {
765         dex::TypeIndex idx(static_cast<uint32_t>(jvalue.i));
766         ObjPtr<mirror::Class> ref =
767             class_linker->ResolveType(*dex_file, idx, dex_cache, class_loader);
768         if (ref.IsNull()) {
769           DCHECK(self->IsExceptionPending());
770           return nullptr;
771         }
772         bootstrap_frame->SetVRegReference(vreg, ref.Ptr());
773         vreg += 1;
774         break;
775       }
776       case EncodedArrayValueIterator::ValueType::kNull:
777         bootstrap_frame->SetVRegReference(vreg, nullptr);
778         vreg += 1;
779         break;
780       case EncodedArrayValueIterator::ValueType::kField:
781       case EncodedArrayValueIterator::ValueType::kMethod:
782       case EncodedArrayValueIterator::ValueType::kEnum:
783       case EncodedArrayValueIterator::ValueType::kArray:
784       case EncodedArrayValueIterator::ValueType::kAnnotation:
785         // Unreachable based on current EncodedArrayValueIterator::Next().
786         UNREACHABLE();
787     }
788 
789     it.Next();
790   }
791 
792   // Invoke the bootstrap method handle.
793   JValue result;
794 
795   // This array of arguments is unused. DoInvokePolymorphic() operates on either a
796   // an argument array or a range, but always takes an array argument.
797   uint32_t args_unused[Instruction::kMaxVarArgRegs];
798   ArtMethod* invoke_exact =
799       jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact);
800   bool invoke_success = DoInvokePolymorphic<true /* is_range */>(self,
801                                                                  invoke_exact,
802                                                                  *bootstrap_frame,
803                                                                  bootstrap,
804                                                                  bootstrap_method_type,
805                                                                  args_unused,
806                                                                  0,
807                                                                  &result);
808   if (!invoke_success) {
809     DCHECK(self->IsExceptionPending());
810     return nullptr;
811   }
812 
813   Handle<mirror::Object> object(hs.NewHandle(result.GetL()));
814 
815   // Check the result is not null.
816   if (UNLIKELY(object.IsNull())) {
817     ThrowNullPointerException("CallSite == null");
818     return nullptr;
819   }
820 
821   // Check the result type is a subclass of CallSite.
822   if (UNLIKELY(!object->InstanceOf(mirror::CallSite::StaticClass()))) {
823     ThrowClassCastException(object->GetClass(), mirror::CallSite::StaticClass());
824     return nullptr;
825   }
826 
827   Handle<mirror::CallSite> call_site =
828       hs.NewHandle(ObjPtr<mirror::CallSite>::DownCast(ObjPtr<mirror::Object>(result.GetL())));
829 
830   // Check the call site target is not null as we're going to invoke it.
831   Handle<mirror::MethodHandle> target = hs.NewHandle(call_site->GetTarget());
832   if (UNLIKELY(target.IsNull())) {
833     ThrowNullPointerException("CallSite target == null");
834     return nullptr;
835   }
836 
837   // Check the target method type matches the method type requested modulo the receiver
838   // needs to be compatible rather than exact.
839   Handle<mirror::MethodType> target_method_type = hs.NewHandle(target->GetMethodType());
840   if (UNLIKELY(!target_method_type->IsExactMatch(method_type.Get()) &&
841                !IsParameterTypeConvertible(target_method_type->GetPTypes()->GetWithoutChecks(0),
842                                            method_type->GetPTypes()->GetWithoutChecks(0)))) {
843     ThrowWrongMethodTypeException(target_method_type.Get(), method_type.Get());
844     return nullptr;
845   }
846 
847   return call_site.Get();
848 }
849 
850 template<bool is_range>
DoInvokeCustom(Thread * self,ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result)851 bool DoInvokeCustom(Thread* self,
852                     ShadowFrame& shadow_frame,
853                     const Instruction* inst,
854                     uint16_t inst_data,
855                     JValue* result)
856     REQUIRES_SHARED(Locks::mutator_lock_) {
857   // invoke-custom is not supported in transactions. In transactions
858   // there is a limited set of types supported. invoke-custom allows
859   // running arbitrary code and instantiating arbitrary types.
860   CHECK(!Runtime::Current()->IsActiveTransaction());
861   StackHandleScope<4> hs(self);
862   Handle<mirror::DexCache> dex_cache(hs.NewHandle(shadow_frame.GetMethod()->GetDexCache()));
863   const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
864   MutableHandle<mirror::CallSite>
865       call_site(hs.NewHandle(dex_cache->GetResolvedCallSite(call_site_idx)));
866   if (call_site.IsNull()) {
867     call_site.Assign(InvokeBootstrapMethod(self, shadow_frame, call_site_idx));
868     if (UNLIKELY(call_site.IsNull())) {
869       CHECK(self->IsExceptionPending());
870       ThrowWrappedBootstrapMethodError("Exception from call site #%u bootstrap method",
871                                        call_site_idx);
872       result->SetJ(0);
873       return false;
874     }
875     mirror::CallSite* winning_call_site =
876         dex_cache->SetResolvedCallSite(call_site_idx, call_site.Get());
877     call_site.Assign(winning_call_site);
878   }
879 
880   // CallSite.java checks the re-assignment of the call site target
881   // when mutating call site targets. We only check the target is
882   // non-null and has the right type during bootstrap method execution.
883   Handle<mirror::MethodHandle> target = hs.NewHandle(call_site->GetTarget());
884   Handle<mirror::MethodType> target_method_type = hs.NewHandle(target->GetMethodType());
885   DCHECK_EQ(static_cast<size_t>(inst->VRegA()), target_method_type->NumberOfVRegs());
886 
887   uint32_t args[Instruction::kMaxVarArgRegs];
888   if (is_range) {
889     args[0] = inst->VRegC_3rc();
890   } else {
891     inst->GetVarArgs(args, inst_data);
892   }
893 
894   ArtMethod* invoke_exact =
895       jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact);
896   return DoInvokePolymorphic<is_range>(self,
897                                        invoke_exact,
898                                        shadow_frame,
899                                        target,
900                                        target_method_type,
901                                        args,
902                                        args[0],
903                                        result);
904 }
905 
906 template <bool is_range>
CopyRegisters(ShadowFrame & caller_frame,ShadowFrame * callee_frame,const uint32_t (& arg)[Instruction::kMaxVarArgRegs],const size_t first_src_reg,const size_t first_dest_reg,const size_t num_regs)907 inline void CopyRegisters(ShadowFrame& caller_frame,
908                           ShadowFrame* callee_frame,
909                           const uint32_t (&arg)[Instruction::kMaxVarArgRegs],
910                           const size_t first_src_reg,
911                           const size_t first_dest_reg,
912                           const size_t num_regs) {
913   if (is_range) {
914     const size_t dest_reg_bound = first_dest_reg + num_regs;
915     for (size_t src_reg = first_src_reg, dest_reg = first_dest_reg; dest_reg < dest_reg_bound;
916         ++dest_reg, ++src_reg) {
917       AssignRegister(callee_frame, caller_frame, dest_reg, src_reg);
918     }
919   } else {
920     DCHECK_LE(num_regs, arraysize(arg));
921 
922     for (size_t arg_index = 0; arg_index < num_regs; ++arg_index) {
923       AssignRegister(callee_frame, caller_frame, first_dest_reg + arg_index, arg[arg_index]);
924     }
925   }
926 }
927 
928 template <bool is_range,
929           bool do_assignability_check>
DoCallCommon(ArtMethod * called_method,Thread * self,ShadowFrame & shadow_frame,JValue * result,uint16_t number_of_inputs,uint32_t (& arg)[Instruction::kMaxVarArgRegs],uint32_t vregC)930 static inline bool DoCallCommon(ArtMethod* called_method,
931                                 Thread* self,
932                                 ShadowFrame& shadow_frame,
933                                 JValue* result,
934                                 uint16_t number_of_inputs,
935                                 uint32_t (&arg)[Instruction::kMaxVarArgRegs],
936                                 uint32_t vregC) {
937   bool string_init = false;
938   // Replace calls to String.<init> with equivalent StringFactory call.
939   if (UNLIKELY(called_method->GetDeclaringClass()->IsStringClass()
940                && called_method->IsConstructor())) {
941     called_method = WellKnownClasses::StringInitToStringFactory(called_method);
942     string_init = true;
943   }
944 
945   // Compute method information.
946   const DexFile::CodeItem* code_item = called_method->GetCodeItem();
947   // Number of registers for the callee's call frame.
948   uint16_t num_regs;
949   // Test whether to use the interpreter or compiler entrypoint, and save that result to pass to
950   // PerformCall. A deoptimization could occur at any time, and we shouldn't change which
951   // entrypoint to use once we start building the shadow frame.
952 
953   // For unstarted runtimes, always use the interpreter entrypoint. This fixes the case where we are
954   // doing cross compilation. Note that GetEntryPointFromQuickCompiledCode doesn't use the image
955   // pointer size here and this may case an overflow if it is called from the compiler. b/62402160
956   const bool use_interpreter_entrypoint = !Runtime::Current()->IsStarted() ||
957       ClassLinker::ShouldUseInterpreterEntrypoint(
958           called_method,
959           called_method->GetEntryPointFromQuickCompiledCode());
960   if (LIKELY(code_item != nullptr)) {
961     // When transitioning to compiled code, space only needs to be reserved for the input registers.
962     // The rest of the frame gets discarded. This also prevents accessing the called method's code
963     // item, saving memory by keeping code items of compiled code untouched.
964     if (!use_interpreter_entrypoint) {
965       DCHECK(!Runtime::Current()->IsAotCompiler()) << "Compiler should use interpreter entrypoint";
966       num_regs = number_of_inputs;
967     } else {
968       num_regs = code_item->registers_size_;
969       DCHECK_EQ(string_init ? number_of_inputs - 1 : number_of_inputs, code_item->ins_size_);
970     }
971   } else {
972     DCHECK(called_method->IsNative() || called_method->IsProxyMethod());
973     num_regs = number_of_inputs;
974   }
975 
976   // Hack for String init:
977   //
978   // Rewrite invoke-x java.lang.String.<init>(this, a, b, c, ...) into:
979   //         invoke-x StringFactory(a, b, c, ...)
980   // by effectively dropping the first virtual register from the invoke.
981   //
982   // (at this point the ArtMethod has already been replaced,
983   // so we just need to fix-up the arguments)
984   //
985   // Note that FindMethodFromCode in entrypoint_utils-inl.h was also special-cased
986   // to handle the compiler optimization of replacing `this` with null without
987   // throwing NullPointerException.
988   uint32_t string_init_vreg_this = is_range ? vregC : arg[0];
989   if (UNLIKELY(string_init)) {
990     DCHECK_GT(num_regs, 0u);  // As the method is an instance method, there should be at least 1.
991 
992     // The new StringFactory call is static and has one fewer argument.
993     if (code_item == nullptr) {
994       DCHECK(called_method->IsNative() || called_method->IsProxyMethod());
995       num_regs--;
996     }  // else ... don't need to change num_regs since it comes up from the string_init's code item
997     number_of_inputs--;
998 
999     // Rewrite the var-args, dropping the 0th argument ("this")
1000     for (uint32_t i = 1; i < arraysize(arg); ++i) {
1001       arg[i - 1] = arg[i];
1002     }
1003     arg[arraysize(arg) - 1] = 0;
1004 
1005     // Rewrite the non-var-arg case
1006     vregC++;  // Skips the 0th vreg in the range ("this").
1007   }
1008 
1009   // Parameter registers go at the end of the shadow frame.
1010   DCHECK_GE(num_regs, number_of_inputs);
1011   size_t first_dest_reg = num_regs - number_of_inputs;
1012   DCHECK_NE(first_dest_reg, (size_t)-1);
1013 
1014   // Allocate shadow frame on the stack.
1015   const char* old_cause = self->StartAssertNoThreadSuspension("DoCallCommon");
1016   ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
1017       CREATE_SHADOW_FRAME(num_regs, &shadow_frame, called_method, /* dex pc */ 0);
1018   ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get();
1019 
1020   // Initialize new shadow frame by copying the registers from the callee shadow frame.
1021   if (do_assignability_check) {
1022     // Slow path.
1023     // We might need to do class loading, which incurs a thread state change to kNative. So
1024     // register the shadow frame as under construction and allow suspension again.
1025     ScopedStackedShadowFramePusher pusher(
1026         self, new_shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction);
1027     self->EndAssertNoThreadSuspension(old_cause);
1028 
1029     // ArtMethod here is needed to check type information of the call site against the callee.
1030     // Type information is retrieved from a DexFile/DexCache for that respective declared method.
1031     //
1032     // As a special case for proxy methods, which are not dex-backed,
1033     // we have to retrieve type information from the proxy's method
1034     // interface method instead (which is dex backed since proxies are never interfaces).
1035     ArtMethod* method =
1036         new_shadow_frame->GetMethod()->GetInterfaceMethodIfProxy(kRuntimePointerSize);
1037 
1038     // We need to do runtime check on reference assignment. We need to load the shorty
1039     // to get the exact type of each reference argument.
1040     const DexFile::TypeList* params = method->GetParameterTypeList();
1041     uint32_t shorty_len = 0;
1042     const char* shorty = method->GetShorty(&shorty_len);
1043 
1044     // Handle receiver apart since it's not part of the shorty.
1045     size_t dest_reg = first_dest_reg;
1046     size_t arg_offset = 0;
1047 
1048     if (!method->IsStatic()) {
1049       size_t receiver_reg = is_range ? vregC : arg[0];
1050       new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg));
1051       ++dest_reg;
1052       ++arg_offset;
1053       DCHECK(!string_init);  // All StringFactory methods are static.
1054     }
1055 
1056     // Copy the caller's invoke-* arguments into the callee's parameter registers.
1057     for (uint32_t shorty_pos = 0; dest_reg < num_regs; ++shorty_pos, ++dest_reg, ++arg_offset) {
1058       // Skip the 0th 'shorty' type since it represents the return type.
1059       DCHECK_LT(shorty_pos + 1, shorty_len) << "for shorty '" << shorty << "'";
1060       const size_t src_reg = (is_range) ? vregC + arg_offset : arg[arg_offset];
1061       switch (shorty[shorty_pos + 1]) {
1062         // Handle Object references. 1 virtual register slot.
1063         case 'L': {
1064           ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference(src_reg);
1065           if (do_assignability_check && o != nullptr) {
1066             const dex::TypeIndex type_idx = params->GetTypeItem(shorty_pos).type_idx_;
1067             ObjPtr<mirror::Class> arg_type = method->GetDexCache()->GetResolvedType(type_idx);
1068             if (arg_type == nullptr) {
1069               StackHandleScope<1> hs(self);
1070               // Preserve o since it is used below and GetClassFromTypeIndex may cause thread
1071               // suspension.
1072               HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&o);
1073               arg_type = method->GetClassFromTypeIndex(type_idx, true /* resolve */);
1074               if (arg_type == nullptr) {
1075                 CHECK(self->IsExceptionPending());
1076                 return false;
1077               }
1078             }
1079             if (!o->VerifierInstanceOf(arg_type)) {
1080               // This should never happen.
1081               std::string temp1, temp2;
1082               self->ThrowNewExceptionF("Ljava/lang/InternalError;",
1083                                        "Invoking %s with bad arg %d, type '%s' not instance of '%s'",
1084                                        new_shadow_frame->GetMethod()->GetName(), shorty_pos,
1085                                        o->GetClass()->GetDescriptor(&temp1),
1086                                        arg_type->GetDescriptor(&temp2));
1087               return false;
1088             }
1089           }
1090           new_shadow_frame->SetVRegReference(dest_reg, o.Ptr());
1091           break;
1092         }
1093         // Handle doubles and longs. 2 consecutive virtual register slots.
1094         case 'J': case 'D': {
1095           uint64_t wide_value =
1096               (static_cast<uint64_t>(shadow_frame.GetVReg(src_reg + 1)) << BitSizeOf<uint32_t>()) |
1097                static_cast<uint32_t>(shadow_frame.GetVReg(src_reg));
1098           new_shadow_frame->SetVRegLong(dest_reg, wide_value);
1099           // Skip the next virtual register slot since we already used it.
1100           ++dest_reg;
1101           ++arg_offset;
1102           break;
1103         }
1104         // Handle all other primitives that are always 1 virtual register slot.
1105         default:
1106           new_shadow_frame->SetVReg(dest_reg, shadow_frame.GetVReg(src_reg));
1107           break;
1108       }
1109     }
1110   } else {
1111     if (is_range) {
1112       DCHECK_EQ(num_regs, first_dest_reg + number_of_inputs);
1113     }
1114 
1115     CopyRegisters<is_range>(shadow_frame,
1116                             new_shadow_frame,
1117                             arg,
1118                             vregC,
1119                             first_dest_reg,
1120                             number_of_inputs);
1121     self->EndAssertNoThreadSuspension(old_cause);
1122   }
1123 
1124   PerformCall(self,
1125               code_item,
1126               shadow_frame.GetMethod(),
1127               first_dest_reg,
1128               new_shadow_frame,
1129               result,
1130               use_interpreter_entrypoint);
1131 
1132   if (string_init && !self->IsExceptionPending()) {
1133     SetStringInitValueToAllAliases(&shadow_frame, string_init_vreg_this, *result);
1134   }
1135 
1136   return !self->IsExceptionPending();
1137 }
1138 
1139 template<bool is_range, bool do_assignability_check>
DoCall(ArtMethod * called_method,Thread * self,ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result)1140 bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
1141             const Instruction* inst, uint16_t inst_data, JValue* result) {
1142   // Argument word count.
1143   const uint16_t number_of_inputs =
1144       (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data);
1145 
1146   // TODO: find a cleaner way to separate non-range and range information without duplicating
1147   //       code.
1148   uint32_t arg[Instruction::kMaxVarArgRegs] = {};  // only used in invoke-XXX.
1149   uint32_t vregC = 0;
1150   if (is_range) {
1151     vregC = inst->VRegC_3rc();
1152   } else {
1153     vregC = inst->VRegC_35c();
1154     inst->GetVarArgs(arg, inst_data);
1155   }
1156 
1157   return DoCallCommon<is_range, do_assignability_check>(
1158       called_method, self, shadow_frame,
1159       result, number_of_inputs, arg, vregC);
1160 }
1161 
1162 template <bool is_range, bool do_access_check, bool transaction_active>
DoFilledNewArray(const Instruction * inst,const ShadowFrame & shadow_frame,Thread * self,JValue * result)1163 bool DoFilledNewArray(const Instruction* inst,
1164                       const ShadowFrame& shadow_frame,
1165                       Thread* self,
1166                       JValue* result) {
1167   DCHECK(inst->Opcode() == Instruction::FILLED_NEW_ARRAY ||
1168          inst->Opcode() == Instruction::FILLED_NEW_ARRAY_RANGE);
1169   const int32_t length = is_range ? inst->VRegA_3rc() : inst->VRegA_35c();
1170   if (!is_range) {
1171     // Checks FILLED_NEW_ARRAY's length does not exceed 5 arguments.
1172     CHECK_LE(length, 5);
1173   }
1174   if (UNLIKELY(length < 0)) {
1175     ThrowNegativeArraySizeException(length);
1176     return false;
1177   }
1178   uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
1179   ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(dex::TypeIndex(type_idx),
1180                                                              shadow_frame.GetMethod(),
1181                                                              self,
1182                                                              false,
1183                                                              do_access_check);
1184   if (UNLIKELY(array_class == nullptr)) {
1185     DCHECK(self->IsExceptionPending());
1186     return false;
1187   }
1188   CHECK(array_class->IsArrayClass());
1189   ObjPtr<mirror::Class> component_class = array_class->GetComponentType();
1190   const bool is_primitive_int_component = component_class->IsPrimitiveInt();
1191   if (UNLIKELY(component_class->IsPrimitive() && !is_primitive_int_component)) {
1192     if (component_class->IsPrimitiveLong() || component_class->IsPrimitiveDouble()) {
1193       ThrowRuntimeException("Bad filled array request for type %s",
1194                             component_class->PrettyDescriptor().c_str());
1195     } else {
1196       self->ThrowNewExceptionF("Ljava/lang/InternalError;",
1197                                "Found type %s; filled-new-array not implemented for anything but 'int'",
1198                                component_class->PrettyDescriptor().c_str());
1199     }
1200     return false;
1201   }
1202   ObjPtr<mirror::Object> new_array = mirror::Array::Alloc<true>(
1203       self,
1204       array_class,
1205       length,
1206       array_class->GetComponentSizeShift(),
1207       Runtime::Current()->GetHeap()->GetCurrentAllocator());
1208   if (UNLIKELY(new_array == nullptr)) {
1209     self->AssertPendingOOMException();
1210     return false;
1211   }
1212   uint32_t arg[Instruction::kMaxVarArgRegs];  // only used in filled-new-array.
1213   uint32_t vregC = 0;   // only used in filled-new-array-range.
1214   if (is_range) {
1215     vregC = inst->VRegC_3rc();
1216   } else {
1217     inst->GetVarArgs(arg);
1218   }
1219   for (int32_t i = 0; i < length; ++i) {
1220     size_t src_reg = is_range ? vregC + i : arg[i];
1221     if (is_primitive_int_component) {
1222       new_array->AsIntArray()->SetWithoutChecks<transaction_active>(
1223           i, shadow_frame.GetVReg(src_reg));
1224     } else {
1225       new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<transaction_active>(
1226           i, shadow_frame.GetVRegReference(src_reg));
1227     }
1228   }
1229 
1230   result->SetL(new_array);
1231   return true;
1232 }
1233 
1234 // TODO: Use ObjPtr here.
1235 template<typename T>
RecordArrayElementsInTransactionImpl(mirror::PrimitiveArray<T> * array,int32_t count)1236 static void RecordArrayElementsInTransactionImpl(mirror::PrimitiveArray<T>* array,
1237                                                  int32_t count)
1238     REQUIRES_SHARED(Locks::mutator_lock_) {
1239   Runtime* runtime = Runtime::Current();
1240   for (int32_t i = 0; i < count; ++i) {
1241     runtime->RecordWriteArray(array, i, array->GetWithoutChecks(i));
1242   }
1243 }
1244 
RecordArrayElementsInTransaction(ObjPtr<mirror::Array> array,int32_t count)1245 void RecordArrayElementsInTransaction(ObjPtr<mirror::Array> array, int32_t count)
1246     REQUIRES_SHARED(Locks::mutator_lock_) {
1247   DCHECK(Runtime::Current()->IsActiveTransaction());
1248   DCHECK(array != nullptr);
1249   DCHECK_LE(count, array->GetLength());
1250   Primitive::Type primitive_component_type = array->GetClass()->GetComponentType()->GetPrimitiveType();
1251   switch (primitive_component_type) {
1252     case Primitive::kPrimBoolean:
1253       RecordArrayElementsInTransactionImpl(array->AsBooleanArray(), count);
1254       break;
1255     case Primitive::kPrimByte:
1256       RecordArrayElementsInTransactionImpl(array->AsByteArray(), count);
1257       break;
1258     case Primitive::kPrimChar:
1259       RecordArrayElementsInTransactionImpl(array->AsCharArray(), count);
1260       break;
1261     case Primitive::kPrimShort:
1262       RecordArrayElementsInTransactionImpl(array->AsShortArray(), count);
1263       break;
1264     case Primitive::kPrimInt:
1265       RecordArrayElementsInTransactionImpl(array->AsIntArray(), count);
1266       break;
1267     case Primitive::kPrimFloat:
1268       RecordArrayElementsInTransactionImpl(array->AsFloatArray(), count);
1269       break;
1270     case Primitive::kPrimLong:
1271       RecordArrayElementsInTransactionImpl(array->AsLongArray(), count);
1272       break;
1273     case Primitive::kPrimDouble:
1274       RecordArrayElementsInTransactionImpl(array->AsDoubleArray(), count);
1275       break;
1276     default:
1277       LOG(FATAL) << "Unsupported primitive type " << primitive_component_type
1278                  << " in fill-array-data";
1279       break;
1280   }
1281 }
1282 
1283 // Explicit DoCall template function declarations.
1284 #define EXPLICIT_DO_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check)                      \
1285   template REQUIRES_SHARED(Locks::mutator_lock_)                                                \
1286   bool DoCall<_is_range, _do_assignability_check>(ArtMethod* method, Thread* self,              \
1287                                                   ShadowFrame& shadow_frame,                    \
1288                                                   const Instruction* inst, uint16_t inst_data,  \
1289                                                   JValue* result)
1290 EXPLICIT_DO_CALL_TEMPLATE_DECL(false, false);
1291 EXPLICIT_DO_CALL_TEMPLATE_DECL(false, true);
1292 EXPLICIT_DO_CALL_TEMPLATE_DECL(true, false);
1293 EXPLICIT_DO_CALL_TEMPLATE_DECL(true, true);
1294 #undef EXPLICIT_DO_CALL_TEMPLATE_DECL
1295 
1296 // Explicit DoInvokeCustom template function declarations.
1297 #define EXPLICIT_DO_INVOKE_CUSTOM_TEMPLATE_DECL(_is_range)               \
1298   template REQUIRES_SHARED(Locks::mutator_lock_)                         \
1299   bool DoInvokeCustom<_is_range>(                                        \
1300       Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,  \
1301       uint16_t inst_data, JValue* result)
1302 EXPLICIT_DO_INVOKE_CUSTOM_TEMPLATE_DECL(false);
1303 EXPLICIT_DO_INVOKE_CUSTOM_TEMPLATE_DECL(true);
1304 #undef EXPLICIT_DO_INVOKE_CUSTOM_TEMPLATE_DECL
1305 
1306 // Explicit DoInvokePolymorphic template function declarations.
1307 #define EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(_is_range)          \
1308   template REQUIRES_SHARED(Locks::mutator_lock_)                         \
1309   bool DoInvokePolymorphic<_is_range>(                                   \
1310       Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,  \
1311       uint16_t inst_data, JValue* result)
1312 EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(false);
1313 EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(true);
1314 #undef EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL
1315 
1316 // Explicit DoFilledNewArray template function declarations.
1317 #define EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(_is_range_, _check, _transaction_active)       \
1318   template REQUIRES_SHARED(Locks::mutator_lock_)                                                  \
1319   bool DoFilledNewArray<_is_range_, _check, _transaction_active>(const Instruction* inst,         \
1320                                                                  const ShadowFrame& shadow_frame, \
1321                                                                  Thread* self, JValue* result)
1322 #define EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(_transaction_active)       \
1323   EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(false, false, _transaction_active);  \
1324   EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(false, true, _transaction_active);   \
1325   EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(true, false, _transaction_active);   \
1326   EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(true, true, _transaction_active)
1327 EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(false);
1328 EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(true);
1329 #undef EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL
1330 #undef EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL
1331 
1332 }  // namespace interpreter
1333 }  // namespace art
1334