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 <memory> | 7 #include <memory> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 return reinterpret_cast<Code*>(code_slot()); | 567 return reinterpret_cast<Code*>(code_slot()); |
568 } | 568 } |
569 | 569 |
570 | 570 |
571 void ExitFrame::ComputeCallerState(State* state) const { | 571 void ExitFrame::ComputeCallerState(State* state) const { |
572 // Set up the caller state. | 572 // Set up the caller state. |
573 state->sp = caller_sp(); | 573 state->sp = caller_sp(); |
574 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 574 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
575 state->pc_address = ResolveReturnAddressLocation( | 575 state->pc_address = ResolveReturnAddressLocation( |
576 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); | 576 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); |
| 577 state->callee_pc_address = nullptr; |
577 if (FLAG_enable_embedded_constant_pool) { | 578 if (FLAG_enable_embedded_constant_pool) { |
578 state->constant_pool_address = reinterpret_cast<Address*>( | 579 state->constant_pool_address = reinterpret_cast<Address*>( |
579 fp() + ExitFrameConstants::kConstantPoolOffset); | 580 fp() + ExitFrameConstants::kConstantPoolOffset); |
580 } | 581 } |
581 } | 582 } |
582 | 583 |
583 | 584 |
584 void ExitFrame::SetCallerFp(Address caller_fp) { | 585 void ExitFrame::SetCallerFp(Address caller_fp) { |
585 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; | 586 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; |
586 } | 587 } |
587 | 588 |
588 | 589 |
589 void ExitFrame::Iterate(ObjectVisitor* v) const { | 590 void ExitFrame::Iterate(ObjectVisitor* v) const { |
590 // The arguments are traversed as part of the expression stack of | 591 // The arguments are traversed as part of the expression stack of |
591 // the calling frame. | 592 // the calling frame. |
592 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 593 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
593 v->VisitPointer(&code_slot()); | 594 v->VisitPointer(&code_slot()); |
594 } | 595 } |
595 | 596 |
596 | 597 |
597 Address ExitFrame::GetCallerStackPointer() const { | 598 Address ExitFrame::GetCallerStackPointer() const { |
598 return fp() + ExitFrameConstants::kCallerSPOffset; | 599 return fp() + ExitFrameConstants::kCallerSPOffset; |
599 } | 600 } |
600 | 601 |
601 | 602 |
602 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { | 603 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
603 if (fp == 0) return NONE; | 604 if (fp == 0) return NONE; |
604 Address sp = ComputeStackPointer(fp); | 605 Address sp = ComputeStackPointer(fp); |
605 FillState(fp, sp, state); | 606 FillState(fp, sp, state); |
606 DCHECK(*state->pc_address != NULL); | 607 DCHECK_NOT_NULL(*state->pc_address); |
607 | 608 |
608 return ComputeFrameType(fp); | 609 return ComputeFrameType(fp); |
609 } | 610 } |
610 | 611 |
611 StackFrame::Type ExitFrame::ComputeFrameType(Address fp) { | 612 StackFrame::Type ExitFrame::ComputeFrameType(Address fp) { |
612 // Distinguish between between regular and builtin exit frames. | 613 // Distinguish between between regular and builtin exit frames. |
613 // Default to EXIT in all hairy cases (e.g., when called from profiler). | 614 // Default to EXIT in all hairy cases (e.g., when called from profiler). |
614 const int offset = ExitFrameConstants::kFrameTypeOffset; | 615 const int offset = ExitFrameConstants::kFrameTypeOffset; |
615 Object* marker = Memory::Object_at(fp + offset); | 616 Object* marker = Memory::Object_at(fp + offset); |
616 | 617 |
(...skipping 13 matching lines...) Expand all Loading... |
630 Address ExitFrame::ComputeStackPointer(Address fp) { | 631 Address ExitFrame::ComputeStackPointer(Address fp) { |
631 MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize); | 632 MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize); |
632 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); | 633 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); |
633 } | 634 } |
634 | 635 |
635 void ExitFrame::FillState(Address fp, Address sp, State* state) { | 636 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
636 state->sp = sp; | 637 state->sp = sp; |
637 state->fp = fp; | 638 state->fp = fp; |
638 state->pc_address = ResolveReturnAddressLocation( | 639 state->pc_address = ResolveReturnAddressLocation( |
639 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 640 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
| 641 state->callee_pc_address = nullptr; |
640 // The constant pool recorded in the exit frame is not associated | 642 // The constant pool recorded in the exit frame is not associated |
641 // with the pc in this state (the return address into a C entry | 643 // with the pc in this state (the return address into a C entry |
642 // stub). ComputeCallerState will retrieve the constant pool | 644 // stub). ComputeCallerState will retrieve the constant pool |
643 // together with the associated caller pc. | 645 // together with the associated caller pc. |
644 state->constant_pool_address = NULL; | 646 state->constant_pool_address = nullptr; |
645 } | 647 } |
646 | 648 |
647 JSFunction* BuiltinExitFrame::function() const { | 649 JSFunction* BuiltinExitFrame::function() const { |
648 return JSFunction::cast(target_slot_object()); | 650 return JSFunction::cast(target_slot_object()); |
649 } | 651 } |
650 | 652 |
651 Object* BuiltinExitFrame::receiver() const { return receiver_slot_object(); } | 653 Object* BuiltinExitFrame::receiver() const { return receiver_slot_object(); } |
652 | 654 |
653 bool BuiltinExitFrame::IsConstructor() const { | 655 bool BuiltinExitFrame::IsConstructor() const { |
654 return !new_target_slot_object()->IsUndefined(isolate()); | 656 return !new_target_slot_object()->IsUndefined(isolate()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 return nullptr; | 740 return nullptr; |
739 } | 741 } |
740 | 742 |
741 int StandardFrame::ComputeParametersCount() const { return 0; } | 743 int StandardFrame::ComputeParametersCount() const { return 0; } |
742 | 744 |
743 void StandardFrame::ComputeCallerState(State* state) const { | 745 void StandardFrame::ComputeCallerState(State* state) const { |
744 state->sp = caller_sp(); | 746 state->sp = caller_sp(); |
745 state->fp = caller_fp(); | 747 state->fp = caller_fp(); |
746 state->pc_address = ResolveReturnAddressLocation( | 748 state->pc_address = ResolveReturnAddressLocation( |
747 reinterpret_cast<Address*>(ComputePCAddress(fp()))); | 749 reinterpret_cast<Address*>(ComputePCAddress(fp()))); |
| 750 state->callee_pc_address = pc_address(); |
748 state->constant_pool_address = | 751 state->constant_pool_address = |
749 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); | 752 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); |
750 } | 753 } |
751 | 754 |
752 | 755 |
753 void StandardFrame::SetCallerFp(Address caller_fp) { | 756 void StandardFrame::SetCallerFp(Address caller_fp) { |
754 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = | 757 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = |
755 caller_fp; | 758 caller_fp; |
756 } | 759 } |
757 | 760 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 } | 875 } |
873 } | 876 } |
874 | 877 |
875 | 878 |
876 void StubFrame::Iterate(ObjectVisitor* v) const { | 879 void StubFrame::Iterate(ObjectVisitor* v) const { |
877 IterateCompiledFrame(v); | 880 IterateCompiledFrame(v); |
878 } | 881 } |
879 | 882 |
880 | 883 |
881 Code* StubFrame::unchecked_code() const { | 884 Code* StubFrame::unchecked_code() const { |
882 return static_cast<Code*>(isolate()->FindCodeObject(pc())); | 885 return isolate()->FindCodeObject(pc()); |
883 } | 886 } |
884 | 887 |
885 | 888 |
886 Address StubFrame::GetCallerStackPointer() const { | 889 Address StubFrame::GetCallerStackPointer() const { |
887 return fp() + ExitFrameConstants::kCallerSPOffset; | 890 return fp() + ExitFrameConstants::kCallerSPOffset; |
888 } | 891 } |
889 | 892 |
890 | 893 |
891 int StubFrame::GetNumberOfIncomingArguments() const { | 894 int StubFrame::GetNumberOfIncomingArguments() const { |
892 return 0; | 895 return 0; |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 } | 1576 } |
1574 | 1577 |
1575 int WasmFrame::position() const { | 1578 int WasmFrame::position() const { |
1576 int position = StandardFrame::position(); | 1579 int position = StandardFrame::position(); |
1577 if (wasm::WasmIsAsmJs(wasm_instance(), isolate())) { | 1580 if (wasm::WasmIsAsmJs(wasm_instance(), isolate())) { |
1578 Handle<WasmCompiledModule> compiled_module( | 1581 Handle<WasmCompiledModule> compiled_module( |
1579 WasmInstanceObject::cast(wasm_instance())->get_compiled_module(), | 1582 WasmInstanceObject::cast(wasm_instance())->get_compiled_module(), |
1580 isolate()); | 1583 isolate()); |
1581 DCHECK_LE(0, position); | 1584 DCHECK_LE(0, position); |
1582 position = WasmCompiledModule::GetAsmJsSourcePosition( | 1585 position = WasmCompiledModule::GetAsmJsSourcePosition( |
1583 compiled_module, function_index(), static_cast<uint32_t>(position)); | 1586 compiled_module, function_index(), static_cast<uint32_t>(position), |
| 1587 at_to_number_conversion()); |
1584 } | 1588 } |
1585 return position; | 1589 return position; |
1586 } | 1590 } |
1587 | 1591 |
| 1592 bool WasmFrame::at_to_number_conversion() const { |
| 1593 // Check whether our callee is a WASM_TO_JS frame, and this frame is at the |
| 1594 // ToNumber conversion call. |
| 1595 Address callee_pc = reinterpret_cast<Address>(this->callee_pc()); |
| 1596 Code* code = callee_pc ? isolate()->FindCodeObject(callee_pc) : nullptr; |
| 1597 if (!code || code->kind() != Code::WASM_TO_JS_FUNCTION) return false; |
| 1598 int offset = static_cast<int>(callee_pc - code->instruction_start()); |
| 1599 int pos = AbstractCode::cast(code)->SourcePosition(offset); |
| 1600 DCHECK(pos == 0 || pos == 1); |
| 1601 // The imported call has position 0, ToNumber has position 1. |
| 1602 return !!pos; |
| 1603 } |
| 1604 |
1588 int WasmFrame::LookupExceptionHandlerInTable(int* stack_slots) { | 1605 int WasmFrame::LookupExceptionHandlerInTable(int* stack_slots) { |
1589 DCHECK_NOT_NULL(stack_slots); | 1606 DCHECK_NOT_NULL(stack_slots); |
1590 Code* code = LookupCode(); | 1607 Code* code = LookupCode(); |
1591 HandlerTable* table = HandlerTable::cast(code->handler_table()); | 1608 HandlerTable* table = HandlerTable::cast(code->handler_table()); |
1592 int pc_offset = static_cast<int>(pc() - code->entry()); | 1609 int pc_offset = static_cast<int>(pc() - code->entry()); |
1593 *stack_slots = code->stack_slots(); | 1610 *stack_slots = code->stack_slots(); |
1594 return table->LookupReturn(pc_offset); | 1611 return table->LookupReturn(pc_offset); |
1595 } | 1612 } |
1596 | 1613 |
1597 namespace { | 1614 namespace { |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 2042 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
2026 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 2043 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
2027 list.Add(frame, zone); | 2044 list.Add(frame, zone); |
2028 } | 2045 } |
2029 return list.ToVector(); | 2046 return list.ToVector(); |
2030 } | 2047 } |
2031 | 2048 |
2032 | 2049 |
2033 } // namespace internal | 2050 } // namespace internal |
2034 } // namespace v8 | 2051 } // namespace v8 |
OLD | NEW |