interpreter_common.cc revision cfa325e4ca65603fdb03a836a6cb394d23ed511f
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.h" 32#include "reflection.h" 33#include "reflection-inl.h" 34#include "stack.h" 35#include "unstarted_runtime.h" 36#include "verifier/method_verifier.h" 37#include "well_known_classes.h" 38 39namespace art { 40namespace interpreter { 41 42void ThrowNullPointerExceptionFromInterpreter() { 43 ThrowNullPointerExceptionFromDexPC(); 44} 45 46template<Primitive::Type field_type> 47static ALWAYS_INLINE void DoFieldGetCommon(Thread* self, 48 const ShadowFrame& shadow_frame, 49 ObjPtr<mirror::Object>& obj, 50 ArtField* field, 51 JValue* result) 52 REQUIRES_SHARED(Locks::mutator_lock_) { 53 field->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 54 55 // Report this field access to instrumentation if needed. 56 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 57 if (UNLIKELY(instrumentation->HasFieldReadListeners())) { 58 StackHandleScope<1> hs(self); 59 // Wrap in handle wrapper in case the listener does thread suspension. 60 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj)); 61 ObjPtr<mirror::Object> this_object; 62 if (!field->IsStatic()) { 63 this_object = obj; 64 } 65 instrumentation->FieldReadEvent(self, 66 this_object.Ptr(), 67 shadow_frame.GetMethod(), 68 shadow_frame.GetDexPC(), 69 field); 70 } 71 72 switch (field_type) { 73 case Primitive::kPrimBoolean: 74 result->SetZ(field->GetBoolean(obj)); 75 break; 76 case Primitive::kPrimByte: 77 result->SetB(field->GetByte(obj)); 78 break; 79 case Primitive::kPrimChar: 80 result->SetC(field->GetChar(obj)); 81 break; 82 case Primitive::kPrimShort: 83 result->SetS(field->GetShort(obj)); 84 break; 85 case Primitive::kPrimInt: 86 result->SetI(field->GetInt(obj)); 87 break; 88 case Primitive::kPrimLong: 89 result->SetJ(field->GetLong(obj)); 90 break; 91 case Primitive::kPrimNot: 92 result->SetL(field->GetObject(obj)); 93 break; 94 default: 95 LOG(FATAL) << "Unreachable: " << field_type; 96 UNREACHABLE(); 97 } 98} 99 100template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check> 101bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, 102 uint16_t inst_data) { 103 const bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead); 104 const uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 105 ArtField* f = 106 FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self, 107 Primitive::ComponentSize(field_type)); 108 if (UNLIKELY(f == nullptr)) { 109 CHECK(self->IsExceptionPending()); 110 return false; 111 } 112 ObjPtr<mirror::Object> obj; 113 if (is_static) { 114 obj = f->GetDeclaringClass(); 115 } else { 116 obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); 117 if (UNLIKELY(obj == nullptr)) { 118 ThrowNullPointerExceptionForFieldAccess(f, true); 119 return false; 120 } 121 } 122 123 JValue result; 124 DoFieldGetCommon<field_type>(self, shadow_frame, obj, f, &result); 125 uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data); 126 switch (field_type) { 127 case Primitive::kPrimBoolean: 128 shadow_frame.SetVReg(vregA, result.GetZ()); 129 break; 130 case Primitive::kPrimByte: 131 shadow_frame.SetVReg(vregA, result.GetB()); 132 break; 133 case Primitive::kPrimChar: 134 shadow_frame.SetVReg(vregA, result.GetC()); 135 break; 136 case Primitive::kPrimShort: 137 shadow_frame.SetVReg(vregA, result.GetS()); 138 break; 139 case Primitive::kPrimInt: 140 shadow_frame.SetVReg(vregA, result.GetI()); 141 break; 142 case Primitive::kPrimLong: 143 shadow_frame.SetVRegLong(vregA, result.GetJ()); 144 break; 145 case Primitive::kPrimNot: 146 shadow_frame.SetVRegReference(vregA, result.GetL()); 147 break; 148 default: 149 LOG(FATAL) << "Unreachable: " << field_type; 150 UNREACHABLE(); 151 } 152 return true; 153} 154 155// Explicitly instantiate all DoFieldGet functions. 156#define EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, _do_check) \ 157 template bool DoFieldGet<_find_type, _field_type, _do_check>(Thread* self, \ 158 ShadowFrame& shadow_frame, \ 159 const Instruction* inst, \ 160 uint16_t inst_data) 161 162#define EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(_find_type, _field_type) \ 163 EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, false); \ 164 EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, true); 165 166// iget-XXX 167EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimBoolean) 168EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimByte) 169EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimChar) 170EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimShort) 171EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimInt) 172EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimLong) 173EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstanceObjectRead, Primitive::kPrimNot) 174 175// sget-XXX 176EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimBoolean) 177EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimByte) 178EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimChar) 179EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimShort) 180EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimInt) 181EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticPrimitiveRead, Primitive::kPrimLong) 182EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticObjectRead, Primitive::kPrimNot) 183 184#undef EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL 185#undef EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL 186 187// Helper for getters in invoke-polymorphic. 188inline static void DoFieldGetForInvokePolymorphic(Thread* self, 189 const ShadowFrame& shadow_frame, 190 ObjPtr<mirror::Object>& obj, 191 ArtField* field, 192 Primitive::Type field_type, 193 JValue* result) 194 REQUIRES_SHARED(Locks::mutator_lock_) { 195 switch (field_type) { 196 case Primitive::kPrimBoolean: 197 DoFieldGetCommon<Primitive::kPrimBoolean>(self, shadow_frame, obj, field, result); 198 break; 199 case Primitive::kPrimByte: 200 DoFieldGetCommon<Primitive::kPrimByte>(self, shadow_frame, obj, field, result); 201 break; 202 case Primitive::kPrimChar: 203 DoFieldGetCommon<Primitive::kPrimChar>(self, shadow_frame, obj, field, result); 204 break; 205 case Primitive::kPrimShort: 206 DoFieldGetCommon<Primitive::kPrimShort>(self, shadow_frame, obj, field, result); 207 break; 208 case Primitive::kPrimInt: 209 DoFieldGetCommon<Primitive::kPrimInt>(self, shadow_frame, obj, field, result); 210 break; 211 case Primitive::kPrimLong: 212 DoFieldGetCommon<Primitive::kPrimLong>(self, shadow_frame, obj, field, result); 213 break; 214 case Primitive::kPrimFloat: 215 DoFieldGetCommon<Primitive::kPrimInt>(self, shadow_frame, obj, field, result); 216 break; 217 case Primitive::kPrimDouble: 218 DoFieldGetCommon<Primitive::kPrimLong>(self, shadow_frame, obj, field, result); 219 break; 220 case Primitive::kPrimNot: 221 DoFieldGetCommon<Primitive::kPrimNot>(self, shadow_frame, obj, field, result); 222 break; 223 case Primitive::kPrimVoid: 224 LOG(FATAL) << "Unreachable: " << field_type; 225 UNREACHABLE(); 226 } 227} 228 229// Handles iget-quick, iget-wide-quick and iget-object-quick instructions. 230// Returns true on success, otherwise throws an exception and returns false. 231template<Primitive::Type field_type> 232bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { 233 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); 234 if (UNLIKELY(obj == nullptr)) { 235 // We lost the reference to the field index so we cannot get a more 236 // precised exception message. 237 ThrowNullPointerExceptionFromDexPC(); 238 return false; 239 } 240 MemberOffset field_offset(inst->VRegC_22c()); 241 // Report this field access to instrumentation if needed. Since we only have the offset of 242 // the field from the base of the object, we need to look for it first. 243 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 244 if (UNLIKELY(instrumentation->HasFieldReadListeners())) { 245 ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(), 246 field_offset.Uint32Value()); 247 DCHECK(f != nullptr); 248 DCHECK(!f->IsStatic()); 249 StackHandleScope<1> hs(Thread::Current()); 250 // Save obj in case the instrumentation event has thread suspension. 251 HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&obj); 252 instrumentation->FieldReadEvent(Thread::Current(), 253 obj.Ptr(), 254 shadow_frame.GetMethod(), 255 shadow_frame.GetDexPC(), 256 f); 257 } 258 // Note: iget-x-quick instructions are only for non-volatile fields. 259 const uint32_t vregA = inst->VRegA_22c(inst_data); 260 switch (field_type) { 261 case Primitive::kPrimInt: 262 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetField32(field_offset))); 263 break; 264 case Primitive::kPrimBoolean: 265 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldBoolean(field_offset))); 266 break; 267 case Primitive::kPrimByte: 268 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldByte(field_offset))); 269 break; 270 case Primitive::kPrimChar: 271 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldChar(field_offset))); 272 break; 273 case Primitive::kPrimShort: 274 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldShort(field_offset))); 275 break; 276 case Primitive::kPrimLong: 277 shadow_frame.SetVRegLong(vregA, static_cast<int64_t>(obj->GetField64(field_offset))); 278 break; 279 case Primitive::kPrimNot: 280 shadow_frame.SetVRegReference(vregA, obj->GetFieldObject<mirror::Object>(field_offset)); 281 break; 282 default: 283 LOG(FATAL) << "Unreachable: " << field_type; 284 UNREACHABLE(); 285 } 286 return true; 287} 288 289// Explicitly instantiate all DoIGetQuick functions. 290#define EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(_field_type) \ 291 template bool DoIGetQuick<_field_type>(ShadowFrame& shadow_frame, const Instruction* inst, \ 292 uint16_t inst_data) 293 294EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimInt); // iget-quick. 295EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimBoolean); // iget-boolean-quick. 296EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimByte); // iget-byte-quick. 297EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimChar); // iget-char-quick. 298EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimShort); // iget-short-quick. 299EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimLong); // iget-wide-quick. 300EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimNot); // iget-object-quick. 301#undef EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL 302 303static JValue GetFieldValue(const ShadowFrame& shadow_frame, 304 Primitive::Type field_type, 305 uint32_t vreg) 306 REQUIRES_SHARED(Locks::mutator_lock_) { 307 JValue field_value; 308 switch (field_type) { 309 case Primitive::kPrimBoolean: 310 field_value.SetZ(static_cast<uint8_t>(shadow_frame.GetVReg(vreg))); 311 break; 312 case Primitive::kPrimByte: 313 field_value.SetB(static_cast<int8_t>(shadow_frame.GetVReg(vreg))); 314 break; 315 case Primitive::kPrimChar: 316 field_value.SetC(static_cast<uint16_t>(shadow_frame.GetVReg(vreg))); 317 break; 318 case Primitive::kPrimShort: 319 field_value.SetS(static_cast<int16_t>(shadow_frame.GetVReg(vreg))); 320 break; 321 case Primitive::kPrimInt: 322 case Primitive::kPrimFloat: 323 field_value.SetI(shadow_frame.GetVReg(vreg)); 324 break; 325 case Primitive::kPrimLong: 326 case Primitive::kPrimDouble: 327 field_value.SetJ(shadow_frame.GetVRegLong(vreg)); 328 break; 329 case Primitive::kPrimNot: 330 field_value.SetL(shadow_frame.GetVRegReference(vreg)); 331 break; 332 case Primitive::kPrimVoid: 333 LOG(FATAL) << "Unreachable: " << field_type; 334 UNREACHABLE(); 335 } 336 return field_value; 337} 338 339template<Primitive::Type field_type> 340static JValue GetFieldValue(const ShadowFrame& shadow_frame, uint32_t vreg) 341 REQUIRES_SHARED(Locks::mutator_lock_) { 342 JValue field_value; 343 switch (field_type) { 344 case Primitive::kPrimBoolean: 345 field_value.SetZ(static_cast<uint8_t>(shadow_frame.GetVReg(vreg))); 346 break; 347 case Primitive::kPrimByte: 348 field_value.SetB(static_cast<int8_t>(shadow_frame.GetVReg(vreg))); 349 break; 350 case Primitive::kPrimChar: 351 field_value.SetC(static_cast<uint16_t>(shadow_frame.GetVReg(vreg))); 352 break; 353 case Primitive::kPrimShort: 354 field_value.SetS(static_cast<int16_t>(shadow_frame.GetVReg(vreg))); 355 break; 356 case Primitive::kPrimInt: 357 field_value.SetI(shadow_frame.GetVReg(vreg)); 358 break; 359 case Primitive::kPrimLong: 360 field_value.SetJ(shadow_frame.GetVRegLong(vreg)); 361 break; 362 case Primitive::kPrimNot: 363 field_value.SetL(shadow_frame.GetVRegReference(vreg)); 364 break; 365 default: 366 LOG(FATAL) << "Unreachable: " << field_type; 367 UNREACHABLE(); 368 } 369 return field_value; 370} 371 372template<Primitive::Type field_type, bool do_assignability_check, bool transaction_active> 373static inline bool DoFieldPutCommon(Thread* self, 374 const ShadowFrame& shadow_frame, 375 ObjPtr<mirror::Object>& obj, 376 ArtField* f, 377 const JValue& value) 378 REQUIRES_SHARED(Locks::mutator_lock_) { 379 f->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 380 381 // Report this field access to instrumentation if needed. Since we only have the offset of 382 // the field from the base of the object, we need to look for it first. 383 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 384 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) { 385 StackHandleScope<1> hs(self); 386 // Wrap in handle wrapper in case the listener does thread suspension. 387 HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj)); 388 ObjPtr<mirror::Object> this_object = f->IsStatic() ? nullptr : obj; 389 instrumentation->FieldWriteEvent(self, this_object.Ptr(), 390 shadow_frame.GetMethod(), 391 shadow_frame.GetDexPC(), 392 f, 393 value); 394 } 395 396 switch (field_type) { 397 case Primitive::kPrimBoolean: 398 f->SetBoolean<transaction_active>(obj, value.GetZ()); 399 break; 400 case Primitive::kPrimByte: 401 f->SetByte<transaction_active>(obj, value.GetB()); 402 break; 403 case Primitive::kPrimChar: 404 f->SetChar<transaction_active>(obj, value.GetC()); 405 break; 406 case Primitive::kPrimShort: 407 f->SetShort<transaction_active>(obj, value.GetS()); 408 break; 409 case Primitive::kPrimInt: 410 f->SetInt<transaction_active>(obj, value.GetI()); 411 break; 412 case Primitive::kPrimLong: 413 f->SetLong<transaction_active>(obj, value.GetJ()); 414 break; 415 case Primitive::kPrimNot: { 416 ObjPtr<mirror::Object> reg = value.GetL(); 417 if (do_assignability_check && reg != nullptr) { 418 // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the 419 // object in the destructor. 420 ObjPtr<mirror::Class> field_class; 421 { 422 StackHandleScope<2> hs(self); 423 HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®)); 424 HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); 425 field_class = f->GetType<true>(); 426 } 427 if (!reg->VerifierInstanceOf(field_class.Ptr())) { 428 // This should never happen. 429 std::string temp1, temp2, temp3; 430 self->ThrowNewExceptionF("Ljava/lang/InternalError;", 431 "Put '%s' that is not instance of field '%s' in '%s'", 432 reg->GetClass()->GetDescriptor(&temp1), 433 field_class->GetDescriptor(&temp2), 434 f->GetDeclaringClass()->GetDescriptor(&temp3)); 435 return false; 436 } 437 } 438 f->SetObj<transaction_active>(obj, reg); 439 break; 440 } 441 default: 442 LOG(FATAL) << "Unreachable: " << field_type; 443 UNREACHABLE(); 444 } 445 return true; 446} 447 448template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check, 449 bool transaction_active> 450bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction* inst, 451 uint16_t inst_data) { 452 const bool do_assignability_check = do_access_check; 453 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite); 454 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 455 ArtField* f = 456 FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self, 457 Primitive::ComponentSize(field_type)); 458 if (UNLIKELY(f == nullptr)) { 459 CHECK(self->IsExceptionPending()); 460 return false; 461 } 462 ObjPtr<mirror::Object> obj; 463 if (is_static) { 464 obj = f->GetDeclaringClass(); 465 } else { 466 obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); 467 if (UNLIKELY(obj == nullptr)) { 468 ThrowNullPointerExceptionForFieldAccess(f, false); 469 return false; 470 } 471 } 472 473 uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data); 474 JValue value = GetFieldValue<field_type>(shadow_frame, vregA); 475 return DoFieldPutCommon<field_type, do_assignability_check, transaction_active>(self, 476 shadow_frame, 477 obj, 478 f, 479 value); 480} 481 482// Explicitly instantiate all DoFieldPut functions. 483#define EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, _do_check, _transaction_active) \ 484 template bool DoFieldPut<_find_type, _field_type, _do_check, _transaction_active>(Thread* self, \ 485 const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) 486 487#define EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(_find_type, _field_type) \ 488 EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, false, false); \ 489 EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, true, false); \ 490 EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, false, true); \ 491 EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL(_find_type, _field_type, true, true); 492 493// iput-XXX 494EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimBoolean) 495EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimByte) 496EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimChar) 497EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimShort) 498EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimInt) 499EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstancePrimitiveWrite, Primitive::kPrimLong) 500EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(InstanceObjectWrite, Primitive::kPrimNot) 501 502// sput-XXX 503EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimBoolean) 504EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimByte) 505EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimChar) 506EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimShort) 507EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimInt) 508EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticPrimitiveWrite, Primitive::kPrimLong) 509EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticObjectWrite, Primitive::kPrimNot) 510 511#undef EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL 512#undef EXPLICIT_DO_FIELD_PUT_TEMPLATE_DECL 513 514// Helper for setters in invoke-polymorphic. 515bool DoFieldPutForInvokePolymorphic(Thread* self, 516 ShadowFrame& shadow_frame, 517 ObjPtr<mirror::Object>& obj, 518 ArtField* field, 519 Primitive::Type field_type, 520 const JValue& value) 521 REQUIRES_SHARED(Locks::mutator_lock_) { 522 static const bool kDoCheckAssignability = false; 523 static const bool kTransaction = false; 524 switch (field_type) { 525 case Primitive::kPrimBoolean: 526 return DoFieldPutCommon<Primitive::kPrimBoolean, kDoCheckAssignability, kTransaction>( 527 self, shadow_frame, obj, field, value); 528 case Primitive::kPrimByte: 529 return DoFieldPutCommon<Primitive::kPrimByte, kDoCheckAssignability, kTransaction>( 530 self, shadow_frame, obj, field, value); 531 case Primitive::kPrimChar: 532 return DoFieldPutCommon<Primitive::kPrimChar, kDoCheckAssignability, kTransaction>( 533 self, shadow_frame, obj, field, value); 534 case Primitive::kPrimShort: 535 return DoFieldPutCommon<Primitive::kPrimShort, kDoCheckAssignability, kTransaction>( 536 self, shadow_frame, obj, field, value); 537 case Primitive::kPrimInt: 538 case Primitive::kPrimFloat: 539 return DoFieldPutCommon<Primitive::kPrimInt, kDoCheckAssignability, kTransaction>( 540 self, shadow_frame, obj, field, value); 541 case Primitive::kPrimLong: 542 case Primitive::kPrimDouble: 543 return DoFieldPutCommon<Primitive::kPrimLong, kDoCheckAssignability, kTransaction>( 544 self, shadow_frame, obj, field, value); 545 case Primitive::kPrimNot: 546 return DoFieldPutCommon<Primitive::kPrimNot, kDoCheckAssignability, kTransaction>( 547 self, shadow_frame, obj, field, value); 548 case Primitive::kPrimVoid: 549 LOG(FATAL) << "Unreachable: " << field_type; 550 UNREACHABLE(); 551 } 552} 553 554template<Primitive::Type field_type, bool transaction_active> 555bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { 556 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); 557 if (UNLIKELY(obj == nullptr)) { 558 // We lost the reference to the field index so we cannot get a more 559 // precised exception message. 560 ThrowNullPointerExceptionFromDexPC(); 561 return false; 562 } 563 MemberOffset field_offset(inst->VRegC_22c()); 564 const uint32_t vregA = inst->VRegA_22c(inst_data); 565 // Report this field modification to instrumentation if needed. Since we only have the offset of 566 // the field from the base of the object, we need to look for it first. 567 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 568 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) { 569 ArtField* f = ArtField::FindInstanceFieldWithOffset(obj->GetClass(), 570 field_offset.Uint32Value()); 571 DCHECK(f != nullptr); 572 DCHECK(!f->IsStatic()); 573 JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA); 574 StackHandleScope<1> hs(Thread::Current()); 575 // Save obj in case the instrumentation event has thread suspension. 576 HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&obj); 577 instrumentation->FieldWriteEvent(Thread::Current(), 578 obj.Ptr(), 579 shadow_frame.GetMethod(), 580 shadow_frame.GetDexPC(), 581 f, 582 field_value); 583 } 584 // Note: iput-x-quick instructions are only for non-volatile fields. 585 switch (field_type) { 586 case Primitive::kPrimBoolean: 587 obj->SetFieldBoolean<transaction_active>(field_offset, shadow_frame.GetVReg(vregA)); 588 break; 589 case Primitive::kPrimByte: 590 obj->SetFieldByte<transaction_active>(field_offset, shadow_frame.GetVReg(vregA)); 591 break; 592 case Primitive::kPrimChar: 593 obj->SetFieldChar<transaction_active>(field_offset, shadow_frame.GetVReg(vregA)); 594 break; 595 case Primitive::kPrimShort: 596 obj->SetFieldShort<transaction_active>(field_offset, shadow_frame.GetVReg(vregA)); 597 break; 598 case Primitive::kPrimInt: 599 obj->SetField32<transaction_active>(field_offset, shadow_frame.GetVReg(vregA)); 600 break; 601 case Primitive::kPrimLong: 602 obj->SetField64<transaction_active>(field_offset, shadow_frame.GetVRegLong(vregA)); 603 break; 604 case Primitive::kPrimNot: 605 obj->SetFieldObject<transaction_active>(field_offset, shadow_frame.GetVRegReference(vregA)); 606 break; 607 default: 608 LOG(FATAL) << "Unreachable: " << field_type; 609 UNREACHABLE(); 610 } 611 return true; 612} 613 614// Explicitly instantiate all DoIPutQuick functions. 615#define EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, _transaction_active) \ 616 template bool DoIPutQuick<_field_type, _transaction_active>(const ShadowFrame& shadow_frame, \ 617 const Instruction* inst, \ 618 uint16_t inst_data) 619 620#define EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(_field_type) \ 621 EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, false); \ 622 EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL(_field_type, true); 623 624EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimInt) // iput-quick. 625EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimBoolean) // iput-boolean-quick. 626EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimByte) // iput-byte-quick. 627EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimChar) // iput-char-quick. 628EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimShort) // iput-short-quick. 629EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimLong) // iput-wide-quick. 630EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL(Primitive::kPrimNot) // iput-object-quick. 631#undef EXPLICIT_DO_IPUT_QUICK_ALL_TEMPLATE_DECL 632#undef EXPLICIT_DO_IPUT_QUICK_TEMPLATE_DECL 633 634// We accept a null Instrumentation* meaning we must not report anything to the instrumentation. 635uint32_t FindNextInstructionFollowingException( 636 Thread* self, ShadowFrame& shadow_frame, uint32_t dex_pc, 637 const instrumentation::Instrumentation* instrumentation) { 638 self->VerifyStack(); 639 StackHandleScope<2> hs(self); 640 Handle<mirror::Throwable> exception(hs.NewHandle(self->GetException())); 641 if (instrumentation != nullptr && instrumentation->HasExceptionCaughtListeners() 642 && self->IsExceptionThrownByCurrentMethod(exception.Get())) { 643 instrumentation->ExceptionCaughtEvent(self, exception.Get()); 644 } 645 bool clear_exception = false; 646 uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock( 647 hs.NewHandle(exception->GetClass()), dex_pc, &clear_exception); 648 if (found_dex_pc == DexFile::kDexNoIndex && instrumentation != nullptr) { 649 // Exception is not caught by the current method. We will unwind to the 650 // caller. Notify any instrumentation listener. 651 instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(), 652 shadow_frame.GetMethod(), dex_pc); 653 } else { 654 // Exception is caught in the current method. We will jump to the found_dex_pc. 655 if (clear_exception) { 656 self->ClearException(); 657 } 658 } 659 return found_dex_pc; 660} 661 662void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame) { 663 LOG(FATAL) << "Unexpected instruction: " 664 << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()); 665 UNREACHABLE(); 666} 667 668void AbortTransactionF(Thread* self, const char* fmt, ...) { 669 va_list args; 670 va_start(args, fmt); 671 AbortTransactionV(self, fmt, args); 672 va_end(args); 673} 674 675void AbortTransactionV(Thread* self, const char* fmt, va_list args) { 676 CHECK(Runtime::Current()->IsActiveTransaction()); 677 // Constructs abort message. 678 std::string abort_msg; 679 StringAppendV(&abort_msg, fmt, args); 680 // Throws an exception so we can abort the transaction and rollback every change. 681 Runtime::Current()->AbortTransactionAndThrowAbortError(self, abort_msg); 682} 683 684// START DECLARATIONS : 685// 686// These additional declarations are required because clang complains 687// about ALWAYS_INLINE (-Werror, -Wgcc-compat) in definitions. 688// 689 690template <bool is_range, bool do_assignability_check> 691static ALWAYS_INLINE bool DoCallCommon(ArtMethod* called_method, 692 Thread* self, 693 ShadowFrame& shadow_frame, 694 JValue* result, 695 uint16_t number_of_inputs, 696 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 697 uint32_t vregC) REQUIRES_SHARED(Locks::mutator_lock_); 698 699template <bool is_range> 700static ALWAYS_INLINE bool DoCallPolymorphic(ArtMethod* called_method, 701 Handle<mirror::MethodType> callsite_type, 702 Handle<mirror::MethodType> target_type, 703 Thread* self, 704 ShadowFrame& shadow_frame, 705 JValue* result, 706 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 707 uint32_t vregC, 708 const MethodHandleKind handle_kind) 709 REQUIRES_SHARED(Locks::mutator_lock_); 710 711template <bool is_range> 712static ALWAYS_INLINE bool DoCallTransform(ArtMethod* called_method, 713 Handle<mirror::MethodType> callsite_type, 714 Handle<mirror::MethodType> callee_type, 715 Thread* self, 716 ShadowFrame& shadow_frame, 717 Handle<mirror::MethodHandleImpl> receiver, 718 JValue* result, 719 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 720 uint32_t vregC) REQUIRES_SHARED(Locks::mutator_lock_); 721 722ALWAYS_INLINE void PerformCall(Thread* self, 723 const DexFile::CodeItem* code_item, 724 ArtMethod* caller_method, 725 const size_t first_dest_reg, 726 ShadowFrame* callee_frame, 727 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_); 728 729template <bool is_range> 730ALWAYS_INLINE void CopyRegisters(ShadowFrame& caller_frame, 731 ShadowFrame* callee_frame, 732 const uint32_t (&arg)[Instruction::kMaxVarArgRegs], 733 const size_t first_src_reg, 734 const size_t first_dest_reg, 735 const size_t num_regs) REQUIRES_SHARED(Locks::mutator_lock_); 736 737// END DECLARATIONS. 738 739void ArtInterpreterToCompiledCodeBridge(Thread* self, 740 ArtMethod* caller, 741 const DexFile::CodeItem* code_item, 742 ShadowFrame* shadow_frame, 743 JValue* result) 744 REQUIRES_SHARED(Locks::mutator_lock_) { 745 ArtMethod* method = shadow_frame->GetMethod(); 746 // Ensure static methods are initialized. 747 if (method->IsStatic()) { 748 ObjPtr<mirror::Class> declaringClass = method->GetDeclaringClass(); 749 if (UNLIKELY(!declaringClass->IsInitialized())) { 750 self->PushShadowFrame(shadow_frame); 751 StackHandleScope<1> hs(self); 752 Handle<mirror::Class> h_class(hs.NewHandle(declaringClass)); 753 if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_class, true, 754 true))) { 755 self->PopShadowFrame(); 756 DCHECK(self->IsExceptionPending()); 757 return; 758 } 759 self->PopShadowFrame(); 760 CHECK(h_class->IsInitializing()); 761 // Reload from shadow frame in case the method moved, this is faster than adding a handle. 762 method = shadow_frame->GetMethod(); 763 } 764 } 765 uint16_t arg_offset = (code_item == nullptr) 766 ? 0 767 : code_item->registers_size_ - code_item->ins_size_; 768 jit::Jit* jit = Runtime::Current()->GetJit(); 769 if (jit != nullptr && caller != nullptr) { 770 jit->NotifyInterpreterToCompiledCodeTransition(self, caller); 771 } 772 method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset), 773 (shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t), 774 result, method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty()); 775} 776 777void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame, 778 uint16_t this_obj_vreg, 779 JValue result) 780 REQUIRES_SHARED(Locks::mutator_lock_) { 781 ObjPtr<mirror::Object> existing = shadow_frame->GetVRegReference(this_obj_vreg); 782 if (existing == nullptr) { 783 // If it's null, we come from compiled code that was deoptimized. Nothing to do, 784 // as the compiler verified there was no alias. 785 // Set the new string result of the StringFactory. 786 shadow_frame->SetVRegReference(this_obj_vreg, result.GetL()); 787 return; 788 } 789 // Set the string init result into all aliases. 790 for (uint32_t i = 0, e = shadow_frame->NumberOfVRegs(); i < e; ++i) { 791 if (shadow_frame->GetVRegReference(i) == existing) { 792 DCHECK_EQ(shadow_frame->GetVRegReference(i), 793 reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i))); 794 shadow_frame->SetVRegReference(i, result.GetL()); 795 DCHECK_EQ(shadow_frame->GetVRegReference(i), 796 reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i))); 797 } 798 } 799} 800 801inline static bool IsInvokeExact(const DexFile& dex_file, int invoke_method_idx) { 802 // This check uses string comparison as it needs less code and data 803 // to do than fetching the associated ArtMethod from the DexCache 804 // and checking against ArtMethods in the well known classes. The 805 // verifier needs to perform a more rigorous check. 806 const char* method_name = dex_file.GetMethodName(dex_file.GetMethodId(invoke_method_idx)); 807 bool is_invoke_exact = (0 == strcmp(method_name, "invokeExact")); 808 DCHECK(is_invoke_exact || (0 == strcmp(method_name, "invoke"))); 809 return is_invoke_exact; 810} 811 812inline static ObjPtr<mirror::Class> GetAndInitializeDeclaringClass(Thread* self, ArtField* field) 813 REQUIRES_SHARED(Locks::mutator_lock_) { 814 // Method handle invocations on static fields should ensure class is 815 // initialized. This usually happens when an instance is constructed 816 // or class members referenced, but this is not guaranteed when 817 // looking up method handles. 818 ObjPtr<mirror::Class> klass = field->GetDeclaringClass(); 819 if (UNLIKELY(!klass->IsInitialized())) { 820 StackHandleScope<1> hs(self); 821 HandleWrapperObjPtr<mirror::Class> h(hs.NewHandleWrapper(&klass)); 822 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h, true, true)) { 823 DCHECK(self->IsExceptionPending()); 824 return nullptr; 825 } 826 } 827 return klass; 828} 829 830// Returns true iff. the callsite type for a polymorphic invoke is transformer 831// like, i.e that it has a single input argument whose type is 832// dalvik.system.EmulatedStackFrame. 833static inline bool IsCallerTransformer(Handle<mirror::MethodType> callsite_type) 834 REQUIRES_SHARED(Locks::mutator_lock_) { 835 ObjPtr<mirror::ObjectArray<mirror::Class>> param_types(callsite_type->GetPTypes()); 836 if (param_types->GetLength() == 1) { 837 ObjPtr<mirror::Class> param(param_types->GetWithoutChecks(0)); 838 return param == WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_EmulatedStackFrame); 839 } 840 841 return false; 842} 843 844template<bool is_range, bool do_access_check> 845inline bool DoInvokePolymorphic(Thread* self, 846 ShadowFrame& shadow_frame, 847 const Instruction* inst, 848 uint16_t inst_data, 849 JValue* result) 850 REQUIRES_SHARED(Locks::mutator_lock_) { 851 // Invoke-polymorphic instructions always take a receiver. i.e, they are never static. 852 const uint32_t vRegC = (is_range) ? inst->VRegC_4rcc() : inst->VRegC_45cc(); 853 const int invoke_method_idx = (is_range) ? inst->VRegB_4rcc() : inst->VRegB_45cc(); 854 855 // Initialize |result| to 0 as this is the default return value for 856 // polymorphic invocations of method handle types with void return 857 // and provides sane return result in error cases. 858 result->SetJ(0); 859 860 // Determine if this invocation is MethodHandle.invoke() or 861 // MethodHandle.invokeExact(). 862 bool is_invoke_exact = IsInvokeExact(shadow_frame.GetMethod()->GetDeclaringClass()->GetDexFile(), 863 invoke_method_idx); 864 865 // The invoke_method_idx here is the name of the signature polymorphic method that 866 // was symbolically invoked in bytecode (say MethodHandle.invoke or MethodHandle.invokeExact) 867 // and not the method that we'll dispatch to in the end. 868 StackHandleScope<6> hs(self); 869 Handle<mirror::MethodHandleImpl> method_handle(hs.NewHandle( 870 ObjPtr<mirror::MethodHandleImpl>::DownCast( 871 MakeObjPtr(shadow_frame.GetVRegReference(vRegC))))); 872 if (UNLIKELY(method_handle.Get() == nullptr)) { 873 // Note that the invoke type is kVirtual here because a call to a signature 874 // polymorphic method is shaped like a virtual call at the bytecode level. 875 ThrowNullPointerExceptionForMethodAccess(invoke_method_idx, InvokeType::kVirtual); 876 return false; 877 } 878 879 // The vRegH value gives the index of the proto_id associated with this 880 // signature polymorphic callsite. 881 const uint32_t callsite_proto_id = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc(); 882 883 // Call through to the classlinker and ask it to resolve the static type associated 884 // with the callsite. This information is stored in the dex cache so it's 885 // guaranteed to be fast after the first resolution. 886 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 887 Handle<mirror::Class> caller_class(hs.NewHandle(shadow_frame.GetMethod()->GetDeclaringClass())); 888 Handle<mirror::MethodType> callsite_type(hs.NewHandle(class_linker->ResolveMethodType( 889 caller_class->GetDexFile(), callsite_proto_id, 890 hs.NewHandle<mirror::DexCache>(caller_class->GetDexCache()), 891 hs.NewHandle<mirror::ClassLoader>(caller_class->GetClassLoader())))); 892 893 // This implies we couldn't resolve one or more types in this method handle. 894 if (UNLIKELY(callsite_type.Get() == nullptr)) { 895 CHECK(self->IsExceptionPending()); 896 return false; 897 } 898 899 const MethodHandleKind handle_kind = method_handle->GetHandleKind(); 900 Handle<mirror::MethodType> handle_type(hs.NewHandle(method_handle->GetMethodType())); 901 CHECK(handle_type.Get() != nullptr); 902 { 903 // We need to check the nominal type of the handle in addition to the 904 // real type. The "nominal" type is present when MethodHandle.asType is 905 // called any handle, and results in the declared type of the handle 906 // changing. 907 ObjPtr<mirror::MethodType> nominal_type(method_handle->GetNominalType()); 908 ObjPtr<mirror::MethodType> check_type(nullptr); 909 if (LIKELY(nominal_type.Ptr() == nullptr)) { 910 check_type.Assign(handle_type.Get()); 911 } else { 912 check_type.Assign(nominal_type.Ptr()); 913 } 914 915 if (is_invoke_exact) { 916 if (UNLIKELY(!callsite_type->IsExactMatch(check_type.Ptr()))) { 917 ThrowWrongMethodTypeException(check_type.Ptr(), callsite_type.Get()); 918 return false; 919 } 920 } else if (!IsInvokeTransform(handle_kind)) { 921 if (UNLIKELY(!IsCallerTransformer(callsite_type) && 922 !callsite_type->IsConvertible(check_type.Ptr()))) { 923 ThrowWrongMethodTypeException(check_type.Ptr(), callsite_type.Get()); 924 return false; 925 } 926 } 927 } 928 929 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; 930 uint32_t first_src_reg = 0; 931 if (is_range) { 932 first_src_reg = (inst->VRegC_4rcc() + 1); 933 } else { 934 inst->GetVarArgs(arg, inst_data); 935 arg[0] = arg[1]; 936 arg[1] = arg[2]; 937 arg[2] = arg[3]; 938 arg[3] = arg[4]; 939 arg[4] = 0; 940 first_src_reg = arg[0]; 941 } 942 943 if (IsInvoke(handle_kind)) { 944 // Get the method we're actually invoking along with the kind of 945 // invoke that is desired. We don't need to perform access checks at this 946 // point because they would have been performed on our behalf at the point 947 // of creation of the method handle. 948 ArtMethod* called_method = method_handle->GetTargetMethod(); 949 CHECK(called_method != nullptr); 950 951 if (handle_kind == kInvokeVirtual || handle_kind == kInvokeInterface) { 952 // TODO: Unfortunately, we have to postpone dynamic receiver based checks 953 // because the receiver might be cast or might come from an emulated stack 954 // frame, which means that it is unknown at this point. We perform these 955 // checks inside DoCallPolymorphic right before we do the actual invoke. 956 } else if (handle_kind == kInvokeDirect) { 957 // String constructors are a special case, they are replaced with StringFactory 958 // methods. 959 if (called_method->IsConstructor() && called_method->GetDeclaringClass()->IsStringClass()) { 960 DCHECK(handle_type->GetRType()->IsStringClass()); 961 called_method = WellKnownClasses::StringInitToStringFactory(called_method); 962 } 963 } else if (handle_kind == kInvokeSuper) { 964 ObjPtr<mirror::Class> declaring_class = called_method->GetDeclaringClass(); 965 966 // Note that we're not dynamically dispatching on the type of the receiver 967 // here. We use the static type of the "receiver" object that we've 968 // recorded in the method handle's type, which will be the same as the 969 // special caller that was specified at the point of lookup. 970 ObjPtr<mirror::Class> referrer_class = handle_type->GetPTypes()->Get(0); 971 if (!declaring_class->IsInterface()) { 972 ObjPtr<mirror::Class> super_class = referrer_class->GetSuperClass(); 973 uint16_t vtable_index = called_method->GetMethodIndex(); 974 DCHECK(super_class != nullptr); 975 DCHECK(super_class->HasVTable()); 976 // Note that super_class is a super of referrer_class and called_method 977 // will always be declared by super_class (or one of its super classes). 978 DCHECK_LT(vtable_index, super_class->GetVTableLength()); 979 called_method = super_class->GetVTableEntry(vtable_index, kRuntimePointerSize); 980 } else { 981 called_method = referrer_class->FindVirtualMethodForInterfaceSuper( 982 called_method, kRuntimePointerSize); 983 } 984 985 CHECK(called_method != nullptr); 986 } 987 988 if (IsInvokeTransform(handle_kind)) { 989 // There are two cases here - method handles representing regular 990 // transforms and those representing call site transforms. Method 991 // handles for call site transforms adapt their MethodType to match 992 // the call site. For these, the |callee_type| is the same as the 993 // |callsite_type|. The VarargsCollector is such a tranform, its 994 // method type depends on the call site, ie. x(a) or x(a, b), or 995 // x(a, b, c). The VarargsCollector invokes a variable arity method 996 // with the arity arguments in an array. 997 Handle<mirror::MethodType> callee_type = 998 (handle_kind == kInvokeCallSiteTransform) ? callsite_type : handle_type; 999 return DoCallTransform<is_range>(called_method, 1000 callsite_type, 1001 callee_type, 1002 self, 1003 shadow_frame, 1004 method_handle /* receiver */, 1005 result, 1006 arg, 1007 first_src_reg); 1008 } else { 1009 return DoCallPolymorphic<is_range>(called_method, 1010 callsite_type, 1011 handle_type, 1012 self, 1013 shadow_frame, 1014 result, 1015 arg, 1016 first_src_reg, 1017 handle_kind); 1018 } 1019 } else { 1020 DCHECK(!is_range); 1021 ArtField* field = method_handle->GetTargetField(); 1022 Primitive::Type field_type = field->GetTypeAsPrimitiveType(); 1023 1024 switch (handle_kind) { 1025 case kInstanceGet: { 1026 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(first_src_reg); 1027 DoFieldGetForInvokePolymorphic(self, shadow_frame, obj, field, field_type, result); 1028 if (!ConvertReturnValue(callsite_type, handle_type, result)) { 1029 DCHECK(self->IsExceptionPending()); 1030 return false; 1031 } 1032 return true; 1033 } 1034 case kStaticGet: { 1035 ObjPtr<mirror::Object> obj = GetAndInitializeDeclaringClass(self, field); 1036 if (obj == nullptr) { 1037 DCHECK(self->IsExceptionPending()); 1038 return false; 1039 } 1040 DoFieldGetForInvokePolymorphic(self, shadow_frame, obj, field, field_type, result); 1041 if (!ConvertReturnValue(callsite_type, handle_type, result)) { 1042 DCHECK(self->IsExceptionPending()); 1043 return false; 1044 } 1045 return true; 1046 } 1047 case kInstancePut: { 1048 JValue value = GetFieldValue(shadow_frame, field_type, arg[1]); 1049 if (!ConvertArgumentValue(callsite_type, handle_type, 1, &value)) { 1050 DCHECK(self->IsExceptionPending()); 1051 return false; 1052 } 1053 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(first_src_reg); 1054 return DoFieldPutForInvokePolymorphic(self, shadow_frame, obj, field, field_type, value); 1055 } 1056 case kStaticPut: { 1057 JValue value = GetFieldValue(shadow_frame, field_type, arg[0]); 1058 if (!ConvertArgumentValue(callsite_type, handle_type, 0, &value)) { 1059 DCHECK(self->IsExceptionPending()); 1060 return false; 1061 } 1062 ObjPtr<mirror::Object> obj = field->GetDeclaringClass(); 1063 return DoFieldPutForInvokePolymorphic(self, shadow_frame, obj, field, field_type, value); 1064 } 1065 default: 1066 LOG(FATAL) << "Unreachable: " << handle_kind; 1067 UNREACHABLE(); 1068 } 1069 } 1070} 1071 1072// Calculate the number of ins for a proxy or native method, where we 1073// can't just look at the code item. 1074static inline size_t GetInsForProxyOrNativeMethod(ArtMethod* method) 1075 REQUIRES_SHARED(Locks::mutator_lock_) { 1076 DCHECK(method->IsNative() || method->IsProxyMethod()); 1077 1078 method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); 1079 size_t num_ins = 0; 1080 // Separate accounting for the receiver, which isn't a part of the 1081 // shorty. 1082 if (!method->IsStatic()) { 1083 ++num_ins; 1084 } 1085 1086 uint32_t shorty_len = 0; 1087 const char* shorty = method->GetShorty(&shorty_len); 1088 for (size_t i = 1; i < shorty_len; ++i) { 1089 const char c = shorty[i]; 1090 ++num_ins; 1091 if (c == 'J' || c == 'D') { 1092 ++num_ins; 1093 } 1094 } 1095 1096 return num_ins; 1097} 1098 1099inline void PerformCall(Thread* self, 1100 const DexFile::CodeItem* code_item, 1101 ArtMethod* caller_method, 1102 const size_t first_dest_reg, 1103 ShadowFrame* callee_frame, 1104 JValue* result) { 1105 if (LIKELY(Runtime::Current()->IsStarted())) { 1106 ArtMethod* target = callee_frame->GetMethod(); 1107 if (ClassLinker::ShouldUseInterpreterEntrypoint( 1108 target, 1109 target->GetEntryPointFromQuickCompiledCode())) { 1110 ArtInterpreterToInterpreterBridge(self, code_item, callee_frame, result); 1111 } else { 1112 ArtInterpreterToCompiledCodeBridge( 1113 self, caller_method, code_item, callee_frame, result); 1114 } 1115 } else { 1116 UnstartedRuntime::Invoke(self, code_item, callee_frame, result, first_dest_reg); 1117 } 1118} 1119 1120template <bool is_range> 1121inline void CopyRegisters(ShadowFrame& caller_frame, 1122 ShadowFrame* callee_frame, 1123 const uint32_t (&arg)[Instruction::kMaxVarArgRegs], 1124 const size_t first_src_reg, 1125 const size_t first_dest_reg, 1126 const size_t num_regs) { 1127 if (is_range) { 1128 const size_t dest_reg_bound = first_dest_reg + num_regs; 1129 for (size_t src_reg = first_src_reg, dest_reg = first_dest_reg; dest_reg < dest_reg_bound; 1130 ++dest_reg, ++src_reg) { 1131 AssignRegister(callee_frame, caller_frame, dest_reg, src_reg); 1132 } 1133 } else { 1134 DCHECK_LE(num_regs, arraysize(arg)); 1135 1136 for (size_t arg_index = 0; arg_index < num_regs; ++arg_index) { 1137 AssignRegister(callee_frame, caller_frame, first_dest_reg + arg_index, arg[arg_index]); 1138 } 1139 } 1140} 1141 1142template <bool is_range> 1143static inline bool DoCallPolymorphic(ArtMethod* called_method, 1144 Handle<mirror::MethodType> callsite_type, 1145 Handle<mirror::MethodType> target_type, 1146 Thread* self, 1147 ShadowFrame& shadow_frame, 1148 JValue* result, 1149 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 1150 uint32_t first_src_reg, 1151 const MethodHandleKind handle_kind) { 1152 // Compute method information. 1153 const DexFile::CodeItem* code_item = called_method->GetCodeItem(); 1154 1155 // Number of registers for the callee's call frame. Note that for non-exact 1156 // invokes, we always derive this information from the callee method. We 1157 // cannot guarantee during verification that the number of registers encoded 1158 // in the invoke is equal to the number of ins for the callee. This is because 1159 // some transformations (such as boxing a long -> Long or wideining an 1160 // int -> long will change that number. 1161 uint16_t num_regs; 1162 size_t num_input_regs; 1163 size_t first_dest_reg; 1164 if (LIKELY(code_item != nullptr)) { 1165 num_regs = code_item->registers_size_; 1166 first_dest_reg = num_regs - code_item->ins_size_; 1167 num_input_regs = code_item->ins_size_; 1168 // Parameter registers go at the end of the shadow frame. 1169 DCHECK_NE(first_dest_reg, (size_t)-1); 1170 } else { 1171 // No local regs for proxy and native methods. 1172 DCHECK(called_method->IsNative() || called_method->IsProxyMethod()); 1173 num_regs = num_input_regs = GetInsForProxyOrNativeMethod(called_method); 1174 first_dest_reg = 0; 1175 } 1176 1177 // Allocate shadow frame on the stack. 1178 ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 1179 CREATE_SHADOW_FRAME(num_regs, &shadow_frame, called_method, /* dex pc */ 0); 1180 ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get(); 1181 1182 // Whether this polymorphic invoke was issued by a transformer method. 1183 bool is_caller_transformer = false; 1184 // Thread might be suspended during PerformArgumentConversions due to the 1185 // allocations performed during boxing. 1186 { 1187 ScopedStackedShadowFramePusher pusher( 1188 self, new_shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction); 1189 if (callsite_type->IsExactMatch(target_type.Get())) { 1190 // This is an exact invoke, we can take the fast path of just copying all 1191 // registers without performing any argument conversions. 1192 CopyRegisters<is_range>(shadow_frame, 1193 new_shadow_frame, 1194 arg, 1195 first_src_reg, 1196 first_dest_reg, 1197 num_input_regs); 1198 } else { 1199 // This includes the case where we're entering this invoke-polymorphic 1200 // from a transformer method. In that case, the callsite_type will contain 1201 // a single argument of type dalvik.system.EmulatedStackFrame. In that 1202 // case, we'll have to unmarshal the EmulatedStackFrame into the 1203 // new_shadow_frame and perform argument conversions on it. 1204 if (IsCallerTransformer(callsite_type)) { 1205 is_caller_transformer = true; 1206 // The emulated stack frame is the first and only argument when we're coming 1207 // through from a transformer. 1208 ObjPtr<mirror::EmulatedStackFrame> emulated_stack_frame( 1209 reinterpret_cast<mirror::EmulatedStackFrame*>( 1210 shadow_frame.GetVRegReference(first_src_reg))); 1211 if (!emulated_stack_frame->WriteToShadowFrame(self, 1212 target_type, 1213 first_dest_reg, 1214 new_shadow_frame)) { 1215 DCHECK(self->IsExceptionPending()); 1216 result->SetL(0); 1217 return false; 1218 } 1219 } else if (!ConvertAndCopyArgumentsFromCallerFrame<is_range>(self, 1220 callsite_type, 1221 target_type, 1222 shadow_frame, 1223 first_src_reg, 1224 first_dest_reg, 1225 arg, 1226 new_shadow_frame)) { 1227 DCHECK(self->IsExceptionPending()); 1228 result->SetL(0); 1229 return false; 1230 } 1231 } 1232 } 1233 1234 // See TODO in DoInvokePolymorphic : We need to perform this dynamic, receiver 1235 // based dispatch right before we perform the actual call, because the 1236 // receiver isn't known very early. 1237 if (handle_kind == kInvokeVirtual || handle_kind == kInvokeInterface) { 1238 ObjPtr<mirror::Object> receiver(new_shadow_frame->GetVRegReference(first_dest_reg)); 1239 ObjPtr<mirror::Class> declaring_class(called_method->GetDeclaringClass()); 1240 // Verify that _vRegC is an object reference and of the type expected by 1241 // the receiver. 1242 if (!VerifyObjectIsClass(receiver, declaring_class)) { 1243 DCHECK(self->IsExceptionPending()); 1244 return false; 1245 } 1246 1247 called_method = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface( 1248 called_method, kRuntimePointerSize); 1249 } 1250 1251 PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result); 1252 if (self->IsExceptionPending()) { 1253 return false; 1254 } 1255 1256 // If the caller of this signature polymorphic method was a transformer, 1257 // we need to copy the result back out to the emulated stack frame. 1258 if (is_caller_transformer) { 1259 StackHandleScope<2> hs(self); 1260 Handle<mirror::EmulatedStackFrame> emulated_stack_frame( 1261 hs.NewHandle(reinterpret_cast<mirror::EmulatedStackFrame*>( 1262 shadow_frame.GetVRegReference(first_src_reg)))); 1263 Handle<mirror::MethodType> emulated_stack_type(hs.NewHandle(emulated_stack_frame->GetType())); 1264 JValue local_result; 1265 local_result.SetJ(result->GetJ()); 1266 1267 if (ConvertReturnValue(emulated_stack_type, target_type, &local_result)) { 1268 emulated_stack_frame->SetReturnValue(self, local_result); 1269 return true; 1270 } else { 1271 DCHECK(self->IsExceptionPending()); 1272 return false; 1273 } 1274 } else { 1275 return ConvertReturnValue(callsite_type, target_type, result); 1276 } 1277} 1278 1279template <bool is_range> 1280static inline bool DoCallTransform(ArtMethod* called_method, 1281 Handle<mirror::MethodType> callsite_type, 1282 Handle<mirror::MethodType> callee_type, 1283 Thread* self, 1284 ShadowFrame& shadow_frame, 1285 Handle<mirror::MethodHandleImpl> receiver, 1286 JValue* result, 1287 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 1288 uint32_t first_src_reg) { 1289 // This can be fixed to two, because the method we're calling here 1290 // (MethodHandle.transformInternal) doesn't have any locals and the signature 1291 // is known : 1292 // 1293 // private MethodHandle.transformInternal(EmulatedStackFrame sf); 1294 // 1295 // This means we need only two vregs : 1296 // - One for the receiver object. 1297 // - One for the only method argument (an EmulatedStackFrame). 1298 static constexpr size_t kNumRegsForTransform = 2; 1299 1300 const DexFile::CodeItem* code_item = called_method->GetCodeItem(); 1301 DCHECK(code_item != nullptr); 1302 DCHECK_EQ(kNumRegsForTransform, code_item->registers_size_); 1303 DCHECK_EQ(kNumRegsForTransform, code_item->ins_size_); 1304 1305 ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 1306 CREATE_SHADOW_FRAME(kNumRegsForTransform, &shadow_frame, called_method, /* dex pc */ 0); 1307 ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get(); 1308 1309 StackHandleScope<1> hs(self); 1310 MutableHandle<mirror::EmulatedStackFrame> sf(hs.NewHandle<mirror::EmulatedStackFrame>(nullptr)); 1311 if (IsCallerTransformer(callsite_type)) { 1312 // If we're entering this transformer from another transformer, we can pass 1313 // through the handle directly to the callee, instead of having to 1314 // instantiate a new stack frame based on the shadow frame. 1315 sf.Assign(reinterpret_cast<mirror::EmulatedStackFrame*>( 1316 shadow_frame.GetVRegReference(first_src_reg))); 1317 } else { 1318 sf.Assign(mirror::EmulatedStackFrame::CreateFromShadowFrameAndArgs<is_range>( 1319 self, 1320 callsite_type, 1321 callee_type, 1322 shadow_frame, 1323 first_src_reg, 1324 arg)); 1325 1326 // Something went wrong while creating the emulated stack frame, we should 1327 // throw the pending exception. 1328 if (sf.Get() == nullptr) { 1329 DCHECK(self->IsExceptionPending()); 1330 return false; 1331 } 1332 } 1333 1334 new_shadow_frame->SetVRegReference(0, receiver.Get()); 1335 new_shadow_frame->SetVRegReference(1, sf.Get()); 1336 1337 PerformCall(self, 1338 code_item, 1339 shadow_frame.GetMethod(), 1340 0 /* first dest reg */, 1341 new_shadow_frame, 1342 result); 1343 if (self->IsExceptionPending()) { 1344 return false; 1345 } 1346 1347 // If the called transformer method we called has returned a value, then we 1348 // need to copy it back to |result|. 1349 sf->GetReturnValue(self, result); 1350 return ConvertReturnValue(callsite_type, callee_type, result); 1351} 1352 1353template <bool is_range, 1354 bool do_assignability_check> 1355static inline bool DoCallCommon(ArtMethod* called_method, 1356 Thread* self, 1357 ShadowFrame& shadow_frame, 1358 JValue* result, 1359 uint16_t number_of_inputs, 1360 uint32_t (&arg)[Instruction::kMaxVarArgRegs], 1361 uint32_t vregC) { 1362 bool string_init = false; 1363 // Replace calls to String.<init> with equivalent StringFactory call. 1364 if (UNLIKELY(called_method->GetDeclaringClass()->IsStringClass() 1365 && called_method->IsConstructor())) { 1366 called_method = WellKnownClasses::StringInitToStringFactory(called_method); 1367 string_init = true; 1368 } 1369 1370 // Compute method information. 1371 const DexFile::CodeItem* code_item = called_method->GetCodeItem(); 1372 1373 // Number of registers for the callee's call frame. 1374 uint16_t num_regs; 1375 if (LIKELY(code_item != nullptr)) { 1376 num_regs = code_item->registers_size_; 1377 DCHECK_EQ(string_init ? number_of_inputs - 1 : number_of_inputs, code_item->ins_size_); 1378 } else { 1379 DCHECK(called_method->IsNative() || called_method->IsProxyMethod()); 1380 num_regs = number_of_inputs; 1381 } 1382 1383 // Hack for String init: 1384 // 1385 // Rewrite invoke-x java.lang.String.<init>(this, a, b, c, ...) into: 1386 // invoke-x StringFactory(a, b, c, ...) 1387 // by effectively dropping the first virtual register from the invoke. 1388 // 1389 // (at this point the ArtMethod has already been replaced, 1390 // so we just need to fix-up the arguments) 1391 // 1392 // Note that FindMethodFromCode in entrypoint_utils-inl.h was also special-cased 1393 // to handle the compiler optimization of replacing `this` with null without 1394 // throwing NullPointerException. 1395 uint32_t string_init_vreg_this = is_range ? vregC : arg[0]; 1396 if (UNLIKELY(string_init)) { 1397 DCHECK_GT(num_regs, 0u); // As the method is an instance method, there should be at least 1. 1398 1399 // The new StringFactory call is static and has one fewer argument. 1400 if (code_item == nullptr) { 1401 DCHECK(called_method->IsNative() || called_method->IsProxyMethod()); 1402 num_regs--; 1403 } // else ... don't need to change num_regs since it comes up from the string_init's code item 1404 number_of_inputs--; 1405 1406 // Rewrite the var-args, dropping the 0th argument ("this") 1407 for (uint32_t i = 1; i < arraysize(arg); ++i) { 1408 arg[i - 1] = arg[i]; 1409 } 1410 arg[arraysize(arg) - 1] = 0; 1411 1412 // Rewrite the non-var-arg case 1413 vregC++; // Skips the 0th vreg in the range ("this"). 1414 } 1415 1416 // Parameter registers go at the end of the shadow frame. 1417 DCHECK_GE(num_regs, number_of_inputs); 1418 size_t first_dest_reg = num_regs - number_of_inputs; 1419 DCHECK_NE(first_dest_reg, (size_t)-1); 1420 1421 // Allocate shadow frame on the stack. 1422 const char* old_cause = self->StartAssertNoThreadSuspension("DoCallCommon"); 1423 ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 1424 CREATE_SHADOW_FRAME(num_regs, &shadow_frame, called_method, /* dex pc */ 0); 1425 ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get(); 1426 1427 // Initialize new shadow frame by copying the registers from the callee shadow frame. 1428 if (do_assignability_check) { 1429 // Slow path. 1430 // We might need to do class loading, which incurs a thread state change to kNative. So 1431 // register the shadow frame as under construction and allow suspension again. 1432 ScopedStackedShadowFramePusher pusher( 1433 self, new_shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction); 1434 self->EndAssertNoThreadSuspension(old_cause); 1435 1436 // ArtMethod here is needed to check type information of the call site against the callee. 1437 // Type information is retrieved from a DexFile/DexCache for that respective declared method. 1438 // 1439 // As a special case for proxy methods, which are not dex-backed, 1440 // we have to retrieve type information from the proxy's method 1441 // interface method instead (which is dex backed since proxies are never interfaces). 1442 ArtMethod* method = 1443 new_shadow_frame->GetMethod()->GetInterfaceMethodIfProxy(kRuntimePointerSize); 1444 1445 // We need to do runtime check on reference assignment. We need to load the shorty 1446 // to get the exact type of each reference argument. 1447 const DexFile::TypeList* params = method->GetParameterTypeList(); 1448 uint32_t shorty_len = 0; 1449 const char* shorty = method->GetShorty(&shorty_len); 1450 1451 // Handle receiver apart since it's not part of the shorty. 1452 size_t dest_reg = first_dest_reg; 1453 size_t arg_offset = 0; 1454 1455 if (!method->IsStatic()) { 1456 size_t receiver_reg = is_range ? vregC : arg[0]; 1457 new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg)); 1458 ++dest_reg; 1459 ++arg_offset; 1460 DCHECK(!string_init); // All StringFactory methods are static. 1461 } 1462 1463 // Copy the caller's invoke-* arguments into the callee's parameter registers. 1464 for (uint32_t shorty_pos = 0; dest_reg < num_regs; ++shorty_pos, ++dest_reg, ++arg_offset) { 1465 // Skip the 0th 'shorty' type since it represents the return type. 1466 DCHECK_LT(shorty_pos + 1, shorty_len) << "for shorty '" << shorty << "'"; 1467 const size_t src_reg = (is_range) ? vregC + arg_offset : arg[arg_offset]; 1468 switch (shorty[shorty_pos + 1]) { 1469 // Handle Object references. 1 virtual register slot. 1470 case 'L': { 1471 ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference(src_reg); 1472 if (do_assignability_check && o != nullptr) { 1473 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 1474 const dex::TypeIndex type_idx = params->GetTypeItem(shorty_pos).type_idx_; 1475 ObjPtr<mirror::Class> arg_type = method->GetDexCacheResolvedType(type_idx, 1476 pointer_size); 1477 if (arg_type == nullptr) { 1478 StackHandleScope<1> hs(self); 1479 // Preserve o since it is used below and GetClassFromTypeIndex may cause thread 1480 // suspension. 1481 HandleWrapperObjPtr<mirror::Object> h = hs.NewHandleWrapper(&o); 1482 arg_type = method->GetClassFromTypeIndex(type_idx, true /* resolve */, pointer_size); 1483 if (arg_type == nullptr) { 1484 CHECK(self->IsExceptionPending()); 1485 return false; 1486 } 1487 } 1488 if (!o->VerifierInstanceOf(arg_type)) { 1489 // This should never happen. 1490 std::string temp1, temp2; 1491 self->ThrowNewExceptionF("Ljava/lang/InternalError;", 1492 "Invoking %s with bad arg %d, type '%s' not instance of '%s'", 1493 new_shadow_frame->GetMethod()->GetName(), shorty_pos, 1494 o->GetClass()->GetDescriptor(&temp1), 1495 arg_type->GetDescriptor(&temp2)); 1496 return false; 1497 } 1498 } 1499 new_shadow_frame->SetVRegReference(dest_reg, o.Ptr()); 1500 break; 1501 } 1502 // Handle doubles and longs. 2 consecutive virtual register slots. 1503 case 'J': case 'D': { 1504 uint64_t wide_value = 1505 (static_cast<uint64_t>(shadow_frame.GetVReg(src_reg + 1)) << BitSizeOf<uint32_t>()) | 1506 static_cast<uint32_t>(shadow_frame.GetVReg(src_reg)); 1507 new_shadow_frame->SetVRegLong(dest_reg, wide_value); 1508 // Skip the next virtual register slot since we already used it. 1509 ++dest_reg; 1510 ++arg_offset; 1511 break; 1512 } 1513 // Handle all other primitives that are always 1 virtual register slot. 1514 default: 1515 new_shadow_frame->SetVReg(dest_reg, shadow_frame.GetVReg(src_reg)); 1516 break; 1517 } 1518 } 1519 } else { 1520 if (is_range) { 1521 DCHECK_EQ(num_regs, first_dest_reg + number_of_inputs); 1522 } 1523 1524 CopyRegisters<is_range>(shadow_frame, 1525 new_shadow_frame, 1526 arg, 1527 vregC, 1528 first_dest_reg, 1529 number_of_inputs); 1530 self->EndAssertNoThreadSuspension(old_cause); 1531 } 1532 1533 PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result); 1534 1535 if (string_init && !self->IsExceptionPending()) { 1536 SetStringInitValueToAllAliases(&shadow_frame, string_init_vreg_this, *result); 1537 } 1538 1539 return !self->IsExceptionPending(); 1540} 1541 1542template<bool is_range, bool do_assignability_check> 1543bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame, 1544 const Instruction* inst, uint16_t inst_data, JValue* result) { 1545 // Argument word count. 1546 const uint16_t number_of_inputs = 1547 (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data); 1548 1549 // TODO: find a cleaner way to separate non-range and range information without duplicating 1550 // code. 1551 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; // only used in invoke-XXX. 1552 uint32_t vregC = 0; 1553 if (is_range) { 1554 vregC = inst->VRegC_3rc(); 1555 } else { 1556 vregC = inst->VRegC_35c(); 1557 inst->GetVarArgs(arg, inst_data); 1558 } 1559 1560 return DoCallCommon<is_range, do_assignability_check>( 1561 called_method, self, shadow_frame, 1562 result, number_of_inputs, arg, vregC); 1563} 1564 1565template <bool is_range, bool do_access_check, bool transaction_active> 1566bool DoFilledNewArray(const Instruction* inst, 1567 const ShadowFrame& shadow_frame, 1568 Thread* self, 1569 JValue* result) { 1570 DCHECK(inst->Opcode() == Instruction::FILLED_NEW_ARRAY || 1571 inst->Opcode() == Instruction::FILLED_NEW_ARRAY_RANGE); 1572 const int32_t length = is_range ? inst->VRegA_3rc() : inst->VRegA_35c(); 1573 if (!is_range) { 1574 // Checks FILLED_NEW_ARRAY's length does not exceed 5 arguments. 1575 CHECK_LE(length, 5); 1576 } 1577 if (UNLIKELY(length < 0)) { 1578 ThrowNegativeArraySizeException(length); 1579 return false; 1580 } 1581 uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); 1582 ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), 1583 shadow_frame.GetMethod(), 1584 self, 1585 false, 1586 do_access_check); 1587 if (UNLIKELY(array_class == nullptr)) { 1588 DCHECK(self->IsExceptionPending()); 1589 return false; 1590 } 1591 CHECK(array_class->IsArrayClass()); 1592 ObjPtr<mirror::Class> component_class = array_class->GetComponentType(); 1593 const bool is_primitive_int_component = component_class->IsPrimitiveInt(); 1594 if (UNLIKELY(component_class->IsPrimitive() && !is_primitive_int_component)) { 1595 if (component_class->IsPrimitiveLong() || component_class->IsPrimitiveDouble()) { 1596 ThrowRuntimeException("Bad filled array request for type %s", 1597 component_class->PrettyDescriptor().c_str()); 1598 } else { 1599 self->ThrowNewExceptionF("Ljava/lang/InternalError;", 1600 "Found type %s; filled-new-array not implemented for anything but 'int'", 1601 component_class->PrettyDescriptor().c_str()); 1602 } 1603 return false; 1604 } 1605 ObjPtr<mirror::Object> new_array = mirror::Array::Alloc<true>( 1606 self, 1607 array_class, 1608 length, 1609 array_class->GetComponentSizeShift(), 1610 Runtime::Current()->GetHeap()->GetCurrentAllocator()); 1611 if (UNLIKELY(new_array == nullptr)) { 1612 self->AssertPendingOOMException(); 1613 return false; 1614 } 1615 uint32_t arg[Instruction::kMaxVarArgRegs]; // only used in filled-new-array. 1616 uint32_t vregC = 0; // only used in filled-new-array-range. 1617 if (is_range) { 1618 vregC = inst->VRegC_3rc(); 1619 } else { 1620 inst->GetVarArgs(arg); 1621 } 1622 for (int32_t i = 0; i < length; ++i) { 1623 size_t src_reg = is_range ? vregC + i : arg[i]; 1624 if (is_primitive_int_component) { 1625 new_array->AsIntArray()->SetWithoutChecks<transaction_active>( 1626 i, shadow_frame.GetVReg(src_reg)); 1627 } else { 1628 new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<transaction_active>( 1629 i, shadow_frame.GetVRegReference(src_reg)); 1630 } 1631 } 1632 1633 result->SetL(new_array); 1634 return true; 1635} 1636 1637// TODO: Use ObjPtr here. 1638template<typename T> 1639static void RecordArrayElementsInTransactionImpl(mirror::PrimitiveArray<T>* array, 1640 int32_t count) 1641 REQUIRES_SHARED(Locks::mutator_lock_) { 1642 Runtime* runtime = Runtime::Current(); 1643 for (int32_t i = 0; i < count; ++i) { 1644 runtime->RecordWriteArray(array, i, array->GetWithoutChecks(i)); 1645 } 1646} 1647 1648void RecordArrayElementsInTransaction(ObjPtr<mirror::Array> array, int32_t count) 1649 REQUIRES_SHARED(Locks::mutator_lock_) { 1650 DCHECK(Runtime::Current()->IsActiveTransaction()); 1651 DCHECK(array != nullptr); 1652 DCHECK_LE(count, array->GetLength()); 1653 Primitive::Type primitive_component_type = array->GetClass()->GetComponentType()->GetPrimitiveType(); 1654 switch (primitive_component_type) { 1655 case Primitive::kPrimBoolean: 1656 RecordArrayElementsInTransactionImpl(array->AsBooleanArray(), count); 1657 break; 1658 case Primitive::kPrimByte: 1659 RecordArrayElementsInTransactionImpl(array->AsByteArray(), count); 1660 break; 1661 case Primitive::kPrimChar: 1662 RecordArrayElementsInTransactionImpl(array->AsCharArray(), count); 1663 break; 1664 case Primitive::kPrimShort: 1665 RecordArrayElementsInTransactionImpl(array->AsShortArray(), count); 1666 break; 1667 case Primitive::kPrimInt: 1668 RecordArrayElementsInTransactionImpl(array->AsIntArray(), count); 1669 break; 1670 case Primitive::kPrimFloat: 1671 RecordArrayElementsInTransactionImpl(array->AsFloatArray(), count); 1672 break; 1673 case Primitive::kPrimLong: 1674 RecordArrayElementsInTransactionImpl(array->AsLongArray(), count); 1675 break; 1676 case Primitive::kPrimDouble: 1677 RecordArrayElementsInTransactionImpl(array->AsDoubleArray(), count); 1678 break; 1679 default: 1680 LOG(FATAL) << "Unsupported primitive type " << primitive_component_type 1681 << " in fill-array-data"; 1682 break; 1683 } 1684} 1685 1686// Explicit DoCall template function declarations. 1687#define EXPLICIT_DO_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check) \ 1688 template REQUIRES_SHARED(Locks::mutator_lock_) \ 1689 bool DoCall<_is_range, _do_assignability_check>(ArtMethod* method, Thread* self, \ 1690 ShadowFrame& shadow_frame, \ 1691 const Instruction* inst, uint16_t inst_data, \ 1692 JValue* result) 1693EXPLICIT_DO_CALL_TEMPLATE_DECL(false, false); 1694EXPLICIT_DO_CALL_TEMPLATE_DECL(false, true); 1695EXPLICIT_DO_CALL_TEMPLATE_DECL(true, false); 1696EXPLICIT_DO_CALL_TEMPLATE_DECL(true, true); 1697#undef EXPLICIT_DO_CALL_TEMPLATE_DECL 1698 1699// Explicit DoInvokePolymorphic template function declarations. 1700#define EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(_is_range, _do_assignability_check) \ 1701 template REQUIRES_SHARED(Locks::mutator_lock_) \ 1702 bool DoInvokePolymorphic<_is_range, _do_assignability_check>( \ 1703 Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \ 1704 uint16_t inst_data, JValue* result) 1705 1706EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(false, false); 1707EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(false, true); 1708EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(true, false); 1709EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL(true, true); 1710#undef EXPLICIT_DO_INVOKE_POLYMORPHIC_TEMPLATE_DECL 1711 1712// Explicit DoFilledNewArray template function declarations. 1713#define EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(_is_range_, _check, _transaction_active) \ 1714 template REQUIRES_SHARED(Locks::mutator_lock_) \ 1715 bool DoFilledNewArray<_is_range_, _check, _transaction_active>(const Instruction* inst, \ 1716 const ShadowFrame& shadow_frame, \ 1717 Thread* self, JValue* result) 1718#define EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(_transaction_active) \ 1719 EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(false, false, _transaction_active); \ 1720 EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(false, true, _transaction_active); \ 1721 EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(true, false, _transaction_active); \ 1722 EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(true, true, _transaction_active) 1723EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(false); 1724EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL(true); 1725#undef EXPLICIT_DO_FILLED_NEW_ARRAY_ALL_TEMPLATE_DECL 1726#undef EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL 1727 1728} // namespace interpreter 1729} // namespace art 1730