#406: working vmx_memchr() in NSPR, passes JS tests, runs browser

This commit is contained in:
Cameron Kaiser 2017-06-26 21:53:45 -07:00
parent 3801f0bc4a
commit 6ee93a8030
7 changed files with 109 additions and 2 deletions

View File

@ -9337,6 +9337,9 @@ ac_configure_args="$ac_configure_args --prefix=$dist"
if test "$MOZ_MEMORY"; then
ac_configure_args="$ac_configure_args --enable-jemalloc"
fi
if test "$TENFOURFOX_VMX"; then
ac_configure_args="$ac_configure_args --enable-tenfourfox-vmx"
fi
if test -n "$ZLIB_IN_MOZGLUE"; then
MOZ_ZLIB_LIBS=
fi
@ -9355,6 +9358,7 @@ export DIST
export MOZ_LINKER
export ZLIB_IN_MOZGLUE
export MOZ_MEMORY
export TENFOURFOX_VMX
if ! test -e js; then
mkdir js

View File

@ -51,6 +51,9 @@
#include "vm/StringObject-inl.h"
#include "vm/TypeInference-inl.h"
#include "mozilla-config.h"
#include "plvmx.h"
using namespace js;
using namespace js::gc;
using namespace js::unicode;
@ -1155,10 +1158,12 @@ FirstCharMatcherUnrolled(const TextChar* text, uint32_t n, const PatChar pat)
static const char*
FirstCharMatcher8bit(const char* text, uint32_t n, const char pat)
{
#if defined(__clang__)
#ifndef TENFOURFOX_VMX
#warning using non-VMX memchr
return FirstCharMatcherUnrolled<char, char>(text, n, pat);
#else
return reinterpret_cast<const char*>(memchr(text, pat, n));
#warning using VMX memchr
return reinterpret_cast<const char*>(vmx_memchr(text, pat, n));
#endif
}

View File

@ -54,6 +54,7 @@ USE_N32 = @USE_N32@
USE_X32 = @USE_X32@
USE_64 = @USE_64@
ENABLE_STRIP = @ENABLE_STRIP@
TENFOURFOX_VMX = @TENFOURFOX_VMX@
USE_PTHREADS = @USE_PTHREADS@
USE_BTHREADS = @USE_BTHREADS@

18
nsprpub/configure vendored
View File

@ -667,6 +667,7 @@ DLL_SUFFIX
LIB_SUFFIX
OBJ_SUFFIX
CPU_ARCH
TENFOURFOX_VMX
PR_MD_ARCH_DIR
PR_MD_ASFILES
PR_MD_CSRCS
@ -801,6 +802,7 @@ enable_x32
enable_64bit
enable_mdupdate
enable_cplus
enable_tenfourfox_vmx
with_arm_kuser
with_macos_sdk
enable_macos_target
@ -1465,6 +1467,7 @@ Optional Features:
--enable-macos-target=VER
Set the minimum MacOS version needed at runtime
10.2 for ppc, 10.4 for x86
--enable-tenfourfox-vmx Enable VMX SIMD features for PowerPC
--disable-os2-high-mem Disable high-memory support on OS/2
--enable-strip Enable stripping of shared libs and programs
@ -2495,6 +2498,7 @@ _HAVE_PTHREADS=
USE_PTHREADS=
USE_USER_PTHREADS=
USE_NSPR_THREADS=
TENFOURFOX_VMX=
USE_N32=
USE_X32=
USE_64=
@ -2904,6 +2908,16 @@ if test "${enable_n32+set}" = set; then :
fi
fi
# Check whether --enable-tenfourfox-vmx was given.
if test "${enable_tenfourfox_vmx+set}" = set; then :
enableval=$enable_tenfourfox_vmx; if test "$enableval" = "yes"; then
TENFOURFOX_VMX=1
else if test "$enableval" = "no"; then
TENFOURFOX_VMX=
fi
fi
fi
# Check whether --enable-x32 was given.
if test "${enable_x32+set}" = set; then :
@ -6524,6 +6538,10 @@ fi
$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
if test -n "$TENFOURFOX_VMX"; then
$as_echo "#define TENFOURFOX_VMX 1" >>confdefs.h
fi
AS='$(CC) -x assembler-with-cpp'
CFLAGS="$CFLAGS -Wall -fno-common"
case "${target_cpu}" in

View File

@ -313,6 +313,15 @@ AC_ARG_ENABLE(optimize,
MOZ_OPTIMIZE=
fi ])
AC_ARG_ENABLE(tenfourfox-vmx,
[ --enable-tenfourfox-vmx Turn on AltiVec-VMX specific options for TenFourFox ],
[ if test "$enableval" != "no"; then
AC_DEFINE(TENFOURFOX_VMX)
TENFOURFOX_VMX=1
else
TENFOURFOX_VMX=
fi ])
AC_ARG_ENABLE(debug,
[ --enable-debug[=DBG] Enable debugging (using compiler flags DBG)],
[ if test "$enableval" != "no"; then
@ -3049,6 +3058,7 @@ AC_SUBST(PR_MD_CSRCS)
AC_SUBST(PR_MD_ASFILES)
AC_SUBST(PR_MD_ARCH_DIR)
AC_SUBST(CPU_ARCH)
AC_SUBST(TENFOURFOX_VMX)
AC_SUBST(OBJ_SUFFIX)
AC_SUBST(LIB_SUFFIX)

View File

@ -39,6 +39,11 @@ LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
RELEASE_LIBS = $(TARGETS)
ifeq ($(TENFOURFOX_VMX),1)
CSRCS += plvmx.c
CFLAGS += -faltivec
endif
ifeq ($(OS_ARCH),WINNT)
RES=$(OBJDIR)/plc.res
RESNAME=plc.rc

View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include "plvmx.h"
void *vmx_memchr(const void *b, int c, size_t length) {
/* From:
https://github.com/ridiculousfish/HexFiend/blob/4d5bcee5715f5f288649f7471d1da5bd06376f46/framework/sources/HFFastMemchr.m
with some optimizations */
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 (void *)haystack;
haystack++;
}
return NULL;
}
size_t numVectors = altivecLength >> 4;
while (prefixLength--) {
if (*haystack == needle) return (void *)haystack;
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)) goto foundResult;
haystack += 16;
}
while (suffixLength--) {
if (*haystack == needle) return (void *)haystack;
haystack++;
}
return NULL;
foundResult:
;
/* some byte has the result - look in groups of 4 to find which it is */
unsigned numWords = 4;
unsigned int val;
while (numWords--) {
val = *(unsigned int*)haystack;
if (((val >> 24) & 0xFF) == needle) return (void *)haystack;
if (((val >> 16) & 0xFF) == needle) return (void *)(1 + haystack);
if (((val >> 8) & 0xFF) == needle) return (void *)(2 + haystack);
if ((val & 0xFF) == needle) return (void *)(3 + haystack);
haystack += 4;
}
/* should never get here */
fprintf(stderr, "failed vmx_memchr()\n");
return NULL;
}