Skip to content

Commit 71bd146

Browse files
backesCommit Bot
authored andcommitted
Fix overlap check in {CopyChars} and use {std::copy_n} unconditionally
This CL fixes the overlap check by using {<=} instead of {<}. This allows us to always use {std::copy_n}, which should fall back to {memcpy} internally (instead of the potentially slower {memmove} we were using before). This might also fix the regressions seen mostly on atom CPUs. R=leszeks@chromium.org Bug: chromium:1006157 Change-Id: Ib61048d65e99a9e7edac5ed894ceaf9e26ad4409 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1844781 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#64131}
1 parent cf182b0 commit 71bd146

1 file changed

Lines changed: 5 additions & 16 deletions

File tree

src/utils/memcopy.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ inline void MemsetPointer(T** dest, U* value, size_t counter) {
198198
}
199199

200200
// Copy from 8bit/16bit chars to 8bit/16bit chars. Values are zero-extended if
201-
// needed. Ranges are not allowed to overlap unless the type sizes match (hence
202-
// {memmove} is used internally).
201+
// needed. Ranges are not allowed to overlap.
203202
// The separate declaration is needed for the V8_NONNULL, which is not allowed
204203
// on a definition.
205204
template <typename SrcType, typename DstType>
@@ -210,27 +209,17 @@ void CopyChars(DstType* dst, const SrcType* src, size_t count) {
210209
STATIC_ASSERT(std::is_integral<SrcType>::value);
211210
STATIC_ASSERT(std::is_integral<DstType>::value);
212211

213-
// If the size of {SrcType} and {DstType} matches, we switch to the more
214-
// general and potentially faster {memmove}. Note that this decision is made
215-
// statically at compile time.
216-
// This {memmove} also allows to pass overlapping ranges if the sizes match.
217-
// We probably should not call {CopyChars} with overlapping ranges, but
218-
// unfortunately we sometimes do.
219-
if (sizeof(SrcType) == sizeof(DstType)) {
220-
memmove(dst, src, count * sizeof(SrcType));
221-
return;
222-
}
223-
224-
using SrcTypeUnsigned = typename std::make_unsigned<SrcType>::type;
225-
using DstTypeUnsigned = typename std::make_unsigned<DstType>::type;
226212
#ifdef DEBUG
227213
// Check for no overlap, otherwise {std::copy_n} cannot be used.
228214
Address src_start = reinterpret_cast<Address>(src);
229215
Address src_end = src_start + count * sizeof(SrcType);
230216
Address dst_start = reinterpret_cast<Address>(dst);
231217
Address dst_end = dst_start + count * sizeof(DstType);
232-
DCHECK(src_end < dst_start || dst_end < src_start);
218+
DCHECK(src_end <= dst_start || dst_end <= src_start);
233219
#endif
220+
221+
using SrcTypeUnsigned = typename std::make_unsigned<SrcType>::type;
222+
using DstTypeUnsigned = typename std::make_unsigned<DstType>::type;
234223
std::copy_n(reinterpret_cast<const SrcTypeUnsigned*>(src), count,
235224
reinterpret_cast<DstTypeUnsigned*>(dst));
236225
}

0 commit comments

Comments
 (0)