v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
maglev-deopt-frame-visitor.h
Go to the documentation of this file.
1// Copyright 2025 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_MAGLEV_MAGLEV_DEOPT_FRAME_VISITOR_H_
6#define V8_MAGLEV_MAGLEV_DEOPT_FRAME_VISITOR_H_
7
8#include <type_traits>
9
12
13namespace v8 {
14namespace internal {
15namespace maglev {
16
17template <typename DeoptInfoT>
19 public:
20 template <typename Function>
21 static void ForEager(DeoptInfoT* deopt_info, Function&& f) {
22 DeoptInfoVisitor<DeoptInfoT> visitor(deopt_info);
23 visitor.Visit(deopt_info->top_frame(), f);
24 }
25
26 template <typename Function>
27 static void ForLazy(DeoptInfoT* deopt_info, Function&& f) {
28 DeoptInfoVisitor<DeoptInfoT> visitor(deopt_info);
29 if (deopt_info->top_frame().parent()) {
30 visitor.Visit(*deopt_info->top_frame().parent(), f);
31 }
32 const bool kSkipResultLocation = true;
33 visitor.VisitSingleFrame<kSkipResultLocation>(deopt_info->top_frame(), f);
34 }
35
36 private:
37 const DeoptInfoT* deopt_info_;
39
40 using DeoptFrameT = std::conditional_t<std::is_const_v<DeoptInfoT>,
41 const DeoptFrame, DeoptFrame>;
42 using ValueNodeT =
43 std::conditional_t<std::is_const_v<DeoptInfoT>, ValueNode*, ValueNode*&>;
44
45 explicit DeoptInfoVisitor(DeoptInfoT* deopt_info)
46 : deopt_info_(deopt_info),
47 virtual_objects_(deopt_info->top_frame().GetVirtualObjects()) {}
48
49 template <typename Function>
50 void Visit(DeoptFrameT& frame, Function&& f) {
51 if (frame.parent()) {
52 Visit(*frame.parent(), f);
53 }
54 VisitSingleFrame(frame, f);
55 }
56
57 template <bool skip_frame_result = false, typename Function>
59 auto updated_f = [&](ValueNodeT node) {
60 DCHECK(!node->template Is<VirtualObject>());
61 if (node->template Is<Identity>()) {
62 node = node->input(0).node();
63 }
64 if (auto alloc = node->template TryCast<InlinedAllocation>()) {
65 VirtualObject* vobject = virtual_objects_.FindAllocatedWith(alloc);
66 if (vobject && (!alloc->HasBeenAnalysed() || alloc->HasBeenElided())) {
68 }
69 }
70 f(node);
71 };
72 switch (frame.type()) {
74 updated_f(frame.as_interpreted().closure());
75 frame.as_interpreted().frame_state()->ForEachValue(
76 frame.as_interpreted().unit(),
78 if constexpr (std::is_same_v<DeoptInfoT, LazyDeoptInfo>) {
79 // Skip over the result location for lazy deopts, since it is
80 // irrelevant for lazy deopts (unoptimized code will recreate
81 // the result).
82 if (skip_frame_result && deopt_info_->IsResultRegister(reg)) {
83 return;
84 }
85 }
86 updated_f(node);
87 });
88 break;
90 // The inlined arguments frame can never be the top frame.
91 updated_f(frame.as_inlined_arguments().closure());
92 for (ValueNode*& node : frame.as_inlined_arguments().arguments()) {
93 updated_f(node);
94 }
95 break;
96 }
98 updated_f(frame.as_construct_stub().receiver());
99 updated_f(frame.as_construct_stub().context());
100 break;
101 }
103 for (ValueNode*& node : frame.as_builtin_continuation().parameters()) {
104 updated_f(node);
105 }
106 updated_f(frame.as_builtin_continuation().context());
107 break;
108 }
109 }
110};
111
112template <typename Function>
113void EagerDeoptInfo::ForEachInput(Function&& f) {
115}
116
117template <typename Function>
118void EagerDeoptInfo::ForEachInput(Function&& f) const {
120}
121
122template <typename Function>
123void LazyDeoptInfo::ForEachInput(Function&& f) {
125}
126
127template <typename Function>
128void LazyDeoptInfo::ForEachInput(Function&& f) const {
130}
131
132} // namespace maglev
133} // namespace internal
134} // namespace v8
135
136#endif // V8_MAGLEV_MAGLEV_DEOPT_FRAME_VISITOR_H_
static void ForEager(DeoptInfoT *deopt_info, Function &&f)
void Visit(DeoptFrameT &frame, Function &&f)
std::conditional_t< std::is_const_v< DeoptInfoT >, const DeoptFrame, DeoptFrame > DeoptFrameT
static void ForLazy(DeoptInfoT *deopt_info, Function &&f)
void VisitSingleFrame(DeoptFrameT &frame, Function &&f)
std::conditional_t< std::is_const_v< DeoptInfoT >, ValueNode *, ValueNode *& > ValueNodeT
void ForEachNestedRuntimeInput(VirtualObjectList virtual_objects, Function &&f)
Definition maglev-ir.h:6057
Node * node
LiftoffRegister reg
bool TryCast(Tagged< From > value, Tagged< To > *out)
Definition casting.h:77
bool Is(IndirectHandle< U > value)
Definition handles-inl.h:51
#define DCHECK(condition)
Definition logging.h:482