1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/frames.h" 6 7 #include <sstream> 8 9 #include "src/ast/ast.h" 10 #include "src/ast/scopeinfo.h" 11 #include "src/base/bits.h" 12 #include "src/deoptimizer.h" 13 #include "src/frames-inl.h" 14 #include "src/full-codegen/full-codegen.h" 15 #include "src/register-configuration.h" 16 #include "src/safepoint-table.h" 17 #include "src/string-stream.h" 18 #include "src/vm-state-inl.h" 19 20 namespace v8 { 21 namespace internal { 22 23 ReturnAddressLocationResolver 24 StackFrame::return_address_location_resolver_ = NULL; 25 26 27 // Iterator that supports traversing the stack handlers of a 28 // particular frame. Needs to know the top of the handler chain. 29 class StackHandlerIterator BASE_EMBEDDED { 30 public: 31 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) 32 : limit_(frame->fp()), handler_(handler) { 33 // Make sure the handler has already been unwound to this frame. 34 DCHECK(frame->sp() <= handler->address()); 35 } 36 37 StackHandler* handler() const { return handler_; } 38 39 bool done() { 40 return handler_ == NULL || handler_->address() > limit_; 41 } 42 void Advance() { 43 DCHECK(!done()); 44 handler_ = handler_->next(); 45 } 46 47 private: 48 const Address limit_; 49 StackHandler* handler_; 50 }; 51 52 53 // ------------------------------------------------------------------------- 54 55 56 #define INITIALIZE_SINGLETON(type, field) field##_(this), 57 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate, 58 bool can_access_heap_objects) 59 : isolate_(isolate), 60 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 61 frame_(NULL), handler_(NULL), 62 can_access_heap_objects_(can_access_heap_objects) { 63 } 64 #undef INITIALIZE_SINGLETON 65 66 67 StackFrameIterator::StackFrameIterator(Isolate* isolate) 68 : StackFrameIteratorBase(isolate, true) { 69 Reset(isolate->thread_local_top()); 70 } 71 72 73 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) 74 : StackFrameIteratorBase(isolate, true) { 75 Reset(t); 76 } 77 78 79 void StackFrameIterator::Advance() { 80 DCHECK(!done()); 81 // Compute the state of the calling frame before restoring 82 // callee-saved registers and unwinding handlers. This allows the 83 // frame code that computes the caller state to access the top 84 // handler and the value of any callee-saved register if needed. 85 StackFrame::State state; 86 StackFrame::Type type = frame_->GetCallerState(&state); 87 88 // Unwind handlers corresponding to the current frame. 89 StackHandlerIterator it(frame_, handler_); 90 while (!it.done()) it.Advance(); 91 handler_ = it.handler(); 92 93 // Advance to the calling frame. 94 frame_ = SingletonFor(type, &state); 95 96 // When we're done iterating over the stack frames, the handler 97 // chain must have been completely unwound. 98 DCHECK(!done() || handler_ == NULL); 99 } 100 101 102 void StackFrameIterator::Reset(ThreadLocalTop* top) { 103 StackFrame::State state; 104 StackFrame::Type type = ExitFrame::GetStateForFramePointer( 105 Isolate::c_entry_fp(top), &state); 106 handler_ = StackHandler::FromAddress(Isolate::handler(top)); 107 if (SingletonFor(type) == NULL) return; 108 frame_ = SingletonFor(type, &state); 109 } 110 111 112 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type, 113 StackFrame::State* state) { 114 if (type == StackFrame::NONE) return NULL; 115 StackFrame* result = SingletonFor(type); 116 DCHECK(result != NULL); 117 result->state_ = *state; 118 return result; 119 } 120 121 122 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) { 123 #define FRAME_TYPE_CASE(type, field) \ 124 case StackFrame::type: result = &field##_; break; 125 126 StackFrame* result = NULL; 127 switch (type) { 128 case StackFrame::NONE: return NULL; 129 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 130 default: break; 131 } 132 return result; 133 134 #undef FRAME_TYPE_CASE 135 } 136 137 138 // ------------------------------------------------------------------------- 139 140 141 JavaScriptFrameIterator::JavaScriptFrameIterator( 142 Isolate* isolate, StackFrame::Id id) 143 : iterator_(isolate) { 144 while (!done()) { 145 Advance(); 146 if (frame()->id() == id) return; 147 } 148 } 149 150 151 void JavaScriptFrameIterator::Advance() { 152 do { 153 iterator_.Advance(); 154 } while (!iterator_.done() && !iterator_.frame()->is_java_script()); 155 } 156 157 158 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { 159 if (!frame()->has_adapted_arguments()) return; 160 iterator_.Advance(); 161 DCHECK(iterator_.frame()->is_arguments_adaptor()); 162 } 163 164 165 // ------------------------------------------------------------------------- 166 167 168 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 169 : JavaScriptFrameIterator(isolate) { 170 if (!done() && !IsValidFrame()) Advance(); 171 } 172 173 174 void StackTraceFrameIterator::Advance() { 175 while (true) { 176 JavaScriptFrameIterator::Advance(); 177 if (done()) return; 178 if (IsValidFrame()) return; 179 } 180 } 181 182 183 bool StackTraceFrameIterator::IsValidFrame() { 184 if (!frame()->function()->IsJSFunction()) return false; 185 Object* script = frame()->function()->shared()->script(); 186 // Don't show functions from native scripts to user. 187 return (script->IsScript() && 188 Script::TYPE_NATIVE != Script::cast(script)->type()); 189 } 190 191 192 // ------------------------------------------------------------------------- 193 194 195 SafeStackFrameIterator::SafeStackFrameIterator( 196 Isolate* isolate, 197 Address fp, Address sp, Address js_entry_sp) 198 : StackFrameIteratorBase(isolate, false), 199 low_bound_(sp), 200 high_bound_(js_entry_sp), 201 top_frame_type_(StackFrame::NONE), 202 external_callback_scope_(isolate->external_callback_scope()) { 203 StackFrame::State state; 204 StackFrame::Type type; 205 ThreadLocalTop* top = isolate->thread_local_top(); 206 if (IsValidTop(top)) { 207 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); 208 top_frame_type_ = type; 209 } else if (IsValidStackAddress(fp)) { 210 DCHECK(fp != NULL); 211 state.fp = fp; 212 state.sp = sp; 213 state.pc_address = StackFrame::ResolveReturnAddressLocation( 214 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); 215 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, 216 // we check only that kMarkerOffset is within the stack bounds and do 217 // compile time check that kContextOffset slot is pushed on the stack before 218 // kMarkerOffset. 219 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset < 220 StandardFrameConstants::kContextOffset); 221 Address frame_marker = fp + StandardFrameConstants::kMarkerOffset; 222 if (IsValidStackAddress(frame_marker)) { 223 type = StackFrame::ComputeType(this, &state); 224 top_frame_type_ = type; 225 } else { 226 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. 227 // The frame anyways will be skipped. 228 type = StackFrame::JAVA_SCRIPT; 229 // Top frame is incomplete so we cannot reliably determine its type. 230 top_frame_type_ = StackFrame::NONE; 231 } 232 } else { 233 return; 234 } 235 if (SingletonFor(type) == NULL) return; 236 frame_ = SingletonFor(type, &state); 237 if (frame_ == NULL) return; 238 239 Advance(); 240 241 if (frame_ != NULL && !frame_->is_exit() && 242 external_callback_scope_ != NULL && 243 external_callback_scope_->scope_address() < frame_->fp()) { 244 // Skip top ExternalCallbackScope if we already advanced to a JS frame 245 // under it. Sampler will anyways take this top external callback. 246 external_callback_scope_ = external_callback_scope_->previous(); 247 } 248 } 249 250 251 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { 252 Address c_entry_fp = Isolate::c_entry_fp(top); 253 if (!IsValidExitFrame(c_entry_fp)) return false; 254 // There should be at least one JS_ENTRY stack handler. 255 Address handler = Isolate::handler(top); 256 if (handler == NULL) return false; 257 // Check that there are no js frames on top of the native frames. 258 return c_entry_fp < handler; 259 } 260 261 262 void SafeStackFrameIterator::AdvanceOneFrame() { 263 DCHECK(!done()); 264 StackFrame* last_frame = frame_; 265 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 266 // Before advancing to the next stack frame, perform pointer validity tests. 267 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { 268 frame_ = NULL; 269 return; 270 } 271 272 // Advance to the previous frame. 273 StackFrame::State state; 274 StackFrame::Type type = frame_->GetCallerState(&state); 275 frame_ = SingletonFor(type, &state); 276 if (frame_ == NULL) return; 277 278 // Check that we have actually moved to the previous frame in the stack. 279 if (frame_->sp() < last_sp || frame_->fp() < last_fp) { 280 frame_ = NULL; 281 } 282 } 283 284 285 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { 286 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()); 287 } 288 289 290 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { 291 StackFrame::State state; 292 if (frame->is_entry() || frame->is_entry_construct()) { 293 // See EntryFrame::GetCallerState. It computes the caller FP address 294 // and calls ExitFrame::GetStateForFramePointer on it. We need to be 295 // sure that caller FP address is valid. 296 Address caller_fp = Memory::Address_at( 297 frame->fp() + EntryFrameConstants::kCallerFPOffset); 298 if (!IsValidExitFrame(caller_fp)) return false; 299 } else if (frame->is_arguments_adaptor()) { 300 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that 301 // the number of arguments is stored on stack as Smi. We need to check 302 // that it really an Smi. 303 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> 304 GetExpression(0); 305 if (!number_of_args->IsSmi()) { 306 return false; 307 } 308 } 309 frame->ComputeCallerState(&state); 310 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) && 311 SingletonFor(frame->GetCallerState(&state)) != NULL; 312 } 313 314 315 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const { 316 if (!IsValidStackAddress(fp)) return false; 317 Address sp = ExitFrame::ComputeStackPointer(fp); 318 if (!IsValidStackAddress(sp)) return false; 319 StackFrame::State state; 320 ExitFrame::FillState(fp, sp, &state); 321 return *state.pc_address != NULL; 322 } 323 324 325 void SafeStackFrameIterator::Advance() { 326 while (true) { 327 AdvanceOneFrame(); 328 if (done()) return; 329 if (frame_->is_java_script()) return; 330 if (frame_->is_exit() && external_callback_scope_) { 331 // Some of the EXIT frames may have ExternalCallbackScope allocated on 332 // top of them. In that case the scope corresponds to the first EXIT 333 // frame beneath it. There may be other EXIT frames on top of the 334 // ExternalCallbackScope, just skip them as we cannot collect any useful 335 // information about them. 336 if (external_callback_scope_->scope_address() < frame_->fp()) { 337 frame_->state_.pc_address = 338 external_callback_scope_->callback_entrypoint_address(); 339 external_callback_scope_ = external_callback_scope_->previous(); 340 DCHECK(external_callback_scope_ == NULL || 341 external_callback_scope_->scope_address() > frame_->fp()); 342 return; 343 } 344 } 345 } 346 } 347 348 349 // ------------------------------------------------------------------------- 350 351 352 Code* StackFrame::GetSafepointData(Isolate* isolate, 353 Address inner_pointer, 354 SafepointEntry* safepoint_entry, 355 unsigned* stack_slots) { 356 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = 357 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); 358 if (!entry->safepoint_entry.is_valid()) { 359 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); 360 DCHECK(entry->safepoint_entry.is_valid()); 361 } else { 362 DCHECK(entry->safepoint_entry.Equals( 363 entry->code->GetSafepointEntry(inner_pointer))); 364 } 365 366 // Fill in the results and return the code. 367 Code* code = entry->code; 368 *safepoint_entry = entry->safepoint_entry; 369 *stack_slots = code->stack_slots(); 370 return code; 371 } 372 373 374 #ifdef DEBUG 375 static bool GcSafeCodeContains(HeapObject* object, Address addr); 376 #endif 377 378 379 void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address, 380 Address* constant_pool_address, Code* holder) { 381 Address pc = *pc_address; 382 DCHECK(GcSafeCodeContains(holder, pc)); 383 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); 384 Object* code = holder; 385 v->VisitPointer(&code); 386 if (code != holder) { 387 holder = reinterpret_cast<Code*>(code); 388 pc = holder->instruction_start() + pc_offset; 389 *pc_address = pc; 390 if (FLAG_enable_embedded_constant_pool && constant_pool_address) { 391 *constant_pool_address = holder->constant_pool(); 392 } 393 } 394 } 395 396 397 void StackFrame::SetReturnAddressLocationResolver( 398 ReturnAddressLocationResolver resolver) { 399 DCHECK(return_address_location_resolver_ == NULL); 400 return_address_location_resolver_ = resolver; 401 } 402 403 404 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, 405 State* state) { 406 DCHECK(state->fp != NULL); 407 408 if (!iterator->can_access_heap_objects_) { 409 // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really 410 // means that we are being called from the profiler, which can interrupt 411 // the VM with a signal at any arbitrary instruction, with essentially 412 // anything on the stack. So basically none of these checks are 100% 413 // reliable. 414 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 415 // An adapter frame has a special SMI constant for the context and 416 // is not distinguished through the marker. 417 return ARGUMENTS_ADAPTOR; 418 } 419 Object* marker = 420 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); 421 if (marker->IsSmi()) { 422 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 423 } else { 424 return JAVA_SCRIPT; 425 } 426 } 427 428 // Look up the code object to figure out the type of the stack frame. 429 Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); 430 431 Object* marker = 432 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); 433 if (code_obj != nullptr) { 434 switch (code_obj->kind()) { 435 case Code::FUNCTION: 436 return JAVA_SCRIPT; 437 case Code::OPTIMIZED_FUNCTION: 438 return OPTIMIZED; 439 case Code::WASM_FUNCTION: 440 return STUB; 441 case Code::BUILTIN: 442 if (!marker->IsSmi()) { 443 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 444 // An adapter frame has a special SMI constant for the context and 445 // is not distinguished through the marker. 446 return ARGUMENTS_ADAPTOR; 447 } else { 448 // The interpreter entry trampoline has a non-SMI marker. 449 DCHECK(code_obj->is_interpreter_entry_trampoline()); 450 return INTERPRETED; 451 } 452 } 453 break; // Marker encodes the frame type. 454 case Code::HANDLER: 455 if (!marker->IsSmi()) { 456 // Only hydrogen code stub handlers can have a non-SMI marker. 457 DCHECK(code_obj->is_hydrogen_stub()); 458 return OPTIMIZED; 459 } 460 break; // Marker encodes the frame type. 461 default: 462 break; // Marker encodes the frame type. 463 } 464 } 465 466 // Didn't find a code object, or the code kind wasn't specific enough. 467 // The marker should encode the frame type. 468 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 469 } 470 471 472 #ifdef DEBUG 473 bool StackFrame::can_access_heap_objects() const { 474 return iterator_->can_access_heap_objects_; 475 } 476 #endif 477 478 479 StackFrame::Type StackFrame::GetCallerState(State* state) const { 480 ComputeCallerState(state); 481 return ComputeType(iterator_, state); 482 } 483 484 485 Address StackFrame::UnpaddedFP() const { 486 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 487 if (!is_optimized()) return fp(); 488 int32_t alignment_state = Memory::int32_at( 489 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); 490 491 return (alignment_state == kAlignmentPaddingPushed) ? 492 (fp() + kPointerSize) : fp(); 493 #else 494 return fp(); 495 #endif 496 } 497 498 499 Code* EntryFrame::unchecked_code() const { 500 return isolate()->heap()->js_entry_code(); 501 } 502 503 504 void EntryFrame::ComputeCallerState(State* state) const { 505 GetCallerState(state); 506 } 507 508 509 void EntryFrame::SetCallerFp(Address caller_fp) { 510 const int offset = EntryFrameConstants::kCallerFPOffset; 511 Memory::Address_at(this->fp() + offset) = caller_fp; 512 } 513 514 515 StackFrame::Type EntryFrame::GetCallerState(State* state) const { 516 const int offset = EntryFrameConstants::kCallerFPOffset; 517 Address fp = Memory::Address_at(this->fp() + offset); 518 return ExitFrame::GetStateForFramePointer(fp, state); 519 } 520 521 522 Code* EntryConstructFrame::unchecked_code() const { 523 return isolate()->heap()->js_construct_entry_code(); 524 } 525 526 527 Object*& ExitFrame::code_slot() const { 528 const int offset = ExitFrameConstants::kCodeOffset; 529 return Memory::Object_at(fp() + offset); 530 } 531 532 533 Code* ExitFrame::unchecked_code() const { 534 return reinterpret_cast<Code*>(code_slot()); 535 } 536 537 538 void ExitFrame::ComputeCallerState(State* state) const { 539 // Set up the caller state. 540 state->sp = caller_sp(); 541 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); 542 state->pc_address = ResolveReturnAddressLocation( 543 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); 544 if (FLAG_enable_embedded_constant_pool) { 545 state->constant_pool_address = reinterpret_cast<Address*>( 546 fp() + ExitFrameConstants::kConstantPoolOffset); 547 } 548 } 549 550 551 void ExitFrame::SetCallerFp(Address caller_fp) { 552 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; 553 } 554 555 556 void ExitFrame::Iterate(ObjectVisitor* v) const { 557 // The arguments are traversed as part of the expression stack of 558 // the calling frame. 559 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 560 v->VisitPointer(&code_slot()); 561 } 562 563 564 Address ExitFrame::GetCallerStackPointer() const { 565 return fp() + ExitFrameConstants::kCallerSPDisplacement; 566 } 567 568 569 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 570 if (fp == 0) return NONE; 571 Address sp = ComputeStackPointer(fp); 572 FillState(fp, sp, state); 573 DCHECK(*state->pc_address != NULL); 574 return EXIT; 575 } 576 577 578 Address ExitFrame::ComputeStackPointer(Address fp) { 579 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); 580 } 581 582 583 void ExitFrame::FillState(Address fp, Address sp, State* state) { 584 state->sp = sp; 585 state->fp = fp; 586 state->pc_address = ResolveReturnAddressLocation( 587 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); 588 // The constant pool recorded in the exit frame is not associated 589 // with the pc in this state (the return address into a C entry 590 // stub). ComputeCallerState will retrieve the constant pool 591 // together with the associated caller pc. 592 state->constant_pool_address = NULL; 593 } 594 595 596 Address StandardFrame::GetExpressionAddress(int n) const { 597 const int offset = StandardFrameConstants::kExpressionsOffset; 598 return fp() + offset - n * kPointerSize; 599 } 600 601 602 Object* StandardFrame::GetExpression(Address fp, int index) { 603 return Memory::Object_at(GetExpressionAddress(fp, index)); 604 } 605 606 607 Address StandardFrame::GetExpressionAddress(Address fp, int n) { 608 const int offset = StandardFrameConstants::kExpressionsOffset; 609 return fp + offset - n * kPointerSize; 610 } 611 612 613 int StandardFrame::ComputeExpressionsCount() const { 614 const int offset = 615 StandardFrameConstants::kExpressionsOffset + kPointerSize; 616 Address base = fp() + offset; 617 Address limit = sp(); 618 DCHECK(base >= limit); // stack grows downwards 619 // Include register-allocated locals in number of expressions. 620 return static_cast<int>((base - limit) / kPointerSize); 621 } 622 623 624 void StandardFrame::ComputeCallerState(State* state) const { 625 state->sp = caller_sp(); 626 state->fp = caller_fp(); 627 state->pc_address = ResolveReturnAddressLocation( 628 reinterpret_cast<Address*>(ComputePCAddress(fp()))); 629 state->constant_pool_address = 630 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); 631 } 632 633 634 void StandardFrame::SetCallerFp(Address caller_fp) { 635 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 636 caller_fp; 637 } 638 639 640 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 641 // Make sure that we're not doing "safe" stack frame iteration. We cannot 642 // possibly find pointers in optimized frames in that state. 643 DCHECK(can_access_heap_objects()); 644 645 // Compute the safepoint information. 646 unsigned stack_slots = 0; 647 SafepointEntry safepoint_entry; 648 Code* code = StackFrame::GetSafepointData( 649 isolate(), pc(), &safepoint_entry, &stack_slots); 650 unsigned slot_space = stack_slots * kPointerSize; 651 652 // Visit the outgoing parameters. 653 Object** parameters_base = &Memory::Object_at(sp()); 654 Object** parameters_limit = &Memory::Object_at( 655 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); 656 657 // Visit the parameters that may be on top of the saved registers. 658 if (safepoint_entry.argument_count() > 0) { 659 v->VisitPointers(parameters_base, 660 parameters_base + safepoint_entry.argument_count()); 661 parameters_base += safepoint_entry.argument_count(); 662 } 663 664 // Skip saved double registers. 665 if (safepoint_entry.has_doubles()) { 666 // Number of doubles not known at snapshot time. 667 DCHECK(!isolate()->serializer_enabled()); 668 parameters_base += 669 RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT) 670 ->num_allocatable_double_registers() * 671 kDoubleSize / kPointerSize; 672 } 673 674 // Visit the registers that contain pointers if any. 675 if (safepoint_entry.HasRegisters()) { 676 for (int i = kNumSafepointRegisters - 1; i >=0; i--) { 677 if (safepoint_entry.HasRegisterAt(i)) { 678 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i); 679 v->VisitPointer(parameters_base + reg_stack_index); 680 } 681 } 682 // Skip the words containing the register values. 683 parameters_base += kNumSafepointRegisters; 684 } 685 686 // We're done dealing with the register bits. 687 uint8_t* safepoint_bits = safepoint_entry.bits(); 688 safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2; 689 690 // Visit the rest of the parameters. 691 v->VisitPointers(parameters_base, parameters_limit); 692 693 // Visit pointer spill slots and locals. 694 for (unsigned index = 0; index < stack_slots; index++) { 695 int byte_index = index >> kBitsPerByteLog2; 696 int bit_index = index & (kBitsPerByte - 1); 697 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { 698 v->VisitPointer(parameters_limit + index); 699 } 700 } 701 702 // Visit the return address in the callee and incoming arguments. 703 IteratePc(v, pc_address(), constant_pool_address(), code); 704 705 // Visit the context in stub frame and JavaScript frame. 706 // Visit the function in JavaScript frame. 707 Object** fixed_base = &Memory::Object_at( 708 fp() + StandardFrameConstants::kMarkerOffset); 709 Object** fixed_limit = &Memory::Object_at(fp()); 710 v->VisitPointers(fixed_base, fixed_limit); 711 } 712 713 714 void StubFrame::Iterate(ObjectVisitor* v) const { 715 IterateCompiledFrame(v); 716 } 717 718 719 Code* StubFrame::unchecked_code() const { 720 return static_cast<Code*>(isolate()->FindCodeObject(pc())); 721 } 722 723 724 Address StubFrame::GetCallerStackPointer() const { 725 return fp() + ExitFrameConstants::kCallerSPDisplacement; 726 } 727 728 729 int StubFrame::GetNumberOfIncomingArguments() const { 730 return 0; 731 } 732 733 734 void OptimizedFrame::Iterate(ObjectVisitor* v) const { 735 IterateCompiledFrame(v); 736 } 737 738 739 void JavaScriptFrame::SetParameterValue(int index, Object* value) const { 740 Memory::Object_at(GetParameterSlot(index)) = value; 741 } 742 743 744 bool JavaScriptFrame::IsConstructor() const { 745 Address fp = caller_fp(); 746 if (has_adapted_arguments()) { 747 // Skip the arguments adaptor frame and look at the real caller. 748 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 749 } 750 return IsConstructFrame(fp); 751 } 752 753 754 bool JavaScriptFrame::HasInlinedFrames() const { 755 List<JSFunction*> functions(1); 756 GetFunctions(&functions); 757 return functions.length() > 1; 758 } 759 760 761 int JavaScriptFrame::GetArgumentsLength() const { 762 // If there is an arguments adaptor frame get the arguments length from it. 763 if (has_adapted_arguments()) { 764 STATIC_ASSERT(ArgumentsAdaptorFrameConstants::kLengthOffset == 765 StandardFrameConstants::kExpressionsOffset); 766 return Smi::cast(GetExpression(caller_fp(), 0))->value(); 767 } else { 768 return GetNumberOfIncomingArguments(); 769 } 770 } 771 772 773 Code* JavaScriptFrame::unchecked_code() const { 774 return function()->code(); 775 } 776 777 778 int JavaScriptFrame::GetNumberOfIncomingArguments() const { 779 DCHECK(can_access_heap_objects() && 780 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); 781 782 return function()->shared()->internal_formal_parameter_count(); 783 } 784 785 786 Address JavaScriptFrame::GetCallerStackPointer() const { 787 return fp() + StandardFrameConstants::kCallerSPOffset; 788 } 789 790 791 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { 792 DCHECK(functions->length() == 0); 793 functions->Add(function()); 794 } 795 796 797 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { 798 DCHECK(functions->length() == 0); 799 Code* code_pointer = LookupCode(); 800 int offset = static_cast<int>(pc() - code_pointer->address()); 801 FrameSummary summary(receiver(), 802 function(), 803 code_pointer, 804 offset, 805 IsConstructor()); 806 functions->Add(summary); 807 } 808 809 810 int JavaScriptFrame::LookupExceptionHandlerInTable( 811 int* stack_slots, HandlerTable::CatchPrediction* prediction) { 812 Code* code = LookupCode(); 813 DCHECK(!code->is_optimized_code()); 814 HandlerTable* table = HandlerTable::cast(code->handler_table()); 815 int pc_offset = static_cast<int>(pc() - code->entry()); 816 return table->LookupRange(pc_offset, stack_slots, prediction); 817 } 818 819 820 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code, 821 Address pc, FILE* file, 822 bool print_line_number) { 823 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); 824 function->PrintName(file); 825 int code_offset = static_cast<int>(pc - code->instruction_start()); 826 PrintF(file, "+%d", code_offset); 827 if (print_line_number) { 828 SharedFunctionInfo* shared = function->shared(); 829 int source_pos = code->SourcePosition(pc); 830 Object* maybe_script = shared->script(); 831 if (maybe_script->IsScript()) { 832 Script* script = Script::cast(maybe_script); 833 int line = script->GetLineNumber(source_pos) + 1; 834 Object* script_name_raw = script->name(); 835 if (script_name_raw->IsString()) { 836 String* script_name = String::cast(script->name()); 837 base::SmartArrayPointer<char> c_script_name = 838 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 839 PrintF(file, " at %s:%d", c_script_name.get(), line); 840 } else { 841 PrintF(file, " at <unknown>:%d", line); 842 } 843 } else { 844 PrintF(file, " at <unknown>:<unknown>"); 845 } 846 } 847 } 848 849 850 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args, 851 bool print_line_number) { 852 // constructor calls 853 DisallowHeapAllocation no_allocation; 854 JavaScriptFrameIterator it(isolate); 855 while (!it.done()) { 856 if (it.frame()->is_java_script()) { 857 JavaScriptFrame* frame = it.frame(); 858 if (frame->IsConstructor()) PrintF(file, "new "); 859 PrintFunctionAndOffset(frame->function(), frame->unchecked_code(), 860 frame->pc(), file, print_line_number); 861 if (print_args) { 862 // function arguments 863 // (we are intentionally only printing the actually 864 // supplied parameters, not all parameters required) 865 PrintF(file, "(this="); 866 frame->receiver()->ShortPrint(file); 867 const int length = frame->ComputeParametersCount(); 868 for (int i = 0; i < length; i++) { 869 PrintF(file, ", "); 870 frame->GetParameter(i)->ShortPrint(file); 871 } 872 PrintF(file, ")"); 873 } 874 break; 875 } 876 it.Advance(); 877 } 878 } 879 880 881 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const { 882 int operands_count = store->length(); 883 DCHECK_LE(operands_count, ComputeOperandsCount()); 884 for (int i = 0; i < operands_count; i++) { 885 store->set(i, GetOperand(i)); 886 } 887 } 888 889 890 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { 891 int operands_count = store->length(); 892 DCHECK_LE(operands_count, ComputeOperandsCount()); 893 for (int i = 0; i < operands_count; i++) { 894 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); 895 Memory::Object_at(GetOperandSlot(i)) = store->get(i); 896 } 897 } 898 899 900 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code, 901 int offset, bool is_constructor) 902 : receiver_(receiver, function->GetIsolate()), 903 function_(function), 904 code_(code), 905 offset_(offset), 906 is_constructor_(is_constructor) {} 907 908 909 void FrameSummary::Print() { 910 PrintF("receiver: "); 911 receiver_->ShortPrint(); 912 PrintF("\nfunction: "); 913 function_->shared()->DebugName()->ShortPrint(); 914 PrintF("\ncode: "); 915 code_->ShortPrint(); 916 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 917 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 918 PrintF("\npc: %d\n", offset_); 919 } 920 921 922 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { 923 DCHECK(frames->length() == 0); 924 DCHECK(is_optimized()); 925 926 // Delegate to JS frame in absence of turbofan deoptimization. 927 // TODO(turbofan): Revisit once we support deoptimization across the board. 928 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && 929 !FLAG_turbo_asm_deoptimization) { 930 return JavaScriptFrame::Summarize(frames); 931 } 932 933 DisallowHeapAllocation no_gc; 934 int deopt_index = Safepoint::kNoDeoptimizationIndex; 935 DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index); 936 FixedArray* const literal_array = data->LiteralArray(); 937 938 TranslationIterator it(data->TranslationByteArray(), 939 data->TranslationIndex(deopt_index)->value()); 940 Translation::Opcode frame_opcode = 941 static_cast<Translation::Opcode>(it.Next()); 942 DCHECK_EQ(Translation::BEGIN, frame_opcode); 943 it.Next(); // Drop frame count. 944 int jsframe_count = it.Next(); 945 946 // We create the summary in reverse order because the frames 947 // in the deoptimization translation are ordered bottom-to-top. 948 bool is_constructor = IsConstructor(); 949 while (jsframe_count != 0) { 950 frame_opcode = static_cast<Translation::Opcode>(it.Next()); 951 if (frame_opcode == Translation::JS_FRAME || 952 frame_opcode == Translation::INTERPRETED_FRAME) { 953 jsframe_count--; 954 BailoutId const ast_id = BailoutId(it.Next()); 955 SharedFunctionInfo* const shared_info = 956 SharedFunctionInfo::cast(literal_array->get(it.Next())); 957 it.Next(); // Skip height. 958 959 // The translation commands are ordered and the function is always 960 // at the first position, and the receiver is next. 961 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 962 963 // Get the correct function in the optimized frame. 964 JSFunction* function; 965 if (opcode == Translation::LITERAL) { 966 function = JSFunction::cast(literal_array->get(it.Next())); 967 } else if (opcode == Translation::STACK_SLOT) { 968 function = JSFunction::cast(StackSlotAt(it.Next())); 969 } else { 970 CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode); 971 function = this->function(); 972 } 973 DCHECK_EQ(shared_info, function->shared()); 974 975 // If we are at a call, the receiver is always in a stack slot. 976 // Otherwise we are not guaranteed to get the receiver value. 977 opcode = static_cast<Translation::Opcode>(it.Next()); 978 979 // Get the correct receiver in the optimized frame. 980 Object* receiver; 981 if (opcode == Translation::LITERAL) { 982 receiver = literal_array->get(it.Next()); 983 } else if (opcode == Translation::STACK_SLOT) { 984 receiver = StackSlotAt(it.Next()); 985 } else if (opcode == Translation::JS_FRAME_FUNCTION) { 986 receiver = this->function(); 987 } else { 988 // The receiver is not in a stack slot nor in a literal. We give up. 989 it.Skip(Translation::NumberOfOperandsFor(opcode)); 990 // TODO(3029): Materializing a captured object (or duplicated 991 // object) is hard, we return undefined for now. This breaks the 992 // produced stack trace, as constructor frames aren't marked as 993 // such anymore. 994 receiver = isolate()->heap()->undefined_value(); 995 } 996 997 Code* const code = shared_info->code(); 998 999 unsigned pc_offset; 1000 if (frame_opcode == Translation::JS_FRAME) { 1001 DeoptimizationOutputData* const output_data = 1002 DeoptimizationOutputData::cast(code->deoptimization_data()); 1003 unsigned const entry = 1004 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); 1005 pc_offset = 1006 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; 1007 DCHECK_NE(0U, pc_offset); 1008 } else { 1009 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize 1010 // based on the BytecodeArray and bytecode offset. 1011 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); 1012 pc_offset = 0; 1013 } 1014 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); 1015 frames->Add(summary); 1016 is_constructor = false; 1017 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { 1018 // The next encountered JS_FRAME will be marked as a constructor call. 1019 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); 1020 DCHECK(!is_constructor); 1021 is_constructor = true; 1022 } else { 1023 // Skip over operands to advance to the next opcode. 1024 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); 1025 } 1026 } 1027 DCHECK(!is_constructor); 1028 } 1029 1030 1031 int OptimizedFrame::LookupExceptionHandlerInTable( 1032 int* stack_slots, HandlerTable::CatchPrediction* prediction) { 1033 Code* code = LookupCode(); 1034 DCHECK(code->is_optimized_code()); 1035 HandlerTable* table = HandlerTable::cast(code->handler_table()); 1036 int pc_offset = static_cast<int>(pc() - code->entry()); 1037 *stack_slots = code->stack_slots(); 1038 return table->LookupReturn(pc_offset, prediction); 1039 } 1040 1041 1042 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( 1043 int* deopt_index) const { 1044 DCHECK(is_optimized()); 1045 1046 JSFunction* opt_function = function(); 1047 Code* code = opt_function->code(); 1048 1049 // The code object may have been replaced by lazy deoptimization. Fall 1050 // back to a slow search in this case to find the original optimized 1051 // code object. 1052 if (!code->contains(pc())) { 1053 code = isolate()->inner_pointer_to_code_cache()-> 1054 GcSafeFindCodeForInnerPointer(pc()); 1055 } 1056 DCHECK(code != NULL); 1057 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 1058 1059 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); 1060 *deopt_index = safepoint_entry.deoptimization_index(); 1061 DCHECK(*deopt_index != Safepoint::kNoDeoptimizationIndex); 1062 1063 return DeoptimizationInputData::cast(code->deoptimization_data()); 1064 } 1065 1066 1067 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const { 1068 DCHECK(functions->length() == 0); 1069 DCHECK(is_optimized()); 1070 1071 // Delegate to JS frame in absence of turbofan deoptimization. 1072 // TODO(turbofan): Revisit once we support deoptimization across the board. 1073 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && 1074 !FLAG_turbo_asm_deoptimization) { 1075 return JavaScriptFrame::GetFunctions(functions); 1076 } 1077 1078 DisallowHeapAllocation no_gc; 1079 int deopt_index = Safepoint::kNoDeoptimizationIndex; 1080 DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index); 1081 FixedArray* const literal_array = data->LiteralArray(); 1082 1083 TranslationIterator it(data->TranslationByteArray(), 1084 data->TranslationIndex(deopt_index)->value()); 1085 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 1086 DCHECK_EQ(Translation::BEGIN, opcode); 1087 it.Next(); // Skip frame count. 1088 int jsframe_count = it.Next(); 1089 1090 // We insert the frames in reverse order because the frames 1091 // in the deoptimization translation are ordered bottom-to-top. 1092 while (jsframe_count != 0) { 1093 opcode = static_cast<Translation::Opcode>(it.Next()); 1094 // Skip over operands to advance to the next opcode. 1095 it.Skip(Translation::NumberOfOperandsFor(opcode)); 1096 if (opcode == Translation::JS_FRAME || 1097 opcode == Translation::INTERPRETED_FRAME) { 1098 jsframe_count--; 1099 1100 // The translation commands are ordered and the function is always at the 1101 // first position. 1102 opcode = static_cast<Translation::Opcode>(it.Next()); 1103 1104 // Get the correct function in the optimized frame. 1105 Object* function; 1106 if (opcode == Translation::LITERAL) { 1107 function = literal_array->get(it.Next()); 1108 } else if (opcode == Translation::STACK_SLOT) { 1109 function = StackSlotAt(it.Next()); 1110 } else { 1111 CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode); 1112 function = this->function(); 1113 } 1114 functions->Add(JSFunction::cast(function)); 1115 } 1116 } 1117 } 1118 1119 1120 int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) { 1121 return StandardFrameConstants::kCallerSPOffset - 1122 ((slot_index + 1) * kPointerSize); 1123 } 1124 1125 1126 Object* OptimizedFrame::StackSlotAt(int index) const { 1127 return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index)); 1128 } 1129 1130 1131 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { 1132 return Smi::cast(GetExpression(0))->value(); 1133 } 1134 1135 1136 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { 1137 return fp() + StandardFrameConstants::kCallerSPOffset; 1138 } 1139 1140 1141 Address InternalFrame::GetCallerStackPointer() const { 1142 // Internal frames have no arguments. The stack pointer of the 1143 // caller is at a fixed offset from the frame pointer. 1144 return fp() + StandardFrameConstants::kCallerSPOffset; 1145 } 1146 1147 1148 Code* ArgumentsAdaptorFrame::unchecked_code() const { 1149 return isolate()->builtins()->builtin( 1150 Builtins::kArgumentsAdaptorTrampoline); 1151 } 1152 1153 1154 Code* InternalFrame::unchecked_code() const { 1155 const int offset = InternalFrameConstants::kCodeOffset; 1156 Object* code = Memory::Object_at(fp() + offset); 1157 DCHECK(code != NULL); 1158 return reinterpret_cast<Code*>(code); 1159 } 1160 1161 1162 void StackFrame::PrintIndex(StringStream* accumulator, 1163 PrintMode mode, 1164 int index) { 1165 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); 1166 } 1167 1168 1169 namespace { 1170 1171 1172 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared, 1173 Code* code) { 1174 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1175 std::ostringstream os; 1176 os << "--------- s o u r c e c o d e ---------\n" 1177 << SourceCodeOf(shared, FLAG_max_stack_trace_source_length) 1178 << "\n-----------------------------------------\n"; 1179 accumulator->Add(os.str().c_str()); 1180 } 1181 } 1182 1183 1184 } // namespace 1185 1186 1187 void JavaScriptFrame::Print(StringStream* accumulator, 1188 PrintMode mode, 1189 int index) const { 1190 DisallowHeapAllocation no_gc; 1191 Object* receiver = this->receiver(); 1192 JSFunction* function = this->function(); 1193 1194 accumulator->PrintSecurityTokenIfChanged(function); 1195 PrintIndex(accumulator, mode, index); 1196 Code* code = NULL; 1197 if (IsConstructor()) accumulator->Add("new "); 1198 accumulator->PrintFunction(function, receiver, &code); 1199 1200 // Get scope information for nicer output, if possible. If code is NULL, or 1201 // doesn't contain scope info, scope_info will return 0 for the number of 1202 // parameters, stack local variables, context local variables, stack slots, 1203 // or context slots. 1204 SharedFunctionInfo* shared = function->shared(); 1205 ScopeInfo* scope_info = shared->scope_info(); 1206 Object* script_obj = shared->script(); 1207 if (script_obj->IsScript()) { 1208 Script* script = Script::cast(script_obj); 1209 accumulator->Add(" ["); 1210 accumulator->PrintName(script->name()); 1211 1212 Address pc = this->pc(); 1213 if (code != NULL && code->kind() == Code::FUNCTION && 1214 pc >= code->instruction_start() && pc < code->instruction_end()) { 1215 int source_pos = code->SourcePosition(pc); 1216 int line = script->GetLineNumber(source_pos) + 1; 1217 accumulator->Add(":%d", line); 1218 } else { 1219 int function_start_pos = shared->start_position(); 1220 int line = script->GetLineNumber(function_start_pos) + 1; 1221 accumulator->Add(":~%d", line); 1222 } 1223 1224 accumulator->Add("] [pc=%p] ", pc); 1225 } 1226 1227 accumulator->Add("(this=%o", receiver); 1228 1229 // Print the parameters. 1230 int parameters_count = ComputeParametersCount(); 1231 for (int i = 0; i < parameters_count; i++) { 1232 accumulator->Add(","); 1233 // If we have a name for the parameter we print it. Nameless 1234 // parameters are either because we have more actual parameters 1235 // than formal parameters or because we have no scope information. 1236 if (i < scope_info->ParameterCount()) { 1237 accumulator->PrintName(scope_info->ParameterName(i)); 1238 accumulator->Add("="); 1239 } 1240 accumulator->Add("%o", GetParameter(i)); 1241 } 1242 1243 accumulator->Add(")"); 1244 if (mode == OVERVIEW) { 1245 accumulator->Add("\n"); 1246 return; 1247 } 1248 if (is_optimized()) { 1249 accumulator->Add(" {\n// optimized frame\n"); 1250 PrintFunctionSource(accumulator, shared, code); 1251 accumulator->Add("}\n"); 1252 return; 1253 } 1254 accumulator->Add(" {\n"); 1255 1256 // Compute the number of locals and expression stack elements. 1257 int stack_locals_count = scope_info->StackLocalCount(); 1258 int heap_locals_count = scope_info->ContextLocalCount(); 1259 int expressions_count = ComputeExpressionsCount(); 1260 1261 // Print stack-allocated local variables. 1262 if (stack_locals_count > 0) { 1263 accumulator->Add(" // stack-allocated locals\n"); 1264 } 1265 for (int i = 0; i < stack_locals_count; i++) { 1266 accumulator->Add(" var "); 1267 accumulator->PrintName(scope_info->StackLocalName(i)); 1268 accumulator->Add(" = "); 1269 if (i < expressions_count) { 1270 accumulator->Add("%o", GetExpression(i)); 1271 } else { 1272 accumulator->Add("// no expression found - inconsistent frame?"); 1273 } 1274 accumulator->Add("\n"); 1275 } 1276 1277 // Try to get hold of the context of this frame. 1278 Context* context = NULL; 1279 if (this->context() != NULL && this->context()->IsContext()) { 1280 context = Context::cast(this->context()); 1281 } 1282 while (context->IsWithContext()) { 1283 context = context->previous(); 1284 DCHECK(context != NULL); 1285 } 1286 1287 // Print heap-allocated local variables. 1288 if (heap_locals_count > 0) { 1289 accumulator->Add(" // heap-allocated locals\n"); 1290 } 1291 for (int i = 0; i < heap_locals_count; i++) { 1292 accumulator->Add(" var "); 1293 accumulator->PrintName(scope_info->ContextLocalName(i)); 1294 accumulator->Add(" = "); 1295 if (context != NULL) { 1296 int index = Context::MIN_CONTEXT_SLOTS + i; 1297 if (index < context->length()) { 1298 accumulator->Add("%o", context->get(index)); 1299 } else { 1300 accumulator->Add( 1301 "// warning: missing context slot - inconsistent frame?"); 1302 } 1303 } else { 1304 accumulator->Add("// warning: no context found - inconsistent frame?"); 1305 } 1306 accumulator->Add("\n"); 1307 } 1308 1309 // Print the expression stack. 1310 int expressions_start = stack_locals_count; 1311 if (expressions_start < expressions_count) { 1312 accumulator->Add(" // expression stack (top to bottom)\n"); 1313 } 1314 for (int i = expressions_count - 1; i >= expressions_start; i--) { 1315 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); 1316 } 1317 1318 PrintFunctionSource(accumulator, shared, code); 1319 1320 accumulator->Add("}\n\n"); 1321 } 1322 1323 1324 void ArgumentsAdaptorFrame::Print(StringStream* accumulator, 1325 PrintMode mode, 1326 int index) const { 1327 int actual = ComputeParametersCount(); 1328 int expected = -1; 1329 JSFunction* function = this->function(); 1330 expected = function->shared()->internal_formal_parameter_count(); 1331 1332 PrintIndex(accumulator, mode, index); 1333 accumulator->Add("arguments adaptor frame: %d->%d", actual, expected); 1334 if (mode == OVERVIEW) { 1335 accumulator->Add("\n"); 1336 return; 1337 } 1338 accumulator->Add(" {\n"); 1339 1340 // Print actual arguments. 1341 if (actual > 0) accumulator->Add(" // actual arguments\n"); 1342 for (int i = 0; i < actual; i++) { 1343 accumulator->Add(" [%02d] : %o", i, GetParameter(i)); 1344 if (expected != -1 && i >= expected) { 1345 accumulator->Add(" // not passed to callee"); 1346 } 1347 accumulator->Add("\n"); 1348 } 1349 1350 accumulator->Add("}\n\n"); 1351 } 1352 1353 1354 void EntryFrame::Iterate(ObjectVisitor* v) const { 1355 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1356 } 1357 1358 1359 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { 1360 const int offset = StandardFrameConstants::kLastObjectOffset; 1361 Object** base = &Memory::Object_at(sp()); 1362 Object** limit = &Memory::Object_at(fp() + offset) + 1; 1363 v->VisitPointers(base, limit); 1364 } 1365 1366 1367 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { 1368 IterateExpressions(v); 1369 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1370 } 1371 1372 1373 void InternalFrame::Iterate(ObjectVisitor* v) const { 1374 // Internal frames only have object pointers on the expression stack 1375 // as they never have any arguments. 1376 IterateExpressions(v); 1377 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1378 } 1379 1380 1381 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { 1382 Object** base = &Memory::Object_at(sp()); 1383 Object** limit = &Memory::Object_at(fp() + 1384 kFirstRegisterParameterFrameOffset); 1385 v->VisitPointers(base, limit); 1386 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); 1387 const int offset = StandardFrameConstants::kLastObjectOffset; 1388 limit = &Memory::Object_at(fp() + offset) + 1; 1389 v->VisitPointers(base, limit); 1390 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1391 } 1392 1393 1394 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { 1395 return fp() + StandardFrameConstants::kCallerSPOffset; 1396 } 1397 1398 1399 Code* StubFailureTrampolineFrame::unchecked_code() const { 1400 Code* trampoline; 1401 StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE). 1402 FindCodeInCache(&trampoline); 1403 if (trampoline->contains(pc())) { 1404 return trampoline; 1405 } 1406 1407 StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE). 1408 FindCodeInCache(&trampoline); 1409 if (trampoline->contains(pc())) { 1410 return trampoline; 1411 } 1412 1413 UNREACHABLE(); 1414 return NULL; 1415 } 1416 1417 1418 // ------------------------------------------------------------------------- 1419 1420 1421 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { 1422 DCHECK(n >= 0); 1423 for (int i = 0; i <= n; i++) { 1424 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); 1425 if (i == n) return JavaScriptFrame::cast(iterator_.frame()); 1426 iterator_.Advance(); 1427 } 1428 UNREACHABLE(); 1429 return NULL; 1430 } 1431 1432 1433 // ------------------------------------------------------------------------- 1434 1435 1436 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) { 1437 MapWord map_word = object->map_word(); 1438 return map_word.IsForwardingAddress() ? 1439 map_word.ToForwardingAddress()->map() : map_word.ToMap(); 1440 } 1441 1442 1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) { 1444 return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object)); 1445 } 1446 1447 1448 #ifdef DEBUG 1449 static bool GcSafeCodeContains(HeapObject* code, Address addr) { 1450 Map* map = GcSafeMapOfCodeSpaceObject(code); 1451 DCHECK(map == code->GetHeap()->code_map()); 1452 Address start = code->address(); 1453 Address end = code->address() + code->SizeFromMap(map); 1454 return start <= addr && addr < end; 1455 } 1456 #endif 1457 1458 1459 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object, 1460 Address inner_pointer) { 1461 Code* code = reinterpret_cast<Code*>(object); 1462 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer)); 1463 return code; 1464 } 1465 1466 1467 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( 1468 Address inner_pointer) { 1469 Heap* heap = isolate_->heap(); 1470 if (!heap->code_space()->Contains(inner_pointer) && 1471 !heap->lo_space()->Contains(inner_pointer)) { 1472 return nullptr; 1473 } 1474 1475 // Check if the inner pointer points into a large object chunk. 1476 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); 1477 if (large_page != NULL) { 1478 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); 1479 } 1480 1481 // Iterate through the page until we reach the end or find an object starting 1482 // after the inner pointer. 1483 Page* page = Page::FromAddress(inner_pointer); 1484 1485 DCHECK_EQ(page->owner(), heap->code_space()); 1486 heap->mark_compact_collector()->SweepOrWaitUntilSweepingCompleted(page); 1487 1488 Address addr = page->skip_list()->StartFor(inner_pointer); 1489 1490 Address top = heap->code_space()->top(); 1491 Address limit = heap->code_space()->limit(); 1492 1493 while (true) { 1494 if (addr == top && addr != limit) { 1495 addr = limit; 1496 continue; 1497 } 1498 1499 HeapObject* obj = HeapObject::FromAddress(addr); 1500 int obj_size = GcSafeSizeOfCodeSpaceObject(obj); 1501 Address next_addr = addr + obj_size; 1502 if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer); 1503 addr = next_addr; 1504 } 1505 } 1506 1507 1508 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* 1509 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) { 1510 isolate_->counters()->pc_to_code()->Increment(); 1511 DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize)); 1512 uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer), 1513 v8::internal::kZeroHashSeed); 1514 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1); 1515 InnerPointerToCodeCacheEntry* entry = cache(index); 1516 if (entry->inner_pointer == inner_pointer) { 1517 isolate_->counters()->pc_to_code_cached()->Increment(); 1518 DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer)); 1519 } else { 1520 // Because this code may be interrupted by a profiling signal that 1521 // also queries the cache, we cannot update inner_pointer before the code 1522 // has been set. Otherwise, we risk trying to use a cache entry before 1523 // the code has been computed. 1524 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); 1525 entry->safepoint_entry.Reset(); 1526 entry->inner_pointer = inner_pointer; 1527 } 1528 return entry; 1529 } 1530 1531 1532 // ------------------------------------------------------------------------- 1533 1534 1535 int NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); } 1536 1537 1538 struct JSCallerSavedCodeData { 1539 int reg_code[kNumJSCallerSaved]; 1540 }; 1541 1542 JSCallerSavedCodeData caller_saved_code_data; 1543 1544 void SetUpJSCallerSavedCodeData() { 1545 int i = 0; 1546 for (int r = 0; r < kNumRegs; r++) 1547 if ((kJSCallerSaved & (1 << r)) != 0) 1548 caller_saved_code_data.reg_code[i++] = r; 1549 1550 DCHECK(i == kNumJSCallerSaved); 1551 } 1552 1553 1554 int JSCallerSavedCode(int n) { 1555 DCHECK(0 <= n && n < kNumJSCallerSaved); 1556 return caller_saved_code_data.reg_code[n]; 1557 } 1558 1559 1560 #define DEFINE_WRAPPER(type, field) \ 1561 class field##_Wrapper : public ZoneObject { \ 1562 public: /* NOLINT */ \ 1563 field##_Wrapper(const field& original) : frame_(original) { \ 1564 } \ 1565 field frame_; \ 1566 }; 1567 STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER) 1568 #undef DEFINE_WRAPPER 1569 1570 static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) { 1571 #define FRAME_TYPE_CASE(type, field) \ 1572 case StackFrame::type: { \ 1573 field##_Wrapper* wrapper = \ 1574 new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \ 1575 return &wrapper->frame_; \ 1576 } 1577 1578 switch (frame->type()) { 1579 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 1580 default: UNREACHABLE(); 1581 } 1582 #undef FRAME_TYPE_CASE 1583 return NULL; 1584 } 1585 1586 1587 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) { 1588 ZoneList<StackFrame*> list(10, zone); 1589 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1590 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1591 list.Add(frame, zone); 1592 } 1593 return list.ToVector(); 1594 } 1595 1596 1597 } // namespace internal 1598 } // namespace v8 1599