Skip to content

(diff name?) perl.h add SVVALIDIVX()/SVVAILDRV/SVVAILDNVX/SVVAILDPVX bitfield testers #23415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: blead
Choose a base branch
from

Conversation

bulk88
Copy link
Contributor

@bulk88 bulk88 commented Jul 8, 2025

edit: this commit originally had a misspelled in english title and misspelled in english macros, now fixed

I think the spelling and capitalization of the macros SVVALIDIVX()/SVVALIDRV/SVVALIDNVX/SVVALIDPVX could be better. But I couldn't think of anything better than what is in this commit. Anyone have ideas for better identifiers?

I cant think of much use right now for these macros as production perl code except for future improvements to CV* API, since various sv_cat*()/sv_set*() and other parts of the SVPV APIs hate dealing with CV*s. Either they have breakage, SEGVs or -DDEBUGGING only assert() fails. CV*s are ultimately POK strings considering XS AUTOLOAD sub name passing, and that prototype string grammar has a rarely used provision for random 3P strings like HTTP URLs, JSON, and REST IDLs.

Another reason I made them is, I really really don't like that SVt_PVGV sits below SVt_PVLV as a SEGV bomb. Since SVt_PVLV is the last traditional POK-able type. An algo that down cast to U8, shift, &, against a bitfield literal is much more production/runtime/speed reasonable, vs these 17 byte arrays. And XS modules will need an angel to save them from double or triple indirection to reach libperl data vars on WinOS and ELF.

SVt_PVCVs can not be passed to SvPV(); IIRC but its been a year since I tried doing that. I did prove that cv_name()/GvNAME/CvNAME are unreachable from miniperl and PP. stringifying a CV* the way croak_xs_usage()/cv_name() do it, AFAIK is impossible from PP space using a standalone libperl.


  • Add faster versions of the PL_valid_types_IVX[], PL_valid_types_PVX[], etc array tests intended for use in -O2/not -DDEBUGGING builds.

  • Currently the PL_valid_types_VX[] arrays are all 17 bytes long and only used for -DDEBUGGING assert()s in sv.h. The same information can be stored in a U32 literal integer instead. By making these macros use a U32 literal integer instead of a const array of bool/8 vars, there is no performance or overhead concerns anymore, if someone finds a reason to use these macros, in an optimized perl build. The U32 literal integers are now part of the CPU's instruction stream like in all other SV flag tests.

  • It is not known yet if there is any good reason to these faster macros, or the old slower PL_valid_types_VX[]s arrays, in an optimized blead perl or optimized stable perl. All "correct enough" code either in CORE or on CPAN already has macros or expressions using existing macros, to test whatever flags they need to test inside a SV head struct.


  • This set of changes does not require a perldelta entry.

@bulk88
Copy link
Contributor Author

bulk88 commented Jul 10, 2025

BEFORE:
my brain counted 17 bytes and 2 mem reads:

mov r11, cs:__imp_PL_valid_types_IVX read void * at PIC offset (PE .dll import table)
cmp [rax+r11], r13b read a U8 from somewhere inside PL_valid_types_IVX

45 33 ED                xor     r13d, r13d
###  ^^^ way earlier at top of func
8B 45 0C                mov     eax, [rbp+sv.sv_flags] ; offset 0x0C
4C 8B 1D 10 46 03 00    mov     r11, cs:__imp_PL_valid_types_IVX
83 E0 1F                and     eax, 1Fh
46 38 2C 18             cmp     [rax+r11], r13b
0F 85 D4 00 00 00       jnz     $failed_0

AFTER:
my brain counted 0 mem reads and 18 bytes of mach code after some asm tweaks in my head

BB 01 00 00 00          mov     ebx, 1
### ^^^ way earlier at top of func
44 8B C3                mov     r8d, ebx
8B 45 0C                mov     eax, [rbp+sv.sv_flags]
8B C8                   mov     ecx, eax ### redundant! CC is starved of x64 registers inside XS-APITest
BD E2 06 00 00          mov     ebp, 6E2h ### redundant! can't the CC write just "test    ebp, 0x6e2" ?
###  AKA   " f7 c5 e2 06 00 00       test   ebp, 0x6e2  "
41 D3 E0                shl     r8d, cl
44 85 C5                test    ebp, r8d
0F 85 E8 00 00 00       jnz     $failed_0

@bulk88 bulk88 force-pushed the faster_sanity_typechk_macros_for_pl_valid_inpvx_array branch from d1a5b41 to c1ad847 Compare July 10, 2025 09:16
@bulk88
Copy link
Contributor Author

bulk88 commented Jul 10, 2025

repushed with C++ fixes

@Leont
Copy link
Contributor

Leont commented Jul 10, 2025

s/VAILD/VALID/g?

- Add faster versions of the PL_valid_types_IVX[], PL_valid_types_PVX[],
  etc array tests intended for use in -O2/not -DDEBUGGING builds.

- Currently the PL_valid_types_*VX[] arrays are all 17 bytes long and only
  used for -DDEBUGGING assert()s in sv.h.  The same information can be
  stored in a U32 literal integer instead.  By making these macros use a
  U32 literal integer instead of a const array of bool/8 vars, there is
  no performance or overhead concerns anymore, if someone finds a reason
  to use these macros, in an optimized perl build. The U32 literal integers
  are now part of the CPU's instruction stream like in all other SV*
  flag tests.
- It is not known yet if there is any good reason to these faster macros,
  or the old slower PL_valid_types_*VX[]s arrays, in an optimized blead
  perl or optimized stable perl. All "correct enough" code either in CORE
  or on CPAN already has macros or expressions using existing macros,
  to test whatever flags they need to test inside a SV* head struct.
@bulk88 bulk88 force-pushed the faster_sanity_typechk_macros_for_pl_valid_inpvx_array branch from c1ad847 to 9a545bb Compare July 10, 2025 23:14
@bulk88
Copy link
Contributor Author

bulk88 commented Jul 10, 2025

s/VAILD/VALID/g?

LOL. Good catch. Repushed. I said from the start I didn't like the spelling of the macros and thought they could be better, but I couldn't figure out why I didn't like the names I invented, I simply didn't like them. Too many UC letters in a row. But its P5P/generic C code style for constants and macros to be all UC. IDK enough, to pick a mixed case name like SvValidPvx() SVValidPVX() SvVALIDPVX() SVVALIDPvx(), I need external opinions for a mixed case name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants