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.h" 18 19 #include <limits> 20 21 #include "common_dex_operations.h" 22 #include "common_throws.h" 23 #include "dex/dex_file_types.h" 24 #include "interpreter_common.h" 25 #include "interpreter_mterp_impl.h" 26 #include "interpreter_switch_impl.h" 27 #include "jit/jit.h" 28 #include "jit/jit_code_cache.h" 29 #include "jvalue-inl.h" 30 #include "mirror/string-inl.h" 31 #include "mterp/mterp.h" 32 #include "nativehelper/scoped_local_ref.h" 33 #include "scoped_thread_state_change-inl.h" 34 #include "stack.h" 35 #include "thread-inl.h" 36 #include "unstarted_runtime.h" 37 38 namespace art { 39 namespace interpreter { 40 41 ALWAYS_INLINE static ObjPtr<mirror::Object> ObjArg(uint32_t arg) 42 REQUIRES_SHARED(Locks::mutator_lock_) { 43 return ObjPtr<mirror::Object>(reinterpret_cast<mirror::Object*>(arg)); 44 } 45 46 static void InterpreterJni(Thread* self, 47 ArtMethod* method, 48 const StringPiece& shorty, 49 ObjPtr<mirror::Object> receiver, 50 uint32_t* args, 51 JValue* result) 52 REQUIRES_SHARED(Locks::mutator_lock_) { 53 // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 54 // it should be removed and JNI compiled stubs used instead. 55 ScopedObjectAccessUnchecked soa(self); 56 if (method->IsStatic()) { 57 if (shorty == "L") { 58 typedef jobject (fntype)(JNIEnv*, jclass); 59 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 60 ScopedLocalRef<jclass> klass(soa.Env(), 61 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 62 jobject jresult; 63 { 64 ScopedThreadStateChange tsc(self, kNative); 65 jresult = fn(soa.Env(), klass.get()); 66 } 67 result->SetL(soa.Decode<mirror::Object>(jresult)); 68 } else if (shorty == "V") { 69 typedef void (fntype)(JNIEnv*, jclass); 70 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 71 ScopedLocalRef<jclass> klass(soa.Env(), 72 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 73 ScopedThreadStateChange tsc(self, kNative); 74 fn(soa.Env(), klass.get()); 75 } else if (shorty == "Z") { 76 typedef jboolean (fntype)(JNIEnv*, jclass); 77 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 78 ScopedLocalRef<jclass> klass(soa.Env(), 79 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 80 ScopedThreadStateChange tsc(self, kNative); 81 result->SetZ(fn(soa.Env(), klass.get())); 82 } else if (shorty == "BI") { 83 typedef jbyte (fntype)(JNIEnv*, jclass, jint); 84 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 85 ScopedLocalRef<jclass> klass(soa.Env(), 86 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 87 ScopedThreadStateChange tsc(self, kNative); 88 result->SetB(fn(soa.Env(), klass.get(), args[0])); 89 } else if (shorty == "II") { 90 typedef jint (fntype)(JNIEnv*, jclass, jint); 91 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 92 ScopedLocalRef<jclass> klass(soa.Env(), 93 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 94 ScopedThreadStateChange tsc(self, kNative); 95 result->SetI(fn(soa.Env(), klass.get(), args[0])); 96 } else if (shorty == "LL") { 97 typedef jobject (fntype)(JNIEnv*, jclass, jobject); 98 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 99 ScopedLocalRef<jclass> klass(soa.Env(), 100 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 101 ScopedLocalRef<jobject> arg0(soa.Env(), 102 soa.AddLocalReference<jobject>(ObjArg(args[0]))); 103 jobject jresult; 104 { 105 ScopedThreadStateChange tsc(self, kNative); 106 jresult = fn(soa.Env(), klass.get(), arg0.get()); 107 } 108 result->SetL(soa.Decode<mirror::Object>(jresult)); 109 } else if (shorty == "IIZ") { 110 typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 111 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 112 ScopedLocalRef<jclass> klass(soa.Env(), 113 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 114 ScopedThreadStateChange tsc(self, kNative); 115 result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 116 } else if (shorty == "ILI") { 117 typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 118 fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>( 119 method->GetEntryPointFromJni())); 120 ScopedLocalRef<jclass> klass(soa.Env(), 121 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 122 ScopedLocalRef<jobject> arg0(soa.Env(), 123 soa.AddLocalReference<jobject>(ObjArg(args[0]))); 124 ScopedThreadStateChange tsc(self, kNative); 125 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 126 } else if (shorty == "SIZ") { 127 typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 128 fntype* const fn = 129 reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni())); 130 ScopedLocalRef<jclass> klass(soa.Env(), 131 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 132 ScopedThreadStateChange tsc(self, kNative); 133 result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 134 } else if (shorty == "VIZ") { 135 typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 136 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 137 ScopedLocalRef<jclass> klass(soa.Env(), 138 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 139 ScopedThreadStateChange tsc(self, kNative); 140 fn(soa.Env(), klass.get(), args[0], args[1]); 141 } else if (shorty == "ZLL") { 142 typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 143 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 144 ScopedLocalRef<jclass> klass(soa.Env(), 145 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 146 ScopedLocalRef<jobject> arg0(soa.Env(), 147 soa.AddLocalReference<jobject>(ObjArg(args[0]))); 148 ScopedLocalRef<jobject> arg1(soa.Env(), 149 soa.AddLocalReference<jobject>(ObjArg(args[1]))); 150 ScopedThreadStateChange tsc(self, kNative); 151 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 152 } else if (shorty == "ZILL") { 153 typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 154 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 155 ScopedLocalRef<jclass> klass(soa.Env(), 156 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 157 ScopedLocalRef<jobject> arg1(soa.Env(), 158 soa.AddLocalReference<jobject>(ObjArg(args[1]))); 159 ScopedLocalRef<jobject> arg2(soa.Env(), 160 soa.AddLocalReference<jobject>(ObjArg(args[2]))); 161 ScopedThreadStateChange tsc(self, kNative); 162 result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 163 } else if (shorty == "VILII") { 164 typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 165 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 166 ScopedLocalRef<jclass> klass(soa.Env(), 167 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 168 ScopedLocalRef<jobject> arg1(soa.Env(), 169 soa.AddLocalReference<jobject>(ObjArg(args[1]))); 170 ScopedThreadStateChange tsc(self, kNative); 171 fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 172 } else if (shorty == "VLILII") { 173 typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 174 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 175 ScopedLocalRef<jclass> klass(soa.Env(), 176 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 177 ScopedLocalRef<jobject> arg0(soa.Env(), 178 soa.AddLocalReference<jobject>(ObjArg(args[0]))); 179 ScopedLocalRef<jobject> arg2(soa.Env(), 180 soa.AddLocalReference<jobject>(ObjArg(args[2]))); 181 ScopedThreadStateChange tsc(self, kNative); 182 fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 183 } else { 184 LOG(FATAL) << "Do something with static native method: " << method->PrettyMethod() 185 << " shorty: " << shorty; 186 } 187 } else { 188 if (shorty == "L") { 189 typedef jobject (fntype)(JNIEnv*, jobject); 190 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 191 ScopedLocalRef<jobject> rcvr(soa.Env(), 192 soa.AddLocalReference<jobject>(receiver)); 193 jobject jresult; 194 { 195 ScopedThreadStateChange tsc(self, kNative); 196 jresult = fn(soa.Env(), rcvr.get()); 197 } 198 result->SetL(soa.Decode<mirror::Object>(jresult)); 199 } else if (shorty == "V") { 200 typedef void (fntype)(JNIEnv*, jobject); 201 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 202 ScopedLocalRef<jobject> rcvr(soa.Env(), 203 soa.AddLocalReference<jobject>(receiver)); 204 ScopedThreadStateChange tsc(self, kNative); 205 fn(soa.Env(), rcvr.get()); 206 } else if (shorty == "LL") { 207 typedef jobject (fntype)(JNIEnv*, jobject, jobject); 208 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 209 ScopedLocalRef<jobject> rcvr(soa.Env(), 210 soa.AddLocalReference<jobject>(receiver)); 211 ScopedLocalRef<jobject> arg0(soa.Env(), 212 soa.AddLocalReference<jobject>(ObjArg(args[0]))); 213 jobject jresult; 214 { 215 ScopedThreadStateChange tsc(self, kNative); 216 jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 217 } 218 result->SetL(soa.Decode<mirror::Object>(jresult)); 219 ScopedThreadStateChange tsc(self, kNative); 220 } else if (shorty == "III") { 221 typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 222 fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 223 ScopedLocalRef<jobject> rcvr(soa.Env(), 224 soa.AddLocalReference<jobject>(receiver)); 225 ScopedThreadStateChange tsc(self, kNative); 226 result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 227 } else { 228 LOG(FATAL) << "Do something with native method: " << method->PrettyMethod() 229 << " shorty: " << shorty; 230 } 231 } 232 } 233 234 enum InterpreterImplKind { 235 kSwitchImplKind, // Switch-based interpreter implementation. 236 kMterpImplKind // Assembly interpreter 237 }; 238 239 static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind; 240 241 static inline JValue Execute( 242 Thread* self, 243 const CodeItemDataAccessor& accessor, 244 ShadowFrame& shadow_frame, 245 JValue result_register, 246 bool stay_in_interpreter = false) REQUIRES_SHARED(Locks::mutator_lock_) { 247 DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 248 DCHECK(!shadow_frame.GetMethod()->IsNative()); 249 if (LIKELY(shadow_frame.GetDexPC() == 0)) { // Entering the method, but not via deoptimization. 250 if (kIsDebugBuild) { 251 self->AssertNoPendingException(); 252 } 253 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 254 ArtMethod *method = shadow_frame.GetMethod(); 255 256 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { 257 instrumentation->MethodEnterEvent(self, 258 shadow_frame.GetThisObject(accessor.InsSize()), 259 method, 260 0); 261 if (UNLIKELY(self->IsExceptionPending())) { 262 instrumentation->MethodUnwindEvent(self, 263 shadow_frame.GetThisObject(accessor.InsSize()), 264 method, 265 0); 266 return JValue(); 267 } 268 } 269 270 if (!stay_in_interpreter) { 271 jit::Jit* jit = Runtime::Current()->GetJit(); 272 if (jit != nullptr) { 273 jit->MethodEntered(self, shadow_frame.GetMethod()); 274 if (jit->CanInvokeCompiledCode(method)) { 275 JValue result; 276 277 // Pop the shadow frame before calling into compiled code. 278 self->PopShadowFrame(); 279 // Calculate the offset of the first input reg. The input registers are in the high regs. 280 // It's ok to access the code item here since JIT code will have been touched by the 281 // interpreter and compiler already. 282 uint16_t arg_offset = accessor.RegistersSize() - accessor.InsSize(); 283 ArtInterpreterToCompiledCodeBridge(self, nullptr, &shadow_frame, arg_offset, &result); 284 // Push the shadow frame back as the caller will expect it. 285 self->PushShadowFrame(&shadow_frame); 286 287 return result; 288 } 289 } 290 } 291 } 292 293 ArtMethod* method = shadow_frame.GetMethod(); 294 295 DCheckStaticState(self, method); 296 297 // Lock counting is a special version of accessibility checks, and for simplicity and 298 // reduction of template parameters, we gate it behind access-checks mode. 299 DCHECK(!method->SkipAccessChecks() || !method->MustCountLocks()); 300 301 bool transaction_active = Runtime::Current()->IsActiveTransaction(); 302 if (LIKELY(method->SkipAccessChecks())) { 303 // Enter the "without access check" interpreter. 304 if (kInterpreterImplKind == kMterpImplKind) { 305 if (transaction_active) { 306 // No Mterp variant - just use the switch interpreter. 307 return ExecuteSwitchImpl<false, true>(self, accessor, shadow_frame, result_register, 308 false); 309 } else if (UNLIKELY(!Runtime::Current()->IsStarted())) { 310 return ExecuteSwitchImpl<false, false>(self, accessor, shadow_frame, result_register, 311 false); 312 } else { 313 while (true) { 314 // Mterp does not support all instrumentation/debugging. 315 if (MterpShouldSwitchInterpreters() != 0) { 316 return ExecuteSwitchImpl<false, false>(self, accessor, shadow_frame, result_register, 317 false); 318 } 319 bool returned = ExecuteMterpImpl(self, 320 accessor.Insns(), 321 &shadow_frame, 322 &result_register); 323 if (returned) { 324 return result_register; 325 } else { 326 // Mterp didn't like that instruction. Single-step it with the reference interpreter. 327 result_register = ExecuteSwitchImpl<false, false>(self, accessor, shadow_frame, 328 result_register, true); 329 if (shadow_frame.GetDexPC() == dex::kDexNoIndex) { 330 // Single-stepped a return or an exception not handled locally. Return to caller. 331 return result_register; 332 } 333 } 334 } 335 } 336 } else { 337 DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind); 338 if (transaction_active) { 339 return ExecuteSwitchImpl<false, true>(self, accessor, shadow_frame, result_register, 340 false); 341 } else { 342 return ExecuteSwitchImpl<false, false>(self, accessor, shadow_frame, result_register, 343 false); 344 } 345 } 346 } else { 347 // Enter the "with access check" interpreter. 348 if (kInterpreterImplKind == kMterpImplKind) { 349 // No access check variants for Mterp. Just use the switch version. 350 if (transaction_active) { 351 return ExecuteSwitchImpl<true, true>(self, accessor, shadow_frame, result_register, 352 false); 353 } else { 354 return ExecuteSwitchImpl<true, false>(self, accessor, shadow_frame, result_register, 355 false); 356 } 357 } else { 358 DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind); 359 if (transaction_active) { 360 return ExecuteSwitchImpl<true, true>(self, accessor, shadow_frame, result_register, 361 false); 362 } else { 363 return ExecuteSwitchImpl<true, false>(self, accessor, shadow_frame, result_register, 364 false); 365 } 366 } 367 } 368 } 369 370 void EnterInterpreterFromInvoke(Thread* self, 371 ArtMethod* method, 372 ObjPtr<mirror::Object> receiver, 373 uint32_t* args, 374 JValue* result, 375 bool stay_in_interpreter) { 376 DCHECK_EQ(self, Thread::Current()); 377 bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 378 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 379 ThrowStackOverflowError(self); 380 return; 381 } 382 383 // This can happen if we are in forced interpreter mode and an obsolete method is called using 384 // reflection. 385 if (UNLIKELY(method->IsObsolete())) { 386 ThrowInternalError("Attempting to invoke obsolete version of '%s'.", 387 method->PrettyMethod().c_str()); 388 return; 389 } 390 391 const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 392 CodeItemDataAccessor accessor(method->DexInstructionData()); 393 uint16_t num_regs; 394 uint16_t num_ins; 395 if (accessor.HasCodeItem()) { 396 num_regs = accessor.RegistersSize(); 397 num_ins = accessor.InsSize(); 398 } else if (!method->IsInvokable()) { 399 self->EndAssertNoThreadSuspension(old_cause); 400 method->ThrowInvocationTimeError(); 401 return; 402 } else { 403 DCHECK(method->IsNative()); 404 num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); 405 if (!method->IsStatic()) { 406 num_regs++; 407 num_ins++; 408 } 409 } 410 // Set up shadow frame with matching number of reference slots to vregs. 411 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 412 ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 413 CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0); 414 ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get(); 415 self->PushShadowFrame(shadow_frame); 416 417 size_t cur_reg = num_regs - num_ins; 418 if (!method->IsStatic()) { 419 CHECK(receiver != nullptr); 420 shadow_frame->SetVRegReference(cur_reg, receiver.Ptr()); 421 ++cur_reg; 422 } 423 uint32_t shorty_len = 0; 424 const char* shorty = method->GetShorty(&shorty_len); 425 for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 426 DCHECK_LT(shorty_pos + 1, shorty_len); 427 switch (shorty[shorty_pos + 1]) { 428 case 'L': { 429 ObjPtr<mirror::Object> o = 430 reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr(); 431 shadow_frame->SetVRegReference(cur_reg, o.Ptr()); 432 break; 433 } 434 case 'J': case 'D': { 435 uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 436 shadow_frame->SetVRegLong(cur_reg, wide_value); 437 cur_reg++; 438 arg_pos++; 439 break; 440 } 441 default: 442 shadow_frame->SetVReg(cur_reg, args[arg_pos]); 443 break; 444 } 445 } 446 self->EndAssertNoThreadSuspension(old_cause); 447 // Do this after populating the shadow frame in case EnsureInitialized causes a GC. 448 if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { 449 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 450 StackHandleScope<1> hs(self); 451 Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); 452 if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) { 453 CHECK(self->IsExceptionPending()); 454 self->PopShadowFrame(); 455 return; 456 } 457 } 458 if (LIKELY(!method->IsNative())) { 459 JValue r = Execute(self, accessor, *shadow_frame, JValue(), stay_in_interpreter); 460 if (result != nullptr) { 461 *result = r; 462 } 463 } else { 464 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 465 // generated stub) except during testing and image writing. 466 // Update args to be the args in the shadow frame since the input ones could hold stale 467 // references pointers due to moving GC. 468 args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 469 if (!Runtime::Current()->IsStarted()) { 470 UnstartedRuntime::Jni(self, method, receiver.Ptr(), args, result); 471 } else { 472 InterpreterJni(self, method, shorty, receiver, args, result); 473 } 474 } 475 self->PopShadowFrame(); 476 } 477 478 static int16_t GetReceiverRegisterForStringInit(const Instruction* instr) { 479 DCHECK(instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE || 480 instr->Opcode() == Instruction::INVOKE_DIRECT); 481 return (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ? 482 instr->VRegC_3rc() : instr->VRegC_35c(); 483 } 484 485 void EnterInterpreterFromDeoptimize(Thread* self, 486 ShadowFrame* shadow_frame, 487 JValue* ret_val, 488 bool from_code, 489 DeoptimizationMethodType deopt_method_type) 490 REQUIRES_SHARED(Locks::mutator_lock_) { 491 JValue value; 492 // Set value to last known result in case the shadow frame chain is empty. 493 value.SetJ(ret_val->GetJ()); 494 // Are we executing the first shadow frame? 495 bool first = true; 496 while (shadow_frame != nullptr) { 497 // We do not want to recover lock state for lock counting when deoptimizing. Currently, 498 // the compiler should not have compiled a method that failed structured-locking checks. 499 DCHECK(!shadow_frame->GetMethod()->MustCountLocks()); 500 501 self->SetTopOfShadowStack(shadow_frame); 502 CodeItemDataAccessor accessor(shadow_frame->GetMethod()->DexInstructionData()); 503 const uint32_t dex_pc = shadow_frame->GetDexPC(); 504 uint32_t new_dex_pc = dex_pc; 505 if (UNLIKELY(self->IsExceptionPending())) { 506 // If we deoptimize from the QuickExceptionHandler, we already reported the exception to 507 // the instrumentation. To prevent from reporting it a second time, we simply pass a 508 // null Instrumentation*. 509 const instrumentation::Instrumentation* const instrumentation = 510 first ? nullptr : Runtime::Current()->GetInstrumentation(); 511 new_dex_pc = MoveToExceptionHandler( 512 self, *shadow_frame, instrumentation) ? shadow_frame->GetDexPC() : dex::kDexNoIndex; 513 } else if (!from_code) { 514 // Deoptimization is not called from code directly. 515 const Instruction* instr = &accessor.InstructionAt(dex_pc); 516 if (deopt_method_type == DeoptimizationMethodType::kKeepDexPc) { 517 DCHECK(first); 518 // Need to re-execute the dex instruction. 519 // (1) An invocation might be split into class initialization and invoke. 520 // In this case, the invoke should not be skipped. 521 // (2) A suspend check should also execute the dex instruction at the 522 // corresponding dex pc. 523 DCHECK_EQ(new_dex_pc, dex_pc); 524 } else if (instr->Opcode() == Instruction::MONITOR_ENTER || 525 instr->Opcode() == Instruction::MONITOR_EXIT) { 526 DCHECK(deopt_method_type == DeoptimizationMethodType::kDefault); 527 DCHECK(first); 528 // Non-idempotent dex instruction should not be re-executed. 529 // On the other hand, if a MONITOR_ENTER is at the dex_pc of a suspend 530 // check, that MONITOR_ENTER should be executed. That case is handled 531 // above. 532 new_dex_pc = dex_pc + instr->SizeInCodeUnits(); 533 } else if (instr->IsInvoke()) { 534 DCHECK(deopt_method_type == DeoptimizationMethodType::kDefault); 535 if (IsStringInit(instr, shadow_frame->GetMethod())) { 536 uint16_t this_obj_vreg = GetReceiverRegisterForStringInit(instr); 537 // Move the StringFactory.newStringFromChars() result into the register representing 538 // "this object" when invoking the string constructor in the original dex instruction. 539 // Also move the result into all aliases. 540 DCHECK(value.GetL()->IsString()); 541 SetStringInitValueToAllAliases(shadow_frame, this_obj_vreg, value); 542 // Calling string constructor in the original dex code doesn't generate a result value. 543 value.SetJ(0); 544 } 545 new_dex_pc = dex_pc + instr->SizeInCodeUnits(); 546 } else if (instr->Opcode() == Instruction::NEW_INSTANCE) { 547 // A NEW_INSTANCE is simply re-executed, including 548 // "new-instance String" which is compiled into a call into 549 // StringFactory.newEmptyString(). 550 DCHECK_EQ(new_dex_pc, dex_pc); 551 } else { 552 DCHECK(deopt_method_type == DeoptimizationMethodType::kDefault); 553 DCHECK(first); 554 // By default, we re-execute the dex instruction since if they are not 555 // an invoke, so that we don't have to decode the dex instruction to move 556 // result into the right vreg. All slow paths have been audited to be 557 // idempotent except monitor-enter/exit and invocation stubs. 558 // TODO: move result and advance dex pc. That also requires that we 559 // can tell the return type of a runtime method, possibly by decoding 560 // the dex instruction at the caller. 561 DCHECK_EQ(new_dex_pc, dex_pc); 562 } 563 } else { 564 // Nothing to do, the dex_pc is the one at which the code requested 565 // the deoptimization. 566 DCHECK(first); 567 DCHECK_EQ(new_dex_pc, dex_pc); 568 } 569 if (new_dex_pc != dex::kDexNoIndex) { 570 shadow_frame->SetDexPC(new_dex_pc); 571 value = Execute(self, accessor, *shadow_frame, value); 572 } 573 ShadowFrame* old_frame = shadow_frame; 574 shadow_frame = shadow_frame->GetLink(); 575 ShadowFrame::DeleteDeoptimizedFrame(old_frame); 576 // Following deoptimizations of shadow frames must be at invocation point 577 // and should advance dex pc past the invoke instruction. 578 from_code = false; 579 deopt_method_type = DeoptimizationMethodType::kDefault; 580 first = false; 581 } 582 ret_val->SetJ(value.GetJ()); 583 } 584 585 JValue EnterInterpreterFromEntryPoint(Thread* self, const CodeItemDataAccessor& accessor, 586 ShadowFrame* shadow_frame) { 587 DCHECK_EQ(self, Thread::Current()); 588 bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 589 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 590 ThrowStackOverflowError(self); 591 return JValue(); 592 } 593 594 jit::Jit* jit = Runtime::Current()->GetJit(); 595 if (jit != nullptr) { 596 jit->NotifyCompiledCodeToInterpreterTransition(self, shadow_frame->GetMethod()); 597 } 598 return Execute(self, accessor, *shadow_frame, JValue()); 599 } 600 601 void ArtInterpreterToInterpreterBridge(Thread* self, 602 const CodeItemDataAccessor& accessor, 603 ShadowFrame* shadow_frame, 604 JValue* result) { 605 bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 606 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 607 ThrowStackOverflowError(self); 608 return; 609 } 610 611 self->PushShadowFrame(shadow_frame); 612 ArtMethod* method = shadow_frame->GetMethod(); 613 // Ensure static methods are initialized. 614 const bool is_static = method->IsStatic(); 615 if (is_static) { 616 ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); 617 if (UNLIKELY(!declaring_class->IsInitialized())) { 618 StackHandleScope<1> hs(self); 619 HandleWrapperObjPtr<mirror::Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); 620 if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( 621 self, h_declaring_class, true, true))) { 622 DCHECK(self->IsExceptionPending()); 623 self->PopShadowFrame(); 624 return; 625 } 626 CHECK(h_declaring_class->IsInitializing()); 627 } 628 } 629 630 if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { 631 result->SetJ(Execute(self, accessor, *shadow_frame, JValue()).GetJ()); 632 } else { 633 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 634 // generated stub) except during testing and image writing. 635 CHECK(!Runtime::Current()->IsStarted()); 636 ObjPtr<mirror::Object> receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); 637 uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); 638 UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver.Ptr(), args, result); 639 } 640 641 self->PopShadowFrame(); 642 } 643 644 void CheckInterpreterAsmConstants() { 645 CheckMterpAsmConstants(); 646 } 647 648 void InitInterpreterTls(Thread* self) { 649 InitMterpTls(self); 650 } 651 652 } // namespace interpreter 653 } // namespace art 654