From 168dd9f1470eba9729ba0a3a1bff9caf4ae600d3 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Wed, 9 Aug 2017 21:02:02 -0700 Subject: [PATCH] #406: add vmx_haschr and use it --- gfx/thebes/gfxFont.cpp | 8 +++--- nsprpub/lib/libc/include/plvmx.h | 7 +++++ nsprpub/lib/libc/src/plvmx.c | 44 +++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index aa75a5d29..05540292a 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -2745,7 +2745,7 @@ inline static bool IsChar8Bit(char16_t aCh) { return aCh < 0x100; } inline static bool HasSpaces(const uint8_t *aString, uint32_t aLen) { - return VMX_MEMCHR(aString, 0x20, aLen) != nullptr; + return VMX_HASCHR(aString, 0x20, aLen); } inline static bool HasSpaces(const char16_t *aString, uint32_t aLen) @@ -2857,7 +2857,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext, aRunScript, aVertical, aTextRun); - if (!ok) { + if (MOZ_UNLIKELY(!ok)) { return false; } } else if (length > 0) { @@ -2875,7 +2875,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext, hash, aRunScript, aVertical, appUnitsPerDevUnit, wordFlags, tp); - if (sw) { + if (MOZ_LIKELY(sw)) { aTextRun->CopyGlyphDataFrom(sw, aRunStart + wordStart); } else { return false; // failed, presumably out of memory? @@ -2905,7 +2905,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext, gfxShapedWord::HashMix(0, boundary), aRunScript, aVertical, appUnitsPerDevUnit, flags | gfxTextRunFactory::TEXT_IS_8BIT, tp); - if (sw) { + if (MOZ_LIKELY(sw)) { aTextRun->CopyGlyphDataFrom(sw, aRunStart + i); } else { return false; diff --git a/nsprpub/lib/libc/include/plvmx.h b/nsprpub/lib/libc/include/plvmx.h index 5291e5dee..b4a651c8a 100644 --- a/nsprpub/lib/libc/include/plvmx.h +++ b/nsprpub/lib/libc/include/plvmx.h @@ -13,14 +13,21 @@ extern "C" { #endif +int vmx_haschr(const void *b, int c, size_t len); void *vmx_memchr(const void *b, int c, size_t len); #if defined (__cplusplus) } #endif +#define VMX_HASCHR vmx_haschr #define VMX_MEMCHR vmx_memchr #else +#if defined (__cplusplus) +#define VMX_HASCHR(a,b,c) (memchr(a,b,c) != nullptr) +#else +#define VMX_HASCHR(a,b,c) (!!memchr(a,b,c)) +#endif #define VMX_MEMCHR memchr #endif diff --git a/nsprpub/lib/libc/src/plvmx.c b/nsprpub/lib/libc/src/plvmx.c index df1a8ff0b..dd80351b3 100644 --- a/nsprpub/lib/libc/src/plvmx.c +++ b/nsprpub/lib/libc/src/plvmx.c @@ -3,12 +3,50 @@ /* VMX/AltiVec specific libc functions for TenFourFox. */ -void *vmx_memchr(const void *b, int c, size_t length) { - -/* From: +/* The below is from https://github.com/ridiculousfish/HexFiend/blob/4d5bcee5715f5f288649f7471d1da5bd06376f46/framework/sources/HFFastMemchr.m with some optimizations and fixes. */ +int vmx_haschr(const void *b, int c, size_t length) { + const unsigned char *haystack = (const unsigned char *)b; + unsigned char needle = (unsigned char)c; + + unsigned prefixLength = (unsigned)((16 - ((unsigned long)haystack) % 16) % 16); + unsigned suffixLength = (unsigned)(((unsigned long)(haystack + length)) % 16); + // It is possible for altivecLength to be < 0 for short strings. + int altivecLength = length - prefixLength - suffixLength; + + if (altivecLength < 16) { + while (length--) { + if (*haystack == needle) return 1; + haystack++; + } + return 0; + } + + size_t numVectors = altivecLength >> 4; + while (prefixLength--) { + if (*haystack == needle) return 1; + haystack++; + } + + unsigned int mashedByte = (needle << 24 ) | (needle << 16) | (needle << 8) | needle; + const vector unsigned char searchVector = (vector unsigned int){mashedByte, mashedByte, mashedByte, mashedByte}; + while (numVectors--) { + if (vec_any_eq(*(const vector unsigned char*)haystack, searchVector)) + return 1; + haystack += 16; + } + + while (suffixLength--) { + if (*haystack == needle) return 1; + haystack++; + } + + return 0; +} + +void *vmx_memchr(const void *b, int c, size_t length) { const unsigned char *haystack = (const unsigned char *)b; unsigned char needle = (unsigned char)c;