summaryrefslogtreecommitdiff
path: root/deps/v8/src/utils/memcopy.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/utils/memcopy.h')
-rw-r--r--deps/v8/src/utils/memcopy.h331
1 files changed, 24 insertions, 307 deletions
diff --git a/deps/v8/src/utils/memcopy.h b/deps/v8/src/utils/memcopy.h
index c1a0afbcb4..7e1b8539df 100644
--- a/deps/v8/src/utils/memcopy.h
+++ b/deps/v8/src/utils/memcopy.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <algorithm>
#include "src/base/logging.h"
#include "src/base/macros.h"
@@ -55,17 +56,8 @@ V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src,
memmove(dest, src, size);
}
-using MemCopyUint16Uint8Function = void (*)(uint16_t* dest, const uint8_t* src,
- size_t size);
-extern MemCopyUint16Uint8Function memcopy_uint16_uint8_function;
-void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
- size_t chars);
// For values < 12, the assembler function is slower than the inlined C code.
const int kMinComplexConvertMemCopy = 12;
-V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src,
- size_t size) {
- (*memcopy_uint16_uint8_function)(dest, src, size);
-}
#elif defined(V8_HOST_ARCH_MIPS)
using MemCopyUint8Function = void (*)(uint8_t* dest, const uint8_t* src,
size_t size);
@@ -109,6 +101,7 @@ inline void CopyImpl(T* dst_ptr, const T* src_ptr, size_t count) {
DCHECK(((src <= dst) && ((src + count * kTWordSize) <= dst)) ||
((dst <= src) && ((dst + count * kTWordSize) <= src)));
#endif
+ if (count == 0) return;
// Use block copying MemCopy if the segment we're copying is
// enough to justify the extra call/setup overhead.
@@ -204,308 +197,32 @@ inline void MemsetPointer(T** dest, U* value, size_t counter) {
reinterpret_cast<Address>(value), counter);
}
-template <typename sourcechar, typename sinkchar>
-V8_INLINE static void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src,
- size_t chars);
-#if defined(V8_HOST_ARCH_ARM)
-V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src,
- size_t chars);
-V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src,
- size_t chars);
-V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
- size_t chars);
-#elif defined(V8_HOST_ARCH_MIPS)
-V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src,
- size_t chars);
-V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
- size_t chars);
-#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390)
-V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src,
- size_t chars);
-V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
- size_t chars);
-#endif
-
-// Copy from 8bit/16bit chars to 8bit/16bit chars.
-template <typename sourcechar, typename sinkchar>
-V8_INLINE void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars);
-
-template <typename sourcechar, typename sinkchar>
-void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars) {
- DCHECK_LE(sizeof(sourcechar), 2);
- DCHECK_LE(sizeof(sinkchar), 2);
- if (sizeof(sinkchar) == 1) {
- if (sizeof(sourcechar) == 1) {
- CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
- reinterpret_cast<const uint8_t*>(src), chars);
- } else {
- CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
- reinterpret_cast<const uint16_t*>(src), chars);
- }
- } else {
- if (sizeof(sourcechar) == 1) {
- CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
- reinterpret_cast<const uint8_t*>(src), chars);
- } else {
- CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
- reinterpret_cast<const uint16_t*>(src), chars);
- }
- }
-}
-
-template <typename sourcechar, typename sinkchar>
-void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, size_t chars) {
- sinkchar* limit = dest + chars;
- if ((sizeof(*dest) == sizeof(*src)) &&
- (chars >= kMinComplexMemCopy / sizeof(*dest))) {
- MemCopy(dest, src, chars * sizeof(*dest));
- } else {
- while (dest < limit) *dest++ = static_cast<sinkchar>(*src++);
- }
-}
+// Copy from 8bit/16bit chars to 8bit/16bit chars. Values are zero-extended if
+// needed. Ranges are not allowed to overlap.
+// The separate declaration is needed for the V8_NONNULL, which is not allowed
+// on a definition.
+template <typename SrcType, typename DstType>
+void CopyChars(DstType* dst, const SrcType* src, size_t count) V8_NONNULL(1, 2);
-#if defined(V8_HOST_ARCH_ARM)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- case 2:
- memcpy(dest, src, 2);
- break;
- case 3:
- memcpy(dest, src, 3);
- break;
- case 4:
- memcpy(dest, src, 4);
- break;
- case 5:
- memcpy(dest, src, 5);
- break;
- case 6:
- memcpy(dest, src, 6);
- break;
- case 7:
- memcpy(dest, src, 7);
- break;
- case 8:
- memcpy(dest, src, 8);
- break;
- case 9:
- memcpy(dest, src, 9);
- break;
- case 10:
- memcpy(dest, src, 10);
- break;
- case 11:
- memcpy(dest, src, 11);
- break;
- case 12:
- memcpy(dest, src, 12);
- break;
- case 13:
- memcpy(dest, src, 13);
- break;
- case 14:
- memcpy(dest, src, 14);
- break;
- case 15:
- memcpy(dest, src, 15);
- break;
- default:
- MemCopy(dest, src, chars);
- break;
- }
-}
-
-void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, size_t chars) {
- if (chars >= static_cast<size_t>(kMinComplexConvertMemCopy)) {
- MemCopyUint16Uint8(dest, src, chars);
- } else {
- MemCopyUint16Uint8Wrapper(dest, src, chars);
- }
-}
+template <typename SrcType, typename DstType>
+void CopyChars(DstType* dst, const SrcType* src, size_t count) {
+ STATIC_ASSERT(std::is_integral<SrcType>::value);
+ STATIC_ASSERT(std::is_integral<DstType>::value);
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- case 2:
- memcpy(dest, src, 4);
- break;
- case 3:
- memcpy(dest, src, 6);
- break;
- case 4:
- memcpy(dest, src, 8);
- break;
- case 5:
- memcpy(dest, src, 10);
- break;
- case 6:
- memcpy(dest, src, 12);
- break;
- case 7:
- memcpy(dest, src, 14);
- break;
- default:
- MemCopy(dest, src, chars * sizeof(*dest));
- break;
- }
-}
-
-#elif defined(V8_HOST_ARCH_MIPS)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
- if (chars < kMinComplexMemCopy) {
- memcpy(dest, src, chars);
- } else {
- MemCopy(dest, src, chars);
- }
-}
-
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
- if (chars < kMinComplexMemCopy) {
- memcpy(dest, src, chars * sizeof(*dest));
- } else {
- MemCopy(dest, src, chars * sizeof(*dest));
- }
-}
-#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390)
-#define CASE(n) \
- case n: \
- memcpy(dest, src, n); \
- break
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- CASE(2);
- CASE(3);
- CASE(4);
- CASE(5);
- CASE(6);
- CASE(7);
- CASE(8);
- CASE(9);
- CASE(10);
- CASE(11);
- CASE(12);
- CASE(13);
- CASE(14);
- CASE(15);
- CASE(16);
- CASE(17);
- CASE(18);
- CASE(19);
- CASE(20);
- CASE(21);
- CASE(22);
- CASE(23);
- CASE(24);
- CASE(25);
- CASE(26);
- CASE(27);
- CASE(28);
- CASE(29);
- CASE(30);
- CASE(31);
- CASE(32);
- CASE(33);
- CASE(34);
- CASE(35);
- CASE(36);
- CASE(37);
- CASE(38);
- CASE(39);
- CASE(40);
- CASE(41);
- CASE(42);
- CASE(43);
- CASE(44);
- CASE(45);
- CASE(46);
- CASE(47);
- CASE(48);
- CASE(49);
- CASE(50);
- CASE(51);
- CASE(52);
- CASE(53);
- CASE(54);
- CASE(55);
- CASE(56);
- CASE(57);
- CASE(58);
- CASE(59);
- CASE(60);
- CASE(61);
- CASE(62);
- CASE(63);
- CASE(64);
- default:
- memcpy(dest, src, chars);
- break;
- }
-}
-#undef CASE
+#ifdef DEBUG
+ // Check for no overlap, otherwise {std::copy_n} cannot be used.
+ Address src_start = reinterpret_cast<Address>(src);
+ Address src_end = src_start + count * sizeof(SrcType);
+ Address dst_start = reinterpret_cast<Address>(dst);
+ Address dst_end = dst_start + count * sizeof(DstType);
+ DCHECK(src_end <= dst_start || dst_end <= src_start);
+#endif
-#define CASE(n) \
- case n: \
- memcpy(dest, src, n * 2); \
- break
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- CASE(2);
- CASE(3);
- CASE(4);
- CASE(5);
- CASE(6);
- CASE(7);
- CASE(8);
- CASE(9);
- CASE(10);
- CASE(11);
- CASE(12);
- CASE(13);
- CASE(14);
- CASE(15);
- CASE(16);
- CASE(17);
- CASE(18);
- CASE(19);
- CASE(20);
- CASE(21);
- CASE(22);
- CASE(23);
- CASE(24);
- CASE(25);
- CASE(26);
- CASE(27);
- CASE(28);
- CASE(29);
- CASE(30);
- CASE(31);
- CASE(32);
- default:
- memcpy(dest, src, chars * 2);
- break;
- }
+ using SrcTypeUnsigned = typename std::make_unsigned<SrcType>::type;
+ using DstTypeUnsigned = typename std::make_unsigned<DstType>::type;
+ std::copy_n(reinterpret_cast<const SrcTypeUnsigned*>(src), count,
+ reinterpret_cast<DstTypeUnsigned*>(dst));
}
-#undef CASE
-#endif
} // namespace internal
} // namespace v8