Skip to content

Commit 5d3d960

Browse files
committed
feature: dynamically enable the STRHASHCRC32 optimization.
1 parent 8872ce4 commit 5d3d960

File tree

8 files changed

+50
-45
lines changed

8 files changed

+50
-45
lines changed

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ before_install:
8080
- export CXX=g++-5
8181

8282
install:
83-
- if [[ "$(uname -m)" == "x86_64" ]]; then XCFLAGS="$XCFLAGS -msse4.2"; fi
84-
- if [[ "$(uname -m)" == "aarch64" ]]; then XCFLAGS="$XCFLAGS -march=armv8-a+crc"; fi
8583
- make -j$JOBS CCDEBUG=-g Q= PREFIX=$PREFIX XCFLAGS="$XCFLAGS" >build.log 2>&1 || (cat build.log && exit 1)
8684
- make install PREFIX=$PREFIX >build.log 2>&1 || (cat build.log && exit 1)
8785
- export PATH="$PREFIX/bin:$PATH"

README.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,8 @@ local newstate = jit.prngstate(123456)
163163
**syntax:** *ok = jit.crc32()*
164164

165165
Returns a boolean value indicating if the current architecture supports a CRC32
166-
instruction set.
167-
168-
CRC32 support will be checked at runtime if LuaJIT was compiled with `-msse4.2`
169-
on x64 architectures, or `-march=armv8-a+crc` on ARM64.
166+
instruction set. CRC32 support will be checked at runtime on x64 and ARM64
167+
platforms.
170168

