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