[tools][wasm] wami: add --section-stats mode

Prints information about sections in a given module and their sizes.

Change-Id: I3bf02f0c8be53756364db4d2dada60bc8a510815
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3743447
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81522}
This commit is contained in:
Jakob Kummerow 2022-07-05 11:57:55 +02:00 committed by V8 LUCI CQ
parent efbadd6096
commit 25c3b1b05b
3 changed files with 50 additions and 4 deletions

View File

@ -204,7 +204,7 @@ class V8_EXPORT_PRIVATE Utf8 {
};
#if V8_ENABLE_WEBASSEMBLY
class Wtf8 {
class V8_EXPORT_PRIVATE Wtf8 {
public:
// Validate that the input has a valid WTF-8 encoding.
//

View File

@ -926,9 +926,11 @@ class ModuleDecoderImpl : public Decoder {
void DecodeFunctionSection() {
uint32_t functions_count =
consume_count("functions count", kV8MaxWasmFunctions);
auto counter =
SELECT_WASM_COUNTER(GetCounters(), origin_, wasm_functions_per, module);
counter->AddSample(static_cast<int>(functions_count));
if (counters_ != nullptr) {
auto counter = SELECT_WASM_COUNTER(GetCounters(), origin_,
wasm_functions_per, module);
counter->AddSample(static_cast<int>(functions_count));
}
DCHECK_EQ(module_->functions.size(), module_->num_imported_functions);
uint32_t total_function_count =
module_->num_imported_functions + functions_count;

View File

@ -24,6 +24,9 @@ int PrintHelp(char** argv) {
<< " --list-functions\n"
<< " List functions in the given module\n"
<< " --section-stats\n"
<< " Show information about sections in the given module\n"
<< "The module name must be a file name.\n";
return 1;
}
@ -81,6 +84,38 @@ class FormatConverter {
}
}
void SectionStats() {
DCHECK(ok_);
Decoder decoder(start(), end());
static constexpr int kModuleHeaderSize = 8;
decoder.consume_bytes(kModuleHeaderSize, "module header");
uint32_t module_size = static_cast<uint32_t>(end() - start());
int digits = 2;
for (uint32_t comparator = 100; module_size >= comparator;
comparator *= 10) {
digits++;
}
size_t kMinNameLength = 8;
// 18 = kMinNameLength + strlen(" section: ").
std::cout << std::setw(18) << std::left << "Module size: ";
std::cout << std::setw(digits) << std::right << module_size << " bytes\n";
for (WasmSectionIterator it(&decoder); it.more(); it.advance(true)) {
const char* name = SectionName(it.section_code());
size_t name_len = strlen(name);
std::cout << SectionName(it.section_code()) << " section: ";
for (; name_len < kMinNameLength; name_len++) std::cout << " ";
uint32_t length = it.section_length();
std::cout << std::setw(name_len > kMinNameLength ? 0 : digits) << length
<< " bytes / ";
std::cout << std::fixed << std::setprecision(1) << std::setw(4)
<< 100.0 * length / module_size;
std::cout << "\% of total\n";
}
}
private:
byte* start() { return raw_bytes_.data(); }
byte* end() { return start() + raw_bytes_.size(); }
@ -104,6 +139,7 @@ enum class Action {
kUnset,
kHelp,
kListFunctions,
kSectionStats,
};
struct Options {
@ -116,6 +152,11 @@ void ListFunctions(const Options& options) {
if (fc.ok()) fc.ListFunctions();
}
void SectionStats(const Options& options) {
FormatConverter fc(options.filename);
if (fc.ok()) fc.SectionStats();
}
int ParseOptions(int argc, char** argv, Options* options) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0 ||
@ -123,6 +164,8 @@ int ParseOptions(int argc, char** argv, Options* options) {
options->action = Action::kHelp;
} else if (strcmp(argv[i], "--list-functions") == 0) {
options->action = Action::kListFunctions;
} else if (strcmp(argv[i], "--section-stats") == 0) {
options->action = Action::kSectionStats;
} else if (options->filename != nullptr) {
return PrintHelp(argv);
} else {
@ -155,6 +198,7 @@ int main(int argc, char** argv) {
// clang-format off
case Action::kHelp: PrintHelp(argv); break;
case Action::kListFunctions: ListFunctions(options); break;
case Action::kSectionStats: SectionStats(options); break;
case Action::kUnset: UNREACHABLE();
// clang-format on
}