-
Notifications
You must be signed in to change notification settings - Fork 600
Update perlhack.pod - fix link to mirror git repo #1
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
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
p5p
pushed a commit
that referenced
this pull request
Feb 9, 2014
to avoid splain output like this on 80-column terminals: rewinddir() attempted on invalid dirhandle foo at -e line 1 (#1) (W io) The dirhandle you tried to do a rewinddir() on is either closed or no t really a dirhandle. Check your control flow.
p5p
pushed a commit
that referenced
this pull request
Sep 19, 2014
to the other part of the message. diagnostics.pm won’t find it otherwise: $ perl -Mdiagnostics -we '"foo"->bar' Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1 (#1) Uncaught exception from user code: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1. Now we have this: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1 (#1) (F) You called a method on a class that did not exist, and the method could not be found in UNIVERSAL. This often means that a method requires a package that has not been loaded. Uncaught exception from user code: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1.
p5p
pushed a commit
that referenced
this pull request
Nov 7, 2014
In the op tree, a statement consists of a nextstate/dbstate op (of
class cop) followed by the contents of the statement. This cop is
created after the statement has been parsed. So if you have nested
statements, the outermost statement has the highest sequence number
(cop_seq). Every sub (including BEGIN blocks) has a sequence number
indicating where it occurs in its containing sub.
So
BEGIN { } #1
# seq 2
{
# seq 1
...
}
is indistinguishable from
# seq 2
{
BEGIN { } #1
# seq 1
...
}
because the sequence number of the BEGIN block is 1 in both examples.
By reserving a sequence number at the start of every block and using
it once the block has finished parsing, we can do this:
BEGIN { } #1
# seq 1
{
# seq 2
...
}
# seq 1
{
BEGIN { } #2
# seq 2
...
}
and now B::Deparse can tell where to put the blocks.
PL_compiling.cop_seq was unused, so this is where I am stashing
the pending sequence number.
p5p
pushed a commit
that referenced
this pull request
Jan 13, 2015
to the other part of the message. diagnostics.pm won’t find it otherwise: $ perl -Mdiagnostics -we '"foo"->bar' Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1 (#1) Uncaught exception from user code: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1. Now we have this: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1 (#1) (F) You called a method on a class that did not exist, and the method could not be found in UNIVERSAL. This often means that a method requires a package that has not been loaded. Uncaught exception from user code: Can't locate object method "bar" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1. (cherry picked from commit 8af56b9)
p5p
pushed a commit
that referenced
this pull request
Mar 2, 2015
8c2e27d changed B::Deparse to deparse $#{1} as that instead of as $#1 which is a syntax error, but also changed $#_ to deparse as $#{_} which isn't necessary, and broke GFUJI/macro-0.06.tar.gz This could be considered a bug in macro.pm, but since we don't need to deparse $#_ as $#{_} let's not do that.
p5p
pushed a commit
that referenced
this pull request
Feb 29, 2016
Coverity CID 135025 (#1 of 1): Out-of-bounds read (OVERRUN) 29. overrun-local: Overrunning array addr.sun_path of 108 bytes at byte offset 108 using index addr_len (which evaluates to 108). 864 for (addr_len = 0; addr.sun_path[addr_len] 28. incr: Incrementing addr_len. The value of addr_len may now be up to 108. 865 && addr_len < maxlen; addr_len++); Reported upstream as https://rt.cpan.org/Ticket/Display.html?id=111707
p5p
pushed a commit
that referenced
this pull request
Mar 1, 2016
Coverity CID 135025 (#1 of 1): Out-of-bounds read (OVERRUN) 29. overrun-local: Overrunning array addr.sun_path of 108 bytes at byte offset 108 using index addr_len (which evaluates to 108). 864 for (addr_len = 0; addr.sun_path[addr_len] 28. incr: Incrementing addr_len. The value of addr_len may now be up to 108. 865 && addr_len < maxlen; addr_len++); Reported upstream as https://rt.cpan.org/Ticket/Display.html?id=111707
preaction
pushed a commit
to preaction/perl5
that referenced
this pull request
Mar 3, 2016
Coverity CID 135025 (Perl#1 of 1): Out-of-bounds read (OVERRUN) 29. overrun-local: Overrunning array addr.sun_path of 108 bytes at byte offset 108 using index addr_len (which evaluates to 108). 864 for (addr_len = 0; addr.sun_path[addr_len] 28. incr: Incrementing addr_len. The value of addr_len may now be up to 108. 865 && addr_len < maxlen; addr_len++); Reported upstream as https://rt.cpan.org/Ticket/Display.html?id=111707
p5p
pushed a commit
that referenced
this pull request
Aug 13, 2016
In an eighty-column terminal, this is what it looked like before this commit: $ ./perl -Ilib -Mdiagnostics -E 'state ($x)=1' Initialization of state variables in list context currently forbidden at -e line 1, at EOF Execution of -e aborted due to compilation errors (#1) (F) state only permits initializing a single scalar variable, in scalar context. So state $a = 42 is allowed, but not state ($a) = 42. To apply state semantics to a hash or array, store a hash or array reference in a sca lar variable.
This was referenced Oct 18, 2019
Closed
Closed
Closed
Closed
bulk88
added a commit
to bulk88/perl5
that referenced
this pull request
Oct 14, 2024
…sv.c
-svfix.pl is quick throwaway garbage done in 20 mins and probably doesnt
regen sv_inline.h properly and copy pasting/replace regexps were
was used anyway to fix up the code, it can be rewritten correctly tho
and put in as a official regen.pl script
how to finish this fix, options
set and unset sv_type as a CPP macro then
-#include a header 17 times that contains ONLY only Perl_newSV_type() and
its mortal() sister creating 17*2 static inline fns (basically
what I did here), code is stepable, extra ms'es of I/O build times
perf degrade debate may or may not come up, I hope the CC has a sane
in memory cache for .h files and doesn't go back to the kernel
or put the entire Perl_newSV_type() fnc in a #define
"#define PETS blah(foo(myarg)) + \
cat(dog(fur)) + \
laser(ball(toy))
"
then execute that macro 17 times
or write 17 Perl_newSV_type() copies into sv_inline.h with
/regen.pl infrastructure (fastest for build speed core and
build speed CPAN and code is c dbg stepable) OR is a dedicated
"sv_newg.h" for regen.pl needed? does the master
Perl_newSV_type() template live in a .pl or a .h? i dont have an
opinion
or against concept of sv_inline.h just have 5-10 hand written
versions sv type specific of Perl_newSV_type(), its a cheap gimick fix
to keep all 17 types together mashed with if/else/switch in 1 func and
expecting bug free perfection from LTO engines of various C compilers,
and expecting perfection from an single vendor LTO engine is very
against the spirit of portable code
-todo ideas, turn those super long #define ==?:==?:==?: into
char array/struct initializers, stored in macros, one faux-string per
each column of struct body_details, use that macro as c auto stk rw
array initializer, then do the
U32 len [3] = "\x01\x02\x03"[sv_type];
or
U8 sizes [3] = {1,2,3};
U32 len = sizes[sv_type];
which in perl core would look
U32 arena_size = SVDB_AR_SZ_DECL;
U32 len = arena_size[sv_type];
maybe VC will optimize those since no global memory is used. Only
Perl_newSV_typeX() needs this.
in this commit static inline Perl_newSV_typeX(pTHX_ const svtype type)
which is the ONLY Perl_newSV_type*() variant that take an arbitrary
svtype arg, this is the fallback for gv_pvn_add_by() since I couldn't
"const" that call to newSV_type() cuz gv_pvn_add_by() is only place in the
whole core that takes a random SV type number.
Internals of Perl_newSV_typeX() are trashy, here is an example, MSVC
DID not turn this into a jump table but instead 17 test/cond_jump ops.
v5 = (char *)S_new_body(v2);
v6 = 40i64;
if ( v2 == 15 )
v6 = 136i64;
if ( v2 == 14 )
v6 = 104i64;
if ( v2 == 13 )
v6 = 104i64;
if ( v2 == 12 )
v6 = 32i64;
if ( v2 == 11 )
v6 = 40i64;
if ( v2 == 10 )
v6 = 80i64;
if ( v2 == 9 )
v6 = 48i64;
if ( v2 == 8 )
v6 = 224i64;
if ( v2 == 7 )
v6 = 48i64;
if ( v2 == 6 )
v6 = 32i64;
if ( v2 == 5 )
v6 = 24i64;
if ( v2 == 4 )
v6 = 40i64;
if ( v2 == 3 )
v6 = 16i64;
if ( v2 == 2 )
v6 = 0i64;
if ( v2 == 1 )
v6 = 0i64;
memset(v5, 0, v6 & -(signed __int64)(v2 != 0));
Solution is move Perl_newSV_typeX() to sv.c, and let it be struct
body_details driven. Cuz it only purpose is when newSV_type() absolutly
CAN NOT be constant folded (random number input). it only has 1 caller
in core.
S_new_body() properly const folded away in 99% of cases except for TWO
callers Perl_newSV_typeX() and Perl_make_trie(). Perl_make_trie() failure
to inline is bizzare, since Perl_make_trie() internally does
"v9 = S_new_body(SVt_PVAV);"
and DID inline Perl_newSV_typeSVt_PVAV() !!! and therefore
Perl_make_trie() has the AV field initing/nulling code.
Here is the "optimized" contents of S_new_body(), its junk
performance/design wise (but runtime correct/no bugs)
void **__fastcall S_new_body(svtype sv_type)
{
svtype v1; // er9
__int64 v2; // rbx
void **result; // rax
signed int v4; // ecx
signed __int64 v5; // rax
v1 = sv_type;
v2 = sv_type;
result = (void **)PL_body_roots[sv_type];
if ( !result )
{
v4 = 4080;
if ( v1 == 15 )
v4 = 3264;
if ( v1 == 14 )
v4 = 2080;
if ( v1 == 13 )
v4 = 4056;
if ( v1 == 12 )
v4 = 4064;
if ( v1 == 11 )
v4 = 4080;
if ( v1 == 10 )
v4 = 4080;
if ( v1 == 9 )
v4 = 4080;
if ( v1 == 8 )
v4 = 4032;
if ( v1 == 7 )
v4 = 4080;
if ( v1 == 6 )
v4 = 3296;
if ( v1 == 5 )
v4 = 3424;
if ( v1 == 4 )
v4 = 3120;
if ( v1 == 3 )
v4 = 3536;
if ( v1 == 2 )
v4 = 0;
if ( v1 == 1 )
v4 = 0;
v5 = 40i64;
if ( v1 == 15 )
v5 = 136i64;
if ( v1 == 14 )
v5 = 104i64;
if ( v1 == 13 )
v5 = 104i64;
if ( v1 == 12 )
v5 = 32i64;
if ( v1 == 11 )
v5 = 40i64;
if ( v1 == 10 )
v5 = 80i64;
if ( v1 == 9 )
v5 = 48i64;
if ( v1 == 8 )
v5 = 224i64;
if ( v1 == 7 )
v5 = 48i64;
if ( v1 == 6 )
v5 = 32i64;
if ( v1 == 5 )
v5 = 24i64;
if ( v1 == 4 )
v5 = 40i64;
if ( v1 == 3 )
v5 = 16i64;
if ( v1 == 2 )
v5 = 0i64;
if ( v1 == 1 )
v5 = 0i64;
result = (void **)Perl_more_bodies(v1, v5 & -(signed __int64)(v1 != 0), v4 & (unsigned int)-(v1 != 0));
}
PL_body_roots[v2] = *result;
return result;
}
------------
disassembly view of S_new_body()
------------
cmp r9d, 0Fh
lea edi, [rbp+28h]
mov r8d, 0FF0h
lea r11d, [rbp+20h]
mov edx, 0CC0h
lea r10d, [rbp+30h]
mov ecx, r8d
mov eax, r9d
cmovz ecx, edx
cmp r9d, 0Eh
mov edx, 820h
cmovz ecx, edx
cmp r9d, 0Dh
lea edx, [r8-18h]
cmovz ecx, edx
cmp r9d, 0Ch
lea edx, [r8-10h]
cmovz ecx, edx
cmp r9d, 0Bh
lea edx, [r8-30h]
cmovz ecx, r8d
cmp r9d, 0Ah
cmovz ecx, r8d
cmp r9d, 9
cmovz ecx, r8d
cmp r9d, 8
cmovz ecx, edx
cmp r9d, 7
mov edx, 0CE0h
cmovz ecx, r8d
cmp r9d, 6
cmovz ecx, edx
cmp r9d, 5
mov edx, 0D60h
cmovz ecx, edx
cmp r9d, 4
mov edx, 0C30h
cmovz ecx, edx
cmp r9d, 3
mov edx, 0DD0h
cmovz ecx, edx
cmp r9d, 2
lea edx, [rdi+60h]
cmovz ecx, ebp
cmp r9d, 1
cmovz ecx, ebp
neg eax
sbb eax, eax
and eax, ecx
mov ecx, r9d
mov r8d, eax
cmp r9d, 0Fh
mov eax, edi
cmovz eax, edx
cmp r9d, 0Eh
lea edx, [rbp+68h]
cmovz eax, edx
cmp r9d, 0Dh
cmovz eax, edx
cmp r9d, 0Ch
lea edx, [rbp+50h]
cmovz eax, r11d
cmp r9d, 0Bh
cmovz eax, edi
cmp r9d, 0Ah
cmovz eax, edx
cmp r9d, 9
mov edx, 0E0h
cmovz eax, r10d
cmp r9d, 8
cmovz eax, edx
cmp r9d, 7
lea edx, [rbp+18h]
cmovz eax, r10d
cmp r9d, 6
cmovz eax, r11d
cmp r9d, 5
cmovz eax, edx
cmp r9d, 4
lea edx, [rbp+10h]
cmovz eax, edi
cmp r9d, 3
cmovz eax, edx
cmp r9d, 2
cmovz eax, ebp
cmp r9d, 1
cmovz eax, ebp
neg ecx
mov ecx, r9d
sbb rdx, rdx
and rdx, rax
call Perl_more_bodies
----------------------
17 test ops and 17 conditional_move_constant_8_bits ops
solution, turn S_new_body() back into a macro so no CC ever tries to
ref-inline it. It was a macro before sv_inline.h branch was merged
TODO add XSApitest.xs that worlds longest macros are identical to the
master correct copy (struct body_details).
byte size drops from before these 3 commits to this "success commit"
mp.exe
0x1241AC-0x1224EC=7360
0x19D3D8-0x19B8E8=6896
p541.dll
0x154886-0x1532A6=5600
0x1AA19E-0x1A862E=7024
BEFORE
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1241AC virtual size
SECTION HEADER Perl#2
.rdata name
19D3D8 virtual size
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
154886 virtual size
SECTION HEADER Perl#2
.rdata name
1AA19E virtual size
AFTER
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
1532A6 virtual size
SECTION HEADER Perl#2
.rdata name
1A862E virtual size
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1224EC virtual size
SECTION HEADER Perl#2
.rdata name
19B8E8 virtual size
This was referenced Oct 14, 2024
bulk88
added a commit
to bulk88/perl5
that referenced
this pull request
Oct 18, 2024
…ly in sv.c
-svfix.pl is quick throwaway garbage done in 20 mins and probably doesnt
regen sv_inline.h properly and copy pasting/replace regexps were
was used anyway to fix up the code, it can be rewritten correctly tho
and put in as a official regen.pl script
how to finish this fix, options
set and unset sv_type as a CPP macro then
-#include a header 17 times that contains ONLY only Perl_newSV_type() and
its mortal() sister creating 17*2 static inline fns (basically
what I did here), code is stepable, extra ms'es of I/O build times
perf degrade debate may or may not come up, I hope the CC has a sane
in memory cache for .h files and doesn't go back to the kernel
or put the entire Perl_newSV_type() fnc in a #define
"#define PETS blah(foo(myarg)) + \
cat(dog(fur)) + \
laser(ball(toy))
"
then execute that macro 17 times
or write 17 Perl_newSV_type() copies into sv_inline.h with
/regen.pl infrastructure (fastest for build speed core and
build speed CPAN and code is c dbg stepable) OR is a dedicated
"sv_newg.h" for regen.pl needed? does the master
Perl_newSV_type() template live in a .pl or a .h? i dont have an
opinion
or against concept of sv_inline.h just have 5-10 hand written
versions sv type specific of Perl_newSV_type(), its a cheap gimick fix
to keep all 17 types together mashed with if/else/switch in 1 func and
expecting bug free perfection from LTO engines of various C compilers,
and expecting perfection from an single vendor LTO engine is very
against the spirit of portable code
-todo ideas, turn those super long #define ==?:==?:==?: into
char array/struct initializers, stored in macros, one faux-string per
each column of struct body_details, use that macro as c auto stk rw
array initializer, then do the
U32 len [3] = "\x01\x02\x03"[sv_type];
or
U8 sizes [3] = {1,2,3};
U32 len = sizes[sv_type];
which in perl core would look
U32 arena_size = SVDB_AR_SZ_DECL;
U32 len = arena_size[sv_type];
maybe VC will optimize those since no global memory is used. Only
Perl_newSV_typeX() needs this.
in this commit static inline Perl_newSV_typeX(pTHX_ const svtype type)
which is the ONLY Perl_newSV_type*() variant that take an arbitrary
svtype arg, this is the fallback for gv_pvn_add_by() since I couldn't
"const" that call to newSV_type() cuz gv_pvn_add_by() is only place in the
whole core that takes a random SV type number.
Internals of Perl_newSV_typeX() are trashy, here is an example, MSVC
DID not turn this into a jump table but instead 17 test/cond_jump ops.
v5 = (char *)S_new_body(v2);
v6 = 40i64;
if ( v2 == 15 )
v6 = 136i64;
if ( v2 == 14 )
v6 = 104i64;
if ( v2 == 13 )
v6 = 104i64;
if ( v2 == 12 )
v6 = 32i64;
if ( v2 == 11 )
v6 = 40i64;
if ( v2 == 10 )
v6 = 80i64;
if ( v2 == 9 )
v6 = 48i64;
if ( v2 == 8 )
v6 = 224i64;
if ( v2 == 7 )
v6 = 48i64;
if ( v2 == 6 )
v6 = 32i64;
if ( v2 == 5 )
v6 = 24i64;
if ( v2 == 4 )
v6 = 40i64;
if ( v2 == 3 )
v6 = 16i64;
if ( v2 == 2 )
v6 = 0i64;
if ( v2 == 1 )
v6 = 0i64;
memset(v5, 0, v6 & -(signed __int64)(v2 != 0));
Solution is move Perl_newSV_typeX() to sv.c, and let it be struct
body_details driven. Cuz it only purpose is when newSV_type() absolutly
CAN NOT be constant folded (random number input). it only has 1 caller
in core.
S_new_body() properly const folded away in 99% of cases except for TWO
callers Perl_newSV_typeX() and Perl_make_trie(). Perl_make_trie() failure
to inline is bizzare, since Perl_make_trie() internally does
"v9 = S_new_body(SVt_PVAV);"
and DID inline Perl_newSV_typeSVt_PVAV() !!! and therefore
Perl_make_trie() has the AV field initing/nulling code.
Here is the "optimized" contents of S_new_body(), its junk
performance/design wise (but runtime correct/no bugs)
void **__fastcall S_new_body(svtype sv_type)
{
svtype v1; // er9
__int64 v2; // rbx
void **result; // rax
signed int v4; // ecx
signed __int64 v5; // rax
v1 = sv_type;
v2 = sv_type;
result = (void **)PL_body_roots[sv_type];
if ( !result )
{
v4 = 4080;
if ( v1 == 15 )
v4 = 3264;
if ( v1 == 14 )
v4 = 2080;
if ( v1 == 13 )
v4 = 4056;
if ( v1 == 12 )
v4 = 4064;
if ( v1 == 11 )
v4 = 4080;
if ( v1 == 10 )
v4 = 4080;
if ( v1 == 9 )
v4 = 4080;
if ( v1 == 8 )
v4 = 4032;
if ( v1 == 7 )
v4 = 4080;
if ( v1 == 6 )
v4 = 3296;
if ( v1 == 5 )
v4 = 3424;
if ( v1 == 4 )
v4 = 3120;
if ( v1 == 3 )
v4 = 3536;
if ( v1 == 2 )
v4 = 0;
if ( v1 == 1 )
v4 = 0;
v5 = 40i64;
if ( v1 == 15 )
v5 = 136i64;
if ( v1 == 14 )
v5 = 104i64;
if ( v1 == 13 )
v5 = 104i64;
if ( v1 == 12 )
v5 = 32i64;
if ( v1 == 11 )
v5 = 40i64;
if ( v1 == 10 )
v5 = 80i64;
if ( v1 == 9 )
v5 = 48i64;
if ( v1 == 8 )
v5 = 224i64;
if ( v1 == 7 )
v5 = 48i64;
if ( v1 == 6 )
v5 = 32i64;
if ( v1 == 5 )
v5 = 24i64;
if ( v1 == 4 )
v5 = 40i64;
if ( v1 == 3 )
v5 = 16i64;
if ( v1 == 2 )
v5 = 0i64;
if ( v1 == 1 )
v5 = 0i64;
result = (void **)Perl_more_bodies(v1, v5 & -(signed __int64)(v1 != 0), v4 & (unsigned int)-(v1 != 0));
}
PL_body_roots[v2] = *result;
return result;
}
------------
disassembly view of S_new_body()
------------
cmp r9d, 0Fh
lea edi, [rbp+28h]
mov r8d, 0FF0h
lea r11d, [rbp+20h]
mov edx, 0CC0h
lea r10d, [rbp+30h]
mov ecx, r8d
mov eax, r9d
cmovz ecx, edx
cmp r9d, 0Eh
mov edx, 820h
cmovz ecx, edx
cmp r9d, 0Dh
lea edx, [r8-18h]
cmovz ecx, edx
cmp r9d, 0Ch
lea edx, [r8-10h]
cmovz ecx, edx
cmp r9d, 0Bh
lea edx, [r8-30h]
cmovz ecx, r8d
cmp r9d, 0Ah
cmovz ecx, r8d
cmp r9d, 9
cmovz ecx, r8d
cmp r9d, 8
cmovz ecx, edx
cmp r9d, 7
mov edx, 0CE0h
cmovz ecx, r8d
cmp r9d, 6
cmovz ecx, edx
cmp r9d, 5
mov edx, 0D60h
cmovz ecx, edx
cmp r9d, 4
mov edx, 0C30h
cmovz ecx, edx
cmp r9d, 3
mov edx, 0DD0h
cmovz ecx, edx
cmp r9d, 2
lea edx, [rdi+60h]
cmovz ecx, ebp
cmp r9d, 1
cmovz ecx, ebp
neg eax
sbb eax, eax
and eax, ecx
mov ecx, r9d
mov r8d, eax
cmp r9d, 0Fh
mov eax, edi
cmovz eax, edx
cmp r9d, 0Eh
lea edx, [rbp+68h]
cmovz eax, edx
cmp r9d, 0Dh
cmovz eax, edx
cmp r9d, 0Ch
lea edx, [rbp+50h]
cmovz eax, r11d
cmp r9d, 0Bh
cmovz eax, edi
cmp r9d, 0Ah
cmovz eax, edx
cmp r9d, 9
mov edx, 0E0h
cmovz eax, r10d
cmp r9d, 8
cmovz eax, edx
cmp r9d, 7
lea edx, [rbp+18h]
cmovz eax, r10d
cmp r9d, 6
cmovz eax, r11d
cmp r9d, 5
cmovz eax, edx
cmp r9d, 4
lea edx, [rbp+10h]
cmovz eax, edi
cmp r9d, 3
cmovz eax, edx
cmp r9d, 2
cmovz eax, ebp
cmp r9d, 1
cmovz eax, ebp
neg ecx
mov ecx, r9d
sbb rdx, rdx
and rdx, rax
call Perl_more_bodies
----------------------
17 test ops and 17 conditional_move_constant_8_bits ops
solution, turn S_new_body() back into a macro so no CC ever tries to
ref-inline it. It was a macro before sv_inline.h branch was merged
TODO add XSApitest.xs that worlds longest macros are identical to the
master correct copy (struct body_details).
byte size drops from before these 3 commits to this "success commit"
mp.exe
0x1241AC-0x1224EC=7360
0x19D3D8-0x19B8E8=6896
p541.dll
0x154886-0x1532A6=5600
0x1AA19E-0x1A862E=7024
BEFORE
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1241AC virtual size
SECTION HEADER Perl#2
.rdata name
19D3D8 virtual size
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
154886 virtual size
SECTION HEADER Perl#2
.rdata name
1AA19E virtual size
AFTER
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
1532A6 virtual size
SECTION HEADER Perl#2
.rdata name
1A862E virtual size
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1224EC virtual size
SECTION HEADER Perl#2
.rdata name
19B8E8 virtual size
bulk88
added a commit
to bulk88/perl5
that referenced
this pull request
Oct 18, 2024
…ly in sv.c
-svfix.pl is quick throwaway garbage done in 20 mins and probably doesnt
regen sv_inline.h properly and copy pasting/replace regexps were
was used anyway to fix up the code, it can be rewritten correctly tho
and put in as a official regen.pl script
how to finish this fix, options
set and unset sv_type as a CPP macro then
-#include a header 17 times that contains ONLY only Perl_newSV_type() and
its mortal() sister creating 17*2 static inline fns (basically
what I did here), code is stepable, extra ms'es of I/O build times
perf degrade debate may or may not come up, I hope the CC has a sane
in memory cache for .h files and doesn't go back to the kernel
or put the entire Perl_newSV_type() fnc in a #define
"#define PETS blah(foo(myarg)) + \
cat(dog(fur)) + \
laser(ball(toy))
"
then execute that macro 17 times
or write 17 Perl_newSV_type() copies into sv_inline.h with
/regen.pl infrastructure (fastest for build speed core and
build speed CPAN and code is c dbg stepable) OR is a dedicated
"sv_newg.h" for regen.pl needed? does the master
Perl_newSV_type() template live in a .pl or a .h? i dont have an
opinion
or against concept of sv_inline.h just have 5-10 hand written
versions sv type specific of Perl_newSV_type(), its a cheap gimick fix
to keep all 17 types together mashed with if/else/switch in 1 func and
expecting bug free perfection from LTO engines of various C compilers,
and expecting perfection from an single vendor LTO engine is very
against the spirit of portable code
-todo ideas, turn those super long #define ==?:==?:==?: into
char array/struct initializers, stored in macros, one faux-string per
each column of struct body_details, use that macro as c auto stk rw
array initializer, then do the
U32 len [3] = "\x01\x02\x03"[sv_type];
or
U8 sizes [3] = {1,2,3};
U32 len = sizes[sv_type];
which in perl core would look
U32 arena_size = SVDB_AR_SZ_DECL;
U32 len = arena_size[sv_type];
maybe VC will optimize those since no global memory is used. Only
Perl_newSV_typeX() needs this.
in this commit static inline Perl_newSV_typeX(pTHX_ const svtype type)
which is the ONLY Perl_newSV_type*() variant that take an arbitrary
svtype arg, this is the fallback for gv_pvn_add_by() since I couldn't
"const" that call to newSV_type() cuz gv_pvn_add_by() is only place in the
whole core that takes a random SV type number.
Internals of Perl_newSV_typeX() are trashy, here is an example, MSVC
DID not turn this into a jump table but instead 17 test/cond_jump ops.
v5 = (char *)S_new_body(v2);
v6 = 40i64;
if ( v2 == 15 )
v6 = 136i64;
if ( v2 == 14 )
v6 = 104i64;
if ( v2 == 13 )
v6 = 104i64;
if ( v2 == 12 )
v6 = 32i64;
if ( v2 == 11 )
v6 = 40i64;
if ( v2 == 10 )
v6 = 80i64;
if ( v2 == 9 )
v6 = 48i64;
if ( v2 == 8 )
v6 = 224i64;
if ( v2 == 7 )
v6 = 48i64;
if ( v2 == 6 )
v6 = 32i64;
if ( v2 == 5 )
v6 = 24i64;
if ( v2 == 4 )
v6 = 40i64;
if ( v2 == 3 )
v6 = 16i64;
if ( v2 == 2 )
v6 = 0i64;
if ( v2 == 1 )
v6 = 0i64;
memset(v5, 0, v6 & -(signed __int64)(v2 != 0));
Solution is move Perl_newSV_typeX() to sv.c, and let it be struct
body_details driven. Cuz it only purpose is when newSV_type() absolutly
CAN NOT be constant folded (random number input). it only has 1 caller
in core.
S_new_body() properly const folded away in 99% of cases except for TWO
callers Perl_newSV_typeX() and Perl_make_trie(). Perl_make_trie() failure
to inline is bizzare, since Perl_make_trie() internally does
"v9 = S_new_body(SVt_PVAV);"
and DID inline Perl_newSV_typeSVt_PVAV() !!! and therefore
Perl_make_trie() has the AV field initing/nulling code.
Here is the "optimized" contents of S_new_body(), its junk
performance/design wise (but runtime correct/no bugs)
void **__fastcall S_new_body(svtype sv_type)
{
svtype v1; // er9
__int64 v2; // rbx
void **result; // rax
signed int v4; // ecx
signed __int64 v5; // rax
v1 = sv_type;
v2 = sv_type;
result = (void **)PL_body_roots[sv_type];
if ( !result )
{
v4 = 4080;
if ( v1 == 15 )
v4 = 3264;
if ( v1 == 14 )
v4 = 2080;
if ( v1 == 13 )
v4 = 4056;
if ( v1 == 12 )
v4 = 4064;
if ( v1 == 11 )
v4 = 4080;
if ( v1 == 10 )
v4 = 4080;
if ( v1 == 9 )
v4 = 4080;
if ( v1 == 8 )
v4 = 4032;
if ( v1 == 7 )
v4 = 4080;
if ( v1 == 6 )
v4 = 3296;
if ( v1 == 5 )
v4 = 3424;
if ( v1 == 4 )
v4 = 3120;
if ( v1 == 3 )
v4 = 3536;
if ( v1 == 2 )
v4 = 0;
if ( v1 == 1 )
v4 = 0;
v5 = 40i64;
if ( v1 == 15 )
v5 = 136i64;
if ( v1 == 14 )
v5 = 104i64;
if ( v1 == 13 )
v5 = 104i64;
if ( v1 == 12 )
v5 = 32i64;
if ( v1 == 11 )
v5 = 40i64;
if ( v1 == 10 )
v5 = 80i64;
if ( v1 == 9 )
v5 = 48i64;
if ( v1 == 8 )
v5 = 224i64;
if ( v1 == 7 )
v5 = 48i64;
if ( v1 == 6 )
v5 = 32i64;
if ( v1 == 5 )
v5 = 24i64;
if ( v1 == 4 )
v5 = 40i64;
if ( v1 == 3 )
v5 = 16i64;
if ( v1 == 2 )
v5 = 0i64;
if ( v1 == 1 )
v5 = 0i64;
result = (void **)Perl_more_bodies(v1, v5 & -(signed __int64)(v1 != 0), v4 & (unsigned int)-(v1 != 0));
}
PL_body_roots[v2] = *result;
return result;
}
------------
disassembly view of S_new_body()
------------
cmp r9d, 0Fh
lea edi, [rbp+28h]
mov r8d, 0FF0h
lea r11d, [rbp+20h]
mov edx, 0CC0h
lea r10d, [rbp+30h]
mov ecx, r8d
mov eax, r9d
cmovz ecx, edx
cmp r9d, 0Eh
mov edx, 820h
cmovz ecx, edx
cmp r9d, 0Dh
lea edx, [r8-18h]
cmovz ecx, edx
cmp r9d, 0Ch
lea edx, [r8-10h]
cmovz ecx, edx
cmp r9d, 0Bh
lea edx, [r8-30h]
cmovz ecx, r8d
cmp r9d, 0Ah
cmovz ecx, r8d
cmp r9d, 9
cmovz ecx, r8d
cmp r9d, 8
cmovz ecx, edx
cmp r9d, 7
mov edx, 0CE0h
cmovz ecx, r8d
cmp r9d, 6
cmovz ecx, edx
cmp r9d, 5
mov edx, 0D60h
cmovz ecx, edx
cmp r9d, 4
mov edx, 0C30h
cmovz ecx, edx
cmp r9d, 3
mov edx, 0DD0h
cmovz ecx, edx
cmp r9d, 2
lea edx, [rdi+60h]
cmovz ecx, ebp
cmp r9d, 1
cmovz ecx, ebp
neg eax
sbb eax, eax
and eax, ecx
mov ecx, r9d
mov r8d, eax
cmp r9d, 0Fh
mov eax, edi
cmovz eax, edx
cmp r9d, 0Eh
lea edx, [rbp+68h]
cmovz eax, edx
cmp r9d, 0Dh
cmovz eax, edx
cmp r9d, 0Ch
lea edx, [rbp+50h]
cmovz eax, r11d
cmp r9d, 0Bh
cmovz eax, edi
cmp r9d, 0Ah
cmovz eax, edx
cmp r9d, 9
mov edx, 0E0h
cmovz eax, r10d
cmp r9d, 8
cmovz eax, edx
cmp r9d, 7
lea edx, [rbp+18h]
cmovz eax, r10d
cmp r9d, 6
cmovz eax, r11d
cmp r9d, 5
cmovz eax, edx
cmp r9d, 4
lea edx, [rbp+10h]
cmovz eax, edi
cmp r9d, 3
cmovz eax, edx
cmp r9d, 2
cmovz eax, ebp
cmp r9d, 1
cmovz eax, ebp
neg ecx
mov ecx, r9d
sbb rdx, rdx
and rdx, rax
call Perl_more_bodies
----------------------
17 test ops and 17 conditional_move_constant_8_bits ops
solution, turn S_new_body() back into a macro so no CC ever tries to
ref-inline it. It was a macro before sv_inline.h branch was merged
TODO add XSApitest.xs that worlds longest macros are identical to the
master correct copy (struct body_details).
byte size drops from before these 3 commits to this "success commit"
mp.exe
0x1241AC-0x1224EC=7360
0x19D3D8-0x19B8E8=6896
p541.dll
0x154886-0x1532A6=5600
0x1AA19E-0x1A862E=7024
BEFORE
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1241AC virtual size
SECTION HEADER Perl#2
.rdata name
19D3D8 virtual size
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
154886 virtual size
SECTION HEADER Perl#2
.rdata name
1AA19E virtual size
AFTER
Dump of file ..\perl541.dll
SECTION HEADER Perl#1
.text name
1532A6 virtual size
SECTION HEADER Perl#2
.rdata name
1A862E virtual size
Dump of file ..\miniperl.exe
SECTION HEADER Perl#1
.text name
1224EC virtual size
SECTION HEADER Perl#2
.rdata name
19B8E8 virtual size
bulk88
added a commit
to bulk88/perl5
that referenced
this pull request
Oct 23, 2024
Add builtin::getcwd Perl#3 gcc syntax fixes -win32_get_childdir() skip the strlen() because GetCurrentDirectoryA() gives it to us, handle 32KB paths if encountered. It is an infinite retry loop since its been reported, in multithreading, GCD()/CWD can change and get longer on our OS thread's between overflow Perl#1 and correct-size attempt Perl#2 because CWD val is a race cond. So all overflow conditions must trigger realloc. If the whole C stack is used up with alloca() and infinite retry. A SEGV is good. Win API/UNICODE_STRING struct is hard coded to USHORT/SHORT. If GetCurrentDirectoryA() returns above 65KB a SEGV is good. If GetCurrentDirectoryA()'s impl is doing {return buflen+1;} which is an API violation, OS is damaged, a SEGV is good. The race retry will never realistically trigger more than 1x ever, 2x rounds through retry loop might happen after a few centuries semi-guess. -CPerlHost::GetChildDir(void) is TODO now that m_pvDir->GetCurrentDirectoryA/W have correct retvals. -perllib.c silence warnings, return debug code accidentally removed in Merge WinCE and Win32 directories -- Initial patch 7bd379e 4/27/2006 7:30:00 PM
This was referenced Dec 1, 2024
bulk88
added a commit
to bulk88/perl5
that referenced
this pull request
Feb 27, 2025
All the code in gv.c, is very old and has gotten zero optimizing since 5.000 alpha. SV*s are instantly turned into PVNs on the front end instantly loosing and chance of [future] SVPV COW Shared HEK key string optimization. HEK*s are unknown to gv_* API. All inputs are continously parsed for ' and :: without exception, even if they are read only (SEGV) C literals or PP SvREADONLY() SvPROTECT() read only literals or API contract read only HEK* PV buffers. Returned from hv_store*() hv_fetch*(), HE*s, aren't exploited to pass the shared HEK* onto gv_init_*() or gv_name_set(), and gv_name_set() on front end only understands PVNs, but on backend, in the GP struct and GV body struct, ONLY understands HEK*s. Therefore no RC++, and looking up the ShHEK again in PL_strtab. The large amount of tiny extern exported symbols wrapper funs added over the years also causes C dbg call stacks even at -O1/-O2, to be 2-5 call frames deep of 3 line shims/stub functions before reaching the main logic. I can't tell what is a mathom and what isn't. So to lay provisions needed for future commits, that add proper SV*/HEK*/U32 hash precalculation, not to mention the memcmp() in hv_common() is skipped if left and right ptr addr are equal. The front end of gv_* needs cleanup. -move U32 flags to the start of the the func, so flags can encode details what void * Perl#1 means, and if vararg void * Perl#2 exists (PVN with N as size_t is only 2nd arg user right now). Since gv_stashpvs() is very common on core and CPAN, and called over and over in 1 proc, since most interp core and CPAN XS devs don't know GV*s have an RC that can be ++ed and stored in a MY_CXT struct. Also nobody knows "stashes" are HV*s or PP packages/classes are implimented with HV*s. So there is reason to pay extra attention to gv_stashpvs() b/c of its high usage/call sites per library. So if the STRLEN can be CC constant folded, and fits in a U8, store the length in the flags arg. Saves on CPU ops in all the callers to push 2 args, vs 3. Public API gv_stashpvs(str, create)'s create arg [flags in reality] can't be optimized away or removed, so combine the 2 CC time constant args, so they fold/optimize into 1 cpu op. -at some point perl core needs to cache/create/move around C level arrays of RC++ed ShHEKs to pass to the gv_*() APIs. SVPVs aren't exactly the right format for storing sanitized (no */::/'/SUPER/main/UNIVERSAL) and pre-parsed/splitted "package tokens", since SVs easily wind up or escape into PP-state, and SV RO flags/COW flags aren't the most honored and respected parts of the API by CPAN XS/maybe core. ShHEKs escaping into PP-state is rarer than "generic SVs" escaping into PP-state or CPAN XS state. All legacy XS code any quality and entry/beginner XS people, will pick "char *" getter macros vs an unknown opaque "HEK" type (and newSVpvn() to capture/move those char *s). Users who know what a HEK* is and how to RC++ it, know not to write to it. Also a bad write to a ShHEK will cause more PP or SEGV breakage/panics or proc exits, alot faster than a bad write to a SVfRO "SVPV" buffer. Hash doesn't match char string in a ShHEK will term the prc faster. So vararg on gv_*() is a provision for a future prototype, that accepts 1, 2, 3 or more HEK*s passed array style, that already were sanitized to not have ::s. 0xFF length was picked b/c there was bitfield space, shaving to 32/64/128 chars for gv_stashpvs(str, create) is possible if the bits are needed b/c a terminal is 80 chars, would fit almost all absolute ("::") C string package names, and everthing in core and CPAN. -the stubs remain as exported stub funcs, on purpose for now, it makes certain diag tools I use slightly easier to use vs optimized out inlines or macros. In 5.43 or 5.45 the exported stub funcs can be converted to macros no static inline, which is intent of this commit. The vararg is the 1 and only entry point to all of gv_stash* logic. -flipping I32 flags to the front requires "_p" suffixes for private for ABI reasons, public API still thinks I32 flags is always the last arg -since all front end wrappers, are 1-away from instead of multiple frames away, they are more likely to LTO inline away inside of libperl (not XS) on any CC. CCs have cost/benefit/wall time cut offs for scoring potential inlines opportunities. Going 2 layers, or 3+ layers of small inlines, is asking alot from a CC, that has to traverse a tree of nodes to do each inline, and the cut off could be as low as 1 inline fn and no more unrolling or folding.
iabyn
added a commit
that referenced
this pull request
Apr 24, 2025
This is #1 of a small series of commits to refactor the INPUT_handler() method and turn it into a Node subclass method. This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
iabyn
added a commit
that referenced
this pull request
Apr 24, 2025
This is #1 of a small series of commits to refactor the OUTPUT_handler() method and turn it into a Node subclass method. This series is very similar to the one earlier in this branch which did the same for INPUT_handler(). This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
iabyn
added a commit
that referenced
this pull request
May 26, 2025
This is #1 of a small series of commits to refactor the INPUT_handler() method and turn it into a Node subclass method. This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
iabyn
added a commit
that referenced
this pull request
May 26, 2025
This is #1 of a small series of commits to refactor the OUTPUT_handler() method and turn it into a Node subclass method. This series is very similar to the one earlier in this branch which did the same for INPUT_handler(). This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
iabyn
added a commit
that referenced
this pull request
Jul 6, 2025
This is #1 of a small series of commits to refactor the INPUT_handler() method and turn it into a Node subclass method. This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
iabyn
added a commit
that referenced
this pull request
Jul 6, 2025
This is #1 of a small series of commits to refactor the OUTPUT_handler() method and turn it into a Node subclass method. This series is very similar to the one earlier in this branch which did the same for INPUT_handler(). This commit changes the main loop from using $_ to hold the current line, to using the variable $line instead.
mauke
added a commit
to mauke/perl5
that referenced
this pull request
Aug 27, 2025
Fixes a Coverity issue:
>>> function_return: Function Perl_delimcpy_no_escape(tmpbuf, tmpbuf + 4096UL, s, bufend, 58, &len) modifies its argument, assigning 2147483647 to len.
3553 s = delimcpy_no_escape(tmpbuf, tmpbuf + sizeof tmpbuf, s, bufend,
3554 ':', &len);
>>> CID 583353: (Perl#1 of 1): Overflowed constant (INTEGER_OVERFLOW)
>>> overflow_const: Expression len + 1, where len is known to be equal to 2147483647, overflows the type of len + 1, which is type int.
3558 if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tmpbuf)
3559 continue; /* don't search dir with too-long name */
If there is not enough available space in tmpbuf, delimcpy_no_escape
sets len to I32_MAX, but the following code does not check for this. (I
believe this case is reachable simply by setting PATH to a huge string.)
Avoid the potential overflow by rewriting
A + B >= C
as
A >= C - B
(Also, make 'len' unsigned (specifically, size_t) to match the type of
sizeof/strlen() and avoid warnings about comparisons between signed and
unsigned integers.)
mauke
added a commit
that referenced
this pull request
Aug 28, 2025
Fixes a Coverity issue:
>>> function_return: Function Perl_delimcpy_no_escape(tmpbuf, tmpbuf + 4096UL, s, bufend, 58, &len) modifies its argument, assigning 2147483647 to len.
3553 s = delimcpy_no_escape(tmpbuf, tmpbuf + sizeof tmpbuf, s, bufend,
3554 ':', &len);
>>> CID 583353: (#1 of 1): Overflowed constant (INTEGER_OVERFLOW)
>>> overflow_const: Expression len + 1, where len is known to be equal to 2147483647, overflows the type of len + 1, which is type int.
3558 if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tmpbuf)
3559 continue; /* don't search dir with too-long name */
If there is not enough available space in tmpbuf, delimcpy_no_escape
sets len to I32_MAX, but the following code does not check for this. (I
believe this case is reachable simply by setting PATH to a huge string.)
Avoid the potential overflow by rewriting
A + B >= C
as
A >= C - B
(Also, make 'len' unsigned (specifically, size_t) to match the type of
sizeof/strlen() and avoid warnings about comparisons between signed and
unsigned integers.)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Change dead link http://github.com/mirrors/perl to https://github.com/Perl/perl5