171169
CRC32 support allows for this branch to use an optimized string hashing
172170
algorithm. See the [String hashing](#string-hashing) section for details on
@@ -285,10 +283,8 @@ but makes hash collision attacks harder for strings up to 127 bytes of size
285283
(see `lj_str_new()`).
286284

287285
This optimization is only available for x64 and ARM64 architectures, and will
288-
be enabled if:
289-
290-
1. LuaJIT is compiled with `-msse4.2` on x64, or `-march=armv8-a+crc` on ARM64.
291-
2. A CRC32 instruction set is detected at runtime (see [jit.crc32](#jitcrc32)).
286+
be enabled if a CRC32 instruction set is detected at runtime (see
287+
[jit.crc32](#jitcrc32)).
292288

293289
**Note:** This optimization can be disabled by compiling LuaJIT with
294290
`-DLJ_OR_DISABLE_STRHASHCRC32`.

src/Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,15 @@ ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
521521
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
522522
ALL_RM= $(ALL_T) $(ALL_GEN) *.o host/*.o $(WIN_RM)
523523

524+
ifeq (x64,$(TARGET_LJARCH))
525+
lj_str_hash-CFLAGS = -msse4.2
526+
endif
527+
ifeq (arm64,$(TARGET_LJARCH))
528+
lj_str_hash-CFLAGS = -march=armv8-a+crc
529+
endif
530+
531+
F_CFLAGS = $($(patsubst %.c,%-CFLAGS,$<))
532+
524533
##############################################################################
525534
# Build mode handling.
526535
##############################################################################
@@ -685,8 +694,8 @@ lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
685694

686695
%.o: %.c
687696
$(E) "CC $@"
688-
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
689-
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
697+
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) $(F_CFLAGS) -c -o $(@:.o=_dyn.o) $<
698+
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) $(F_CFLAGS) -c -o $@ $<
690699

691700
%.o: %.S
692701
$(E) "ASM $@"

src/lib_jit.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,7 @@ LJLIB_CF(jit_prngstate)
159159

160160
LJLIB_CF(jit_crc32)
161161
{
162-
#if LJ_OR_STRHASHCRC32
163162
setboolV(L->top++, lj_check_crc32_support());
164-
#else
165-
setboolV(L->top++, 0);
166-
#endif
167163
return 1;
168164
}
169165

src/lj_arch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ extern void *LJ_WIN_LOADLIBA(const char *path);
616616
#endif
617617

618618
/* Optimized string hashing, added by OpenResty. */
619-
#if (LUAJIT_TARGET == LUAJIT_ARCH_X64 && defined(__SSE4_2__) || LUAJIT_TARGET == LUAJIT_ARCH_ARM64 && __ARM_FEATURE_CRC32) && defined(__GNUC__)
619+
#if defined(__GNUC__) && (LUAJIT_TARGET == LUAJIT_ARCH_X64 || LUAJIT_TARGET == LUAJIT_ARCH_ARM64)
620620
#ifndef LJ_OR_DISABLE_STRHASHCRC32
621621
#define LJ_OR_STRHASHCRC32 1
622622
#endif

src/lj_str_hash.c

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,39 @@
1313

1414
#include "lj_str_hash.h"
1515

16-
#if LJ_OR_STRHASHCRC32
16+
#if LUAJIT_TARGET == LUAJIT_ARCH_X64
17+
#include "lj_vm.h"
18+
19+
#ifndef F_CPU_SSE4_2
20+
#define F_CPU_SSE4_2 (1 << 20)
21+
#endif
22+
23+
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
24+
#include <sys/auxv.h>
25+
#include <errno.h>
26+
27+
#ifndef HWCAP_CRC32
28+
#define HWCAP_CRC32 (1 << 7)
29+
#endif
30+
#endif
1731

32+
#if LJ_OR_STRHASHCRC32
1833
#include <sys/types.h>
1934
#include <unistd.h>
2035
#include <time.h>
21-
#include "lj_vm.h"
2236

2337
#if LUAJIT_TARGET == LUAJIT_ARCH_X64
2438
#include <smmintrin.h>
2539

2640
#define lj_crc32_u32 _mm_crc32_u32
2741
#define lj_crc32_u64 _mm_crc32_u64
2842

29-
#ifndef F_CPU_SSE4_2
30-
#define F_CPU_SSE4_2 (1 << 20)
31-
#endif
32-
3343
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
34-
#include <sys/auxv.h>
3544
#include <arm_acle.h>
36-
#include <errno.h>
3745

3846
#define lj_crc32_u32 __crc32cw
3947
#define lj_crc32_u64 __crc32cd
4048

41-
#ifndef HWCAP_CRC32
42-
#define HWCAP_CRC32 (1 << 7)
43-
#endif
44-
4549
#else
4650
#error "LJ_OR_STRHASHCRC32 not supported on this architecture"
4751
#endif
@@ -288,20 +292,6 @@ static void lj_str_hash_init_random(void)
288292

289293
#undef POW2_MASK
290294

291-
LJ_FUNC unsigned char lj_check_crc32_support()
292-
{
293-
#if LUAJIT_TARGET == LUAJIT_ARCH_X64
294-
uint32_t features[4];
295-
if (lj_vm_cpuid(1, features))
296-
return (features[2] & F_CPU_SSE4_2) != 0;
297-
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
298-
uint32_t hwcap = getauxval(AT_HWCAP);
299-
if (hwcap != ENOENT)
300-
return (hwcap & HWCAP_CRC32) != 0;
301-
#endif
302-
return 0;
303-
}
304-
305295
LJ_FUNC void lj_init_strhashfn(global_State *g)
306296
{
307297
static StrHashFunction strhashfn;
@@ -318,6 +308,20 @@ LJ_FUNC void lj_init_strhashfn(global_State *g)
318308

319309
#endif
320310

311+
LJ_FUNC unsigned char lj_check_crc32_support()
312+
{
313+
#if LUAJIT_TARGET == LUAJIT_ARCH_X64
314+
uint32_t features[4];
315+
if (lj_vm_cpuid(1, features))
316+
return (features[2] & F_CPU_SSE4_2) != 0;
317+
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
318+
uint32_t hwcap = getauxval(AT_HWCAP);
319+
if (hwcap != ENOENT)
320+
return (hwcap & HWCAP_CRC32) != 0;
321+
#endif
322+
return 0;
323+
}
324+
321325
LJ_FUNC MSize lj_str_hash_orig(const char *str, size_t lenx)
322326
{
323327
MSize len = (MSize)lenx;

src/lj_str_hash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#include "lj_obj.h"
55

66
LJ_FUNC MSize lj_str_hash_orig(const char *str, size_t lenx);
7+
LJ_FUNC unsigned char lj_check_crc32_support();
78

89
#if LJ_OR_STRHASHCRC32
9-
LJ_FUNC unsigned char lj_check_crc32_support();
1010
LJ_FUNC void lj_init_strhashfn(global_State *g);
1111
#endif
1212

t/strhashcrc32.t

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ __DATA__
1313
--- lua
1414
jit.off()
1515
16-
if jit.crc32() then
16+
if os.getenv("NO_STRHASHCRC32") == "1" then
17+
assert(jit.strhashcrc32() == false, "strhashcrc32 should be disabled (LJ_OR_DISABLE_STRHASHCRC32)")
18+
elseif jit.crc32() then
1719
assert(jit.strhashcrc32() == true, "strhashcrc32 should be enabled")
1820
else
1921
assert(jit.strhashcrc32() == false, "strhashcrc32 should be disabled")

0 commit comments

Comments
 (0)