From 2899588f28f4d02a61a19ecc8454ddaf14c7b6b3 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 15 Jun 2020 00:56:09 +0200 Subject: [PATCH] src: simplify alignment-handling code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a common function to handle alignment computations in multiple places. PR-URL: https://github.com/nodejs/node/pull/33884 Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius Reviewed-By: Tobias Nießen --- src/node_http2.cc | 4 +--- src/node_http_common-inl.h | 3 +-- src/string_bytes.cc | 6 ++---- src/util-inl.h | 9 +++------ src/util.h | 7 +++++++ 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/node_http2.cc b/src/node_http2.cc index 4d1309e08a1a78..de7a7f044e28c2 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -373,9 +373,7 @@ Origins::Origins( origin_string_len); // Make sure the start address is aligned appropriately for an nghttp2_nv*. - char* start = reinterpret_cast( - RoundUp(reinterpret_cast(buf_.data()), - alignof(nghttp2_origin_entry))); + char* start = AlignUp(buf_.data(), alignof(nghttp2_origin_entry)); char* origin_contents = start + (count_ * sizeof(nghttp2_origin_entry)); nghttp2_origin_entry* const nva = reinterpret_cast(start); diff --git a/src/node_http_common-inl.h b/src/node_http_common-inl.h index 54f2faf39c49bc..7cd4bdec99c3d6 100644 --- a/src/node_http_common-inl.h +++ b/src/node_http_common-inl.h @@ -31,8 +31,7 @@ NgHeaders::NgHeaders(Environment* env, v8::Local headers) { count_ * sizeof(nv_t) + header_string_len); - char* start = reinterpret_cast( - RoundUp(reinterpret_cast(*buf_), alignof(nv_t))); + char* start = AlignUp(buf_.out(), alignof(nv_t)); char* header_contents = start + (count_ * sizeof(nv_t)); nv_t* const nva = reinterpret_cast(start); diff --git a/src/string_bytes.cc b/src/string_bytes.cc index e0c2d6901fc429..68c7c06d8df1de 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -273,16 +273,14 @@ size_t StringBytes::WriteUCS2(Isolate* isolate, return 0; } + uint16_t* const aligned_dst = AlignUp(dst, sizeof(*dst)); size_t nchars; - size_t alignment = reinterpret_cast(dst) % sizeof(*dst); - if (alignment == 0) { + if (aligned_dst == dst) { nchars = str->Write(isolate, dst, 0, max_chars, flags); *chars_written = nchars; return nchars * sizeof(*dst); } - uint16_t* aligned_dst = - reinterpret_cast(buf + sizeof(*dst) - alignment); CHECK_EQ(reinterpret_cast(aligned_dst) % sizeof(*dst), 0); // Write all but the last char diff --git a/src/util-inl.h b/src/util-inl.h index 6b4bdfe034d64f..1af87d492ade06 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -208,8 +208,7 @@ void SwapBytes16(char* data, size_t nbytes) { CHECK_EQ(nbytes % 2, 0); #if defined(_MSC_VER) - int align = reinterpret_cast(data) % sizeof(uint16_t); - if (align == 0) { + if (AlignUp(data, sizeof(uint16_t)) == data) { // MSVC has no strict aliasing, and is able to highly optimize this case. uint16_t* data16 = reinterpret_cast(data); size_t len16 = nbytes / sizeof(*data16); @@ -232,9 +231,8 @@ void SwapBytes32(char* data, size_t nbytes) { CHECK_EQ(nbytes % 4, 0); #if defined(_MSC_VER) - int align = reinterpret_cast(data) % sizeof(uint32_t); // MSVC has no strict aliasing, and is able to highly optimize this case. - if (align == 0) { + if (AlignUp(data, sizeof(uint32_t)) == data) { uint32_t* data32 = reinterpret_cast(data); size_t len32 = nbytes / sizeof(*data32); for (size_t i = 0; i < len32; i++) { @@ -256,8 +254,7 @@ void SwapBytes64(char* data, size_t nbytes) { CHECK_EQ(nbytes % 8, 0); #if defined(_MSC_VER) - int align = reinterpret_cast(data) % sizeof(uint64_t); - if (align == 0) { + if (AlignUp(data, sizeof(uint64_t)) == data) { // MSVC has no strict aliasing, and is able to highly optimize this case. uint64_t* data64 = reinterpret_cast(data); size_t len64 = nbytes / sizeof(*data64); diff --git a/src/util.h b/src/util.h index 8cec9a8aab956b..2a4d6e27d59d9e 100644 --- a/src/util.h +++ b/src/util.h @@ -729,6 +729,13 @@ constexpr T RoundUp(T a, T b) { return a % b != 0 ? a + b - (a % b) : a; } +// Align ptr to an `alignment`-bytes boundary. +template +constexpr T* AlignUp(T* ptr, U alignment) { + return reinterpret_cast( + RoundUp(reinterpret_cast(ptr), alignment)); +} + class SlicedArguments : public MaybeStackBuffer> { public: inline explicit SlicedArguments(