stack.cc revision 524e7ea8cd17bad17bd9f3e0ccbb19ad0d4d9c02
1/* 2 * Copyright (C) 2011 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 "stack.h" 18 19#include "arch/context.h" 20#include "art_method-inl.h" 21#include "base/hex_dump.h" 22#include "entrypoints/entrypoint_utils-inl.h" 23#include "entrypoints/runtime_asm_entrypoints.h" 24#include "gc_map.h" 25#include "gc/space/image_space.h" 26#include "gc/space/space-inl.h" 27#include "jit/jit.h" 28#include "jit/jit_code_cache.h" 29#include "linear_alloc.h" 30#include "mirror/class-inl.h" 31#include "mirror/object-inl.h" 32#include "mirror/object_array-inl.h" 33#include "oat_quick_method_header.h" 34#include "quick/quick_method_frame_info.h" 35#include "runtime.h" 36#include "thread.h" 37#include "thread_list.h" 38#include "verify_object-inl.h" 39#include "vmap_table.h" 40 41namespace art { 42 43static constexpr bool kDebugStackWalk = false; 44 45mirror::Object* ShadowFrame::GetThisObject() const { 46 ArtMethod* m = GetMethod(); 47 if (m->IsStatic()) { 48 return nullptr; 49 } else if (m->IsNative()) { 50 return GetVRegReference(0); 51 } else { 52 const DexFile::CodeItem* code_item = m->GetCodeItem(); 53 CHECK(code_item != nullptr) << PrettyMethod(m); 54 uint16_t reg = code_item->registers_size_ - code_item->ins_size_; 55 return GetVRegReference(reg); 56 } 57} 58 59mirror::Object* ShadowFrame::GetThisObject(uint16_t num_ins) const { 60 ArtMethod* m = GetMethod(); 61 if (m->IsStatic()) { 62 return nullptr; 63 } else { 64 return GetVRegReference(NumberOfVRegs() - num_ins); 65 } 66} 67 68size_t ManagedStack::NumJniShadowFrameReferences() const { 69 size_t count = 0; 70 for (const ManagedStack* current_fragment = this; current_fragment != nullptr; 71 current_fragment = current_fragment->GetLink()) { 72 for (ShadowFrame* current_frame = current_fragment->top_shadow_frame_; current_frame != nullptr; 73 current_frame = current_frame->GetLink()) { 74 if (current_frame->GetMethod()->IsNative()) { 75 // The JNI ShadowFrame only contains references. (For indirect reference.) 76 count += current_frame->NumberOfVRegs(); 77 } 78 } 79 } 80 return count; 81} 82 83bool ManagedStack::ShadowFramesContain(StackReference<mirror::Object>* shadow_frame_entry) const { 84 for (const ManagedStack* current_fragment = this; current_fragment != nullptr; 85 current_fragment = current_fragment->GetLink()) { 86 for (ShadowFrame* current_frame = current_fragment->top_shadow_frame_; current_frame != nullptr; 87 current_frame = current_frame->GetLink()) { 88 if (current_frame->Contains(shadow_frame_entry)) { 89 return true; 90 } 91 } 92 } 93 return false; 94} 95 96StackVisitor::StackVisitor(Thread* thread, Context* context, StackWalkKind walk_kind) 97 : StackVisitor(thread, context, walk_kind, 0) {} 98 99StackVisitor::StackVisitor(Thread* thread, 100 Context* context, 101 StackWalkKind walk_kind, 102 size_t num_frames) 103 : thread_(thread), 104 walk_kind_(walk_kind), 105 cur_shadow_frame_(nullptr), 106 cur_quick_frame_(nullptr), 107 cur_quick_frame_pc_(0), 108 cur_oat_quick_method_header_(nullptr), 109 num_frames_(num_frames), 110 cur_depth_(0), 111 current_inlining_depth_(0), 112 context_(context) { 113 DCHECK(thread == Thread::Current() || thread->IsSuspended()) << *thread; 114} 115 116InlineInfo StackVisitor::GetCurrentInlineInfo() const { 117 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 118 uint32_t native_pc_offset = method_header->NativeQuickPcOffset(cur_quick_frame_pc_); 119 CodeInfo code_info = method_header->GetOptimizedCodeInfo(); 120 StackMapEncoding encoding = code_info.ExtractEncoding(); 121 StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding); 122 DCHECK(stack_map.IsValid()); 123 return code_info.GetInlineInfoOf(stack_map, encoding); 124} 125 126ArtMethod* StackVisitor::GetMethod() const { 127 if (cur_shadow_frame_ != nullptr) { 128 return cur_shadow_frame_->GetMethod(); 129 } else if (cur_quick_frame_ != nullptr) { 130 if (IsInInlinedFrame()) { 131 size_t depth_in_stack_map = current_inlining_depth_ - 1; 132 InlineInfo inline_info = GetCurrentInlineInfo(); 133 return GetResolvedMethod(*GetCurrentQuickFrame(), inline_info, depth_in_stack_map); 134 } else { 135 return *cur_quick_frame_; 136 } 137 } 138 return nullptr; 139} 140 141uint32_t StackVisitor::GetDexPc(bool abort_on_failure) const { 142 if (cur_shadow_frame_ != nullptr) { 143 return cur_shadow_frame_->GetDexPC(); 144 } else if (cur_quick_frame_ != nullptr) { 145 if (IsInInlinedFrame()) { 146 size_t depth_in_stack_map = current_inlining_depth_ - 1; 147 return GetCurrentInlineInfo().GetDexPcAtDepth(depth_in_stack_map); 148 } else if (cur_oat_quick_method_header_ == nullptr) { 149 return DexFile::kDexNoIndex; 150 } else { 151 return cur_oat_quick_method_header_->ToDexPc( 152 GetMethod(), cur_quick_frame_pc_, abort_on_failure); 153 } 154 } else { 155 return 0; 156 } 157} 158 159extern "C" mirror::Object* artQuickGetProxyThisObject(ArtMethod** sp) 160 SHARED_REQUIRES(Locks::mutator_lock_); 161 162mirror::Object* StackVisitor::GetThisObject() const { 163 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*)); 164 ArtMethod* m = GetMethod(); 165 if (m->IsStatic()) { 166 return nullptr; 167 } else if (m->IsNative()) { 168 if (cur_quick_frame_ != nullptr) { 169 HandleScope* hs = reinterpret_cast<HandleScope*>( 170 reinterpret_cast<char*>(cur_quick_frame_) + sizeof(ArtMethod*)); 171 return hs->GetReference(0); 172 } else { 173 return cur_shadow_frame_->GetVRegReference(0); 174 } 175 } else if (m->IsProxyMethod()) { 176 if (cur_quick_frame_ != nullptr) { 177 return artQuickGetProxyThisObject(cur_quick_frame_); 178 } else { 179 return cur_shadow_frame_->GetVRegReference(0); 180 } 181 } else { 182 const DexFile::CodeItem* code_item = m->GetCodeItem(); 183 if (code_item == nullptr) { 184 UNIMPLEMENTED(ERROR) << "Failed to determine this object of abstract or proxy method: " 185 << PrettyMethod(m); 186 return nullptr; 187 } else { 188 uint16_t reg = code_item->registers_size_ - code_item->ins_size_; 189 uint32_t value = 0; 190 bool success = GetVReg(m, reg, kReferenceVReg, &value); 191 // We currently always guarantee the `this` object is live throughout the method. 192 CHECK(success) << "Failed to read the this object in " << PrettyMethod(m); 193 return reinterpret_cast<mirror::Object*>(value); 194 } 195 } 196} 197 198size_t StackVisitor::GetNativePcOffset() const { 199 DCHECK(!IsShadowFrame()); 200 return GetCurrentOatQuickMethodHeader()->NativeQuickPcOffset(cur_quick_frame_pc_); 201} 202 203bool StackVisitor::IsReferenceVReg(ArtMethod* m, uint16_t vreg) { 204 DCHECK_EQ(m, GetMethod()); 205 // Process register map (which native and runtime methods don't have) 206 if (m->IsNative() || m->IsRuntimeMethod() || m->IsProxyMethod()) { 207 return false; 208 } 209 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 210 if (method_header->IsOptimized()) { 211 return true; // TODO: Implement. 212 } 213 const uint8_t* native_gc_map = method_header->GetNativeGcMap(); 214 CHECK(native_gc_map != nullptr) << PrettyMethod(m); 215 const DexFile::CodeItem* code_item = m->GetCodeItem(); 216 // Can't be null or how would we compile its instructions? 217 DCHECK(code_item != nullptr) << PrettyMethod(m); 218 NativePcOffsetToReferenceMap map(native_gc_map); 219 size_t num_regs = std::min(map.RegWidth() * 8, static_cast<size_t>(code_item->registers_size_)); 220 const uint8_t* reg_bitmap = nullptr; 221 if (num_regs > 0) { 222 uintptr_t native_pc_offset = method_header->NativeQuickPcOffset(GetCurrentQuickFramePc()); 223 reg_bitmap = map.FindBitMap(native_pc_offset); 224 DCHECK(reg_bitmap != nullptr); 225 } 226 // Does this register hold a reference? 227 return vreg < num_regs && TestBitmap(vreg, reg_bitmap); 228} 229 230bool StackVisitor::GetVRegFromDebuggerShadowFrame(uint16_t vreg, 231 VRegKind kind, 232 uint32_t* val) const { 233 size_t frame_id = const_cast<StackVisitor*>(this)->GetFrameId(); 234 ShadowFrame* shadow_frame = thread_->FindDebuggerShadowFrame(frame_id); 235 if (shadow_frame != nullptr) { 236 bool* updated_vreg_flags = thread_->GetUpdatedVRegFlags(frame_id); 237 DCHECK(updated_vreg_flags != nullptr); 238 if (updated_vreg_flags[vreg]) { 239 // Value is set by the debugger. 240 if (kind == kReferenceVReg) { 241 *val = static_cast<uint32_t>(reinterpret_cast<uintptr_t>( 242 shadow_frame->GetVRegReference(vreg))); 243 } else { 244 *val = shadow_frame->GetVReg(vreg); 245 } 246 return true; 247 } 248 } 249 // No value is set by the debugger. 250 return false; 251} 252 253bool StackVisitor::GetVReg(ArtMethod* m, uint16_t vreg, VRegKind kind, uint32_t* val) const { 254 if (cur_quick_frame_ != nullptr) { 255 DCHECK(context_ != nullptr); // You can't reliably read registers without a context. 256 DCHECK(m == GetMethod()); 257 // Check if there is value set by the debugger. 258 if (GetVRegFromDebuggerShadowFrame(vreg, kind, val)) { 259 return true; 260 } 261 if (cur_oat_quick_method_header_->IsOptimized()) { 262 return GetVRegFromOptimizedCode(m, vreg, kind, val); 263 } else { 264 return GetVRegFromQuickCode(m, vreg, kind, val); 265 } 266 } else { 267 DCHECK(cur_shadow_frame_ != nullptr); 268 *val = cur_shadow_frame_->GetVReg(vreg); 269 return true; 270 } 271} 272 273bool StackVisitor::GetVRegFromQuickCode(ArtMethod* m, uint16_t vreg, VRegKind kind, 274 uint32_t* val) const { 275 DCHECK_EQ(m, GetMethod()); 276 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 277 QuickMethodFrameInfo frame_info = method_header->GetFrameInfo(); 278 const VmapTable vmap_table(method_header->GetVmapTable()); 279 uint32_t vmap_offset; 280 // TODO: IsInContext stops before spotting floating point registers. 281 if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) { 282 bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); 283 uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); 284 uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind); 285 return GetRegisterIfAccessible(reg, kind, val); 286 } else { 287 const DexFile::CodeItem* code_item = m->GetCodeItem(); 288 DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile 289 // its instructions? 290 *val = *GetVRegAddrFromQuickCode(cur_quick_frame_, code_item, frame_info.CoreSpillMask(), 291 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg); 292 return true; 293 } 294} 295 296bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKind kind, 297 uint32_t* val) const { 298 DCHECK_EQ(m, GetMethod()); 299 const DexFile::CodeItem* code_item = m->GetCodeItem(); 300 DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile 301 // its instructions? 302 uint16_t number_of_dex_registers = code_item->registers_size_; 303 DCHECK_LT(vreg, code_item->registers_size_); 304 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 305 CodeInfo code_info = method_header->GetOptimizedCodeInfo(); 306 StackMapEncoding encoding = code_info.ExtractEncoding(); 307 308 uint32_t native_pc_offset = method_header->NativeQuickPcOffset(cur_quick_frame_pc_); 309 StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding); 310 DCHECK(stack_map.IsValid()); 311 size_t depth_in_stack_map = current_inlining_depth_ - 1; 312 313 DexRegisterMap dex_register_map = IsInInlinedFrame() 314 ? code_info.GetDexRegisterMapAtDepth(depth_in_stack_map, 315 code_info.GetInlineInfoOf(stack_map, encoding), 316 encoding, 317 number_of_dex_registers) 318 : code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 319 320 DexRegisterLocation::Kind location_kind = 321 dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info, encoding); 322 switch (location_kind) { 323 case DexRegisterLocation::Kind::kInStack: { 324 const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg, 325 number_of_dex_registers, 326 code_info, 327 encoding); 328 const uint8_t* addr = reinterpret_cast<const uint8_t*>(cur_quick_frame_) + offset; 329 *val = *reinterpret_cast<const uint32_t*>(addr); 330 return true; 331 } 332 case DexRegisterLocation::Kind::kInRegister: 333 case DexRegisterLocation::Kind::kInRegisterHigh: 334 case DexRegisterLocation::Kind::kInFpuRegister: 335 case DexRegisterLocation::Kind::kInFpuRegisterHigh: { 336 uint32_t reg = 337 dex_register_map.GetMachineRegister(vreg, number_of_dex_registers, code_info, encoding); 338 return GetRegisterIfAccessible(reg, kind, val); 339 } 340 case DexRegisterLocation::Kind::kConstant: 341 *val = dex_register_map.GetConstant(vreg, number_of_dex_registers, code_info, encoding); 342 return true; 343 case DexRegisterLocation::Kind::kNone: 344 return false; 345 default: 346 LOG(FATAL) 347 << "Unexpected location kind" 348 << DexRegisterLocation::PrettyDescriptor( 349 dex_register_map.GetLocationInternalKind(vreg, 350 number_of_dex_registers, 351 code_info, 352 encoding)); 353 UNREACHABLE(); 354 } 355} 356 357bool StackVisitor::GetRegisterIfAccessible(uint32_t reg, VRegKind kind, uint32_t* val) const { 358 const bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); 359 360 // X86 float registers are 64-bit and the logic below does not apply. 361 DCHECK(!is_float || kRuntimeISA != InstructionSet::kX86); 362 363 if (!IsAccessibleRegister(reg, is_float)) { 364 return false; 365 } 366 uintptr_t ptr_val = GetRegister(reg, is_float); 367 const bool target64 = Is64BitInstructionSet(kRuntimeISA); 368 if (target64) { 369 const bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg); 370 const bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg); 371 int64_t value_long = static_cast<int64_t>(ptr_val); 372 if (wide_lo) { 373 ptr_val = static_cast<uintptr_t>(Low32Bits(value_long)); 374 } else if (wide_hi) { 375 ptr_val = static_cast<uintptr_t>(High32Bits(value_long)); 376 } 377 } 378 *val = ptr_val; 379 return true; 380} 381 382bool StackVisitor::GetVRegPairFromDebuggerShadowFrame(uint16_t vreg, 383 VRegKind kind_lo, 384 VRegKind kind_hi, 385 uint64_t* val) const { 386 uint32_t low_32bits; 387 uint32_t high_32bits; 388 bool success = GetVRegFromDebuggerShadowFrame(vreg, kind_lo, &low_32bits); 389 success &= GetVRegFromDebuggerShadowFrame(vreg + 1, kind_hi, &high_32bits); 390 if (success) { 391 *val = (static_cast<uint64_t>(high_32bits) << 32) | static_cast<uint64_t>(low_32bits); 392 } 393 return success; 394} 395 396bool StackVisitor::GetVRegPair(ArtMethod* m, uint16_t vreg, VRegKind kind_lo, 397 VRegKind kind_hi, uint64_t* val) const { 398 if (kind_lo == kLongLoVReg) { 399 DCHECK_EQ(kind_hi, kLongHiVReg); 400 } else if (kind_lo == kDoubleLoVReg) { 401 DCHECK_EQ(kind_hi, kDoubleHiVReg); 402 } else { 403 LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi; 404 UNREACHABLE(); 405 } 406 // Check if there is value set by the debugger. 407 if (GetVRegPairFromDebuggerShadowFrame(vreg, kind_lo, kind_hi, val)) { 408 return true; 409 } 410 if (cur_quick_frame_ != nullptr) { 411 DCHECK(context_ != nullptr); // You can't reliably read registers without a context. 412 DCHECK(m == GetMethod()); 413 if (cur_oat_quick_method_header_->IsOptimized()) { 414 return GetVRegPairFromOptimizedCode(m, vreg, kind_lo, kind_hi, val); 415 } else { 416 return GetVRegPairFromQuickCode(m, vreg, kind_lo, kind_hi, val); 417 } 418 } else { 419 DCHECK(cur_shadow_frame_ != nullptr); 420 *val = cur_shadow_frame_->GetVRegLong(vreg); 421 return true; 422 } 423} 424 425bool StackVisitor::GetVRegPairFromQuickCode(ArtMethod* m, uint16_t vreg, VRegKind kind_lo, 426 VRegKind kind_hi, uint64_t* val) const { 427 DCHECK_EQ(m, GetMethod()); 428 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 429 QuickMethodFrameInfo frame_info = method_header->GetFrameInfo(); 430 const VmapTable vmap_table(method_header->GetVmapTable()); 431 uint32_t vmap_offset_lo, vmap_offset_hi; 432 // TODO: IsInContext stops before spotting floating point registers. 433 if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) && 434 vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) { 435 bool is_float = (kind_lo == kDoubleLoVReg); 436 uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); 437 uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo); 438 uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi); 439 return GetRegisterPairIfAccessible(reg_lo, reg_hi, kind_lo, val); 440 } else { 441 const DexFile::CodeItem* code_item = m->GetCodeItem(); 442 DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile 443 // its instructions? 444 uint32_t* addr = GetVRegAddrFromQuickCode( 445 cur_quick_frame_, code_item, frame_info.CoreSpillMask(), 446 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg); 447 *val = *reinterpret_cast<uint64_t*>(addr); 448 return true; 449 } 450} 451 452bool StackVisitor::GetVRegPairFromOptimizedCode(ArtMethod* m, uint16_t vreg, 453 VRegKind kind_lo, VRegKind kind_hi, 454 uint64_t* val) const { 455 uint32_t low_32bits; 456 uint32_t high_32bits; 457 bool success = GetVRegFromOptimizedCode(m, vreg, kind_lo, &low_32bits); 458 success &= GetVRegFromOptimizedCode(m, vreg + 1, kind_hi, &high_32bits); 459 if (success) { 460 *val = (static_cast<uint64_t>(high_32bits) << 32) | static_cast<uint64_t>(low_32bits); 461 } 462 return success; 463} 464 465bool StackVisitor::GetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi, 466 VRegKind kind_lo, uint64_t* val) const { 467 const bool is_float = (kind_lo == kDoubleLoVReg); 468 if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) { 469 return false; 470 } 471 uintptr_t ptr_val_lo = GetRegister(reg_lo, is_float); 472 uintptr_t ptr_val_hi = GetRegister(reg_hi, is_float); 473 bool target64 = Is64BitInstructionSet(kRuntimeISA); 474 if (target64) { 475 int64_t value_long_lo = static_cast<int64_t>(ptr_val_lo); 476 int64_t value_long_hi = static_cast<int64_t>(ptr_val_hi); 477 ptr_val_lo = static_cast<uintptr_t>(Low32Bits(value_long_lo)); 478 ptr_val_hi = static_cast<uintptr_t>(High32Bits(value_long_hi)); 479 } 480 *val = (static_cast<uint64_t>(ptr_val_hi) << 32) | static_cast<uint32_t>(ptr_val_lo); 481 return true; 482} 483 484bool StackVisitor::SetVReg(ArtMethod* m, uint16_t vreg, uint32_t new_value, 485 VRegKind kind) { 486 if (cur_quick_frame_ != nullptr) { 487 DCHECK(context_ != nullptr); // You can't reliably write registers without a context. 488 DCHECK(m == GetMethod()); 489 if (cur_oat_quick_method_header_->IsOptimized()) { 490 return false; 491 } else { 492 return SetVRegFromQuickCode(m, vreg, new_value, kind); 493 } 494 } else { 495 cur_shadow_frame_->SetVReg(vreg, new_value); 496 return true; 497 } 498} 499 500bool StackVisitor::SetVRegFromQuickCode(ArtMethod* m, uint16_t vreg, uint32_t new_value, 501 VRegKind kind) { 502 DCHECK(context_ != nullptr); // You can't reliably write registers without a context. 503 DCHECK(m == GetMethod()); 504 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 505 QuickMethodFrameInfo frame_info = method_header->GetFrameInfo(); 506 const VmapTable vmap_table(method_header->GetVmapTable()); 507 uint32_t vmap_offset; 508 // TODO: IsInContext stops before spotting floating point registers. 509 if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) { 510 bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); 511 uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); 512 uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind); 513 return SetRegisterIfAccessible(reg, new_value, kind); 514 } else { 515 const DexFile::CodeItem* code_item = m->GetCodeItem(); 516 DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile 517 // its instructions? 518 uint32_t* addr = GetVRegAddrFromQuickCode( 519 cur_quick_frame_, code_item, frame_info.CoreSpillMask(), 520 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg); 521 *addr = new_value; 522 return true; 523 } 524} 525 526bool StackVisitor::SetVRegFromDebugger(ArtMethod* m, 527 uint16_t vreg, 528 uint32_t new_value, 529 VRegKind kind) { 530 const DexFile::CodeItem* code_item = m->GetCodeItem(); 531 if (code_item == nullptr) { 532 return false; 533 } 534 ShadowFrame* shadow_frame = GetCurrentShadowFrame(); 535 if (shadow_frame == nullptr) { 536 // This is a compiled frame: we must prepare and update a shadow frame that will 537 // be executed by the interpreter after deoptimization of the stack. 538 const size_t frame_id = GetFrameId(); 539 const uint16_t num_regs = code_item->registers_size_; 540 shadow_frame = thread_->FindOrCreateDebuggerShadowFrame(frame_id, num_regs, m, GetDexPc()); 541 CHECK(shadow_frame != nullptr); 542 // Remember the vreg has been set for debugging and must not be overwritten by the 543 // original value during deoptimization of the stack. 544 thread_->GetUpdatedVRegFlags(frame_id)[vreg] = true; 545 } 546 if (kind == kReferenceVReg) { 547 shadow_frame->SetVRegReference(vreg, reinterpret_cast<mirror::Object*>(new_value)); 548 } else { 549 shadow_frame->SetVReg(vreg, new_value); 550 } 551 return true; 552} 553 554bool StackVisitor::SetRegisterIfAccessible(uint32_t reg, uint32_t new_value, VRegKind kind) { 555 const bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); 556 if (!IsAccessibleRegister(reg, is_float)) { 557 return false; 558 } 559 const bool target64 = Is64BitInstructionSet(kRuntimeISA); 560 561 // Create a new value that can hold both low 32 and high 32 bits, in 562 // case we are running 64 bits. 563 uintptr_t full_new_value = new_value; 564 // Deal with 32 or 64-bit wide registers in a way that builds on all targets. 565 if (target64) { 566 bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg); 567 bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg); 568 if (wide_lo || wide_hi) { 569 uintptr_t old_reg_val = GetRegister(reg, is_float); 570 uint64_t new_vreg_portion = static_cast<uint64_t>(new_value); 571 uint64_t old_reg_val_as_wide = static_cast<uint64_t>(old_reg_val); 572 uint64_t mask = 0xffffffff; 573 if (wide_lo) { 574 mask = mask << 32; 575 } else { 576 new_vreg_portion = new_vreg_portion << 32; 577 } 578 full_new_value = static_cast<uintptr_t>((old_reg_val_as_wide & mask) | new_vreg_portion); 579 } 580 } 581 SetRegister(reg, full_new_value, is_float); 582 return true; 583} 584 585bool StackVisitor::SetVRegPair(ArtMethod* m, uint16_t vreg, uint64_t new_value, 586 VRegKind kind_lo, VRegKind kind_hi) { 587 if (kind_lo == kLongLoVReg) { 588 DCHECK_EQ(kind_hi, kLongHiVReg); 589 } else if (kind_lo == kDoubleLoVReg) { 590 DCHECK_EQ(kind_hi, kDoubleHiVReg); 591 } else { 592 LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi; 593 } 594 if (cur_quick_frame_ != nullptr) { 595 DCHECK(context_ != nullptr); // You can't reliably write registers without a context. 596 DCHECK(m == GetMethod()); 597 if (cur_oat_quick_method_header_->IsOptimized()) { 598 return false; 599 } else { 600 return SetVRegPairFromQuickCode(m, vreg, new_value, kind_lo, kind_hi); 601 } 602 } else { 603 DCHECK(cur_shadow_frame_ != nullptr); 604 cur_shadow_frame_->SetVRegLong(vreg, new_value); 605 return true; 606 } 607} 608 609bool StackVisitor::SetVRegPairFromQuickCode( 610 ArtMethod* m, uint16_t vreg, uint64_t new_value, VRegKind kind_lo, VRegKind kind_hi) { 611 DCHECK_EQ(m, GetMethod()); 612 const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); 613 QuickMethodFrameInfo frame_info = method_header->GetFrameInfo(); 614 const VmapTable vmap_table(method_header->GetVmapTable()); 615 uint32_t vmap_offset_lo, vmap_offset_hi; 616 // TODO: IsInContext stops before spotting floating point registers. 617 if (vmap_table.IsInContext(vreg, kind_lo, &vmap_offset_lo) && 618 vmap_table.IsInContext(vreg + 1, kind_hi, &vmap_offset_hi)) { 619 bool is_float = (kind_lo == kDoubleLoVReg); 620 uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); 621 uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo); 622 uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi); 623 return SetRegisterPairIfAccessible(reg_lo, reg_hi, new_value, is_float); 624 } else { 625 const DexFile::CodeItem* code_item = m->GetCodeItem(); 626 DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile 627 // its instructions? 628 uint32_t* addr = GetVRegAddrFromQuickCode( 629 cur_quick_frame_, code_item, frame_info.CoreSpillMask(), 630 frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg); 631 *reinterpret_cast<uint64_t*>(addr) = new_value; 632 return true; 633 } 634} 635 636bool StackVisitor::SetVRegPairFromDebugger(ArtMethod* m, 637 uint16_t vreg, 638 uint64_t new_value, 639 VRegKind kind_lo, 640 VRegKind kind_hi) { 641 if (kind_lo == kLongLoVReg) { 642 DCHECK_EQ(kind_hi, kLongHiVReg); 643 } else if (kind_lo == kDoubleLoVReg) { 644 DCHECK_EQ(kind_hi, kDoubleHiVReg); 645 } else { 646 LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi; 647 UNREACHABLE(); 648 } 649 const DexFile::CodeItem* code_item = m->GetCodeItem(); 650 if (code_item == nullptr) { 651 return false; 652 } 653 ShadowFrame* shadow_frame = GetCurrentShadowFrame(); 654 if (shadow_frame == nullptr) { 655 // This is a compiled frame: we must prepare for deoptimization (see SetVRegFromDebugger). 656 const size_t frame_id = GetFrameId(); 657 const uint16_t num_regs = code_item->registers_size_; 658 shadow_frame = thread_->FindOrCreateDebuggerShadowFrame(frame_id, num_regs, m, GetDexPc()); 659 CHECK(shadow_frame != nullptr); 660 // Remember the vreg pair has been set for debugging and must not be overwritten by the 661 // original value during deoptimization of the stack. 662 thread_->GetUpdatedVRegFlags(frame_id)[vreg] = true; 663 thread_->GetUpdatedVRegFlags(frame_id)[vreg + 1] = true; 664 } 665 shadow_frame->SetVRegLong(vreg, new_value); 666 return true; 667} 668 669bool StackVisitor::SetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi, 670 uint64_t new_value, bool is_float) { 671 if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) { 672 return false; 673 } 674 uintptr_t new_value_lo = static_cast<uintptr_t>(new_value & 0xFFFFFFFF); 675 uintptr_t new_value_hi = static_cast<uintptr_t>(new_value >> 32); 676 bool target64 = Is64BitInstructionSet(kRuntimeISA); 677 // Deal with 32 or 64-bit wide registers in a way that builds on all targets. 678 if (target64) { 679 DCHECK_EQ(reg_lo, reg_hi); 680 SetRegister(reg_lo, new_value, is_float); 681 } else { 682 SetRegister(reg_lo, new_value_lo, is_float); 683 SetRegister(reg_hi, new_value_hi, is_float); 684 } 685 return true; 686} 687 688bool StackVisitor::IsAccessibleGPR(uint32_t reg) const { 689 DCHECK(context_ != nullptr); 690 return context_->IsAccessibleGPR(reg); 691} 692 693uintptr_t* StackVisitor::GetGPRAddress(uint32_t reg) const { 694 DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine"; 695 DCHECK(context_ != nullptr); 696 return context_->GetGPRAddress(reg); 697} 698 699uintptr_t StackVisitor::GetGPR(uint32_t reg) const { 700 DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine"; 701 DCHECK(context_ != nullptr); 702 return context_->GetGPR(reg); 703} 704 705void StackVisitor::SetGPR(uint32_t reg, uintptr_t value) { 706 DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine"; 707 DCHECK(context_ != nullptr); 708 context_->SetGPR(reg, value); 709} 710 711bool StackVisitor::IsAccessibleFPR(uint32_t reg) const { 712 DCHECK(context_ != nullptr); 713 return context_->IsAccessibleFPR(reg); 714} 715 716uintptr_t StackVisitor::GetFPR(uint32_t reg) const { 717 DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine"; 718 DCHECK(context_ != nullptr); 719 return context_->GetFPR(reg); 720} 721 722void StackVisitor::SetFPR(uint32_t reg, uintptr_t value) { 723 DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine"; 724 DCHECK(context_ != nullptr); 725 context_->SetFPR(reg, value); 726} 727 728uintptr_t StackVisitor::GetReturnPc() const { 729 uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame()); 730 DCHECK(sp != nullptr); 731 uint8_t* pc_addr = sp + GetCurrentQuickFrameInfo().GetReturnPcOffset(); 732 return *reinterpret_cast<uintptr_t*>(pc_addr); 733} 734 735void StackVisitor::SetReturnPc(uintptr_t new_ret_pc) { 736 uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame()); 737 CHECK(sp != nullptr); 738 uint8_t* pc_addr = sp + GetCurrentQuickFrameInfo().GetReturnPcOffset(); 739 *reinterpret_cast<uintptr_t*>(pc_addr) = new_ret_pc; 740} 741 742size_t StackVisitor::ComputeNumFrames(Thread* thread, StackWalkKind walk_kind) { 743 struct NumFramesVisitor : public StackVisitor { 744 NumFramesVisitor(Thread* thread_in, StackWalkKind walk_kind_in) 745 : StackVisitor(thread_in, nullptr, walk_kind_in), frames(0) {} 746 747 bool VisitFrame() OVERRIDE { 748 frames++; 749 return true; 750 } 751 752 size_t frames; 753 }; 754 NumFramesVisitor visitor(thread, walk_kind); 755 visitor.WalkStack(true); 756 return visitor.frames; 757} 758 759bool StackVisitor::GetNextMethodAndDexPc(ArtMethod** next_method, uint32_t* next_dex_pc) { 760 struct HasMoreFramesVisitor : public StackVisitor { 761 HasMoreFramesVisitor(Thread* thread, 762 StackWalkKind walk_kind, 763 size_t num_frames, 764 size_t frame_height) 765 : StackVisitor(thread, nullptr, walk_kind, num_frames), 766 frame_height_(frame_height), 767 found_frame_(false), 768 has_more_frames_(false), 769 next_method_(nullptr), 770 next_dex_pc_(0) { 771 } 772 773 bool VisitFrame() OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { 774 if (found_frame_) { 775 ArtMethod* method = GetMethod(); 776 if (method != nullptr && !method->IsRuntimeMethod()) { 777 has_more_frames_ = true; 778 next_method_ = method; 779 next_dex_pc_ = GetDexPc(); 780 return false; // End stack walk once next method is found. 781 } 782 } else if (GetFrameHeight() == frame_height_) { 783 found_frame_ = true; 784 } 785 return true; 786 } 787 788 size_t frame_height_; 789 bool found_frame_; 790 bool has_more_frames_; 791 ArtMethod* next_method_; 792 uint32_t next_dex_pc_; 793 }; 794 HasMoreFramesVisitor visitor(thread_, walk_kind_, GetNumFrames(), GetFrameHeight()); 795 visitor.WalkStack(true); 796 *next_method = visitor.next_method_; 797 *next_dex_pc = visitor.next_dex_pc_; 798 return visitor.has_more_frames_; 799} 800 801void StackVisitor::DescribeStack(Thread* thread) { 802 struct DescribeStackVisitor : public StackVisitor { 803 explicit DescribeStackVisitor(Thread* thread_in) 804 : StackVisitor(thread_in, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {} 805 806 bool VisitFrame() OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { 807 LOG(INFO) << "Frame Id=" << GetFrameId() << " " << DescribeLocation(); 808 return true; 809 } 810 }; 811 DescribeStackVisitor visitor(thread); 812 visitor.WalkStack(true); 813} 814 815std::string StackVisitor::DescribeLocation() const { 816 std::string result("Visiting method '"); 817 ArtMethod* m = GetMethod(); 818 if (m == nullptr) { 819 return "upcall"; 820 } 821 result += PrettyMethod(m); 822 result += StringPrintf("' at dex PC 0x%04x", GetDexPc()); 823 if (!IsShadowFrame()) { 824 result += StringPrintf(" (native PC %p)", reinterpret_cast<void*>(GetCurrentQuickFramePc())); 825 } 826 return result; 827} 828 829static instrumentation::InstrumentationStackFrame& GetInstrumentationStackFrame(Thread* thread, 830 uint32_t depth) { 831 CHECK_LT(depth, thread->GetInstrumentationStack()->size()); 832 return thread->GetInstrumentationStack()->at(depth); 833} 834 835static void AssertPcIsWithinQuickCode(ArtMethod* method, uintptr_t pc) 836 SHARED_REQUIRES(Locks::mutator_lock_) { 837 if (method->IsNative() || method->IsRuntimeMethod() || method->IsProxyMethod()) { 838 return; 839 } 840 841 if (pc == reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc())) { 842 return; 843 } 844 845 const void* code = method->GetEntryPointFromQuickCompiledCode(); 846 if (code == GetQuickInstrumentationEntryPoint()) { 847 return; 848 } 849 850 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 851 if (class_linker->IsQuickToInterpreterBridge(code) || 852 class_linker->IsQuickResolutionStub(code)) { 853 return; 854 } 855 856 // If we are the JIT then we may have just compiled the method after the 857 // IsQuickToInterpreterBridge check. 858 jit::Jit* const jit = Runtime::Current()->GetJit(); 859 if (jit != nullptr && 860 jit->GetCodeCache()->ContainsCodePtr(reinterpret_cast<const void*>(code))) { 861 return; 862 } 863 864 uint32_t code_size = reinterpret_cast<const OatQuickMethodHeader*>( 865 EntryPointToCodePointer(code))[-1].code_size_; 866 uintptr_t code_start = reinterpret_cast<uintptr_t>(code); 867 CHECK(code_start <= pc && pc <= (code_start + code_size)) 868 << PrettyMethod(method) 869 << " pc=" << std::hex << pc 870 << " code=" << code 871 << " size=" << code_size; 872} 873 874void StackVisitor::SanityCheckFrame() const { 875 if (kIsDebugBuild) { 876 ArtMethod* method = GetMethod(); 877 auto* declaring_class = method->GetDeclaringClass(); 878 // Runtime methods have null declaring class. 879 if (!method->IsRuntimeMethod()) { 880 CHECK(declaring_class != nullptr); 881 CHECK_EQ(declaring_class->GetClass(), declaring_class->GetClass()->GetClass()) 882 << declaring_class; 883 } else { 884 CHECK(declaring_class == nullptr); 885 } 886 Runtime* const runtime = Runtime::Current(); 887 LinearAlloc* const linear_alloc = runtime->GetLinearAlloc(); 888 if (!linear_alloc->Contains(method)) { 889 // Check class linker linear allocs. 890 mirror::Class* klass = method->GetDeclaringClass(); 891 LinearAlloc* const class_linear_alloc = (klass != nullptr) 892 ? ClassLinker::GetAllocatorForClassLoader(klass->GetClassLoader()) 893 : linear_alloc; 894 if (!class_linear_alloc->Contains(method)) { 895 // Check image space. 896 bool in_image = false; 897 for (auto& space : runtime->GetHeap()->GetContinuousSpaces()) { 898 if (space->IsImageSpace()) { 899 auto* image_space = space->AsImageSpace(); 900 const auto& header = image_space->GetImageHeader(); 901 const auto* methods = &header.GetMethodsSection(); 902 if (methods->Contains(reinterpret_cast<const uint8_t*>(method) - image_space->Begin())) { 903 in_image = true; 904 break; 905 } 906 } 907 } 908 CHECK(in_image) << PrettyMethod(method) << " not in linear alloc or image"; 909 } 910 } 911 if (cur_quick_frame_ != nullptr) { 912 AssertPcIsWithinQuickCode(method, cur_quick_frame_pc_); 913 // Frame sanity. 914 size_t frame_size = GetCurrentQuickFrameInfo().FrameSizeInBytes(); 915 CHECK_NE(frame_size, 0u); 916 // A rough guess at an upper size we expect to see for a frame. 917 // 256 registers 918 // 2 words HandleScope overhead 919 // 3+3 register spills 920 // TODO: this seems architecture specific for the case of JNI frames. 921 // TODO: 083-compiler-regressions ManyFloatArgs shows this estimate is wrong. 922 // const size_t kMaxExpectedFrameSize = (256 + 2 + 3 + 3) * sizeof(word); 923 const size_t kMaxExpectedFrameSize = 2 * KB; 924 CHECK_LE(frame_size, kMaxExpectedFrameSize) << PrettyMethod(method); 925 size_t return_pc_offset = GetCurrentQuickFrameInfo().GetReturnPcOffset(); 926 CHECK_LT(return_pc_offset, frame_size); 927 } 928 } 929} 930 931// Counts the number of references in the parameter list of the corresponding method. 932// Note: Thus does _not_ include "this" for non-static methods. 933static uint32_t GetNumberOfReferenceArgsWithoutReceiver(ArtMethod* method) 934 SHARED_REQUIRES(Locks::mutator_lock_) { 935 uint32_t shorty_len; 936 const char* shorty = method->GetShorty(&shorty_len); 937 uint32_t refs = 0; 938 for (uint32_t i = 1; i < shorty_len ; ++i) { 939 if (shorty[i] == 'L') { 940 refs++; 941 } 942 } 943 return refs; 944} 945 946QuickMethodFrameInfo StackVisitor::GetCurrentQuickFrameInfo() const { 947 if (cur_oat_quick_method_header_ != nullptr) { 948 return cur_oat_quick_method_header_->GetFrameInfo(); 949 } 950 951 ArtMethod* method = GetMethod(); 952 Runtime* runtime = Runtime::Current(); 953 954 if (method->IsAbstract()) { 955 return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); 956 } 957 958 // This goes before IsProxyMethod since runtime methods have a null declaring class. 959 if (method->IsRuntimeMethod()) { 960 return runtime->GetRuntimeMethodFrameInfo(method); 961 } 962 963 // For Proxy method we add special handling for the direct method case (there is only one 964 // direct method - constructor). Direct method is cloned from original 965 // java.lang.reflect.Proxy class together with code and as a result it is executed as usual 966 // quick compiled method without any stubs. So the frame info should be returned as it is a 967 // quick method not a stub. However, if instrumentation stubs are installed, the 968 // instrumentation->GetQuickCodeFor() returns the artQuickProxyInvokeHandler instead of an 969 // oat code pointer, thus we have to add a special case here. 970 if (method->IsProxyMethod()) { 971 if (method->IsDirect()) { 972 CHECK(method->IsConstructor()); 973 const void* code_pointer = 974 EntryPointToCodePointer(method->GetEntryPointFromQuickCompiledCode()); 975 return reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].frame_info_; 976 } else { 977 return runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); 978 } 979 } 980 981 ClassLinker* class_linker = runtime->GetClassLinker(); 982 DCHECK(method->IsNative()); 983 const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(method, sizeof(void*)); 984 DCHECK(class_linker->IsQuickGenericJniStub(entry_point)) << PrettyMethod(method); 985 // Generic JNI frame. 986 uint32_t handle_refs = GetNumberOfReferenceArgsWithoutReceiver(method) + 1; 987 size_t scope_size = HandleScope::SizeOf(handle_refs); 988 QuickMethodFrameInfo callee_info = runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); 989 990 // Callee saves + handle scope + method ref + alignment 991 // Note: -sizeof(void*) since callee-save frame stores a whole method pointer. 992 size_t frame_size = RoundUp( 993 callee_info.FrameSizeInBytes() - sizeof(void*) + sizeof(ArtMethod*) + scope_size, 994 kStackAlignment); 995 return QuickMethodFrameInfo(frame_size, callee_info.CoreSpillMask(), callee_info.FpSpillMask()); 996} 997 998void StackVisitor::WalkStack(bool include_transitions) { 999 DCHECK(thread_ == Thread::Current() || thread_->IsSuspended()); 1000 CHECK_EQ(cur_depth_, 0U); 1001 bool exit_stubs_installed = Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled(); 1002 uint32_t instrumentation_stack_depth = 0; 1003 size_t inlined_frames_count = 0; 1004 1005 for (const ManagedStack* current_fragment = thread_->GetManagedStack(); 1006 current_fragment != nullptr; current_fragment = current_fragment->GetLink()) { 1007 cur_shadow_frame_ = current_fragment->GetTopShadowFrame(); 1008 cur_quick_frame_ = current_fragment->GetTopQuickFrame(); 1009 cur_quick_frame_pc_ = 0; 1010 cur_oat_quick_method_header_ = nullptr; 1011 1012 if (cur_quick_frame_ != nullptr) { // Handle quick stack frames. 1013 // Can't be both a shadow and a quick fragment. 1014 DCHECK(current_fragment->GetTopShadowFrame() == nullptr); 1015 ArtMethod* method = *cur_quick_frame_; 1016 while (method != nullptr) { 1017 cur_oat_quick_method_header_ = method->GetOatQuickMethodHeader(cur_quick_frame_pc_); 1018 SanityCheckFrame(); 1019 1020 if ((walk_kind_ == StackWalkKind::kIncludeInlinedFrames) 1021 && (cur_oat_quick_method_header_ != nullptr) 1022 && cur_oat_quick_method_header_->IsOptimized()) { 1023 CodeInfo code_info = cur_oat_quick_method_header_->GetOptimizedCodeInfo(); 1024 StackMapEncoding encoding = code_info.ExtractEncoding(); 1025 uint32_t native_pc_offset = 1026 cur_oat_quick_method_header_->NativeQuickPcOffset(cur_quick_frame_pc_); 1027 StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding); 1028 if (stack_map.IsValid() && stack_map.HasInlineInfo(encoding)) { 1029 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding); 1030 DCHECK_EQ(current_inlining_depth_, 0u); 1031 for (current_inlining_depth_ = inline_info.GetDepth(); 1032 current_inlining_depth_ != 0; 1033 --current_inlining_depth_) { 1034 bool should_continue = VisitFrame(); 1035 if (UNLIKELY(!should_continue)) { 1036 return; 1037 } 1038 cur_depth_++; 1039 inlined_frames_count++; 1040 } 1041 } 1042 } 1043 1044 bool should_continue = VisitFrame(); 1045 if (UNLIKELY(!should_continue)) { 1046 return; 1047 } 1048 1049 QuickMethodFrameInfo frame_info = GetCurrentQuickFrameInfo(); 1050 if (context_ != nullptr) { 1051 context_->FillCalleeSaves(reinterpret_cast<uint8_t*>(cur_quick_frame_), frame_info); 1052 } 1053 // Compute PC for next stack frame from return PC. 1054 size_t frame_size = frame_info.FrameSizeInBytes(); 1055 size_t return_pc_offset = frame_size - sizeof(void*); 1056 uint8_t* return_pc_addr = reinterpret_cast<uint8_t*>(cur_quick_frame_) + return_pc_offset; 1057 uintptr_t return_pc = *reinterpret_cast<uintptr_t*>(return_pc_addr); 1058 1059 if (UNLIKELY(exit_stubs_installed)) { 1060 // While profiling, the return pc is restored from the side stack, except when walking 1061 // the stack for an exception where the side stack will be unwound in VisitFrame. 1062 if (reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()) == return_pc) { 1063 const instrumentation::InstrumentationStackFrame& instrumentation_frame = 1064 GetInstrumentationStackFrame(thread_, instrumentation_stack_depth); 1065 instrumentation_stack_depth++; 1066 if (GetMethod() == Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)) { 1067 // Skip runtime save all callee frames which are used to deliver exceptions. 1068 } else if (instrumentation_frame.interpreter_entry_) { 1069 ArtMethod* callee = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs); 1070 CHECK_EQ(GetMethod(), callee) << "Expected: " << PrettyMethod(callee) << " Found: " 1071 << PrettyMethod(GetMethod()); 1072 } else { 1073 CHECK_EQ(instrumentation_frame.method_, GetMethod()) 1074 << "Expected: " << PrettyMethod(instrumentation_frame.method_) 1075 << " Found: " << PrettyMethod(GetMethod()); 1076 } 1077 if (num_frames_ != 0) { 1078 // Check agreement of frame Ids only if num_frames_ is computed to avoid infinite 1079 // recursion. 1080 size_t frame_id = instrumentation::Instrumentation::ComputeFrameId( 1081 thread_, 1082 cur_depth_, 1083 inlined_frames_count); 1084 CHECK_EQ(instrumentation_frame.frame_id_, frame_id); 1085 } 1086 return_pc = instrumentation_frame.return_pc_; 1087 } 1088 } 1089 1090 cur_quick_frame_pc_ = return_pc; 1091 uint8_t* next_frame = reinterpret_cast<uint8_t*>(cur_quick_frame_) + frame_size; 1092 cur_quick_frame_ = reinterpret_cast<ArtMethod**>(next_frame); 1093 1094 if (kDebugStackWalk) { 1095 LOG(INFO) << PrettyMethod(method) << "@" << method << " size=" << frame_size 1096 << std::boolalpha 1097 << " optimized=" << (cur_oat_quick_method_header_ != nullptr && 1098 cur_oat_quick_method_header_->IsOptimized()) 1099 << " native=" << method->IsNative() 1100 << std::noboolalpha 1101 << " entrypoints=" << method->GetEntryPointFromQuickCompiledCode() 1102 << "," << method->GetEntryPointFromJni() 1103 << " next=" << *cur_quick_frame_; 1104 } 1105 1106 cur_depth_++; 1107 method = *cur_quick_frame_; 1108 } 1109 } else if (cur_shadow_frame_ != nullptr) { 1110 do { 1111 SanityCheckFrame(); 1112 bool should_continue = VisitFrame(); 1113 if (UNLIKELY(!should_continue)) { 1114 return; 1115 } 1116 cur_depth_++; 1117 cur_shadow_frame_ = cur_shadow_frame_->GetLink(); 1118 } while (cur_shadow_frame_ != nullptr); 1119 } 1120 if (include_transitions) { 1121 bool should_continue = VisitFrame(); 1122 if (!should_continue) { 1123 return; 1124 } 1125 } 1126 cur_depth_++; 1127 } 1128 if (num_frames_ != 0) { 1129 CHECK_EQ(cur_depth_, num_frames_); 1130 } 1131} 1132 1133void JavaFrameRootInfo::Describe(std::ostream& os) const { 1134 const StackVisitor* visitor = stack_visitor_; 1135 CHECK(visitor != nullptr); 1136 os << "Type=" << GetType() << " thread_id=" << GetThreadId() << " location=" << 1137 visitor->DescribeLocation() << " vreg=" << vreg_; 1138} 1139 1140int StackVisitor::GetVRegOffsetFromQuickCode(const DexFile::CodeItem* code_item, 1141 uint32_t core_spills, uint32_t fp_spills, 1142 size_t frame_size, int reg, InstructionSet isa) { 1143 size_t pointer_size = InstructionSetPointerSize(isa); 1144 if (kIsDebugBuild) { 1145 auto* runtime = Runtime::Current(); 1146 if (runtime != nullptr) { 1147 CHECK_EQ(runtime->GetClassLinker()->GetImagePointerSize(), pointer_size); 1148 } 1149 } 1150 DCHECK_ALIGNED(frame_size, kStackAlignment); 1151 DCHECK_NE(reg, -1); 1152 int spill_size = POPCOUNT(core_spills) * GetBytesPerGprSpillLocation(isa) 1153 + POPCOUNT(fp_spills) * GetBytesPerFprSpillLocation(isa) 1154 + sizeof(uint32_t); // Filler. 1155 int num_regs = code_item->registers_size_ - code_item->ins_size_; 1156 int temp_threshold = code_item->registers_size_; 1157 const int max_num_special_temps = 1; 1158 if (reg == temp_threshold) { 1159 // The current method pointer corresponds to special location on stack. 1160 return 0; 1161 } else if (reg >= temp_threshold + max_num_special_temps) { 1162 /* 1163 * Special temporaries may have custom locations and the logic above deals with that. 1164 * However, non-special temporaries are placed relative to the outs. 1165 */ 1166 int temps_start = code_item->outs_size_ * sizeof(uint32_t) + pointer_size /* art method */; 1167 int relative_offset = (reg - (temp_threshold + max_num_special_temps)) * sizeof(uint32_t); 1168 return temps_start + relative_offset; 1169 } else if (reg < num_regs) { 1170 int locals_start = frame_size - spill_size - num_regs * sizeof(uint32_t); 1171 return locals_start + (reg * sizeof(uint32_t)); 1172 } else { 1173 // Handle ins. 1174 return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + pointer_size /* art method */; 1175 } 1176} 1177 1178void LockCountData::AddMonitorInternal(Thread* self, mirror::Object* obj) { 1179 if (obj == nullptr) { 1180 return; 1181 } 1182 1183 // If there's an error during enter, we won't have locked the monitor. So check there's no 1184 // exception. 1185 if (self->IsExceptionPending()) { 1186 return; 1187 } 1188 1189 if (monitors_ == nullptr) { 1190 monitors_.reset(new std::vector<mirror::Object*>()); 1191 } 1192 monitors_->push_back(obj); 1193} 1194 1195void LockCountData::RemoveMonitorInternal(Thread* self, const mirror::Object* obj) { 1196 if (obj == nullptr) { 1197 return; 1198 } 1199 bool found_object = false; 1200 if (monitors_ != nullptr) { 1201 // We need to remove one pointer to ref, as duplicates are used for counting recursive locks. 1202 // We arbitrarily choose the first one. 1203 auto it = std::find(monitors_->begin(), monitors_->end(), obj); 1204 if (it != monitors_->end()) { 1205 monitors_->erase(it); 1206 found_object = true; 1207 } 1208 } 1209 if (!found_object) { 1210 // The object wasn't found. Time for an IllegalMonitorStateException. 1211 // The order here isn't fully clear. Assume that any other pending exception is swallowed. 1212 // TODO: Maybe make already pending exception a suppressed exception. 1213 self->ClearException(); 1214 self->ThrowNewExceptionF("Ljava/lang/IllegalMonitorStateException;", 1215 "did not lock monitor on object of type '%s' before unlocking", 1216 PrettyTypeOf(const_cast<mirror::Object*>(obj)).c_str()); 1217 } 1218} 1219 1220// Helper to unlock a monitor. Must be NO_THREAD_SAFETY_ANALYSIS, as we can't statically show 1221// that the object was locked. 1222void MonitorExitHelper(Thread* self, mirror::Object* obj) NO_THREAD_SAFETY_ANALYSIS { 1223 DCHECK(self != nullptr); 1224 DCHECK(obj != nullptr); 1225 obj->MonitorExit(self); 1226} 1227 1228bool LockCountData::CheckAllMonitorsReleasedInternal(Thread* self) { 1229 DCHECK(self != nullptr); 1230 if (monitors_ != nullptr) { 1231 if (!monitors_->empty()) { 1232 // There may be an exception pending, if the method is terminating abruptly. Clear it. 1233 // TODO: Should we add this as a suppressed exception? 1234 self->ClearException(); 1235 1236 // OK, there are monitors that are still locked. To enforce structured locking (and avoid 1237 // deadlocks) we unlock all of them before we raise the IllegalMonitorState exception. 1238 for (mirror::Object* obj : *monitors_) { 1239 MonitorExitHelper(self, obj); 1240 // If this raised an exception, ignore. TODO: Should we add this as suppressed 1241 // exceptions? 1242 if (self->IsExceptionPending()) { 1243 self->ClearException(); 1244 } 1245 } 1246 // Raise an exception, just give the first object as the sample. 1247 mirror::Object* first = (*monitors_)[0]; 1248 self->ThrowNewExceptionF("Ljava/lang/IllegalMonitorStateException;", 1249 "did not unlock monitor on object of type '%s'", 1250 PrettyTypeOf(first).c_str()); 1251 1252 // To make sure this path is not triggered again, clean out the monitors. 1253 monitors_->clear(); 1254 1255 return false; 1256 } 1257 } 1258 return true; 1259} 1260 1261} // namespace art 1262