Commit f6c9a545 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[flags] add --print-flag-values helper

It's not always easy to spot what exact configuration of V8 is run
within embedders. With --print-flag-values we can easily compare
different configurations.

Drive-by-fix:
- Use new FlagValue and FlagName helpers for printing
- Remove unused FlagList::argv helper

Change-Id: Ic8a25479d7b1e72f714b22ae7d2e56e06e810556
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3197713Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77189}
parent 1c3085e2
......@@ -1816,6 +1816,8 @@ DEFINE_BOOL_READONLY(minor_mc, false,
//
DEFINE_BOOL(help, false, "Print usage message, including flags, on console")
DEFINE_BOOL(print_flag_values, false, "Print all flag values of V8")
DEFINE_BOOL(dump_counters, false, "Dump counters on exit")
DEFINE_BOOL(slow_histograms, false,
"Enable slow histograms with more overhead.")
......
......@@ -9,6 +9,7 @@
#include <cinttypes>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include "src/base/functional.h"
......@@ -40,6 +41,8 @@ namespace internal {
namespace {
char NormalizeChar(char ch) { return ch == '_' ? '-' : ch; }
struct Flag;
Flag* FindFlagByPointer(const void* ptr);
Flag* FindFlagByName(const char* name);
......@@ -380,8 +383,6 @@ Flag flags[] = {
const size_t num_flags = sizeof(flags) / sizeof(*flags);
inline char NormalizeChar(char ch) { return ch == '_' ? '-' : ch; }
bool EqualNames(const char* a, const char* b) {
for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
if (a[i] == '\0') {
......@@ -429,7 +430,27 @@ static const char* Type2String(Flag::FlagType type) {
UNREACHABLE();
}
std::ostream& operator<<(std::ostream& os, const Flag& flag) {
// Helper struct for printing normalize Flag names.
struct FlagName {
explicit FlagName(const Flag& flag) : flag(flag) {}
const Flag& flag;
};
std::ostream& operator<<(std::ostream& os, const FlagName& flag_name) {
for (const char* c = flag_name.flag.name(); *c != '\0'; ++c) {
os << NormalizeChar(*c);
}
return os;
}
// Helper for printing flag values.
struct FlagValue {
explicit FlagValue(const Flag& flag) : flag(flag) {}
const Flag& flag;
};
std::ostream& operator<<(std::ostream& os, const FlagValue& flag_value) {
const Flag& flag = flag_value.flag;
switch (flag.type()) {
case Flag::TYPE_BOOL:
os << (flag.bool_variable() ? "true" : "false");
......@@ -456,33 +477,20 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) {
break;
case Flag::TYPE_STRING: {
const char* str = flag.string_value();
os << (str ? str : "nullptr");
os << std::quoted(str ? str : "");
break;
}
}
return os;
}
// static
std::vector<const char*>* FlagList::argv() {
std::vector<const char*>* args = new std::vector<const char*>(8);
for (size_t i = 0; i < num_flags; ++i) {
Flag* f = &flags[i];
if (!f->IsDefault()) {
{
bool disabled = f->type() == Flag::TYPE_BOOL && !f->bool_variable();
std::ostringstream os;
os << (disabled ? "--no" : "--") << f->name();
args->push_back(StrDup(os.str().c_str()));
}
if (f->type() != Flag::TYPE_BOOL) {
std::ostringstream os;
os << *f;
args->push_back(StrDup(os.str().c_str()));
}
}
std::ostream& operator<<(std::ostream& os, const Flag& flag) {
if (flag.type() == Flag::TYPE_BOOL) {
os << (flag.bool_variable() ? "--" : "--no") << FlagName(flag);
} else {
os << "--" << FlagName(flag) << "=" << FlagValue(flag);
}
return args;
return os;
}
// Helper function to parse flags: Takes an argument arg and splits it into
......@@ -768,16 +776,20 @@ void FlagList::PrintHelp() {
os << "Options:\n";
for (const Flag& f : flags) {
os << " --";
for (const char* c = f.name(); *c != '\0'; ++c) {
os << NormalizeChar(*c);
}
os << " (" << f.comment() << ")\n"
os << " --" << FlagName(f) << " (" << f.comment() << ")\n"
<< " type: " << Type2String(f.type()) << " default: " << f
<< "\n";
}
}
// static
void FlagList::PrintValues() {
StdoutStream os;
for (const Flag& f : flags) {
os << f << "\n";
}
}
namespace {
static uint32_t flag_hash = 0;
......
......@@ -19,15 +19,6 @@ namespace internal {
// The global list of all flags.
class V8_EXPORT_PRIVATE FlagList {
public:
// The list of all flags with a value different from the default
// and their values. The format of the list is like the format of the
// argv array passed to the main function, e.g.
// ("--prof", "--log-file", "v8.prof", "--nolazy").
//
// The caller is responsible for disposing the list, as well
// as every element of it.
static std::vector<const char*>* argv();
class HelpOptions {
public:
enum ExitBehavior : bool { kExit = true, kDontExit = false };
......@@ -78,6 +69,8 @@ class V8_EXPORT_PRIVATE FlagList {
// Print help to stdout with flags, types, and default values.
static void PrintHelp();
static void PrintValues();
// Set flags as consequence of being implied by another flag.
static void EnforceFlagImplications();
......
......@@ -181,6 +181,8 @@ void V8::InitializeOncePerProcessImpl() {
if (FLAG_random_seed) SetRandomMmapSeed(FLAG_random_seed);
if (FLAG_print_flag_values) FlagList::PrintValues();
#if defined(V8_USE_PERFETTO)
if (perfetto::Tracing::IsInitialized()) TrackEvent::Register();
#endif
......
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