Skip to content

Commit 24ae366

Browse files
victorgomesV8 LUCI CQ
authored andcommitted
[maglev] Allow maglev graph building to abort
Fixed: 441668149 Change-Id: I2e10f0c06783a9e513c615efc0b29740b74f42c2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6904548 Reviewed-by: Leszek Swirski <[email protected]> Commit-Queue: Leszek Swirski <[email protected]> Auto-Submit: Victor Gomes <[email protected]> Commit-Queue: Victor Gomes <[email protected]> Cr-Commit-Position: refs/heads/main@{#102162}
1 parent 1ef99c9 commit 24ae366

File tree

8 files changed

+62
-25
lines changed

8 files changed

+62
-25
lines changed

src/codegen/bailout-reason.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace internal {
4040
V(kInvalidJumpTableIndex, "Invalid jump table index") \
4141
V(kInvalidParametersAndRegistersInGenerator, \
4242
"invalid parameters and registers in generator") \
43+
V(kMaglevGraphBuildingFailed, "Maglev optimized graph construction failed") \
4344
V(kMissingBytecodeArray, "Missing bytecode array from function") \
4445
V(kObjectNotTagged, "The object is not tagged") \
4546
V(kObjectTagged, "The object is tagged") \

src/compiler/turboshaft/turbolev-graph-builder.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6427,13 +6427,13 @@ bool ShouldPrintMaglevGraph(PipelineData* data) {
64276427
// SimplifiedLowering, but is much less powerful (doesn't take truncations into
64286428
// account, doesn't do proper range analysis, doesn't run a fixpoint
64296429
// analysis...).
6430-
void RunMaglevOptimizations(PipelineData* data,
6430+
bool RunMaglevOptimizations(PipelineData* data,
64316431
maglev::MaglevCompilationInfo* compilation_info,
64326432
maglev::Graph* maglev_graph) {
64336433
// Non-eager inlining.
64346434
if (v8_flags.turbolev_non_eager_inlining) {
64356435
maglev::MaglevInliner inliner(maglev_graph);
6436-
inliner.Run();
6436+
if (inliner.Run()) return false;
64376437
}
64386438

64396439
// Truncation pass.
@@ -6487,6 +6487,8 @@ void RunMaglevOptimizations(PipelineData* data,
64876487
PrintMaglevGraph(*data, maglev_graph,
64886488
"After escape analysis and dead node sweeping");
64896489
}
6490+
6491+
return true;
64906492
}
64916493

64926494
std::optional<BailoutReason> TurbolevGraphBuildingPhase::Run(PipelineData* data,
@@ -6525,13 +6527,17 @@ std::optional<BailoutReason> TurbolevGraphBuildingPhase::Run(PipelineData* data,
65256527
maglev::MaglevGraphBuilder maglev_graph_builder(
65266528
local_isolate, compilation_info->toplevel_compilation_unit(),
65276529
maglev_graph);
6528-
maglev_graph_builder.Build();
6530+
if (!maglev_graph_builder.Build()) {
6531+
return BailoutReason::kMaglevGraphBuildingFailed;
6532+
}
65296533

65306534
if (V8_UNLIKELY(ShouldPrintMaglevGraph(data))) {
65316535
PrintMaglevGraph(*data, maglev_graph, "After graph building");
65326536
}
65336537

6534-
RunMaglevOptimizations(data, compilation_info.get(), maglev_graph);
6538+
if (!RunMaglevOptimizations(data, compilation_info.get(), maglev_graph)) {
6539+
return BailoutReason::kMaglevGraphBuildingFailed;
6540+
}
65356541

65366542
// TODO(nicohartmann): Should we have source positions here?
65376543
data->InitializeGraphComponent(nullptr);

src/maglev/maglev-compiler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ bool MaglevCompiler::Compile(LocalIsolate* local_isolate,
101101
"V8.Maglev.GraphBuilding");
102102
MaglevGraphBuilder graph_builder(
103103
local_isolate, compilation_info->toplevel_compilation_unit(), graph);
104-
graph_builder.Build();
104+
if (!graph_builder.Build()) return false;
105105
PrintGraph(graph, v8_flags.print_maglev_graphs, "After graph building");
106106
VerifyGraph(graph);
107107
}
@@ -110,7 +110,7 @@ bool MaglevCompiler::Compile(LocalIsolate* local_isolate,
110110
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
111111
"V8.Maglev.Inlining");
112112
MaglevInliner inliner(graph);
113-
inliner.Run();
113+
if (!inliner.Run()) return false;
114114
VerifyGraph(graph);
115115
}
116116

src/maglev/maglev-graph-builder.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "src/base/vector.h"
2020
#include "src/builtins/builtins-constructor.h"
2121
#include "src/builtins/builtins.h"
22+
#include "src/codegen/bailout-reason.h"
2223
#include "src/codegen/cpu-features.h"
2324
#include "src/codegen/interface-descriptors-inl.h"
2425
#include "src/common/assert-scope.h"
@@ -7922,6 +7923,11 @@ ReduceResult MaglevGraphBuilder::BuildInlineFunction(
79227923
}
79237924
inlining_id_ = static_cast<int>(graph()->inlined_functions().size() - 1);
79247925

7926+
if (should_abort_compilation_) {
7927+
// We will abort the compilation at the end.
7928+
return BuildAbort(AbortReason::kMaglevGraphBuildingFailed);
7929+
}
7930+
79257931
DCHECK_NE(inlining_id_, SourcePosition::kNotInlined);
79267932
reducer_.SetBytecodeOffset(entrypoint_);
79277933
reducer_.SetStartSourcePosition(inlining_id_);
@@ -8229,7 +8235,7 @@ ReduceResult MaglevGraphBuilder::BuildEagerInlineCall(
82298235
ReduceResult result = inner_graph_builder.BuildInlineFunction(
82308236
GetCurrentSourcePosition(), context, function, new_target);
82318237

8232-
// Prapagate back (or reset) builder state.
8238+
// Propagate back (or reset) builder state.
82338239
unobserved_context_slot_stores_ =
82348240
inner_graph_builder.unobserved_context_slot_stores_;
82358241
latest_checkpointed_frame_ = nullptr;
@@ -15386,8 +15392,9 @@ DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK)
1538615392
#undef DEBUG_BREAK
1538715393
ReduceResult MaglevGraphBuilder::VisitIllegal() { UNREACHABLE(); }
1538815394

15389-
void MaglevGraphBuilder::Build() {
15395+
bool MaglevGraphBuilder::Build() {
1539015396
DCHECK(!is_inline());
15397+
if (should_abort_compilation_) return false;
1539115398

1539215399
DCHECK_EQ(inlining_id_, SourcePosition::kNotInlined);
1539315400
reducer_.SetBytecodeOffset(entrypoint_);
@@ -15442,6 +15449,7 @@ void MaglevGraphBuilder::Build() {
1544215449
}
1544315450

1544415451
BuildBody();
15452+
return !should_abort_compilation_;
1544515453
}
1544615454

1544715455
void MaglevGraphBuilder::BuildBody() {

src/maglev/maglev-graph-builder.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class MaglevGraphBuilder {
101101
Graph* graph,
102102
MaglevCallerDetails* caller_details = nullptr);
103103

104-
void Build();
104+
bool Build();
105105

106106
ReduceResult BuildInlineFunction(SourcePosition call_site_position,
107107
ValueNode* context, ValueNode* function,
@@ -216,6 +216,8 @@ class MaglevGraphBuilder {
216216

217217
bool is_turbolev() const { return is_turbolev_; }
218218

219+
bool should_abort_compilation() const { return should_abort_compilation_; }
220+
219221
bool is_non_eager_inlining_enabled() const {
220222
if (is_turbolev()) {
221223
return v8_flags.turbolev_non_eager_inlining;
@@ -1889,7 +1891,12 @@ class MaglevGraphBuilder {
18891891
DCHECK_IMPLIES(merge_states_[offset],
18901892
merge_states_[offset]->predecessor_count() ==
18911893
predecessor_count_[offset] + diff);
1892-
predecessor_count_[offset] += diff;
1894+
uint32_t updated_pred_count = predecessor_count_[offset] + diff;
1895+
if (updated_pred_count > NodeBase::kMaxInputs) {
1896+
should_abort_compilation_ = true;
1897+
return;
1898+
}
1899+
predecessor_count_[offset] = updated_pred_count;
18931900
}
18941901
uint32_t predecessor_count(uint32_t offset) {
18951902
DCHECK_LE(offset, bytecode().length());
@@ -1965,6 +1972,7 @@ class MaglevGraphBuilder {
19651972
ValueNode* inlined_new_target_ = nullptr;
19661973

19671974
bool is_turbolev_ = false;
1975+
bool should_abort_compilation_ = false;
19681976

19691977
// Bytecode offset at which compilation should start.
19701978
int entrypoint_;

src/maglev/maglev-inlining.cc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ bool MaglevInliner::IsSmallWithHeapNumberInputsOutputs(
6666
max_inlined_bytecode_size_small_with_heapnum_in_out();
6767
}
6868

69-
void MaglevInliner::Run() {
70-
if (graph_->inlineable_calls().empty()) return;
69+
bool MaglevInliner::Run() {
70+
if (graph_->inlineable_calls().empty()) return true;
7171

7272
while (!graph_->inlineable_calls().empty()) {
7373
MaglevCallSiteInfo* call_site = ChooseNextCallSite();
@@ -100,10 +100,12 @@ void MaglevInliner::Run() {
100100
}
101101
}
102102

103-
TRACE("> Inlining!");
104-
MaybeReduceResult result =
103+
InliningResult result =
105104
BuildInlineFunction(call_site, is_small_with_heapnum_input_outputs);
106-
if (result.IsFail()) continue;
105+
if (result == InliningResult::kAbort) return false;
106+
if (result == InliningResult::kFail) continue;
107+
DCHECK_EQ(result, InliningResult::kDone);
108+
107109
// If --trace-maglev-inlining-verbose, we print the graph after each
108110
// inlining step/call.
109111
if (V8_UNLIKELY(ShouldPrintMaglevGraph())) {
@@ -136,6 +138,8 @@ void MaglevInliner::Run() {
136138
std::cout << "\nAfter inlining" << std::endl;
137139
PrintGraph(std::cout, graph_);
138140
}
141+
142+
return true;
139143
}
140144

141145
int MaglevInliner::max_inlined_bytecode_size_cumulative() const {
@@ -166,7 +170,7 @@ MaglevCallSiteInfo* MaglevInliner::ChooseNextCallSite() {
166170
return call_site;
167171
}
168172

169-
MaybeReduceResult MaglevInliner::BuildInlineFunction(
173+
MaglevInliner::InliningResult MaglevInliner::BuildInlineFunction(
170174
MaglevCallSiteInfo* call_site, bool is_small) {
171175
CallKnownJSFunction* call_node = call_site->generic_call_node;
172176
BasicBlock* call_block = call_node->owner();
@@ -179,7 +183,7 @@ MaybeReduceResult MaglevInliner::BuildInlineFunction(
179183
if (!call_block || call_block->is_dead()) {
180184
// The block containing the call is unreachable, and it was previously
181185
// removed. Do not try to inline the call.
182-
return ReduceResult::Fail();
186+
return InliningResult::kFail;
183187
}
184188

185189
if (V8_UNLIKELY(v8_flags.trace_maglev_inlining && is_tracing_enabled())) {
@@ -267,6 +271,10 @@ MaybeReduceResult MaglevInliner::BuildInlineFunction(
267271
call_node->new_target().node()->Unwrap());
268272

269273
if (result.IsDoneWithAbort()) {
274+
if (inner_graph_builder.should_abort_compilation()) {
275+
return InliningResult::kAbort;
276+
}
277+
270278
// Since the rest of the block is dead, these nodes don't belong
271279
// to any basic block anymore.
272280
for (auto node : rem_nodes_in_call_block) {
@@ -282,7 +290,7 @@ MaybeReduceResult MaglevInliner::BuildInlineFunction(
282290
// remove unreachable blocks, but only the successors of control_node in
283291
// saved_bbs.
284292
RemoveUnreachableBlocks();
285-
return result;
293+
return InliningResult::kDone;
286294
}
287295

288296
DCHECK(result.IsDoneWithValue());
@@ -326,7 +334,7 @@ MaybeReduceResult MaglevInliner::BuildInlineFunction(
326334
RemoveUnreachableBlocks();
327335
}
328336

329-
return ReduceResult::Done();
337+
return InliningResult::kDone;
330338
}
331339

332340
std::vector<BasicBlock*> MaglevInliner::TruncateGraphAt(BasicBlock* block) {

src/maglev/maglev-inlining.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,31 @@ class MaglevInliner {
3838
public:
3939
explicit MaglevInliner(Graph* graph) : graph_(graph) {}
4040

41-
void Run();
41+
bool Run();
4242

4343
private:
44+
Graph* graph_;
45+
4446
int max_inlined_bytecode_size_cumulative() const;
4547
int max_inlined_bytecode_size_small_total() const;
4648
int max_inlined_bytecode_size_small_with_heapnum_in_out() const;
4749

4850
bool IsSmallWithHeapNumberInputsOutputs(MaglevCallSiteInfo* call_site) const;
4951

50-
Graph* graph_;
51-
5252
compiler::JSHeapBroker* broker() const { return graph_->broker(); }
5353
Zone* zone() const { return graph_->zone(); }
5454

5555
bool is_tracing_enabled() const { return graph_->is_tracing_enabled(); }
5656

5757
MaglevCallSiteInfo* ChooseNextCallSite();
58-
MaybeReduceResult BuildInlineFunction(MaglevCallSiteInfo* call_site,
59-
bool is_small);
58+
59+
enum class InliningResult {
60+
kDone,
61+
kFail,
62+
kAbort,
63+
};
64+
InliningResult BuildInlineFunction(MaglevCallSiteInfo* call_site,
65+
bool is_small);
6066

6167
// Truncates the graph at the given basic block `block`. All blocks
6268
// following `block` (exclusive) are removed from the graph and returned.

src/maglev/maglev-ir.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2290,9 +2290,9 @@ class NodeBase : public ZoneObject {
22902290
template <class T, int size>
22912291
using NextBitField = ReservedFields::Next<T, size>;
22922292

2293+
public:
22932294
static constexpr int kMaxInputs = InputCountField::kMax;
22942295

2295-
public:
22962296
template <class T>
22972297
static constexpr Opcode opcode_of = detail::opcode_of_helper<T>::value;
22982298

0 commit comments

Comments
 (0)