| Index: src/v8utils.h
|
| ===================================================================
|
| --- src/v8utils.h (revision 10961)
|
| +++ src/v8utils.h (working copy)
|
| @@ -198,31 +198,144 @@
|
| bool* exists,
|
| bool verbose = true);
|
|
|
| +template<typename sourcechar, typename sinkchar>
|
| +static inline void AlignedCharCopy(sinkchar* dest,
|
| + const sourcechar* src, int chars) {
|
| + #define COPY(offset) \
|
| + *(dest+offset) = static_cast<sinkchar>(*(src+offset));
|
|
|
| + int div = chars >> 4;
|
| + while ( div ) {
|
| + COPY(0) COPY(1) COPY(2) COPY(3)
|
| + COPY(4) COPY(5) COPY(6) COPY(7)
|
| + COPY(8) COPY(9) COPY(10) COPY(11)
|
| + COPY(12) COPY(13) COPY(14) COPY(15)
|
| + dest += 16;
|
| + src += 16;
|
| + div--;
|
| + }
|
|
|
| -// Copy from ASCII/16bit chars to ASCII/16bit chars.
|
| -template <typename sourcechar, typename sinkchar>
|
| -inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
|
| - sinkchar* limit = dest + chars;
|
| + #define CASE_COPY(N) \
|
| + case N : COPY(N-1)
|
| +
|
| + int mod = chars & 0xF;
|
| + switch ( mod ) {
|
| + CASE_COPY(15) CASE_COPY(14) CASE_COPY(13) CASE_COPY(12)
|
| + CASE_COPY(11) CASE_COPY(10) CASE_COPY(9) CASE_COPY(8)
|
| + CASE_COPY(7) CASE_COPY(6) CASE_COPY(5) CASE_COPY(4)
|
| + CASE_COPY(3) CASE_COPY(2) CASE_COPY(1)
|
| + break;
|
| + }
|
| +
|
| + #undef CASE_COPY
|
| + #undef COPY
|
| +}
|
| +
|
| #ifdef V8_HOST_CAN_READ_UNALIGNED
|
| - if (sizeof(*dest) == sizeof(*src)) {
|
| - if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
|
| - OS::MemCopy(dest, src, chars * sizeof(*dest));
|
| - return;
|
| - }
|
| - // Number of characters in a uintptr_t.
|
| - static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
|
| - while (dest <= limit - kStepSize) {
|
| - *reinterpret_cast<uintptr_t*>(dest) =
|
| - *reinterpret_cast<const uintptr_t*>(src);
|
| - dest += kStepSize;
|
| - src += kStepSize;
|
| - }
|
| +template<typename Char>
|
| +static inline void UnalignedCharCopy(Char* dest, const Char* src, int chars) {
|
| + int size = static_cast<int>(chars * sizeof(Char));
|
| + if ( size >= OS::kMinComplexMemCopy ) {
|
| + OS::MemCopy(dest, src, size);
|
| + return;
|
| }
|
| +
|
| + unsigned int* dest_ = reinterpret_cast<unsigned int*>(dest);
|
| + const unsigned int* src_ = reinterpret_cast<const unsigned int*>(src);
|
| + const int cell = size / sizeof(unsigned int);
|
| +
|
| + #define COPY(offset) \
|
| + *(dest_+offset) = *(src_+offset);
|
| +
|
| + // copy patch cells by 16
|
| + int div = cell >> 4;
|
| + while ( div ) {
|
| + COPY(0) COPY(1) COPY(2) COPY(3)
|
| + COPY(4) COPY(5) COPY(6) COPY(7)
|
| + COPY(8) COPY(9) COPY(10) COPY(11)
|
| + COPY(12) COPY(13) COPY(14) COPY(15)
|
| + dest_ += 16;
|
| + src_ += 16;
|
| + div--;
|
| + }
|
| +
|
| + #define CASE_COPY(N) \
|
| + case N : COPY(N-1)
|
| +
|
| + // copy left cells
|
| + int mod = cell & 0xF;
|
| + switch ( mod ) {
|
| + CASE_COPY(15) CASE_COPY(14) CASE_COPY(13) CASE_COPY(12)
|
| + CASE_COPY(11) CASE_COPY(10) CASE_COPY(9) CASE_COPY(8)
|
| + CASE_COPY(7) CASE_COPY(6) CASE_COPY(5) CASE_COPY(4)
|
| + CASE_COPY(3) CASE_COPY(2) CASE_COPY(1)
|
| + dest_ += mod;
|
| + src_ += mod;
|
| + break;
|
| + }
|
| +
|
| + // copy left chars
|
| + Char* limit = dest + chars;
|
| + dest = reinterpret_cast<Char*>(dest_);
|
| + src = reinterpret_cast<const Char*>(src_);
|
| + while ( dest < limit ) {
|
| + *dest++ = *src++;
|
| + }
|
| +
|
| + #undef CASE_COPY
|
| + #undef COPY
|
| +}
|
| #endif
|
| - while (dest < limit) {
|
| - *dest++ = static_cast<sinkchar>(*src++);
|
| +
|
| +template<typename sourcechar, typename sinkchar>
|
| +class CharCopier {
|
| + public:
|
| + static void Copy(sinkchar* dest, const sourcechar* src, int chars) {
|
| + AlignedCharCopy(dest, src, chars);
|
| }
|
| +};
|
| +
|
| +template<>
|
| +class CharCopier<char, char> {
|
| + public:
|
| + static void Copy(char* dest, const char* src, int chars) {
|
| + #ifdef V8_HOST_CAN_READ_UNALIGNED
|
| + UnalignedCharCopy(dest, src, chars);
|
| + #else
|
| + AlignedCharCopy(dest, src, chars);
|
| + #endif
|
| + }
|
| +};
|
| +
|
| +template<>
|
| +class CharCopier<uc16, uc16> {
|
| + public:
|
| + static void Copy(uc16* dest, const uc16* src, int chars) {
|
| + #ifdef V8_HOST_CAN_READ_UNALIGNED
|
| + UnalignedCharCopy(dest, src, chars);
|
| + #else
|
| + AlignedCharCopy(dest, src, chars);
|
| + #endif
|
| + }
|
| +};
|
| +
|
| +// Copy from ASCII/16bit chars to ASCII/16bit chars.
|
| +template <typename sourcechar, typename sinkchar>
|
| +static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
|
| + // return faster if chars is small
|
| + switch ( chars ) {
|
| + #define CASE_COPY(N) \
|
| + case N : *(dest+N-1) = static_cast<sinkchar>(*(src+N-1));
|
| + CASE_COPY(8) CASE_COPY(7)
|
| + CASE_COPY(6) CASE_COPY(5)
|
| + CASE_COPY(4) CASE_COPY(3)
|
| + CASE_COPY(2) CASE_COPY(1)
|
| + return;
|
| + #undef CASE_COPY
|
| + }
|
| +
|
| + // fall to copier
|
| + CharCopier<sourcechar, sinkchar>::Copy(dest, src, chars);
|
| }
|
|
|
|
|
|
|