| 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 #ifndef V8_FRAMES_H_ | 5 #ifndef V8_FRAMES_H_ |
| 6 #define V8_FRAMES_H_ | 6 #define V8_FRAMES_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/handles.h" | 9 #include "src/handles.h" |
| 10 #include "src/safepoint-table.h" | 10 #include "src/safepoint-table.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 V(OPTIMIZED, OptimizedFrame) \ | 105 V(OPTIMIZED, OptimizedFrame) \ |
| 106 V(WASM, WasmFrame) \ | 106 V(WASM, WasmFrame) \ |
| 107 V(WASM_TO_JS, WasmToJsFrame) \ | 107 V(WASM_TO_JS, WasmToJsFrame) \ |
| 108 V(JS_TO_WASM, JsToWasmFrame) \ | 108 V(JS_TO_WASM, JsToWasmFrame) \ |
| 109 V(INTERPRETED, InterpretedFrame) \ | 109 V(INTERPRETED, InterpretedFrame) \ |
| 110 V(STUB, StubFrame) \ | 110 V(STUB, StubFrame) \ |
| 111 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \ | 111 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \ |
| 112 V(INTERNAL, InternalFrame) \ | 112 V(INTERNAL, InternalFrame) \ |
| 113 V(CONSTRUCT, ConstructFrame) \ | 113 V(CONSTRUCT, ConstructFrame) \ |
| 114 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \ | 114 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \ |
| 115 V(BUILTIN, BuiltinFrame) | 115 V(BUILTIN, BuiltinFrame) \ |
| 116 V(BUILTIN_EXIT, BuiltinExitFrame) |
| 116 | 117 |
| 117 // Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume | 118 // Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume |
| 118 // two slots. | 119 // two slots. |
| 119 // | 120 // |
| 120 // Stack slot indices >= 0 access the callee stack with slot 0 corresponding to | 121 // Stack slot indices >= 0 access the callee stack with slot 0 corresponding to |
| 121 // the callee's saved return address and 1 corresponding to the saved frame | 122 // the callee's saved return address and 1 corresponding to the saved frame |
| 122 // pointer. Some frames have additional information stored in the fixed header, | 123 // pointer. Some frames have additional information stored in the fixed header, |
| 123 // for example JSFunctions store the function context and marker in the fixed | 124 // for example JSFunctions store the function context and marker in the fixed |
| 124 // header, with slot index 2 corresponding to the current function context and 3 | 125 // header, with slot index 2 corresponding to the current function context and 3 |
| 125 // corresponding to the frame marker/JSFunction. | 126 // corresponding to the frame marker/JSFunction. |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 class StubFailureTrampolineFrameConstants : public InternalFrameConstants { | 317 class StubFailureTrampolineFrameConstants : public InternalFrameConstants { |
| 317 public: | 318 public: |
| 318 static const int kArgumentsArgumentsOffset = | 319 static const int kArgumentsArgumentsOffset = |
| 319 TYPED_FRAME_PUSHED_VALUE_OFFSET(0); | 320 TYPED_FRAME_PUSHED_VALUE_OFFSET(0); |
| 320 static const int kArgumentsLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1); | 321 static const int kArgumentsLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1); |
| 321 static const int kArgumentsPointerOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2); | 322 static const int kArgumentsPointerOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2); |
| 322 static const int kFixedHeaderBottomOffset = kArgumentsPointerOffset; | 323 static const int kFixedHeaderBottomOffset = kArgumentsPointerOffset; |
| 323 DEFINE_TYPED_FRAME_SIZES(3); | 324 DEFINE_TYPED_FRAME_SIZES(3); |
| 324 }; | 325 }; |
| 325 | 326 |
| 327 // Behaves like an exit frame but with target and new target args. |
| 328 class BuiltinExitFrameConstants : public CommonFrameConstants { |
| 329 public: |
| 330 static const int kNewTargetOffset = kCallerPCOffset + 1 * kPointerSize; |
| 331 static const int kTargetOffset = kNewTargetOffset + 1 * kPointerSize; |
| 332 }; |
| 326 | 333 |
| 327 class InterpreterFrameConstants : public AllStatic { | 334 class InterpreterFrameConstants : public AllStatic { |
| 328 public: | 335 public: |
| 329 // Fixed frame includes new.target and bytecode offset. | 336 // Fixed frame includes new.target and bytecode offset. |
| 330 static const int kFixedFrameSize = | 337 static const int kFixedFrameSize = |
| 331 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize; | 338 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize; |
| 332 static const int kFixedFrameSizeFromFp = | 339 static const int kFixedFrameSizeFromFp = |
| 333 StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize; | 340 StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize; |
| 334 | 341 |
| 335 // FP-relative. | 342 // FP-relative. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 bool is_wasm() const { return type() == WASM; } | 426 bool is_wasm() const { return type() == WASM; } |
| 420 bool is_wasm_to_js() const { return type() == WASM_TO_JS; } | 427 bool is_wasm_to_js() const { return type() == WASM_TO_JS; } |
| 421 bool is_js_to_wasm() const { return type() == JS_TO_WASM; } | 428 bool is_js_to_wasm() const { return type() == JS_TO_WASM; } |
| 422 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } | 429 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } |
| 423 bool is_builtin() const { return type() == BUILTIN; } | 430 bool is_builtin() const { return type() == BUILTIN; } |
| 424 bool is_internal() const { return type() == INTERNAL; } | 431 bool is_internal() const { return type() == INTERNAL; } |
| 425 bool is_stub_failure_trampoline() const { | 432 bool is_stub_failure_trampoline() const { |
| 426 return type() == STUB_FAILURE_TRAMPOLINE; | 433 return type() == STUB_FAILURE_TRAMPOLINE; |
| 427 } | 434 } |
| 428 bool is_construct() const { return type() == CONSTRUCT; } | 435 bool is_construct() const { return type() == CONSTRUCT; } |
| 436 bool is_builtin_exit() const { return type() == BUILTIN_EXIT; } |
| 429 virtual bool is_standard() const { return false; } | 437 virtual bool is_standard() const { return false; } |
| 430 | 438 |
| 431 bool is_java_script() const { | 439 bool is_java_script() const { |
| 432 Type type = this->type(); | 440 Type type = this->type(); |
| 433 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) || | 441 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) || |
| 434 (type == INTERPRETED) || (type == BUILTIN); | 442 (type == INTERPRETED) || (type == BUILTIN); |
| 435 } | 443 } |
| 436 | 444 |
| 437 // Accessors. | 445 // Accessors. |
| 438 Address sp() const { return state_.sp; } | 446 Address sp() const { return state_.sp; } |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 static ExitFrame* cast(StackFrame* frame) { | 631 static ExitFrame* cast(StackFrame* frame) { |
| 624 DCHECK(frame->is_exit()); | 632 DCHECK(frame->is_exit()); |
| 625 return static_cast<ExitFrame*>(frame); | 633 return static_cast<ExitFrame*>(frame); |
| 626 } | 634 } |
| 627 | 635 |
| 628 // Compute the state and type of an exit frame given a frame | 636 // Compute the state and type of an exit frame given a frame |
| 629 // pointer. Used when constructing the first stack frame seen by an | 637 // pointer. Used when constructing the first stack frame seen by an |
| 630 // iterator and the frames following entry frames. | 638 // iterator and the frames following entry frames. |
| 631 static Type GetStateForFramePointer(Address fp, State* state); | 639 static Type GetStateForFramePointer(Address fp, State* state); |
| 632 static Address ComputeStackPointer(Address fp); | 640 static Address ComputeStackPointer(Address fp); |
| 641 static StackFrame::Type ComputeFrameType(Address fp); |
| 633 static void FillState(Address fp, Address sp, State* state); | 642 static void FillState(Address fp, Address sp, State* state); |
| 634 | 643 |
| 635 protected: | 644 protected: |
| 636 inline explicit ExitFrame(StackFrameIteratorBase* iterator); | 645 inline explicit ExitFrame(StackFrameIteratorBase* iterator); |
| 637 | 646 |
| 638 Address GetCallerStackPointer() const override; | 647 Address GetCallerStackPointer() const override; |
| 639 | 648 |
| 640 private: | 649 private: |
| 641 void ComputeCallerState(State* state) const override; | 650 void ComputeCallerState(State* state) const override; |
| 642 | 651 |
| 643 friend class StackFrameIteratorBase; | 652 friend class StackFrameIteratorBase; |
| 644 }; | 653 }; |
| 645 | 654 |
| 655 // Builtin exit frames are a special case of exit frames, which are used |
| 656 // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is |
| 657 // to allow such builtins to appear in stack traces. |
| 658 class BuiltinExitFrame : public ExitFrame { |
| 659 public: |
| 660 Type type() const override { return BUILTIN_EXIT; } |
| 661 |
| 662 static BuiltinExitFrame* cast(StackFrame* frame) { |
| 663 DCHECK(frame->is_builtin_exit()); |
| 664 return static_cast<BuiltinExitFrame*>(frame); |
| 665 } |
| 666 |
| 667 virtual JSFunction* function() const; |
| 668 |
| 669 protected: |
| 670 inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator); |
| 671 |
| 672 private: |
| 673 inline Object* function_slot_object() const; |
| 674 |
| 675 friend class StackFrameIteratorBase; |
| 676 }; |
| 677 |
| 646 class JavaScriptFrame; | 678 class JavaScriptFrame; |
| 647 | 679 |
| 648 class FrameSummary BASE_EMBEDDED { | 680 class FrameSummary BASE_EMBEDDED { |
| 649 public: | 681 public: |
| 650 // Mode for JavaScriptFrame::Summarize. Exact summary is required to produce | 682 // Mode for JavaScriptFrame::Summarize. Exact summary is required to produce |
| 651 // an exact stack trace. It will trigger an assertion failure if that is not | 683 // an exact stack trace. It will trigger an assertion failure if that is not |
| 652 // possible, e.g., because of missing deoptimization information. The | 684 // possible, e.g., because of missing deoptimization information. The |
| 653 // approximate mode should produce a summary even without deoptimization | 685 // approximate mode should produce a summary even without deoptimization |
| 654 // information, but it might miss frames. | 686 // information, but it might miss frames. |
| 655 enum Mode { kExactSummary, kApproximateSummary }; | 687 enum Mode { kExactSummary, kApproximateSummary }; |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 | 1283 |
| 1252 | 1284 |
| 1253 // Reads all frames on the current stack and copies them into the current | 1285 // Reads all frames on the current stack and copies them into the current |
| 1254 // zone memory. | 1286 // zone memory. |
| 1255 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone); | 1287 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone); |
| 1256 | 1288 |
| 1257 } // namespace internal | 1289 } // namespace internal |
| 1258 } // namespace v8 | 1290 } // namespace v8 |
| 1259 | 1291 |
| 1260 #endif // V8_FRAMES_H_ | 1292 #endif // V8_FRAMES_H_ |
| OLD | NEW |