[flags] Allow arbitrary conditions for flag implications

This patch refactors the flag implication macros to accept arbitrary
boolean conditions instead of just a single flag.

This is implemented by creating local references to all flags within
EnforceImplications(), allowing conditions to be written as natural
C++ expressions.

This simplifies several existing implications, removing the need for
intermediate helper flags.

Change-Id: Ida2d778975ec1e5402835e05553a23059c110e50
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7112559
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#103538}
This commit is contained in:
Leszek Swirski authored and V8 LUCI CQ committed 2025-11-05 08:22:06 -08:00
1 parent d508d68adb
commit 7c4b41ebac
3 files changed
+50 -37

No files matched your search

+5
View File
@@ -14,6 +14,11 @@ Macros:
- CASE_=case
- FOR_WITH_HANDLE_SCOPE(isolate, init, loop_var, limit_check, increment)=for(init; loop_var; increment)
- WHILE_WITH_HANDLE_SCOPE(isolate, limit_check)=while(limit_check)
# Make clang-format parse conditions in flag implications as expressions, not type definitions.
- DEFINE_IMPLICATION(cond,flag,value)=if(cond) { flag; };
- DEFINE_WEAK_IMPLICATION(cond,flag,value)=if(cond) { flag; };
- DEFINE_VALUE_IMPLICATION(cond,flag,value)=if(cond) { flag = value; };
- DEFINE_WEAK_VALUE_IMPLICATION(cond,flag,value)=if(cond) { flag = value; };
StatementMacros:
- DECL_CAST
- DECL_VERIFIER
+31 -34
View File
@@ -12,19 +12,19 @@
//
// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD
#define DEFINE_IMPLICATION(whenflag, thenflag) \
DEFINE_VALUE_IMPLICATION(whenflag, thenflag, true)
#define DEFINE_IMPLICATION(cond, thenflag) \
DEFINE_VALUE_IMPLICATION(cond, thenflag, true)
// A weak implication will be overwritten by a normal implication or by an
// explicit flag.
#define DEFINE_WEAK_IMPLICATION(whenflag, thenflag) \
DEFINE_WEAK_VALUE_IMPLICATION(whenflag, thenflag, true)
#define DEFINE_WEAK_IMPLICATION(cond, thenflag) \
DEFINE_WEAK_VALUE_IMPLICATION(cond, thenflag, true)
#define DEFINE_WEAK_NEG_IMPLICATION(whenflag, thenflag) \
DEFINE_WEAK_VALUE_IMPLICATION(whenflag, thenflag, false)
#define DEFINE_WEAK_NEG_IMPLICATION(cond, thenflag) \
DEFINE_WEAK_VALUE_IMPLICATION(cond, thenflag, false)
#define DEFINE_NEG_IMPLICATION(whenflag, thenflag) \
DEFINE_VALUE_IMPLICATION(whenflag, thenflag, false)
#define DEFINE_NEG_IMPLICATION(cond, thenflag) \
DEFINE_VALUE_IMPLICATION(cond, thenflag, false)
#define DEFINE_NEG_NEG_IMPLICATION(whenflag, thenflag) \
DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, false)
@@ -60,29 +60,29 @@
// We produce the code to set flags when it is implied by another flag.
#elif defined(FLAG_MODE_DEFINE_IMPLICATIONS)
#define DEFINE_VALUE_IMPLICATION(whenflag, thenflag, value) \
changed |= TriggerImplication(v8_flags.whenflag, #whenflag, \
&v8_flags.thenflag, #thenflag, value, false);
#define DEFINE_VALUE_IMPLICATION(cond, thenflag, value) \
changed |= TriggerImplication(cond, #cond, &v8_flags.thenflag, #thenflag, \
value, false);
// A weak implication will be overwritten by a normal implication or by an
// explicit flag.
#define DEFINE_WEAK_VALUE_IMPLICATION(whenflag, thenflag, value) \
changed |= TriggerImplication(v8_flags.whenflag, #whenflag, \
&v8_flags.thenflag, #thenflag, value, true);
#define DEFINE_WEAK_VALUE_IMPLICATION(cond, thenflag, value) \
changed |= TriggerImplication(cond, #cond, &v8_flags.thenflag, #thenflag, \
value, true);
#define DEFINE_GENERIC_IMPLICATION(whenflag, statement) \
if (v8_flags.whenflag) statement;
#define DEFINE_GENERIC_IMPLICATION(cond, statement) \
if (cond) statement;
// TODO(457654443): can we use FlagError for this, too?
#define DEFINE_REQUIREMENT(statement) CHECK_NO_SECURITY_IMPACT(statement);
// Enforce that a flag was not explicitly set via command line. Setting a value
// via implications is still allowed.
#define DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(whenflag, thenflag) \
TriggerNotExplicitlySetImplication(v8_flags.whenflag, #whenflag, #thenflag);
#define DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(cond, thenflag) \
TriggerNotExplicitlySetImplication(cond, #cond, #thenflag);
#define DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, value) \
changed |= TriggerImplication(!v8_flags.whenflag, "!" #whenflag, \
#define DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, value) \
changed |= TriggerImplication(!(whenflag), "!" #whenflag, \
&v8_flags.thenflag, #thenflag, value, false);
#define DEFINE_NEG_VALUE_VALUE_IMPLICATION(whenflag, whenvalue, thenflag, \
@@ -97,17 +97,23 @@
&v8_flags.flag, #flag, min_value, false);
#define DEFINE_DISABLE_FLAG_IMPLICATION(whenflag, thenflag) \
if (v8_flags.whenflag && v8_flags.thenflag) { \
if (whenflag && thenflag) { \
PrintF(stderr, "Warning: disabling flag --" #thenflag \
" due to conflicting flags\n"); \
} \
DEFINE_VALUE_IMPLICATION(whenflag, thenflag, false)
// We apply a generic macro to the flags.
// We apply a generic macro to the full flags.
#elif defined(FLAG_MODE_APPLY)
#define FLAG_FULL FLAG_MODE_APPLY
// We apply a generic macro to the flag names.
#elif defined(FLAG_MODE_APPLY_NAME)
#define FLAG_FULL(ftype, ctype, nam, def, cmt) FLAG_MODE_APPLY_NAME(nam)
#define FLAG_READONLY(ftype, ctype, nam, def, cmt) FLAG_MODE_APPLY_NAME(nam)
#else
#error No mode supplied when including flags.defs
#endif
@@ -140,10 +146,6 @@
#ifndef DEFINE_NEG_VALUE_IMPLICATION
#define DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, value)
#endif
#ifndef DEFINE_NEG_VALUE_VALUE_IMPLICATION
#define DEFINE_NEG_VALUE_VALUE_IMPLICATION(whenflag, whenvalue, thenflag, \
thenvalue)
#endif
#ifndef DEFINE_MIN_VALUE_IMPLICATION
#define DEFINE_MIN_VALUE_IMPLICATION(flag, min_value)
@@ -1530,8 +1532,8 @@ DEFINE_BOOL(maglev_osr, true, "use maglev as on-stack replacement target")
// When using maglev as OSR target allow us to tier up further
DEFINE_WEAK_VALUE_IMPLICATION(maglev_osr, osr_from_maglev, true)
DEFINE_NEG_VALUE_IMPLICATION(use_osr, maglev_osr, false)
DEFINE_NEG_VALUE_IMPLICATION(turbofan, osr_from_maglev, false)
DEFINE_VALUE_IMPLICATION(!use_osr, maglev_osr, false)
DEFINE_VALUE_IMPLICATION(!turbofan, osr_from_maglev, false)
DEFINE_BOOL(concurrent_osr, true, "enable concurrent OSR")
DEFINE_INT(maglev_allocation_folding, 2, "maglev allocation folding level")
@@ -3778,12 +3780,7 @@ DEFINE_NEG_IMPLICATION(predictable, maglev_deopt_data_on_background)
DEFINE_NEG_IMPLICATION(predictable, maglev_build_code_on_background)
#endif // V8_ENABLE_MAGLEV
// Avoid random seeds in predictable mode.
DEFINE_BOOL(predictable_and_random_seed_is_0, true,
"predictable && (random_seed == 0)")
DEFINE_NEG_NEG_IMPLICATION(predictable, predictable_and_random_seed_is_0)
DEFINE_NEG_VALUE_VALUE_IMPLICATION(random_seed, 0,
predictable_and_random_seed_is_0, false)
DEFINE_VALUE_IMPLICATION(predictable_and_random_seed_is_0, random_seed, 12347)
DEFINE_VALUE_IMPLICATION(predictable && random_seed == 0, random_seed, 12347)
DEFINE_BOOL(predictable_gc_schedule, false,
"Predictable garbage collection schedule. Fixes heap growing, "
+14 -3
View File
@@ -487,7 +487,10 @@ uint32_t ComputeFlagListHash() {
for (const Flag& flag : flags) {
if (flag.IsDefault()) continue;
#ifdef DEBUG
if (flag.ImpliedBy(&v8_flags.predictable)) {
if (flag.ImpliedBy(&v8_flags.predictable) &&
// Ignore --random-seed, which is implied by predictable but also just
// its own thing.
!flag.PointsTo(&v8_flags.random_seed)) {
flags_implied_by_predictable.insert(flag.name());
}
#endif
@@ -529,8 +532,7 @@ uint32_t ComputeFlagListHash() {
flag.PointsTo(&v8_flags.cppheap_concurrent_marking) ||
flag.PointsTo(&v8_flags.cppheap_incremental_marking) ||
flag.PointsTo(&v8_flags.single_threaded_gc) ||
flag.PointsTo(&v8_flags.fuzzing_and_concurrent_recompilation) ||
flag.PointsTo(&v8_flags.predictable_and_random_seed_is_0)) {
flag.PointsTo(&v8_flags.fuzzing_and_concurrent_recompilation)) {
#ifdef DEBUG
if (flag.ImpliedBy(&v8_flags.predictable)) {
flags_ignored_because_of_predictable.insert(flag.name());
@@ -1028,6 +1030,15 @@ class ImplicationProcessor {
// Returns {true} if any flag value was changed.
bool EnforceImplications() {
bool changed = false;
// For each flag, alias with a mutable reference so that implications don't
// need the v8_flags prefix.
#define FLAG_MODE_APPLY_NAME(name) \
auto& name = v8_flags.name; \
USE(name);
#include "src/flags/flag-definitions.h"
#undef FLAG_MODE_APPLY_NAME
#define FLAG_MODE_DEFINE_IMPLICATIONS
#include "src/flags/flag-definitions.h" // NOLINT(build/include)
#undef FLAG_MODE_DEFINE_IMPLICATIONS