#440: implement vmx_strchr() for JS; expand jsstr to use vmx_memchr() for js_strchr_limit Latin-1 strings

This commit is contained in:
Cameron Kaiser 2017-09-29 09:09:02 -07:00
parent 9ba7a9029c
commit 9d4ebbc228
4 changed files with 79 additions and 4 deletions

View File

@ -41,6 +41,9 @@
#include "vm/NativeObject-inl.h"
#include "mozilla-config.h"
#include "plvmx.h"
using namespace js;
using mozilla::IsFinite;
@ -452,7 +455,7 @@ intl_availableLocales(JSContext* cx, CountAvailable countAvailable,
if (!lang)
return false;
char* p;
while ((p = strchr(lang, '_')))
while ((p = VMX_STRCHR(lang, '_')))
*p = '-';
RootedAtom a(cx, Atomize(cx, lang, strlen(lang)));
if (!a)

View File

@ -4722,12 +4722,26 @@ js_strchr_limit(const CharT* s, char16_t c, const CharT* limit)
return nullptr;
}
template const Latin1Char*
js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit);
template const char16_t*
js_strchr_limit(const char16_t* s, char16_t c, const char16_t* limit);
#ifdef TENFOURFOX_VMX
#warning using VMX latin-1 js_strchr_limit
template <> const Latin1Char *
js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit)
{
return (const Latin1Char *)VMX_MEMCHR((const void *)s, c,
(1 + (uint32_t)limit - (uint32_t)s));
}
#else
#warning using template latin-1 js_strchr_limit
template const Latin1Char*
js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit);
#endif
char16_t*
js::InflateString(ExclusiveContext* cx, const char* bytes, size_t* lengthp)
{

View File

@ -15,6 +15,7 @@ extern "C" {
int vmx_haschr(const void *b, int c, size_t len);
void *vmx_memchr(const void *b, int c, size_t len);
char *vmx_strchr(const char *p, int ch);
#if defined (__cplusplus)
}
@ -22,6 +23,7 @@ void *vmx_memchr(const void *b, int c, size_t len);
#define VMX_HASCHR vmx_haschr
#define VMX_MEMCHR vmx_memchr
#define VMX_STRCHR vmx_strchr
#else
#if defined (__cplusplus)
#define VMX_HASCHR(a,b,c) (memchr(a,b,c) != nullptr)
@ -29,6 +31,7 @@ void *vmx_memchr(const void *b, int c, size_t len);
#define VMX_HASCHR(a,b,c) (!!memchr(a,b,c))
#endif
#define VMX_MEMCHR memchr
#define VMX_STRCHR strchr
#endif
#endif

View File

@ -117,3 +117,58 @@ foundResult:
fprintf(stderr, "failed vmx_memchr()\n");
return NULL;
}
char *vmx_strchr(const char *p, int ch) {
unsigned char c = (unsigned char)ch;
unsigned int val;
if ((uint32_t)p & 15) {
for (;((uint32_t)p & 15);++p) {
if (*p == c) return ((char *)p);
if (*p == '\0') return NULL;
}
}
unsigned int mashedByte = (c << 24) |
(c << 16) |
(c << 8) | c;
const vector unsigned char searchVector = (vector unsigned int){
mashedByte, mashedByte, mashedByte, mashedByte};
const vector unsigned char nullVector = vec_splat_u8(0);
for(; ; p+=16) {
const vector unsigned char *w = (const vector unsigned char*)p;
if (vec_any_eq(*w, searchVector)) break;
if (vec_any_eq(*w, nullVector)) return NULL;
}
// Some byte has the result; look in groups of 4 to find which one.
// Unroll the loop.
val = *(unsigned int*)p;
if (((val >> 24) & 0xFF) == c) return (void *)p;
if (((val >> 16) & 0xFF) == c) return (void *)(1 + p);
if (((val >> 8) & 0xFF) == c) return (void *)(2 + p);
if ((val & 0xFF) == c) return (void *)(3 + p);
p += 4;
val = *(unsigned int*)p;
if (((val >> 24) & 0xFF) == c) return (void *)p;
if (((val >> 16) & 0xFF) == c) return (void *)(1 + p);
if (((val >> 8) & 0xFF) == c) return (void *)(2 + p);
if ((val & 0xFF) == c) return (void *)(3 + p);
p += 4;
val = *(unsigned int*)p;
if (((val >> 24) & 0xFF) == c) return (void *)p;
if (((val >> 16) & 0xFF) == c) return (void *)(1 + p);
if (((val >> 8) & 0xFF) == c) return (void *)(2 + p);
if ((val & 0xFF) == c) return (void *)(3 + p);
p += 4;
val = *(unsigned int*)p;
if (((val >> 24) & 0xFF) == c) return (void *)p;
if (((val >> 16) & 0xFF) == c) return (void *)(1 + p);
if (((val >> 8) & 0xFF) == c) return (void *)(2 + p);
if ((val & 0xFF) == c) return (void *)(3 + p);
// unreachable
fprintf(stderr, "failed vmx_strchr()\n");
return NULL;
}