v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
profile-data-reader.cc
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <fstream>
8#include <iostream>
9#include <unordered_map>
10
12#include "src/flags/flags.h"
13#include "src/utils/utils.h"
14
15namespace v8 {
16namespace internal {
17
18namespace {
19
20class ProfileDataFromFileInternal : public ProfileDataFromFile {
21 public:
22 bool hash_has_value() const { return hash_has_value_; }
23
24 void set_hash(int hash) {
25 hash_ = hash;
26 hash_has_value_ = true;
27 }
28
29 void AddHintToBlock(size_t true_block_id, size_t false_block_id,
30 uint64_t hint) {
31 CHECK_LT(hint, 2);
32 block_hints_by_id.insert(std::make_pair(
33 std::make_pair(true_block_id, false_block_id), hint != 0));
34 }
35
36#ifdef LOG_BUILTIN_BLOCK_COUNT
37 void AddBlockExecutionCount(size_t block_id, uint64_t executed_count) {
38 executed_count_.emplace(block_id, executed_count);
39 }
40#endif
41
42 private:
43 bool hash_has_value_ = false;
44};
45
46const std::unordered_map<std::string, ProfileDataFromFileInternal>&
47EnsureInitProfileData() {
48 static base::LeakyObject<
49 std::unordered_map<std::string, ProfileDataFromFileInternal>>
50 data;
51 static bool initialized = false;
52
53 if (initialized) return *data.get();
54 initialized = true;
55#ifdef LOG_BUILTIN_BLOCK_COUNT
56 if (v8_flags.turbo_log_builtins_count_input) {
57 std::ifstream raw_count_file(
58 v8_flags.turbo_log_builtins_count_input.value());
59 CHECK_WITH_MSG(raw_count_file.good(),
60 "Can't read raw count file for log builtin hotness.");
61 for (std::string line; std::getline(raw_count_file, line);) {
62 std::string token;
63 std::istringstream line_stream(line);
64 if (!std::getline(line_stream, token, '\t')) continue;
66 // Any line starting with kBlockCounterMarker is a basic block execution
67 // count. The format is:
68 // literal kBlockCounterMarker \t builtin_name \t block_id \t count
69 std::string builtin_name;
70 CHECK(std::getline(line_stream, builtin_name, '\t'));
71 std::string block_id_str;
72 CHECK(std::getline(line_stream, block_id_str, '\t'));
73 char* end = nullptr;
74 errno = 0;
75 uint32_t block_id =
76 static_cast<uint32_t>(strtoul(block_id_str.c_str(), &end, 10));
77 CHECK(errno == 0);
78 std::string executed_count_str;
79 CHECK(std::getline(line_stream, executed_count_str, '\t'));
80 uint64_t executed_count = static_cast<uint64_t>(
81 strtoul(executed_count_str.c_str(), &end, 10));
82 CHECK(errno == 0 && end != token.c_str());
83 std::getline(line_stream, token, '\t');
84 ProfileDataFromFileInternal& block_count = (*data.get())[builtin_name];
85 block_count.AddBlockExecutionCount(block_id, executed_count);
86 CHECK(line_stream.eof());
88 // Any line starting with kBuiltinHashMarker is a function hash record.
89 // As defined by V8FileLogger::BuiltinHashEvent, the format is:
90 // literal kBuiltinHashMarker \t builtin_name \t hash
91 std::string builtin_name;
92 CHECK(std::getline(line_stream, builtin_name, '\t'));
93 std::getline(line_stream, token, '\t');
94 CHECK(line_stream.eof());
95 char* end = nullptr;
96 int hash = static_cast<int>(strtol(token.c_str(), &end, 0));
97 CHECK(errno == 0 && end != token.c_str());
98 ProfileDataFromFileInternal& block_count = (*data.get())[builtin_name];
99 CHECK_IMPLIES(block_count.hash_has_value(), block_count.hash() == hash);
100 block_count.set_hash(hash);
101 }
102 }
103 }
104#endif
105 const char* filename = v8_flags.turbo_profiling_input;
106 if (filename == nullptr) return *data.get();
107 std::ifstream file(filename);
108 CHECK_WITH_MSG(file.good(), "Can't read log file");
109 for (std::string line; std::getline(file, line);) {
110 std::string token;
111 std::istringstream line_stream(line);
112 if (!std::getline(line_stream, token, ',')) continue;
114 // Any line starting with kBlockHintMarker is a basic block branch hint.
115 // The format is:
116 // literal kBlockHintMarker , builtin_name , true_id , false_id , hint
117 std::string builtin_name;
118 CHECK(std::getline(line_stream, builtin_name, ','));
119 CHECK(std::getline(line_stream, token, ','));
120 char* end = nullptr;
121 errno = 0;
122 uint32_t true_id = static_cast<uint32_t>(strtoul(token.c_str(), &end, 0));
123 CHECK(errno == 0 && end != token.c_str());
124 CHECK(std::getline(line_stream, token, ','));
125 uint32_t false_id =
126 static_cast<uint32_t>(strtoul(token.c_str(), &end, 0));
127 CHECK(errno == 0 && end != token.c_str());
128 std::getline(line_stream, token, ',');
129 CHECK(line_stream.eof());
130 uint64_t hint = strtoul(token.c_str(), &end, 10);
131 CHECK(errno == 0 && end != token.c_str());
132 ProfileDataFromFileInternal& hints_and_hash = (*data.get())[builtin_name];
133 // Only the first hint for each branch will be used.
134 hints_and_hash.AddHintToBlock(true_id, false_id, hint);
135 CHECK(line_stream.eof());
137 // Any line starting with kBuiltinHashMarker is a function hash record.
138 // As defined by V8FileLogger::BuiltinHashEvent, the format is:
139 // literal kBuiltinHashMarker , builtin_name , hash
140 std::string builtin_name;
141 CHECK(std::getline(line_stream, builtin_name, ','));
142 std::getline(line_stream, token, ',');
143 CHECK(line_stream.eof());
144 char* end = nullptr;
145 int hash = static_cast<int>(strtol(token.c_str(), &end, 0));
146 CHECK(errno == 0 && end != token.c_str());
147 ProfileDataFromFileInternal& hints_and_hash = (*data.get())[builtin_name];
148 // We allow concatenating data from several Isolates, but expect them all
149 // to be running the same build. Any file with mismatched hashes for a
150 // function is considered ill-formed.
151 CHECK_IMPLIES(hints_and_hash.hash_has_value(),
152 hints_and_hash.hash() == hash);
153 hints_and_hash.set_hash(hash);
154 }
155 }
156 for (const auto& pair : *data.get()) {
157 // Every function is required to have a hash in the log.
158 CHECK(pair.second.hash_has_value());
159 }
160 return *data.get();
161}
162
163} // namespace
164
166 const auto& data = EnsureInitProfileData();
167 auto it = data.find(name);
168 return it == data.end() ? nullptr : &it->second;
169}
170
171} // namespace internal
172} // namespace v8
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
static const ProfileDataFromFile * TryRead(const char *name)
int end
std::string filename
V8_EXPORT_PRIVATE FlagValues v8_flags
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation nullptr
Definition flags.cc:1263
bool hash_has_value_
#define CHECK_IMPLIES(lhs, rhs)
#define CHECK(condition)
Definition logging.h:124
#define CHECK_LT(lhs, rhs)
#define CHECK_WITH_MSG(condition, message)
Definition logging.h:118
Symbol file