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 62229e3c448637..b5b6cb9226f420 100644 --- a/src/util.h +++ b/src/util.h @@ -719,6 +719,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(