Skip to content

Commit 8068edd

Browse files
committed
Optimize buffering_error_reporter::report_impl
Optimize report_impl for binary size by using memcpy instead of a switch statement. On my machine, this shrinks quick-lint-js-vscode-node_darwin-x64.node from 902 KiB to 866 KiB. This commit should not change behavior.
1 parent 82a9261 commit 8068edd

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

src/buffering-error-reporter.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace quick_lint_js {
1313
struct buffering_error_reporter::impl {
1414
struct any_error {
1515
union underlying_error {
16+
explicit underlying_error() noexcept {}
17+
1618
#define QLJS_ERROR_TYPE(name, code, struct_body, format) \
1719
::quick_lint_js::name name; \
1820
static_assert(std::is_trivially_copyable_v<::quick_lint_js::name>, \
@@ -40,18 +42,16 @@ buffering_error_reporter &buffering_error_reporter::operator=(
4042
buffering_error_reporter::~buffering_error_reporter() = default;
4143

4244
void buffering_error_reporter::report_impl(error_type type, void *error) {
43-
// TODO(strager): memcpy instead of switching.
44-
switch (type) {
45-
#define QLJS_ERROR_TYPE(name, code, struct_body, format) \
46-
case error_type::name: \
47-
this->impl_->errors_.push_back(impl::any_error{ \
48-
.type = error_type::name, \
49-
.error = {.name = *reinterpret_cast<const name *>(error)}, \
50-
}); \
51-
break;
52-
QLJS_X_ERROR_TYPES
45+
static constexpr unsigned char error_sizes[] = {
46+
#define QLJS_ERROR_TYPE(name, code, struct_body, format) \
47+
sizeof(::quick_lint_js::name),
48+
QLJS_X_ERROR_TYPES
5349
#undef QLJS_ERROR_TYPE
54-
}
50+
};
51+
52+
impl::any_error &e = this->impl_->errors_.emplace_back();
53+
e.type = type;
54+
std::memcpy(&e.error, error, error_sizes[static_cast<std::ptrdiff_t>(type)]);
5555
}
5656

5757
void buffering_error_reporter::copy_into(error_reporter *other) const {

0 commit comments

Comments
 (0)