| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/frames.h" | 5 #include "src/frames.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
| 10 #include "src/ast/scopeinfo.h" | 10 #include "src/ast/scopeinfo.h" |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 external_callback_scope_->scope_address() < frame_->fp()) { | 318 external_callback_scope_->scope_address() < frame_->fp()) { |
| 319 // As long as the setup of a frame is not atomic, we may happen to be | 319 // As long as the setup of a frame is not atomic, we may happen to be |
| 320 // in an interval where an ExternalCallbackScope is already created, | 320 // in an interval where an ExternalCallbackScope is already created, |
| 321 // but the frame is not yet entered. So we are actually observing | 321 // but the frame is not yet entered. So we are actually observing |
| 322 // the previous frame. | 322 // the previous frame. |
| 323 // Skip all the ExternalCallbackScope's that are below the current fp. | 323 // Skip all the ExternalCallbackScope's that are below the current fp. |
| 324 last_callback_scope = external_callback_scope_; | 324 last_callback_scope = external_callback_scope_; |
| 325 external_callback_scope_ = external_callback_scope_->previous(); | 325 external_callback_scope_ = external_callback_scope_->previous(); |
| 326 } | 326 } |
| 327 if (frame_->is_java_script()) break; | 327 if (frame_->is_java_script()) break; |
| 328 if (frame_->is_exit() || frame_->is_builtin_exit()) { | 328 if (frame_->is_exit()) { |
| 329 // Some of the EXIT frames may have ExternalCallbackScope allocated on | 329 // Some of the EXIT frames may have ExternalCallbackScope allocated on |
| 330 // top of them. In that case the scope corresponds to the first EXIT | 330 // top of them. In that case the scope corresponds to the first EXIT |
| 331 // frame beneath it. There may be other EXIT frames on top of the | 331 // frame beneath it. There may be other EXIT frames on top of the |
| 332 // ExternalCallbackScope, just skip them as we cannot collect any useful | 332 // ExternalCallbackScope, just skip them as we cannot collect any useful |
| 333 // information about them. | 333 // information about them. |
| 334 if (last_callback_scope) { | 334 if (last_callback_scope) { |
| 335 frame_->state_.pc_address = | 335 frame_->state_.pc_address = |
| 336 last_callback_scope->callback_entrypoint_address(); | 336 last_callback_scope->callback_entrypoint_address(); |
| 337 } | 337 } |
| 338 break; | 338 break; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 } | 478 } |
| 479 } | 479 } |
| 480 | 480 |
| 481 DCHECK(marker->IsSmi()); | 481 DCHECK(marker->IsSmi()); |
| 482 StackFrame::Type candidate = | 482 StackFrame::Type candidate = |
| 483 static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 483 static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| 484 switch (candidate) { | 484 switch (candidate) { |
| 485 case ENTRY: | 485 case ENTRY: |
| 486 case ENTRY_CONSTRUCT: | 486 case ENTRY_CONSTRUCT: |
| 487 case EXIT: | 487 case EXIT: |
| 488 case BUILTIN_EXIT: | |
| 489 case STUB: | 488 case STUB: |
| 490 case STUB_FAILURE_TRAMPOLINE: | 489 case STUB_FAILURE_TRAMPOLINE: |
| 491 case INTERNAL: | 490 case INTERNAL: |
| 492 case CONSTRUCT: | 491 case CONSTRUCT: |
| 493 case ARGUMENTS_ADAPTOR: | 492 case ARGUMENTS_ADAPTOR: |
| 494 case WASM_TO_JS: | 493 case WASM_TO_JS: |
| 495 case WASM: | 494 case WASM: |
| 496 return candidate; | 495 return candidate; |
| 497 case JS_TO_WASM: | 496 case JS_TO_WASM: |
| 498 case JAVA_SCRIPT: | 497 case JAVA_SCRIPT: |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 Code* EntryConstructFrame::unchecked_code() const { | 551 Code* EntryConstructFrame::unchecked_code() const { |
| 553 return isolate()->heap()->js_construct_entry_code(); | 552 return isolate()->heap()->js_construct_entry_code(); |
| 554 } | 553 } |
| 555 | 554 |
| 556 | 555 |
| 557 Object*& ExitFrame::code_slot() const { | 556 Object*& ExitFrame::code_slot() const { |
| 558 const int offset = ExitFrameConstants::kCodeOffset; | 557 const int offset = ExitFrameConstants::kCodeOffset; |
| 559 return Memory::Object_at(fp() + offset); | 558 return Memory::Object_at(fp() + offset); |
| 560 } | 559 } |
| 561 | 560 |
| 561 |
| 562 Code* ExitFrame::unchecked_code() const { | 562 Code* ExitFrame::unchecked_code() const { |
| 563 return reinterpret_cast<Code*>(code_slot()); | 563 return reinterpret_cast<Code*>(code_slot()); |
| 564 } | 564 } |
| 565 | 565 |
| 566 | 566 |
| 567 void ExitFrame::ComputeCallerState(State* state) const { | 567 void ExitFrame::ComputeCallerState(State* state) const { |
| 568 // Set up the caller state. | 568 // Set up the caller state. |
| 569 state->sp = caller_sp(); | 569 state->sp = caller_sp(); |
| 570 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 570 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
| 571 state->pc_address = ResolveReturnAddressLocation( | 571 state->pc_address = ResolveReturnAddressLocation( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 593 Address ExitFrame::GetCallerStackPointer() const { | 593 Address ExitFrame::GetCallerStackPointer() const { |
| 594 return fp() + ExitFrameConstants::kCallerSPOffset; | 594 return fp() + ExitFrameConstants::kCallerSPOffset; |
| 595 } | 595 } |
| 596 | 596 |
| 597 | 597 |
| 598 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { | 598 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
| 599 if (fp == 0) return NONE; | 599 if (fp == 0) return NONE; |
| 600 Address sp = ComputeStackPointer(fp); | 600 Address sp = ComputeStackPointer(fp); |
| 601 FillState(fp, sp, state); | 601 FillState(fp, sp, state); |
| 602 DCHECK(*state->pc_address != NULL); | 602 DCHECK(*state->pc_address != NULL); |
| 603 | |
| 604 return ComputeFrameType(fp); | |
| 605 } | |
| 606 | |
| 607 StackFrame::Type ExitFrame::ComputeFrameType(Address fp) { | |
| 608 // Distinguish between between regular and builtin exit frames. | |
| 609 // Default to EXIT in all hairy cases (e.g., when called from profiler). | |
| 610 const int offset = ExitFrameConstants::kFrameTypeOffset; | |
| 611 Object* marker = Memory::Object_at(fp + offset); | |
| 612 | |
| 613 if (!marker->IsSmi()) { | |
| 614 return EXIT; | |
| 615 } | |
| 616 | |
| 617 StackFrame::Type frame_type = | |
| 618 static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | |
| 619 if (frame_type == EXIT || frame_type == BUILTIN_EXIT) { | |
| 620 return frame_type; | |
| 621 } | |
| 622 | |
| 623 return EXIT; | 603 return EXIT; |
| 624 } | 604 } |
| 625 | 605 |
| 626 Address ExitFrame::ComputeStackPointer(Address fp) { | 606 Address ExitFrame::ComputeStackPointer(Address fp) { |
| 627 MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize); | 607 MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize); |
| 628 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); | 608 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); |
| 629 } | 609 } |
| 630 | 610 |
| 631 void ExitFrame::FillState(Address fp, Address sp, State* state) { | 611 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
| 632 state->sp = sp; | 612 state->sp = sp; |
| 633 state->fp = fp; | 613 state->fp = fp; |
| 634 state->pc_address = ResolveReturnAddressLocation( | 614 state->pc_address = ResolveReturnAddressLocation( |
| 635 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 615 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
| 636 // The constant pool recorded in the exit frame is not associated | 616 // The constant pool recorded in the exit frame is not associated |
| 637 // with the pc in this state (the return address into a C entry | 617 // with the pc in this state (the return address into a C entry |
| 638 // stub). ComputeCallerState will retrieve the constant pool | 618 // stub). ComputeCallerState will retrieve the constant pool |
| 639 // together with the associated caller pc. | 619 // together with the associated caller pc. |
| 640 state->constant_pool_address = NULL; | 620 state->constant_pool_address = NULL; |
| 641 } | 621 } |
| 642 | 622 |
| 643 JSFunction* BuiltinExitFrame::function() const { | |
| 644 return JSFunction::cast(function_slot_object()); | |
| 645 } | |
| 646 | |
| 647 Address StandardFrame::GetExpressionAddress(int n) const { | 623 Address StandardFrame::GetExpressionAddress(int n) const { |
| 648 const int offset = StandardFrameConstants::kExpressionsOffset; | 624 const int offset = StandardFrameConstants::kExpressionsOffset; |
| 649 return fp() + offset - n * kPointerSize; | 625 return fp() + offset - n * kPointerSize; |
| 650 } | 626 } |
| 651 | 627 |
| 652 Address InterpretedFrame::GetExpressionAddress(int n) const { | 628 Address InterpretedFrame::GetExpressionAddress(int n) const { |
| 653 const int offset = InterpreterFrameConstants::kExpressionsOffset; | 629 const int offset = InterpreterFrameConstants::kExpressionsOffset; |
| 654 return fp() + offset - n * kPointerSize; | 630 return fp() + offset - n * kPointerSize; |
| 655 } | 631 } |
| 656 | 632 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp; | 671 int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp; |
| 696 Object* marker = | 672 Object* marker = |
| 697 Memory::Object_at(fp() + CommonFrameConstants::kContextOrFrameTypeOffset); | 673 Memory::Object_at(fp() + CommonFrameConstants::kContextOrFrameTypeOffset); |
| 698 if (marker->IsSmi()) { | 674 if (marker->IsSmi()) { |
| 699 StackFrame::Type candidate = | 675 StackFrame::Type candidate = |
| 700 static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 676 static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| 701 switch (candidate) { | 677 switch (candidate) { |
| 702 case ENTRY: | 678 case ENTRY: |
| 703 case ENTRY_CONSTRUCT: | 679 case ENTRY_CONSTRUCT: |
| 704 case EXIT: | 680 case EXIT: |
| 705 case BUILTIN_EXIT: | |
| 706 case STUB_FAILURE_TRAMPOLINE: | 681 case STUB_FAILURE_TRAMPOLINE: |
| 707 case ARGUMENTS_ADAPTOR: | 682 case ARGUMENTS_ADAPTOR: |
| 708 case STUB: | 683 case STUB: |
| 709 case INTERNAL: | 684 case INTERNAL: |
| 710 case CONSTRUCT: | 685 case CONSTRUCT: |
| 711 case JS_TO_WASM: | 686 case JS_TO_WASM: |
| 712 case WASM_TO_JS: | 687 case WASM_TO_JS: |
| 713 case WASM: | 688 case WASM: |
| 714 frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp; | 689 frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp; |
| 715 break; | 690 break; |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1791 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1817 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1792 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1818 list.Add(frame, zone); | 1793 list.Add(frame, zone); |
| 1819 } | 1794 } |
| 1820 return list.ToVector(); | 1795 return list.ToVector(); |
| 1821 } | 1796 } |
| 1822 | 1797 |
| 1823 | 1798 |
| 1824 } // namespace internal | 1799 } // namespace internal |
| 1825 } // namespace v8 | 1800 } // namespace v8 |
| OLD | NEW |