Skip to content

Commit 595599a

Browse files
committed
Refactor: shrink diagnostic tables; AoS -> SoA
diagnostic_message_info contains a byte of padding. This padding adds up to two bytes per diagnostic. This padding is wasteful. Refactor diagnostic_info's use of diagnostic_message_info, replacing the array-of-structs (AoS) with structs-of-arrays (SoA). This removes the padding bytes. This commit should not change behavior.
1 parent 8a10c39 commit 595599a

File tree

6 files changed

+172
-214
lines changed

6 files changed

+172
-214
lines changed

src/diagnostic.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,14 @@ class diagnostic_info_builder {
7474
template <class... Args>
7575
constexpr diagnostic_info_builder add(const translatable_message& message,
7676
const Args&... arg_infos) {
77-
diagnostic_message_info& message_info =
78-
this->info_.messages[this->current_message_index_++];
79-
message_info.format = message;
77+
this->info_.message_formats[this->current_message_index_] = message;
8078

81-
int current_arg_index = 0;
82-
((message_info.args[current_arg_index++] = arg_infos), ...);
79+
std::size_t current_arg_index = 0;
80+
diagnostic_message_args& args =
81+
this->info_.message_args[this->current_message_index_];
82+
((args[current_arg_index++] = arg_infos), ...);
8383

84+
++this->current_message_index_;
8485
return *this;
8586
}
8687

src/quick-lint-js/diagnostic-formatter.h

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ string8_view translated_singular_statement_kind(statement_kind) noexcept;
2626
class diagnostic_formatter_base {
2727
public:
2828
static source_code_span get_argument_source_code_span(
29-
const diagnostic_message_info& message_info, const void* diagnostic,
29+
const diagnostic_message_args& args, const void* diagnostic,
3030
int arg_index) {
31-
auto [arg_data, arg_type] = get_arg(message_info, diagnostic, arg_index);
31+
auto [arg_data, arg_type] = get_arg(args, diagnostic, arg_index);
3232
switch (arg_type) {
3333
case diagnostic_arg_type::identifier:
3434
return reinterpret_cast<const identifier*>(arg_data)->span();
@@ -46,10 +46,9 @@ class diagnostic_formatter_base {
4646
QLJS_UNREACHABLE();
4747
}
4848

49-
static string8_view expand_argument(
50-
const diagnostic_message_info& message_info, const void* diagnostic,
51-
int arg_index) {
52-
auto [arg_data, arg_type] = get_arg(message_info, diagnostic, arg_index);
49+
static string8_view expand_argument(const diagnostic_message_args& args,
50+
const void* diagnostic, int arg_index) {
51+
auto [arg_data, arg_type] = get_arg(args, diagnostic, arg_index);
5352
switch (arg_type) {
5453
case diagnostic_arg_type::char8:
5554
return string8_view(reinterpret_cast<const char8*>(arg_data), 1);
@@ -74,9 +73,9 @@ class diagnostic_formatter_base {
7473
}
7574

7675
static string8_view expand_argument_headlinese(
77-
const diagnostic_message_info& message_info, const void* diagnostic,
76+
const diagnostic_message_args& args, const void* diagnostic,
7877
int arg_index) {
79-
auto [arg_data, arg_type] = get_arg(message_info, diagnostic, arg_index);
78+
auto [arg_data, arg_type] = get_arg(args, diagnostic, arg_index);
8079
switch (arg_type) {
8180
case diagnostic_arg_type::statement_kind:
8281
return translated_headlinese_statement_kind(
@@ -94,9 +93,9 @@ class diagnostic_formatter_base {
9493
}
9594

9695
static string8_view expand_argument_singular(
97-
const diagnostic_message_info& message_info, const void* diagnostic,
96+
const diagnostic_message_args& args, const void* diagnostic,
9897
int arg_index) {
99-
auto [arg_data, arg_type] = get_arg(message_info, diagnostic, arg_index);
98+
auto [arg_data, arg_type] = get_arg(args, diagnostic, arg_index);
10099
switch (arg_type) {
101100
case diagnostic_arg_type::statement_kind:
102101
return translated_singular_statement_kind(
@@ -115,9 +114,10 @@ class diagnostic_formatter_base {
115114

116115
private:
117116
static std::pair<const void*, diagnostic_arg_type> get_arg(
118-
const diagnostic_message_info& message_info, const void* diagnostic,
117+
const diagnostic_message_args& args, const void* diagnostic,
119118
int arg_index) noexcept {
120-
const diagnostic_message_arg_info& arg_info = message_info.args[arg_index];
119+
const diagnostic_message_arg_info& arg_info =
120+
args[narrow_cast<std::size_t>(arg_index)];
121121
const void* arg_data =
122122
reinterpret_cast<const char*>(diagnostic) + arg_info.offset();
123123
return std::make_pair(arg_data, arg_info.type);
@@ -137,7 +137,8 @@ class diagnostic_formatter : private diagnostic_formatter_base {
137137
void format(const diagnostic_info& info, const void* diagnostic);
138138

139139
void format_message(std::string_view code, diagnostic_severity severity,
140-
const diagnostic_message_info& info,
140+
translatable_message format,
141+
const diagnostic_message_args& args,
141142
const void* diagnostic);
142143
};
143144

@@ -147,28 +148,30 @@ inline void diagnostic_formatter<Derived>::format(const diagnostic_info& info,
147148
auto code_string = info.code_string();
148149
std::string_view code_string_view(code_string.data(), code_string.size());
149150

150-
this->format_message(code_string_view, info.severity, info.messages[0],
151-
diagnostic);
152-
if (info.messages[1].format.valid()) {
151+
this->format_message(code_string_view, info.severity, info.message_formats[0],
152+
info.message_args[0], diagnostic);
153+
if (info.message_formats[1].valid()) {
153154
this->format_message(code_string_view, diagnostic_severity::note,
154-
info.messages[1], diagnostic);
155+
info.message_formats[1], info.message_args[1],
156+
diagnostic);
155157
}
156158
}
157159

158160
template <class Derived>
159161
inline void diagnostic_formatter<Derived>::format_message(
160162
std::string_view code, diagnostic_severity severity,
161-
const diagnostic_message_info& info, const void* diagnostic) {
163+
translatable_message message_format, const diagnostic_message_args& args,
164+
const void* diagnostic) {
162165
static constexpr auto npos = string8_view::npos;
163166
using string8_pos = string8_view::size_type;
164167

165168
Derived* self = static_cast<Derived*>(this);
166169

167170
source_code_span origin_span =
168-
get_argument_source_code_span(info, diagnostic, 0);
171+
get_argument_source_code_span(args, diagnostic, 0);
169172
self->write_before_message(code, severity, origin_span);
170173

171-
string8_view remaining_message(translate(info.format));
174+
string8_view remaining_message(translate(message_format));
172175
string8_pos left_curly_index;
173176
while ((left_curly_index = remaining_message.find(u8'{')) != npos) {
174177
QLJS_ASSERT(left_curly_index != remaining_message.size() &&
@@ -194,16 +197,16 @@ inline void diagnostic_formatter<Derived>::format_message(
194197

195198
string8_view expanded_parameter;
196199
if (curly_content == u8"0") {
197-
expanded_parameter = this->expand_argument(info, diagnostic, 0);
200+
expanded_parameter = this->expand_argument(args, diagnostic, 0);
198201
} else if (curly_content == u8"1") {
199-
expanded_parameter = this->expand_argument(info, diagnostic, 1);
202+
expanded_parameter = this->expand_argument(args, diagnostic, 1);
200203
} else if (curly_content == u8"1:headlinese") {
201204
expanded_parameter =
202-
this->expand_argument_headlinese(info, diagnostic, 1);
205+
this->expand_argument_headlinese(args, diagnostic, 1);
203206
} else if (curly_content == u8"1:singular") {
204-
expanded_parameter = this->expand_argument_singular(info, diagnostic, 1);
207+
expanded_parameter = this->expand_argument_singular(args, diagnostic, 1);
205208
} else if (curly_content == u8"2") {
206-
expanded_parameter = this->expand_argument(info, diagnostic, 2);
209+
expanded_parameter = this->expand_argument(args, diagnostic, 2);
207210
} else {
208211
QLJS_ASSERT(false && "invalid message format: unrecognized placeholder");
209212
QLJS_UNREACHABLE();

src/quick-lint-js/diagnostic.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,16 @@ struct diagnostic_message_arg_info {
7777
diagnostic_arg_type type : (8 - offset_bits) QLJS_WORK_AROUND_GCC_BUG_105191;
7878
};
7979

80-
struct diagnostic_message_info {
81-
translatable_message format;
82-
diagnostic_message_arg_info args[3];
83-
};
80+
using diagnostic_message_args = std::array<diagnostic_message_arg_info, 3>;
8481

8582
struct diagnostic_info {
8683
std::array<char, 5> code_string() const noexcept;
8784

8885
std::uint16_t code : 14;
8986
diagnostic_severity severity : 2 QLJS_WORK_AROUND_GCC_BUG_105191;
90-
diagnostic_message_info messages[diagnostic_max_message_count];
87+
88+
translatable_message message_formats[diagnostic_max_message_count];
89+
diagnostic_message_args message_args[diagnostic_max_message_count];
9190
};
9291

9392
const diagnostic_info &get_diagnostic_info(error_type) noexcept;

0 commit comments

Comments
 (0)