Skip to content

Add newSV_type_generic, a non-inline function for creating new SVs - #24809

Open
richardleach wants to merge 7 commits into
Perl:bleadfrom
richardleach:newSV_type_generic
Open

richardleach wants to merge 7 commits into
Perl:bleadfrom
richardleach:newSV_type_generic

Conversation

@richardleach

Copy link
Copy Markdown
Contributor

Perl_newSV_type was introduced as an inline function several releases
back in order to overcome the inefficiencies of doing things like:

SV* sv = newSV(0);
sv_upgrade(sv, SVt_PV);

It somewhat achieved its objectives, but with lingering shortcomings:

  • It was still quite large, reducing the chance of inlining
  • Moving bodies_by_type[] into a header file caused bloatage

Really, Perl_newSV_type is of most use for types that are going to
regularly created in large quantities at runtime, such as SVt_IV and
SVt_PV. Something like SVt_PVIO isn't going to be created in the
same sort of quantities, and other types are mostly going to be created
in smaller quantities at compile time.

This series of commits:

  • Duplicates the body of Perl_newSV_type into a new function (Perl_newSV_type_generic) in sv.c.
  • Specialized Perl_newSV_type for the hot-at-runtime SV types.
  • Optimizes both functions.
  • Moves the bodies_by_type[] structure back into sv.c.
  • Uses the new function in preference in a small number of spots.

  • This set of changes requires a perldelta entry, and it is included.

`U64` was arbitrarily chosen as a debugging counter type but causes
warnings on 32-bit systems when _re_comp.c_ is compiled.

For its use case, it seems reasonable to make it a `UV` and cap the
value at `UV_MAX`.
`Perl_newSV_type` was introduced as an inline function several releases
back in order to overcome the inefficiencies of doing things like:

    SV* sv = newSV(0);
    sv_upgrade(sv, SVt_PV);

It somewhat achieved its objectives, but with lingering shortcomings:
* It was still quite large, reducing the chance of inlining
* Moving `bodies_by_type[]` into a header file caused bloatage

Really, `Perl_newSV_type` is of most use for types that are going to
regularly created in large quantities at runtime, such as `SVt_IV` and
`SVt_PV`. Something like `SVt_PVIO` isn't going to be created in the
same sort of quantities, and other types are mostly going to be created
in smaller quantities at compile time.

This commit duplicates the body of `Perl_newSV_type` into a new
function (`Perl_newSV_type_generic`) in _sv.c_. This function will be
able to create all SV types, with `Perl_newSV_type` then able to
specialize in types that are most in-demand at runtime.

A follow-up commit will also move `bodies_by_type[]` back into _sv.c_.
`SVt_PV` and below are handled by this function, with every other case
being passed to `Perl_newSV_type_generic`.

These types were largely selected as a result of a _gcov_ build, but it
might be that some other types should come back in. (e.g. `SVt_PVCV` for
things like _Future::AsyncAwait_?)

The function has also been microoptimized to keep its size low,
maximising the opportunities for inlining.
Get rid of some duplicate initializations, avoid unnecessary work, reduce
the need to repeatedly chase `SvANY(sv)`.
Comment thread sv.c Outdated
`Perl_newSV_type` originally needed the `bodies_by_type[]` structure to
be located inside _sv_inline.h_ for type values to be propagated at
compile time. Unfortunately, this led to some binary bloating.

`Perl_newSV_type` doesn't have this dependency any more, though it does
still need the structure to be accessible under `DEBUGGING` or `PURIFY`
builds. This commit declares it `EXTCONST` to make it available in
all compilation units but only be populated in _globals.c_.

The `PL_` has been added to keep namespace pollution to the usual
prefixes.
Avoid binary bloating when the target type is not known at compile time,
or the call site/type is pretty cold.
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