10
10
#include < cstdlib>
11
11
#include < cstring>
12
12
#include < iomanip>
13
+ #include < set>
13
14
#include < sstream>
14
15
15
16
#include " src/base/functional.h"
@@ -103,7 +104,12 @@ struct Flag {
103
104
const char * cmt_; // A comment about the flags purpose.
104
105
bool owns_ptr_; // Does the flag own its string value?
105
106
SetBy set_by_ = SetBy::kDefault ;
107
+ // Name of the flag implying this flag, if any.
106
108
const char * implied_by_ = nullptr ;
109
+ #ifdef DEBUG
110
+ // Pointer to the flag implying this flag, if any.
111
+ const Flag* implied_by_ptr_ = nullptr ;
112
+ #endif
107
113
108
114
FlagType type () const { return type_; }
109
115
@@ -113,6 +119,17 @@ struct Flag {
113
119
114
120
bool PointsTo (const void * ptr) const { return valptr_ == ptr; }
115
121
122
+ #ifdef DEBUG
123
+ bool ImpliedBy (const void * ptr) const {
124
+ const Flag* current = this ->implied_by_ptr_ ;
125
+ while (current != nullptr ) {
126
+ if (current->PointsTo (ptr)) return true ;
127
+ current = current->implied_by_ptr_ ;
128
+ }
129
+ return false ;
130
+ }
131
+ #endif
132
+
116
133
bool bool_variable () const { return GetValue<TYPE_BOOL, bool >(); }
117
134
118
135
void set_bool_variable (bool value, SetBy set_by) {
@@ -333,6 +350,15 @@ struct Flag {
333
350
if (IsAnyImplication (new_set_by)) {
334
351
DCHECK_NOT_NULL (implied_by);
335
352
implied_by_ = implied_by;
353
+ #ifdef DEBUG
354
+ // This only works when implied_by is a flag_name or !flag_name, but it
355
+ // can also be a condition e.g. flag_name > 3. Since this is only used for
356
+ // checks in DEBUG mode, we will just ignore the more complex conditions
357
+ // for now - that will just lead to a nullptr which won't be followed.
358
+ implied_by_ptr_ = static_cast <Flag*>(
359
+ FindFlagByName (implied_by[0 ] == ' !' ? implied_by + 1 : implied_by));
360
+ DCHECK_NE (implied_by_ptr_, this );
361
+ #endif
336
362
}
337
363
return change_flag;
338
364
}
@@ -534,17 +560,71 @@ uint32_t ComputeFlagListHash() {
534
560
std::ostringstream modified_args_as_string;
535
561
if (COMPRESS_POINTERS_BOOL) modified_args_as_string << " ptr-compr" ;
536
562
if (DEBUG_BOOL) modified_args_as_string << " debug" ;
563
+
564
+ #ifdef DEBUG
565
+ // These two sets are used to check that we don't leave out any flags
566
+ // implied by --predictable in the list below.
567
+ std::set<const char *> flags_implied_by_predictable;
568
+ std::set<const char *> flags_ignored_because_of_predictable;
569
+ #endif
570
+
537
571
for (const Flag& flag : flags) {
538
572
if (flag.IsDefault ()) continue ;
573
+ #ifdef DEBUG
574
+ if (flag.ImpliedBy (&v8_flags.predictable )) {
575
+ flags_implied_by_predictable.insert (flag.name ());
576
+ }
577
+ #endif
539
578
// We want to be able to flip --profile-deserialization without
540
579
// causing the code cache to get invalidated by this hash.
541
580
if (flag.PointsTo (&v8_flags.profile_deserialization )) continue ;
542
581
// Skip v8_flags.random_seed and v8_flags.predictable to allow predictable
543
582
// code caching.
544
583
if (flag.PointsTo (&v8_flags.random_seed )) continue ;
545
584
if (flag.PointsTo (&v8_flags.predictable )) continue ;
585
+
586
+ // The following flags are implied by --predictable (some negated).
587
+ if (flag.PointsTo (&v8_flags.concurrent_sparkplug ) ||
588
+ flag.PointsTo (&v8_flags.concurrent_recompilation ) ||
589
+ #ifdef V8_ENABLE_MAGLEV
590
+ flag.PointsTo (&v8_flags.maglev_deopt_data_on_background ) ||
591
+ flag.PointsTo (&v8_flags.maglev_build_code_on_background ) ||
592
+ #endif
593
+ flag.PointsTo (&v8_flags.parallel_scavenge ) ||
594
+ flag.PointsTo (&v8_flags.concurrent_marking ) ||
595
+ flag.PointsTo (&v8_flags.concurrent_array_buffer_sweeping ) ||
596
+ flag.PointsTo (&v8_flags.parallel_marking ) ||
597
+ flag.PointsTo (&v8_flags.concurrent_sweeping ) ||
598
+ flag.PointsTo (&v8_flags.parallel_compaction ) ||
599
+ flag.PointsTo (&v8_flags.parallel_pointer_update ) ||
600
+ flag.PointsTo (&v8_flags.parallel_weak_ref_clearing ) ||
601
+ flag.PointsTo (&v8_flags.memory_reducer ) ||
602
+ flag.PointsTo (&v8_flags.cppheap_concurrent_marking ) ||
603
+ flag.PointsTo (&v8_flags.cppheap_incremental_marking ) ||
604
+ flag.PointsTo (&v8_flags.single_threaded_gc )) {
605
+ #ifdef DEBUG
606
+ if (flag.ImpliedBy (&v8_flags.predictable )) {
607
+ flags_ignored_because_of_predictable.insert (flag.name ());
608
+ }
609
+ #endif
610
+ continue ;
611
+ }
546
612
modified_args_as_string << flag;
547
613
}
614
+
615
+ #ifdef DEBUG
616
+ for (const char * name : flags_implied_by_predictable) {
617
+ if (flags_ignored_because_of_predictable.find (name) ==
618
+ flags_ignored_because_of_predictable.end ()) {
619
+ PrintF (
620
+ " %s should be added to the list of "
621
+ " flags_ignored_because_of_predictable\n " ,
622
+ name);
623
+ UNREACHABLE ();
624
+ }
625
+ }
626
+ #endif
627
+
548
628
std::string args (modified_args_as_string.str ());
549
629
// Generate a hash that is not 0.
550
630
uint32_t hash = static_cast <uint32_t >(base::hash_range (
0 commit comments