From eb882bfa4ba0983f00f531c8d511616b84f90f00 Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Thu, 24 Oct 2024 15:27:16 -0400 Subject: [PATCH 1/2] convert last small purpose of builtin.pm to C and NOOP require's I/O -builtin.pm is now primarily for POD and .pm indexing tools, core, CPAN or user written. It also is a backup mechanism for very strange %INC localization, clearing, or manipulation done by users, probably in a .t, and whatever %INC manipulation is being done is probably developer error. -This removes all the libc/kernel I/O calls for builtin.pm, and Perl code parser overhead. -A large benefit is, this commit is 50% of the work, to make perl -E 'say "hi";' "/lib"-less or not dependent on any file I/O. perl.bin, libperl.so, and miniperl.bin should be able to execute as a standalone binary. If perl -e "1;" doesn't need a dozen separate library files, perl -E "1;" also shouldn't need a dozen files. perl -E "say 'Hello world';" should work, even with a broken perl installation or unreachable "/lib/*.pm"s or broken "portable" perls. Only a feature.pm dep is left, for -E to be lib-less. That is for another patch and PR in the the future. --- builtin.c | 10 ++++++++++ lib/builtin.pm | 12 +++++++++--- lib/builtin.t | 7 +++++++ pod/perldelta.pod | 21 ++++++++++++++++----- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/builtin.c b/builtin.c index 34865ec9a4bb..4acf11683700 100644 --- a/builtin.c +++ b/builtin.c @@ -774,6 +774,9 @@ XS(XS_builtin_import) void Perl_boot_core_builtin(pTHX) { + HV * inc_hv; + GV * ver_gv; + SV * ver_sv; I32 i; for(i = 0; builtins[i].name; i++) { const struct BuiltinFuncDescriptor *builtin = &builtins[i]; @@ -807,6 +810,13 @@ Perl_boot_core_builtin(pTHX) } newXS_flags("builtin::import", &XS_builtin_import, __FILE__, NULL, 0); + + inc_hv = GvHVn(PL_incgv); + hv_store(inc_hv, "builtin.pm", STRLENs("builtin.pm"), newSVpvs(__FILE__), 0); + ver_gv = gv_fetchpvs("builtin::VERSION", GV_ADDMULTI, SVt_PV); + ver_sv = GvSV(ver_gv); + /* Remember to keep $VERSION in this file and $VERSION in builtin.pm synced. */ + sv_setpvs(ver_sv, "0.016"); } /* diff --git a/lib/builtin.pm b/lib/builtin.pm index 0980884359b7..b7b2f2936bbb 100644 --- a/lib/builtin.pm +++ b/lib/builtin.pm @@ -1,10 +1,16 @@ -package builtin 0.015; +package builtin 0.016; use v5.40; # All code, including &import, is implemented by always-present -# functions in the perl interpreter itself. -# See also `builtin.c` in perl source +# functions in the perl interpreter itself in `builtin.c`. +# +# $builtin::VERSION and %INC are also set by the interpreter in `builtin.c` +# since this file is a NOOP. Therefore this file is unlikely to ever execute +# and primarily serves as POD. +# +# Remember to keep $VERSION in this file and $VERSION in builtin.c synced! + __END__ diff --git a/lib/builtin.t b/lib/builtin.t index ce5de3455b60..2dbef504ed53 100644 --- a/lib/builtin.t +++ b/lib/builtin.t @@ -645,6 +645,13 @@ EOS } } +like($INC{'builtin.pm'}, qr/builtin\.c/, 'check that \'builtin.pm\' is in %INC'); +{ + my $xsv = $builtin::VERSION; + delete $INC{'builtin.pm'}; + eval "use builtin;"; + is($xsv, $builtin::VERSION, 'XS $VERSION matches PP $VERSION'); +} # vim: tabstop=4 shiftwidth=4 expandtab autoindent softtabstop=4 done_testing(); diff --git a/pod/perldelta.pod b/pod/perldelta.pod index d932427b6fb4..d8b4ded09e83 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -123,11 +123,22 @@ XXX Remove this section if F did not add any cont =over 4 -=item * - -L has been upgraded from version A.xx to B.yy. - -XXX If there was something important to note about this change, include that here. +=item builtin.pm + +L has been upgraded from version 0.015 to 0.016. +As an optimization the C package and module is now fully +implemented in C to save on file system I/O and startup time. + +Specifically the C statement and any permutations of +C will not internally perform a per process first time +C anymore and C<$INC{'builtin.pm'}> is already filled in at +process startup. All C<.pm> functionality is embedded in the interpreter at +startup now. This optimization removes all I/O calls and time overhead of +parsing the C file. The C file will remain as +documentation. + +C's C, C<$VERSION>, and all available subroutines/APIs +have not changed. No changes are required to previously written code. =back From da73dd09a5cb2bf45a5d1556fdb6236487d1b5c7 Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Thu, 24 Oct 2024 15:27:16 -0400 Subject: [PATCH 2/2] convert last small purpose of builtin.pm to C and NOOP require's I/O -builtin.pm is now primarily for POD and .pm indexing tools, core, CPAN or user written. It also is a backup mechanism for very strange %INC localization, clearing, or manipulation done by users, probably in a .t, and whatever %INC manipulation is being done is probably developer error. -This removes all the libc/kernel I/O calls for builtin.pm, and Perl code parser overhead. -A large benefit is, this commit is 50% of the work, to make perl -E 'say "hi";' "/lib"-less or not dependent on any file I/O. perl.bin, libperl.so, and miniperl.bin should be able to execute as a standalone binary. If perl -e "1;" doesn't need a dozen separate library files, perl -E "1;" also shouldn't need a dozen files. perl -E "say 'Hello world';" should work, even with a broken perl installation or unreachable "/lib/*.pm"s or broken "portable" perls. Only a feature.pm dep is left, for -E to be lib-less. That is for another patch and PR in the the future. -silence nearby MSVC x64 only truncation warnings --- builtin.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/builtin.c b/builtin.c index 4acf11683700..b61e99ec2197 100644 --- a/builtin.c +++ b/builtin.c @@ -447,7 +447,7 @@ static OP *ck_builtin_func1(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) entersubop = ck_entersub_args_proto(entersubop, namegv, prototype); - OPCODE opcode = builtin->ckval; + OPCODE opcode = (OPCODE)builtin->ckval; if(!opcode) return entersubop; @@ -752,7 +752,7 @@ XS(XS_builtin_import) if(!S_parse_version(sympv + 1, sympv + symlen, &vmajor, &vminor)) Perl_croak(aTHX_ "Invalid version bundle %" SVf_QUOTEDPREFIX, sym); - U16 want_ver = SHORTVER(vmajor, vminor); + U16 want_ver = (U16)SHORTVER(vmajor, vminor); if(want_ver < SHORTVER(5,39) || /* round up devel version to next major release; e.g. 5.39 => 5.40 */ @@ -774,9 +774,6 @@ XS(XS_builtin_import) void Perl_boot_core_builtin(pTHX) { - HV * inc_hv; - GV * ver_gv; - SV * ver_sv; I32 i; for(i = 0; builtins[i].name; i++) { const struct BuiltinFuncDescriptor *builtin = &builtins[i]; @@ -792,7 +789,7 @@ Perl_boot_core_builtin(pTHX) SV *name = newSVpvs_flags("builtin::", SVs_TEMP); sv_catpv(name, builtin->name); CV *cv = newXS_flags(SvPV_nolen(name), builtin->xsub, __FILE__, proto, 0); - XSANY.any_i32 = builtin->ckval; + XSANY.any_i32 = (I32)builtin->ckval; if ( builtin->xsub == &XS_builtin_func1_void || builtin->xsub == &XS_builtin_func1_scalar) @@ -811,10 +808,11 @@ Perl_boot_core_builtin(pTHX) newXS_flags("builtin::import", &XS_builtin_import, __FILE__, NULL, 0); - inc_hv = GvHVn(PL_incgv); - hv_store(inc_hv, "builtin.pm", STRLENs("builtin.pm"), newSVpvs(__FILE__), 0); - ver_gv = gv_fetchpvs("builtin::VERSION", GV_ADDMULTI, SVt_PV); - ver_sv = GvSV(ver_gv); + HV * inc_hv = GvHVn(PL_incgv); + hv_stores(inc_hv, "builtin.pm", newSVpvs(__FILE__)); + + GV * ver_gv = gv_fetchpvs("builtin::VERSION", GV_ADDMULTI, SVt_PV); + SV * ver_sv = GvSV(ver_gv); /* Remember to keep $VERSION in this file and $VERSION in builtin.pm synced. */ sv_setpvs(ver_sv, "0.016"); }