Skip to content

Commit

Permalink
src: simplify alignment-handling code
Browse files Browse the repository at this point in the history
Use a common function to handle alignment computations in
multiple places.

PR-URL: #33884
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
Reviewed-By: Tobias Nießen <[email protected]>
  • Loading branch information
addaleax authored and codebytere committed Jun 30, 2020
1 parent eb2e31e commit e8cbefe
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 15 deletions.
4 changes: 1 addition & 3 deletions src/node_http2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<char*>(
RoundUp(reinterpret_cast<uintptr_t>(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<nghttp2_origin_entry*>(start);
Expand Down
3 changes: 1 addition & 2 deletions src/node_http_common-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
count_ * sizeof(nv_t) +
header_string_len);

char* start = reinterpret_cast<char*>(
RoundUp(reinterpret_cast<uintptr_t>(*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<nv_t*>(start);

Expand Down
6 changes: 2 additions & 4 deletions src/string_bytes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<uintptr_t>(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<uint16_t*>(buf + sizeof(*dst) - alignment);
CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);

// Write all but the last char
Expand Down
9 changes: 3 additions & 6 deletions src/util-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ void SwapBytes16(char* data, size_t nbytes) {
CHECK_EQ(nbytes % 2, 0);

#if defined(_MSC_VER)
int align = reinterpret_cast<uintptr_t>(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<uint16_t*>(data);
size_t len16 = nbytes / sizeof(*data16);
Expand All @@ -232,9 +231,8 @@ void SwapBytes32(char* data, size_t nbytes) {
CHECK_EQ(nbytes % 4, 0);

#if defined(_MSC_VER)
int align = reinterpret_cast<uintptr_t>(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<uint32_t*>(data);
size_t len32 = nbytes / sizeof(*data32);
for (size_t i = 0; i < len32; i++) {
Expand All @@ -256,8 +254,7 @@ void SwapBytes64(char* data, size_t nbytes) {
CHECK_EQ(nbytes % 8, 0);

#if defined(_MSC_VER)
int align = reinterpret_cast<uintptr_t>(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<uint64_t*>(data);
size_t len64 = nbytes / sizeof(*data64);
Expand Down
7 changes: 7 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T, typename U>
constexpr T* AlignUp(T* ptr, U alignment) {
return reinterpret_cast<T*>(
RoundUp(reinterpret_cast<uintptr_t>(ptr), alignment));
}

class SlicedArguments : public MaybeStackBuffer<v8::Local<v8::Value>> {
public:
inline explicit SlicedArguments(
Expand Down

0 comments on commit e8cbefe

Please sign in to comment.