| 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 |