From c26cececd3b422c3dcbd0fee1d4b226c8387b1ee Mon Sep 17 00:00:00 2001 From: Modestas Valauskas Date: Fri, 29 May 2026 01:08:04 -0700 Subject: [PATCH] [vm/compiler] Mark BlockEntryInstr Predecessor* overrides as final. Add `final` to PredecessorAt and PredecessorCount on the six concrete BlockEntryInstr subclasses (GraphEntry, JoinEntry, TargetEntry, FunctionEntry, OsrEntry, CatchBlockEntry), so the compiler can devirtualize the calls. Measured on a naive 49 KLOC generated lexer with --huge_method_cutoff gates lifted and with synchronous compilation: JIT compile drops from ~30.6s to ~27.4s (about 10%). Work towards https://github.com/dart-lang/sdk/issues/63230 TEST=ci Change-Id: Ia2ef2761646a4c94748bcd7dfe0591262d93cd69 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505401 Reviewed-by: Martin Kustermann Commit-Queue: Slava Egorov Reviewed-by: Slava Egorov Auto-Submit: Modestas Valauskas --- runtime/vm/compiler/backend/il.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index ca0263939f8..a98f99c4e82 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h @@ -1984,8 +1984,8 @@ class GraphEntryInstr : public BlockEntryWithInitialDefs { DECLARE_INSTRUCTION(GraphEntry) - virtual intptr_t PredecessorCount() const { return 0; } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + intptr_t PredecessorCount() const final { return 0; } + BlockEntryInstr* PredecessorAt(intptr_t index) const final { UNREACHABLE(); return nullptr; } @@ -2082,8 +2082,8 @@ class JoinEntryInstr : public BlockEntryInstr { DECLARE_INSTRUCTION(JoinEntry) - virtual intptr_t PredecessorCount() const { return predecessors_.length(); } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + intptr_t PredecessorCount() const final { return predecessors_.length(); } + BlockEntryInstr* PredecessorAt(intptr_t index) const final { return predecessors_[index]; } @@ -2167,10 +2167,10 @@ class TargetEntryInstr : public BlockEntryInstr { void set_edge_weight(double weight) { edge_weight_ = weight; } void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } - virtual intptr_t PredecessorCount() const { + intptr_t PredecessorCount() const final { return (predecessor_ == nullptr) ? 0 : 1; } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + BlockEntryInstr* PredecessorAt(intptr_t index) const final { ASSERT((index == 0) && (predecessor_ != nullptr)); return predecessor_; } @@ -2221,10 +2221,10 @@ class FunctionEntryInstr : public BlockEntryWithInitialDefs { DECLARE_INSTRUCTION(FunctionEntry) - virtual intptr_t PredecessorCount() const { + intptr_t PredecessorCount() const final { return (graph_entry_ == nullptr) ? 0 : 1; } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + BlockEntryInstr* PredecessorAt(intptr_t index) const final { ASSERT(index == 0 && graph_entry_ != nullptr); return graph_entry_; } @@ -2295,10 +2295,10 @@ class OsrEntryInstr : public BlockEntryWithInitialDefs { DECLARE_INSTRUCTION(OsrEntry) - virtual intptr_t PredecessorCount() const { + intptr_t PredecessorCount() const final { return (graph_entry_ == nullptr) ? 0 : 1; } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + BlockEntryInstr* PredecessorAt(intptr_t index) const final { ASSERT(index == 0 && graph_entry_ != nullptr); return graph_entry_; } @@ -2430,10 +2430,10 @@ class CatchBlockEntryInstr : public BlockEntryWithInitialDefs { DECLARE_INSTRUCTION(CatchBlockEntry) - virtual intptr_t PredecessorCount() const { + intptr_t PredecessorCount() const final { return (predecessor_ == nullptr) ? 0 : 1; } - virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { + BlockEntryInstr* PredecessorAt(intptr_t index) const final { ASSERT((index == 0) && (predecessor_ != nullptr)); return predecessor_; }