Commit 012665e3 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[flags] Check for frozen flags only when values change

This allows to run a test repeatedly (in the same process) which
always sets the flag(s) to the same value. This also applies to
fuzzers.

The {FlagValue<T>::operator=} is the central bottleneck which is now
used for any flag value updates, either via the FLAG_foo globals, or
via the internal or public API.

R=cbruni@chromium.org

Bug: v8:12887, chromium:1346284
Change-Id: I46662322e1420ee12314544302ad9700523dcf90
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3780525
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81909}
parent 48ae9bb6
......@@ -568,7 +568,6 @@ bool TryParseUnsigned(Flag* flag, const char* arg, const char* value,
// static
int FlagList::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags,
HelpOptions help_options) {
CHECK(!IsFrozen());
int return_code = 0;
// parse arguments
for (int i = 1; i < *argc;) {
......@@ -890,8 +889,6 @@ class ImplicationProcessor {
// static
void FlagList::EnforceFlagImplications() {
CHECK(!IsFrozen());
flag_hash = 0;
for (ImplicationProcessor proc; proc.EnforceImplications();) {
// Continue processing (recursive) implications. The processor has an
// internal limit to avoid endless recursion.
......@@ -906,6 +903,14 @@ uint32_t FlagList::Hash() {
return hash;
}
// static
void FlagList::ResetFlagHash() {
// If flags are frozen, we should not need to reset the hash since we cannot
// change flag values anyway.
CHECK(!IsFrozen());
flag_hash = 0;
}
#undef FLAG_MODE_DEFINE
#undef FLAG_MODE_DEFINE_DEFAULTS
#undef FLAG_MODE_META
......
......@@ -104,12 +104,24 @@ class V8_EXPORT_PRIVATE FlagList {
// Hash of flags (to quickly determine mismatching flag expectations).
// This hash is calculated during V8::Initialize and cached.
static uint32_t Hash();
private:
// Reset the flag hash on flag changes. This is a private method called from
// {FlagValue<T>::operator=}; there should be no need to call it from any
// other place.
static void ResetFlagHash();
// Make {FlagValue<T>} a friend, so it can call {ResetFlagHash()}.
template <typename T>
friend class FlagValue;
};
template <typename T>
FlagValue<T>& FlagValue<T>::operator=(T new_value) {
CHECK(!FlagList::IsFrozen());
value_ = new_value;
if (new_value != value_) {
FlagList::ResetFlagHash();
value_ = new_value;
}
return *this;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment