1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "v8.h" 29 30 #include "ast.h" 31 #include "deoptimizer.h" 32 #include "frames-inl.h" 33 #include "full-codegen.h" 34 #include "mark-compact.h" 35 #include "safepoint-table.h" 36 #include "scopeinfo.h" 37 #include "string-stream.h" 38 39 namespace v8 { 40 namespace internal { 41 42 // Iterator that supports traversing the stack handlers of a 43 // particular frame. Needs to know the top of the handler chain. 44 class StackHandlerIterator BASE_EMBEDDED { 45 public: 46 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) 47 : limit_(frame->fp()), handler_(handler) { 48 // Make sure the handler has already been unwound to this frame. 49 ASSERT(frame->sp() <= handler->address()); 50 } 51 52 StackHandler* handler() const { return handler_; } 53 54 bool done() { 55 return handler_ == NULL || handler_->address() > limit_; 56 } 57 void Advance() { 58 ASSERT(!done()); 59 handler_ = handler_->next(); 60 } 61 62 private: 63 const Address limit_; 64 StackHandler* handler_; 65 }; 66 67 68 // ------------------------------------------------------------------------- 69 70 71 #define INITIALIZE_SINGLETON(type, field) field##_(this), 72 StackFrameIterator::StackFrameIterator() 73 : isolate_(Isolate::Current()), 74 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 75 frame_(NULL), handler_(NULL), 76 thread_(isolate_->thread_local_top()), 77 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 78 Reset(); 79 } 80 StackFrameIterator::StackFrameIterator(Isolate* isolate) 81 : isolate_(isolate), 82 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 83 frame_(NULL), handler_(NULL), 84 thread_(isolate_->thread_local_top()), 85 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 86 Reset(); 87 } 88 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) 89 : isolate_(isolate), 90 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 91 frame_(NULL), handler_(NULL), thread_(t), 92 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 93 Reset(); 94 } 95 StackFrameIterator::StackFrameIterator(Isolate* isolate, 96 bool use_top, Address fp, Address sp) 97 : isolate_(isolate), 98 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 99 frame_(NULL), handler_(NULL), 100 thread_(use_top ? isolate_->thread_local_top() : NULL), 101 fp_(use_top ? NULL : fp), sp_(sp), 102 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : 103 &StackFrameIterator::AdvanceWithoutHandler) { 104 if (use_top || fp != NULL) { 105 Reset(); 106 } 107 } 108 109 #undef INITIALIZE_SINGLETON 110 111 112 void StackFrameIterator::AdvanceWithHandler() { 113 ASSERT(!done()); 114 // Compute the state of the calling frame before restoring 115 // callee-saved registers and unwinding handlers. This allows the 116 // frame code that computes the caller state to access the top 117 // handler and the value of any callee-saved register if needed. 118 StackFrame::State state; 119 StackFrame::Type type = frame_->GetCallerState(&state); 120 121 // Unwind handlers corresponding to the current frame. 122 StackHandlerIterator it(frame_, handler_); 123 while (!it.done()) it.Advance(); 124 handler_ = it.handler(); 125 126 // Advance to the calling frame. 127 frame_ = SingletonFor(type, &state); 128 129 // When we're done iterating over the stack frames, the handler 130 // chain must have been completely unwound. 131 ASSERT(!done() || handler_ == NULL); 132 } 133 134 135 void StackFrameIterator::AdvanceWithoutHandler() { 136 // A simpler version of Advance which doesn't care about handler. 137 ASSERT(!done()); 138 StackFrame::State state; 139 StackFrame::Type type = frame_->GetCallerState(&state); 140 frame_ = SingletonFor(type, &state); 141 } 142 143 144 void StackFrameIterator::Reset() { 145 StackFrame::State state; 146 StackFrame::Type type; 147 if (thread_ != NULL) { 148 type = ExitFrame::GetStateForFramePointer( 149 Isolate::c_entry_fp(thread_), &state); 150 handler_ = StackHandler::FromAddress( 151 Isolate::handler(thread_)); 152 } else { 153 ASSERT(fp_ != NULL); 154 state.fp = fp_; 155 state.sp = sp_; 156 state.pc_address = 157 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); 158 type = StackFrame::ComputeType(isolate(), &state); 159 } 160 if (SingletonFor(type) == NULL) return; 161 frame_ = SingletonFor(type, &state); 162 } 163 164 165 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, 166 StackFrame::State* state) { 167 if (type == StackFrame::NONE) return NULL; 168 StackFrame* result = SingletonFor(type); 169 ASSERT(result != NULL); 170 result->state_ = *state; 171 return result; 172 } 173 174 175 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) { 176 #define FRAME_TYPE_CASE(type, field) \ 177 case StackFrame::type: result = &field##_; break; 178 179 StackFrame* result = NULL; 180 switch (type) { 181 case StackFrame::NONE: return NULL; 182 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 183 default: break; 184 } 185 return result; 186 187 #undef FRAME_TYPE_CASE 188 } 189 190 191 // ------------------------------------------------------------------------- 192 193 194 StackTraceFrameIterator::StackTraceFrameIterator() { 195 if (!done() && !IsValidFrame()) Advance(); 196 } 197 198 199 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 200 : JavaScriptFrameIterator(isolate) { 201 if (!done() && !IsValidFrame()) Advance(); 202 } 203 204 205 void StackTraceFrameIterator::Advance() { 206 while (true) { 207 JavaScriptFrameIterator::Advance(); 208 if (done()) return; 209 if (IsValidFrame()) return; 210 } 211 } 212 213 bool StackTraceFrameIterator::IsValidFrame() { 214 if (!frame()->function()->IsJSFunction()) return false; 215 Object* script = JSFunction::cast(frame()->function())->shared()->script(); 216 // Don't show functions from native scripts to user. 217 return (script->IsScript() && 218 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); 219 } 220 221 222 // ------------------------------------------------------------------------- 223 224 225 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { 226 if (!validator_.IsValid(fp)) return false; 227 Address sp = ExitFrame::ComputeStackPointer(fp); 228 if (!validator_.IsValid(sp)) return false; 229 StackFrame::State state; 230 ExitFrame::FillState(fp, sp, &state); 231 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { 232 return false; 233 } 234 return *state.pc_address != NULL; 235 } 236 237 238 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer( 239 Isolate* isolate) 240 : isolate_(isolate) { 241 isolate_->set_safe_stack_iterator_counter( 242 isolate_->safe_stack_iterator_counter() + 1); 243 } 244 245 246 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() { 247 isolate_->set_safe_stack_iterator_counter( 248 isolate_->safe_stack_iterator_counter() - 1); 249 } 250 251 252 SafeStackFrameIterator::SafeStackFrameIterator( 253 Isolate* isolate, 254 Address fp, Address sp, Address low_bound, Address high_bound) : 255 maintainer_(isolate), 256 stack_validator_(low_bound, high_bound), 257 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), 258 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), 259 is_working_iterator_(is_valid_top_ || is_valid_fp_), 260 iteration_done_(!is_working_iterator_), 261 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { 262 } 263 264 bool SafeStackFrameIterator::is_active(Isolate* isolate) { 265 return isolate->safe_stack_iterator_counter() > 0; 266 } 267 268 269 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, 270 Address low_bound, Address high_bound) { 271 ThreadLocalTop* top = isolate->thread_local_top(); 272 Address fp = Isolate::c_entry_fp(top); 273 ExitFrameValidator validator(low_bound, high_bound); 274 if (!validator.IsValidFP(fp)) return false; 275 return Isolate::handler(top) != NULL; 276 } 277 278 279 void SafeStackFrameIterator::Advance() { 280 ASSERT(is_working_iterator_); 281 ASSERT(!done()); 282 StackFrame* last_frame = iterator_.frame(); 283 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 284 // Before advancing to the next stack frame, perform pointer validity tests 285 iteration_done_ = !IsValidFrame(last_frame) || 286 !CanIterateHandles(last_frame, iterator_.handler()) || 287 !IsValidCaller(last_frame); 288 if (iteration_done_) return; 289 290 iterator_.Advance(); 291 if (iterator_.done()) return; 292 // Check that we have actually moved to the previous frame in the stack 293 StackFrame* prev_frame = iterator_.frame(); 294 iteration_done_ = prev_frame->sp() < last_sp || prev_frame->fp() < last_fp; 295 } 296 297 298 bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame, 299 StackHandler* handler) { 300 // If StackIterator iterates over StackHandles, verify that 301 // StackHandlerIterator can be instantiated (see StackHandlerIterator 302 // constructor.) 303 return !is_valid_top_ || (frame->sp() <= handler->address()); 304 } 305 306 307 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { 308 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()); 309 } 310 311 312 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { 313 StackFrame::State state; 314 if (frame->is_entry() || frame->is_entry_construct()) { 315 // See EntryFrame::GetCallerState. It computes the caller FP address 316 // and calls ExitFrame::GetStateForFramePointer on it. We need to be 317 // sure that caller FP address is valid. 318 Address caller_fp = Memory::Address_at( 319 frame->fp() + EntryFrameConstants::kCallerFPOffset); 320 ExitFrameValidator validator(stack_validator_); 321 if (!validator.IsValidFP(caller_fp)) return false; 322 } else if (frame->is_arguments_adaptor()) { 323 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that 324 // the number of arguments is stored on stack as Smi. We need to check 325 // that it really an Smi. 326 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> 327 GetExpression(0); 328 if (!number_of_args->IsSmi()) { 329 return false; 330 } 331 } 332 frame->ComputeCallerState(&state); 333 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) && 334 iterator_.SingletonFor(frame->GetCallerState(&state)) != NULL; 335 } 336 337 338 void SafeStackFrameIterator::Reset() { 339 if (is_working_iterator_) { 340 iterator_.Reset(); 341 iteration_done_ = false; 342 } 343 } 344 345 346 // ------------------------------------------------------------------------- 347 348 349 #ifdef ENABLE_LOGGING_AND_PROFILING 350 SafeStackTraceFrameIterator::SafeStackTraceFrameIterator( 351 Isolate* isolate, 352 Address fp, Address sp, Address low_bound, Address high_bound) : 353 SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) { 354 if (!done() && !frame()->is_java_script()) Advance(); 355 } 356 357 358 void SafeStackTraceFrameIterator::Advance() { 359 while (true) { 360 SafeJavaScriptFrameIterator::Advance(); 361 if (done()) return; 362 if (frame()->is_java_script()) return; 363 } 364 } 365 #endif 366 367 368 Code* StackFrame::GetSafepointData(Isolate* isolate, 369 Address pc, 370 SafepointEntry* safepoint_entry, 371 unsigned* stack_slots) { 372 PcToCodeCache::PcToCodeCacheEntry* entry = 373 isolate->pc_to_code_cache()->GetCacheEntry(pc); 374 SafepointEntry cached_safepoint_entry = entry->safepoint_entry; 375 if (!entry->safepoint_entry.is_valid()) { 376 entry->safepoint_entry = entry->code->GetSafepointEntry(pc); 377 ASSERT(entry->safepoint_entry.is_valid()); 378 } else { 379 ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc))); 380 } 381 382 // Fill in the results and return the code. 383 Code* code = entry->code; 384 *safepoint_entry = entry->safepoint_entry; 385 *stack_slots = code->stack_slots(); 386 return code; 387 } 388 389 390 bool StackFrame::HasHandler() const { 391 StackHandlerIterator it(this, top_handler()); 392 return !it.done(); 393 } 394 395 396 void StackFrame::IteratePc(ObjectVisitor* v, 397 Address* pc_address, 398 Code* holder) { 399 Address pc = *pc_address; 400 ASSERT(holder->contains(pc)); 401 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); 402 Object* code = holder; 403 v->VisitPointer(&code); 404 if (code != holder) { 405 holder = reinterpret_cast<Code*>(code); 406 pc = holder->instruction_start() + pc_offset; 407 *pc_address = pc; 408 } 409 } 410 411 412 StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { 413 ASSERT(state->fp != NULL); 414 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 415 return ARGUMENTS_ADAPTOR; 416 } 417 // The marker and function offsets overlap. If the marker isn't a 418 // smi then the frame is a JavaScript frame -- and the marker is 419 // really the function. 420 const int offset = StandardFrameConstants::kMarkerOffset; 421 Object* marker = Memory::Object_at(state->fp + offset); 422 if (!marker->IsSmi()) { 423 // If we're using a "safe" stack iterator, we treat optimized 424 // frames as normal JavaScript frames to avoid having to look 425 // into the heap to determine the state. This is safe as long 426 // as nobody tries to GC... 427 if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT; 428 Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); 429 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); 430 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; 431 } 432 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 433 } 434 435 436 437 StackFrame::Type StackFrame::GetCallerState(State* state) const { 438 ComputeCallerState(state); 439 return ComputeType(isolate(), state); 440 } 441 442 443 Code* EntryFrame::unchecked_code() const { 444 return HEAP->raw_unchecked_js_entry_code(); 445 } 446 447 448 void EntryFrame::ComputeCallerState(State* state) const { 449 GetCallerState(state); 450 } 451 452 453 void EntryFrame::SetCallerFp(Address caller_fp) { 454 const int offset = EntryFrameConstants::kCallerFPOffset; 455 Memory::Address_at(this->fp() + offset) = caller_fp; 456 } 457 458 459 StackFrame::Type EntryFrame::GetCallerState(State* state) const { 460 const int offset = EntryFrameConstants::kCallerFPOffset; 461 Address fp = Memory::Address_at(this->fp() + offset); 462 return ExitFrame::GetStateForFramePointer(fp, state); 463 } 464 465 466 Code* EntryConstructFrame::unchecked_code() const { 467 return HEAP->raw_unchecked_js_construct_entry_code(); 468 } 469 470 471 Object*& ExitFrame::code_slot() const { 472 const int offset = ExitFrameConstants::kCodeOffset; 473 return Memory::Object_at(fp() + offset); 474 } 475 476 477 Code* ExitFrame::unchecked_code() const { 478 return reinterpret_cast<Code*>(code_slot()); 479 } 480 481 482 void ExitFrame::ComputeCallerState(State* state) const { 483 // Setup the caller state. 484 state->sp = caller_sp(); 485 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); 486 state->pc_address 487 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); 488 } 489 490 491 void ExitFrame::SetCallerFp(Address caller_fp) { 492 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; 493 } 494 495 496 void ExitFrame::Iterate(ObjectVisitor* v) const { 497 // The arguments are traversed as part of the expression stack of 498 // the calling frame. 499 IteratePc(v, pc_address(), LookupCode()); 500 v->VisitPointer(&code_slot()); 501 } 502 503 504 Address ExitFrame::GetCallerStackPointer() const { 505 return fp() + ExitFrameConstants::kCallerSPDisplacement; 506 } 507 508 509 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 510 if (fp == 0) return NONE; 511 Address sp = ComputeStackPointer(fp); 512 FillState(fp, sp, state); 513 ASSERT(*state->pc_address != NULL); 514 return EXIT; 515 } 516 517 518 void ExitFrame::FillState(Address fp, Address sp, State* state) { 519 state->sp = sp; 520 state->fp = fp; 521 state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); 522 } 523 524 525 Address StandardFrame::GetExpressionAddress(int n) const { 526 const int offset = StandardFrameConstants::kExpressionsOffset; 527 return fp() + offset - n * kPointerSize; 528 } 529 530 531 int StandardFrame::ComputeExpressionsCount() const { 532 const int offset = 533 StandardFrameConstants::kExpressionsOffset + kPointerSize; 534 Address base = fp() + offset; 535 Address limit = sp(); 536 ASSERT(base >= limit); // stack grows downwards 537 // Include register-allocated locals in number of expressions. 538 return static_cast<int>((base - limit) / kPointerSize); 539 } 540 541 542 void StandardFrame::ComputeCallerState(State* state) const { 543 state->sp = caller_sp(); 544 state->fp = caller_fp(); 545 state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp())); 546 } 547 548 549 void StandardFrame::SetCallerFp(Address caller_fp) { 550 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 551 caller_fp; 552 } 553 554 555 bool StandardFrame::IsExpressionInsideHandler(int n) const { 556 Address address = GetExpressionAddress(n); 557 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 558 if (it.handler()->includes(address)) return true; 559 } 560 return false; 561 } 562 563 564 void OptimizedFrame::Iterate(ObjectVisitor* v) const { 565 #ifdef DEBUG 566 // Make sure that optimized frames do not contain any stack handlers. 567 StackHandlerIterator it(this, top_handler()); 568 ASSERT(it.done()); 569 #endif 570 571 // Make sure that we're not doing "safe" stack frame iteration. We cannot 572 // possibly find pointers in optimized frames in that state. 573 ASSERT(!SafeStackFrameIterator::is_active(isolate())); 574 575 // Compute the safepoint information. 576 unsigned stack_slots = 0; 577 SafepointEntry safepoint_entry; 578 Code* code = StackFrame::GetSafepointData( 579 isolate(), pc(), &safepoint_entry, &stack_slots); 580 unsigned slot_space = stack_slots * kPointerSize; 581 582 // Visit the outgoing parameters. 583 Object** parameters_base = &Memory::Object_at(sp()); 584 Object** parameters_limit = &Memory::Object_at( 585 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); 586 587 // Visit the parameters that may be on top of the saved registers. 588 if (safepoint_entry.argument_count() > 0) { 589 v->VisitPointers(parameters_base, 590 parameters_base + safepoint_entry.argument_count()); 591 parameters_base += safepoint_entry.argument_count(); 592 } 593 594 // Skip saved double registers. 595 if (safepoint_entry.has_doubles()) { 596 parameters_base += DoubleRegister::kNumAllocatableRegisters * 597 kDoubleSize / kPointerSize; 598 } 599 600 // Visit the registers that contain pointers if any. 601 if (safepoint_entry.HasRegisters()) { 602 for (int i = kNumSafepointRegisters - 1; i >=0; i--) { 603 if (safepoint_entry.HasRegisterAt(i)) { 604 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i); 605 v->VisitPointer(parameters_base + reg_stack_index); 606 } 607 } 608 // Skip the words containing the register values. 609 parameters_base += kNumSafepointRegisters; 610 } 611 612 // We're done dealing with the register bits. 613 uint8_t* safepoint_bits = safepoint_entry.bits(); 614 safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2; 615 616 // Visit the rest of the parameters. 617 v->VisitPointers(parameters_base, parameters_limit); 618 619 // Visit pointer spill slots and locals. 620 for (unsigned index = 0; index < stack_slots; index++) { 621 int byte_index = index >> kBitsPerByteLog2; 622 int bit_index = index & (kBitsPerByte - 1); 623 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { 624 v->VisitPointer(parameters_limit + index); 625 } 626 } 627 628 // Visit the context and the function. 629 Object** fixed_base = &Memory::Object_at( 630 fp() + JavaScriptFrameConstants::kFunctionOffset); 631 Object** fixed_limit = &Memory::Object_at(fp()); 632 v->VisitPointers(fixed_base, fixed_limit); 633 634 // Visit the return address in the callee and incoming arguments. 635 IteratePc(v, pc_address(), code); 636 } 637 638 639 bool JavaScriptFrame::IsConstructor() const { 640 Address fp = caller_fp(); 641 if (has_adapted_arguments()) { 642 // Skip the arguments adaptor frame and look at the real caller. 643 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 644 } 645 return IsConstructFrame(fp); 646 } 647 648 649 Code* JavaScriptFrame::unchecked_code() const { 650 JSFunction* function = JSFunction::cast(this->function()); 651 return function->unchecked_code(); 652 } 653 654 655 int JavaScriptFrame::GetNumberOfIncomingArguments() const { 656 ASSERT(!SafeStackFrameIterator::is_active(isolate()) && 657 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); 658 659 JSFunction* function = JSFunction::cast(this->function()); 660 return function->shared()->formal_parameter_count(); 661 } 662 663 664 Address JavaScriptFrame::GetCallerStackPointer() const { 665 return fp() + StandardFrameConstants::kCallerSPOffset; 666 } 667 668 669 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { 670 ASSERT(functions->length() == 0); 671 functions->Add(JSFunction::cast(function())); 672 } 673 674 675 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { 676 ASSERT(functions->length() == 0); 677 Code* code_pointer = LookupCode(); 678 int offset = static_cast<int>(pc() - code_pointer->address()); 679 FrameSummary summary(receiver(), 680 JSFunction::cast(function()), 681 code_pointer, 682 offset, 683 IsConstructor()); 684 functions->Add(summary); 685 } 686 687 688 void FrameSummary::Print() { 689 PrintF("receiver: "); 690 receiver_->ShortPrint(); 691 PrintF("\nfunction: "); 692 function_->shared()->DebugName()->ShortPrint(); 693 PrintF("\ncode: "); 694 code_->ShortPrint(); 695 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 696 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 697 PrintF("\npc: %d\n", offset_); 698 } 699 700 701 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { 702 ASSERT(frames->length() == 0); 703 ASSERT(is_optimized()); 704 705 int deopt_index = Safepoint::kNoDeoptimizationIndex; 706 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 707 708 // BUG(3243555): Since we don't have a lazy-deopt registered at 709 // throw-statements, we can't use the translation at the call-site of 710 // throw. An entry with no deoptimization index indicates a call-site 711 // without a lazy-deopt. As a consequence we are not allowed to inline 712 // functions containing throw. 713 if (deopt_index == Safepoint::kNoDeoptimizationIndex) { 714 JavaScriptFrame::Summarize(frames); 715 return; 716 } 717 718 TranslationIterator it(data->TranslationByteArray(), 719 data->TranslationIndex(deopt_index)->value()); 720 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 721 ASSERT(opcode == Translation::BEGIN); 722 int frame_count = it.Next(); 723 724 // We create the summary in reverse order because the frames 725 // in the deoptimization translation are ordered bottom-to-top. 726 int i = frame_count; 727 while (i > 0) { 728 opcode = static_cast<Translation::Opcode>(it.Next()); 729 if (opcode == Translation::FRAME) { 730 // We don't inline constructor calls, so only the first, outermost 731 // frame can be a constructor frame in case of inlining. 732 bool is_constructor = (i == frame_count) && IsConstructor(); 733 734 i--; 735 int ast_id = it.Next(); 736 int function_id = it.Next(); 737 it.Next(); // Skip height. 738 JSFunction* function = 739 JSFunction::cast(data->LiteralArray()->get(function_id)); 740 741 // The translation commands are ordered and the receiver is always 742 // at the first position. Since we are always at a call when we need 743 // to construct a stack trace, the receiver is always in a stack slot. 744 opcode = static_cast<Translation::Opcode>(it.Next()); 745 ASSERT(opcode == Translation::STACK_SLOT); 746 int input_slot_index = it.Next(); 747 748 // Get the correct receiver in the optimized frame. 749 Object* receiver = NULL; 750 // Positive index means the value is spilled to the locals area. Negative 751 // means it is stored in the incoming parameter area. 752 if (input_slot_index >= 0) { 753 receiver = GetExpression(input_slot_index); 754 } else { 755 // Index -1 overlaps with last parameter, -n with the first parameter, 756 // (-n - 1) with the receiver with n being the number of parameters 757 // of the outermost, optimized frame. 758 int parameter_count = ComputeParametersCount(); 759 int parameter_index = input_slot_index + parameter_count; 760 receiver = (parameter_index == -1) 761 ? this->receiver() 762 : this->GetParameter(parameter_index); 763 } 764 765 Code* code = function->shared()->code(); 766 DeoptimizationOutputData* output_data = 767 DeoptimizationOutputData::cast(code->deoptimization_data()); 768 unsigned entry = Deoptimizer::GetOutputInfo(output_data, 769 ast_id, 770 function->shared()); 771 unsigned pc_offset = 772 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; 773 ASSERT(pc_offset > 0); 774 775 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); 776 frames->Add(summary); 777 } else { 778 // Skip over operands to advance to the next opcode. 779 it.Skip(Translation::NumberOfOperandsFor(opcode)); 780 } 781 } 782 } 783 784 785 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( 786 int* deopt_index) { 787 ASSERT(is_optimized()); 788 789 JSFunction* opt_function = JSFunction::cast(function()); 790 Code* code = opt_function->code(); 791 792 // The code object may have been replaced by lazy deoptimization. Fall 793 // back to a slow search in this case to find the original optimized 794 // code object. 795 if (!code->contains(pc())) { 796 code = isolate()->pc_to_code_cache()->GcSafeFindCodeForPc(pc()); 797 } 798 ASSERT(code != NULL); 799 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 800 801 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); 802 *deopt_index = safepoint_entry.deoptimization_index(); 803 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); 804 805 return DeoptimizationInputData::cast(code->deoptimization_data()); 806 } 807 808 809 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) { 810 ASSERT(functions->length() == 0); 811 ASSERT(is_optimized()); 812 813 int deopt_index = Safepoint::kNoDeoptimizationIndex; 814 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 815 816 TranslationIterator it(data->TranslationByteArray(), 817 data->TranslationIndex(deopt_index)->value()); 818 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 819 ASSERT(opcode == Translation::BEGIN); 820 int frame_count = it.Next(); 821 822 // We insert the frames in reverse order because the frames 823 // in the deoptimization translation are ordered bottom-to-top. 824 while (frame_count > 0) { 825 opcode = static_cast<Translation::Opcode>(it.Next()); 826 if (opcode == Translation::FRAME) { 827 frame_count--; 828 it.Next(); // Skip ast id. 829 int function_id = it.Next(); 830 it.Next(); // Skip height. 831 JSFunction* function = 832 JSFunction::cast(data->LiteralArray()->get(function_id)); 833 functions->Add(function); 834 } else { 835 // Skip over operands to advance to the next opcode. 836 it.Skip(Translation::NumberOfOperandsFor(opcode)); 837 } 838 } 839 } 840 841 842 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { 843 return fp() + StandardFrameConstants::kCallerSPOffset; 844 } 845 846 847 Address InternalFrame::GetCallerStackPointer() const { 848 // Internal frames have no arguments. The stack pointer of the 849 // caller is at a fixed offset from the frame pointer. 850 return fp() + StandardFrameConstants::kCallerSPOffset; 851 } 852 853 854 Code* ArgumentsAdaptorFrame::unchecked_code() const { 855 return isolate()->builtins()->builtin( 856 Builtins::kArgumentsAdaptorTrampoline); 857 } 858 859 860 Code* InternalFrame::unchecked_code() const { 861 const int offset = InternalFrameConstants::kCodeOffset; 862 Object* code = Memory::Object_at(fp() + offset); 863 ASSERT(code != NULL); 864 return reinterpret_cast<Code*>(code); 865 } 866 867 868 void StackFrame::PrintIndex(StringStream* accumulator, 869 PrintMode mode, 870 int index) { 871 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); 872 } 873 874 875 void JavaScriptFrame::Print(StringStream* accumulator, 876 PrintMode mode, 877 int index) const { 878 HandleScope scope; 879 Object* receiver = this->receiver(); 880 Object* function = this->function(); 881 882 accumulator->PrintSecurityTokenIfChanged(function); 883 PrintIndex(accumulator, mode, index); 884 Code* code = NULL; 885 if (IsConstructor()) accumulator->Add("new "); 886 accumulator->PrintFunction(function, receiver, &code); 887 888 Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty()); 889 890 if (function->IsJSFunction()) { 891 Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared()); 892 scope_info = Handle<SerializedScopeInfo>(shared->scope_info()); 893 Object* script_obj = shared->script(); 894 if (script_obj->IsScript()) { 895 Handle<Script> script(Script::cast(script_obj)); 896 accumulator->Add(" ["); 897 accumulator->PrintName(script->name()); 898 899 Address pc = this->pc(); 900 if (code != NULL && code->kind() == Code::FUNCTION && 901 pc >= code->instruction_start() && pc < code->instruction_end()) { 902 int source_pos = code->SourcePosition(pc); 903 int line = GetScriptLineNumberSafe(script, source_pos) + 1; 904 accumulator->Add(":%d", line); 905 } else { 906 int function_start_pos = shared->start_position(); 907 int line = GetScriptLineNumberSafe(script, function_start_pos) + 1; 908 accumulator->Add(":~%d", line); 909 } 910 911 accumulator->Add("] "); 912 } 913 } 914 915 accumulator->Add("(this=%o", receiver); 916 917 // Get scope information for nicer output, if possible. If code is 918 // NULL, or doesn't contain scope info, info will return 0 for the 919 // number of parameters, stack slots, or context slots. 920 ScopeInfo<PreallocatedStorage> info(*scope_info); 921 922 // Print the parameters. 923 int parameters_count = ComputeParametersCount(); 924 for (int i = 0; i < parameters_count; i++) { 925 accumulator->Add(","); 926 // If we have a name for the parameter we print it. Nameless 927 // parameters are either because we have more actual parameters 928 // than formal parameters or because we have no scope information. 929 if (i < info.number_of_parameters()) { 930 accumulator->PrintName(*info.parameter_name(i)); 931 accumulator->Add("="); 932 } 933 accumulator->Add("%o", GetParameter(i)); 934 } 935 936 accumulator->Add(")"); 937 if (mode == OVERVIEW) { 938 accumulator->Add("\n"); 939 return; 940 } 941 accumulator->Add(" {\n"); 942 943 // Compute the number of locals and expression stack elements. 944 int stack_locals_count = info.number_of_stack_slots(); 945 int heap_locals_count = info.number_of_context_slots(); 946 int expressions_count = ComputeExpressionsCount(); 947 948 // Print stack-allocated local variables. 949 if (stack_locals_count > 0) { 950 accumulator->Add(" // stack-allocated locals\n"); 951 } 952 for (int i = 0; i < stack_locals_count; i++) { 953 accumulator->Add(" var "); 954 accumulator->PrintName(*info.stack_slot_name(i)); 955 accumulator->Add(" = "); 956 if (i < expressions_count) { 957 accumulator->Add("%o", GetExpression(i)); 958 } else { 959 accumulator->Add("// no expression found - inconsistent frame?"); 960 } 961 accumulator->Add("\n"); 962 } 963 964 // Try to get hold of the context of this frame. 965 Context* context = NULL; 966 if (this->context() != NULL && this->context()->IsContext()) { 967 context = Context::cast(this->context()); 968 } 969 970 // Print heap-allocated local variables. 971 if (heap_locals_count > Context::MIN_CONTEXT_SLOTS) { 972 accumulator->Add(" // heap-allocated locals\n"); 973 } 974 for (int i = Context::MIN_CONTEXT_SLOTS; i < heap_locals_count; i++) { 975 accumulator->Add(" var "); 976 accumulator->PrintName(*info.context_slot_name(i)); 977 accumulator->Add(" = "); 978 if (context != NULL) { 979 if (i < context->length()) { 980 accumulator->Add("%o", context->get(i)); 981 } else { 982 accumulator->Add( 983 "// warning: missing context slot - inconsistent frame?"); 984 } 985 } else { 986 accumulator->Add("// warning: no context found - inconsistent frame?"); 987 } 988 accumulator->Add("\n"); 989 } 990 991 // Print the expression stack. 992 int expressions_start = stack_locals_count; 993 if (expressions_start < expressions_count) { 994 accumulator->Add(" // expression stack (top to bottom)\n"); 995 } 996 for (int i = expressions_count - 1; i >= expressions_start; i--) { 997 if (IsExpressionInsideHandler(i)) continue; 998 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); 999 } 1000 1001 // Print details about the function. 1002 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1003 SharedFunctionInfo* shared = JSFunction::cast(function)->shared(); 1004 accumulator->Add("--------- s o u r c e c o d e ---------\n"); 1005 shared->SourceCodePrint(accumulator, FLAG_max_stack_trace_source_length); 1006 accumulator->Add("\n-----------------------------------------\n"); 1007 } 1008 1009 accumulator->Add("}\n\n"); 1010 } 1011 1012 1013 void ArgumentsAdaptorFrame::Print(StringStream* accumulator, 1014 PrintMode mode, 1015 int index) const { 1016 int actual = ComputeParametersCount(); 1017 int expected = -1; 1018 Object* function = this->function(); 1019 if (function->IsJSFunction()) { 1020 expected = JSFunction::cast(function)->shared()->formal_parameter_count(); 1021 } 1022 1023 PrintIndex(accumulator, mode, index); 1024 accumulator->Add("arguments adaptor frame: %d->%d", actual, expected); 1025 if (mode == OVERVIEW) { 1026 accumulator->Add("\n"); 1027 return; 1028 } 1029 accumulator->Add(" {\n"); 1030 1031 // Print actual arguments. 1032 if (actual > 0) accumulator->Add(" // actual arguments\n"); 1033 for (int i = 0; i < actual; i++) { 1034 accumulator->Add(" [%02d] : %o", i, GetParameter(i)); 1035 if (expected != -1 && i >= expected) { 1036 accumulator->Add(" // not passed to callee"); 1037 } 1038 accumulator->Add("\n"); 1039 } 1040 1041 accumulator->Add("}\n\n"); 1042 } 1043 1044 1045 void EntryFrame::Iterate(ObjectVisitor* v) const { 1046 StackHandlerIterator it(this, top_handler()); 1047 ASSERT(!it.done()); 1048 StackHandler* handler = it.handler(); 1049 ASSERT(handler->is_entry()); 1050 handler->Iterate(v, LookupCode()); 1051 #ifdef DEBUG 1052 // Make sure that the entry frame does not contain more than one 1053 // stack handler. 1054 it.Advance(); 1055 ASSERT(it.done()); 1056 #endif 1057 IteratePc(v, pc_address(), LookupCode()); 1058 } 1059 1060 1061 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { 1062 const int offset = StandardFrameConstants::kContextOffset; 1063 Object** base = &Memory::Object_at(sp()); 1064 Object** limit = &Memory::Object_at(fp() + offset) + 1; 1065 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 1066 StackHandler* handler = it.handler(); 1067 // Traverse pointers down to - but not including - the next 1068 // handler in the handler chain. Update the base to skip the 1069 // handler and allow the handler to traverse its own pointers. 1070 const Address address = handler->address(); 1071 v->VisitPointers(base, reinterpret_cast<Object**>(address)); 1072 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize); 1073 // Traverse the pointers in the handler itself. 1074 handler->Iterate(v, LookupCode()); 1075 } 1076 v->VisitPointers(base, limit); 1077 } 1078 1079 1080 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { 1081 IterateExpressions(v); 1082 IteratePc(v, pc_address(), LookupCode()); 1083 } 1084 1085 1086 void InternalFrame::Iterate(ObjectVisitor* v) const { 1087 // Internal frames only have object pointers on the expression stack 1088 // as they never have any arguments. 1089 IterateExpressions(v); 1090 IteratePc(v, pc_address(), LookupCode()); 1091 } 1092 1093 1094 // ------------------------------------------------------------------------- 1095 1096 1097 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { 1098 ASSERT(n >= 0); 1099 for (int i = 0; i <= n; i++) { 1100 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); 1101 if (i == n) return JavaScriptFrame::cast(iterator_.frame()); 1102 iterator_.Advance(); 1103 } 1104 UNREACHABLE(); 1105 return NULL; 1106 } 1107 1108 1109 // ------------------------------------------------------------------------- 1110 1111 1112 Code* PcToCodeCache::GcSafeCastToCode(HeapObject* object, Address pc) { 1113 Code* code = reinterpret_cast<Code*>(object); 1114 ASSERT(code != NULL && code->contains(pc)); 1115 return code; 1116 } 1117 1118 1119 Code* PcToCodeCache::GcSafeFindCodeForPc(Address pc) { 1120 Heap* heap = isolate_->heap(); 1121 // Check if the pc points into a large object chunk. 1122 LargeObjectChunk* chunk = heap->lo_space()->FindChunkContainingPc(pc); 1123 if (chunk != NULL) return GcSafeCastToCode(chunk->GetObject(), pc); 1124 1125 // Iterate through the 8K page until we reach the end or find an 1126 // object starting after the pc. 1127 Page* page = Page::FromAddress(pc); 1128 HeapObjectIterator iterator(page, heap->GcSafeSizeOfOldObjectFunction()); 1129 HeapObject* previous = NULL; 1130 while (true) { 1131 HeapObject* next = iterator.next(); 1132 if (next == NULL || next->address() >= pc) { 1133 return GcSafeCastToCode(previous, pc); 1134 } 1135 previous = next; 1136 } 1137 } 1138 1139 1140 PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) { 1141 isolate_->counters()->pc_to_code()->Increment(); 1142 ASSERT(IsPowerOf2(kPcToCodeCacheSize)); 1143 uint32_t hash = ComputeIntegerHash( 1144 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc))); 1145 uint32_t index = hash & (kPcToCodeCacheSize - 1); 1146 PcToCodeCacheEntry* entry = cache(index); 1147 if (entry->pc == pc) { 1148 isolate_->counters()->pc_to_code_cached()->Increment(); 1149 ASSERT(entry->code == GcSafeFindCodeForPc(pc)); 1150 } else { 1151 // Because this code may be interrupted by a profiling signal that 1152 // also queries the cache, we cannot update pc before the code has 1153 // been set. Otherwise, we risk trying to use a cache entry before 1154 // the code has been computed. 1155 entry->code = GcSafeFindCodeForPc(pc); 1156 entry->safepoint_entry.Reset(); 1157 entry->pc = pc; 1158 } 1159 return entry; 1160 } 1161 1162 1163 // ------------------------------------------------------------------------- 1164 1165 int NumRegs(RegList reglist) { 1166 int n = 0; 1167 while (reglist != 0) { 1168 n++; 1169 reglist &= reglist - 1; // clear one bit 1170 } 1171 return n; 1172 } 1173 1174 1175 struct JSCallerSavedCodeData { 1176 JSCallerSavedCodeData() { 1177 int i = 0; 1178 for (int r = 0; r < kNumRegs; r++) 1179 if ((kJSCallerSaved & (1 << r)) != 0) 1180 reg_code[i++] = r; 1181 1182 ASSERT(i == kNumJSCallerSaved); 1183 } 1184 int reg_code[kNumJSCallerSaved]; 1185 }; 1186 1187 1188 static const JSCallerSavedCodeData kCallerSavedCodeData; 1189 1190 1191 int JSCallerSavedCode(int n) { 1192 ASSERT(0 <= n && n < kNumJSCallerSaved); 1193 return kCallerSavedCodeData.reg_code[n]; 1194 } 1195 1196 1197 #define DEFINE_WRAPPER(type, field) \ 1198 class field##_Wrapper : public ZoneObject { \ 1199 public: /* NOLINT */ \ 1200 field##_Wrapper(const field& original) : frame_(original) { \ 1201 } \ 1202 field frame_; \ 1203 }; 1204 STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER) 1205 #undef DEFINE_WRAPPER 1206 1207 static StackFrame* AllocateFrameCopy(StackFrame* frame) { 1208 #define FRAME_TYPE_CASE(type, field) \ 1209 case StackFrame::type: { \ 1210 field##_Wrapper* wrapper = \ 1211 new field##_Wrapper(*(reinterpret_cast<field*>(frame))); \ 1212 return &wrapper->frame_; \ 1213 } 1214 1215 switch (frame->type()) { 1216 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 1217 default: UNREACHABLE(); 1218 } 1219 #undef FRAME_TYPE_CASE 1220 return NULL; 1221 } 1222 1223 Vector<StackFrame*> CreateStackMap() { 1224 ZoneList<StackFrame*> list(10); 1225 for (StackFrameIterator it; !it.done(); it.Advance()) { 1226 StackFrame* frame = AllocateFrameCopy(it.frame()); 1227 list.Add(frame); 1228 } 1229 return list.ToVector(); 1230 } 1231 1232 1233 } } // namespace v8::internal 1234