v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assert-types-reducer.h
Go to the documentation of this file.
1// Copyright 2022 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_COMPILER_TURBOSHAFT_ASSERT_TYPES_REDUCER_H_
6#define V8_COMPILER_TURBOSHAFT_ASSERT_TYPES_REDUCER_H_
7
8#include <limits>
9
10#include "src/base/logging.h"
12#include "src/base/vector.h"
14#include "src/compiler/frame.h"
24
26
28
29template <class Next>
31 : public UniformReducerAdapter<AssertTypesReducer, Next> {
32#if defined(__clang__)
34#endif
35
36 public:
38
40
44
45 template <typename Op, typename Continuation>
46 OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op& operation) {
47 OpIndex og_index = Continuation{this}.ReduceInputGraph(ig_index, operation);
48 if constexpr (std::is_same_v<Op, LoadRootRegisterOp>) {
49 // LoadRootRegister is a bit special and should never be materialized,
50 // hence we cannot assert its type.
51 return og_index;
52 }
53 if (std::is_same_v<Op, ConstantOp>) {
54 // Constants are constant by definition, so asserting their types doesn't
55 // seem super useful. Additionally, they can appear before Parameters in
56 // the graph, which leads to issues because asserting their types requires
57 // inserting a Call in the graph, which can overwrite the value of
58 // Parameters.
59 return og_index;
60 }
61 if (!og_index.valid()) return og_index;
62 if (!CanBeTyped(operation)) return og_index;
63 // Unfortunately, we cannot insert assertions after block terminators, so we
64 // skip them here.
65 if (operation.IsBlockTerminator()) return og_index;
66
67 auto reps = operation.outputs_rep();
68 DCHECK_GT(reps.size(), 0);
69 if (reps.size() == 1) {
70 Type type = __ GetInputGraphType(ig_index);
71 InsertTypeAssert(reps[0], og_index, type);
72 }
73 return og_index;
74 }
75
77 const Type& type) {
78 if (!type_assertions_allowed_) return;
79
80 DCHECK(!type.IsInvalid());
81 if (type.IsNone()) {
82 __ Unreachable();
83 return;
84 }
85
86 if (type.IsAny()) {
87 // Ignore any typed for now.
88 return;
89 }
90
91 auto GenerateBuiltinCall =
92 [this](Builtin builtin, OpIndex original_value,
93 base::SmallVector<OpIndex, 6> actual_value_indices,
94 const Type& type) {
95 i::Tagged<Smi> op_id = Smi::FromInt(original_value.id());
96 // Add expected type and operation id.
97 Handle<TurboshaftType> expected_type = type.AllocateOnHeap(factory());
98 actual_value_indices.push_back(__ HeapConstant(expected_type));
99 actual_value_indices.push_back(__ SmiConstant(op_id));
100 actual_value_indices.push_back(__ SmiConstant(NoContextConstant()));
101 __ CallBuiltin(
102 builtin, OpIndex::Invalid(),
103 {actual_value_indices.data(), actual_value_indices.size()},
105#ifdef DEBUG
106 // Used for debugging
107 if (v8_flags.turboshaft_trace_typing) {
108 PrintF("Inserted assert for %3d:%-40s (%s)\n", original_value.id(),
109 __ output_graph().Get(original_value).ToString().c_str(),
110 type.ToString().c_str());
111 }
112#endif
113 };
114
115 switch (rep.value()) {
117 DCHECK(type.IsWord32());
118 base::SmallVector<OpIndex, 6> actual_value_indices = {value};
119 GenerateBuiltinCall(Builtin::kCheckTurboshaftWord32Type, value,
120 std::move(actual_value_indices), type);
121 break;
122 }
124 DCHECK(type.IsWord64());
125 OpIndex value_high =
126 __ TruncateWord64ToWord32(__ Word64ShiftRightLogical(value, 32));
127 OpIndex value_low = __ TruncateWord64ToWord32(value);
128 base::SmallVector<OpIndex, 6> actual_value_indices = {value_high,
129 value_low};
130 GenerateBuiltinCall(Builtin::kCheckTurboshaftWord64Type, value,
131 std::move(actual_value_indices), type);
132 break;
133 }
135 DCHECK(type.IsFloat32());
136 base::SmallVector<OpIndex, 6> actual_value_indices = {value};
137 GenerateBuiltinCall(Builtin::kCheckTurboshaftFloat32Type, value,
138 std::move(actual_value_indices), type);
139 break;
140 }
142 DCHECK(type.IsFloat64());
143 base::SmallVector<OpIndex, 6> actual_value_indices = {value};
144 GenerateBuiltinCall(Builtin::kCheckTurboshaftFloat64Type, value,
145 std::move(actual_value_indices), type);
146 break;
147 }
152 // TODO(nicohartmann@): Handle remaining cases.
153 break;
154 }
155 }
156
157 private:
158 Factory* factory() { return isolate_->factory(); }
160 // We cannot emit type assertions in graphs that have lowered fast api
161 // calls that can throw, because a call to the type assertion builtin could
162 // be emitted between the throwing call and the branch to the handler. This
163 // will violate checks that we are not crossing runtime boundaries while an
164 // exception is still pending.
166 !__ data() -> graph_has_lowered_fast_api_calls();
167};
168
170
171} // namespace v8::internal::compiler::turboshaft
172
173#endif // V8_COMPILER_TURBOSHAFT_ASSERT_TYPES_REDUCER_H_
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
static const int kNoContext
Definition contexts.h:577
v8::internal::Factory * factory()
Definition isolate.h:1527
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
void InsertTypeAssert(RegisterRepresentation rep, OpIndex value, const Type &type)
OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op &operation)
static constexpr OpIndex Invalid()
Definition index.h:88
static constexpr RegisterRepresentation Compressed()
static constexpr RegisterRepresentation Simd128()
static constexpr RegisterRepresentation Word32()
static constexpr RegisterRepresentation Float64()
static constexpr RegisterRepresentation Float32()
static constexpr RegisterRepresentation Simd256()
static constexpr RegisterRepresentation Word64()
static constexpr RegisterRepresentation Tagged()
#define TURBOSHAFT_REDUCER_BOILERPLATE(Name)
Definition assembler.h:823
Isolate * isolate
Builtin builtin
V8_INLINE bool CanBeTyped(const Op &operation)
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
Definition graph.h:1231
std::string ToString(const BytecodeLivenessState &liveness)
void PrintF(const char *format,...)
Definition utils.cc:39
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_GT(v1, v2)
Definition logging.h:487
wasm::ValueType type