Skip to content

Commit

Permalink
#440: implement vmx_strchr() for JS; expand jsstr to use vmx_memchr()…
Browse files Browse the repository at this point in the history
… for js_strchr_limit Latin-1 strings
  • Loading branch information
classilla committed Sep 29, 2017
1 parent 9ba7a90 commit 9d4ebbc
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
5 changes: 4 additions & 1 deletion js/src/builtin/Intl.cpp
Expand Up @@ -41,6 +41,9 @@

#include "vm/NativeObject-inl.h"

#include "mozilla-config.h"
#include "plvmx.h"

using namespace js;

using mozilla::IsFinite;
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions js/src/jsstr.cpp
Expand Up @@ -4722,11 +4722,25 @@ js_strchr_limit(const CharT* s, char16_t c, const CharT* limit)
return nullptr;
}

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

template const char16_t*
js_strchr_limit(const char16_t* s, char16_t c, const char16_t* limit);

char16_t*
js::InflateString(ExclusiveContext* cx, const char* bytes, size_t* lengthp)
Expand Down
3 changes: 3 additions & 0 deletions nsprpub/lib/libc/include/plvmx.h
Expand Up @@ -15,20 +15,23 @@ 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)
}
#endif

#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)
#else
#define VMX_HASCHR(a,b,c) (!!memchr(a,b,c))
#endif
#define VMX_MEMCHR memchr
#define VMX_STRCHR strchr
#endif

#endif
55 changes: 55 additions & 0 deletions nsprpub/lib/libc/src/plvmx.c
Expand Up @@ -117,3 +117,58 @@ void *vmx_memchr(const void *b, int c, size_t length) {
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;
}

0 comments on commit 9d4ebbc

Please sign in to comment.