Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does sv_setref_pv() store its void * argument in the IV slot?

Tags:

perl

xs

When looking at the Perl API, I was wondering why

  • sv_setref_iv() stores its IV argument in the IV slot,
  • sv_setref_nv() stores its NV argument in the NV slot,
  • but sv_setref_pv() stores its void * argument in the IV slot, instead of the PV slot?

I have a hunch (the CUR and LEN fields wouldn't make sense for such a variable), but I'd like to have the opinion of someone knowledgeable in XS :-)

like image 723
Edward Avatar asked Nov 22 '25 18:11

Edward


1 Answers

There are many different types of scalars.

  • SvNULL isn't capable of holding any value except undef.
  • SvIV is capable of holding an IV, UV or RV.
  • SvNV is capable of holding an NV.
  • SvPV is capable of holding a PV.
  • SvPVIV is capable of holding a PV, as well as an IV, UV or RV.
  • ...

AV, HV, CV, GV are really just types of scalar too.

Note I said "capable" of holding. You can think of scalars as being objects, and the above as being classes and subclasses. Each of the above has a different structure.

Having these different types of scalars allows one to save memory.

An SvIV (the smallest scalar type capable of holding an IV) is smaller than an SvPV (the smallest scalar type capable of holding a PV).

$ perl -le'
   use Devel::Size qw( total_size );

   use Inline C => <<'\''__EOI__'\'';

      void upgrade_to_iv(SV* sv) {
         SvUPGRADE(sv, SVt_IV);
      }

      void upgrade_to_pv(SV* sv) {
         SvUPGRADE(sv, SVt_PV);
      }

__EOI__

   { my $x; upgrade_to_iv($x); print total_size($x); }
   { my $x; upgrade_to_pv($x); print total_size($x); }
'
24
40

Using an SvIV instead of an SvPV is a savings of 16 bytes per reference.

like image 114
ikegami Avatar answered Nov 24 '25 12:11

ikegami



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!