XS :reader & :writer accessors for core classes#24187
XS :reader & :writer accessors for core classes#24187richardleach wants to merge 2 commits intoPerl:bleadfrom
Conversation
|
The other thing I considered was whether the XSUBs should support RC_STACK instead of depending on Perl_xs_wrap, but I only see a test case for that (rc_add in XS::APItest). |
f1d6cd9 to
6d4eeb8
Compare
I wasn't sure about that either. Couldn't remember - and haven't yet checked - if all XSUBs will get the split-stack treatement or what. |
You can set CvXS_RCSTACK() on the XSUB CV if it is RCSTACK safe, which the current implementations aren't. |
6d4eeb8 to
5b7b053
Compare
Hopefully they are now. 😁 |
leonerd
left a comment
There was a problem hiding this comment.
I see this is still draft, but while I'm here here's a few comments anyway.
5b7b053 to
01eae7a
Compare
01eae7a to
6a09fa4
Compare
The existing `:reader` and `:writer` accessors are replaced with XS CVs to more than double performance (in the simple scalar field case, at least).
6a09fa4 to
63c9862
Compare
|
|
||
| SV* const fsv = fields[fieldix]; | ||
| /* Assigning magic to a field SV is currently unused and unsupported. */ | ||
| assert(!SvMAGICAL(fsv)); |
There was a problem hiding this comment.
Magic is everywhere, if you know where to look:
$ ./perl -Ilib -MDevel::Peek -Mfeature=class -e 'class C { field $x:reader :writer; method f { length $x } method d { ::Dump($x) } } my $c = C->new; $c->set_x("\x{100}"); $c->f; $c->d; $c->x'
class is experimental at -e line 1.
field is experimental at -e line 1.
method is experimental at -e line 1.
method is experimental at -e line 1.
SV = PVMG(0x561a15549be8) at 0x561a154d3900
REFCNT = 2
FLAGS = (SMG,POK,IsCOW,pPOK,UTF8)
IV = 0
NV = 0
PV = 0x561a15530348 "\xC4\x80"\0 [UTF8 "\x{100}"]
CUR = 2
LEN = 16
COW_REFCNT = 1
MAGIC = 0x561a15518dc8
MG_VIRTUAL = &PL_vtbl_utf8
MG_TYPE = PERL_MAGIC_utf8(w)
MG_LEN = 1
perl: class.c:396: class_reader_sv_xsub: Assertion `!SvMAGICAL(fsv)' failed.
Aborted
And as I said elsewhere, I don't think it's reasonable to restrict ties from fields anyway.
There was a problem hiding this comment.
Another possible hole in the "no magic" is refaliasing, field %env; ... \%env = \%ENV
Though there seems to be another bug here:
$ gdb --args ./perl -Ilib -MDevel::Peek -Mfeature=class,refaliasing -le 'class C { field %x:reader; method d { ::Dump(%x) } method add_magic_blue_smoke { \%x = \%ENV; $self } } my $c = C->new->add_magic_blue_smoke; print $c->x'
...
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
class is experimental at -e line 1.
field is experimental at -e line 1.
method is experimental at -e line 1.
method is experimental at -e line 1.
Aliasing via reference is experimental at -e line 1.
perl: class.c:481: class_reader_hv_xsub: Assertion `SvTYPE(fsv) == SVt_PVHV' failed.
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6,
no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
warning: 44 ./nptl/pthread_kill.c: No such file or directory
(gdb) up 5
#5 0x0000555555629451 in class_reader_hv_xsub (my_perl=0x555555cbd2a0,
cv=0x555555d53588) at class.c:481
481 assert(SvTYPE(fsv) == SVt_PVHV);
(gdb) call Perl_sv_dump(my_perl, fsv)
SV = UNKNOWN(0xff) (0x555555ce3870) at 0x555555cc0918
REFCNT = 0
FLAGS = ()
(non-RC_STACK)
But that crashes without this patch, yay.
| } | ||
|
|
||
| dXSTARG; | ||
| SV *rsv = SvROK(fsv) ? sv_newmortal() : TARG; |
There was a problem hiding this comment.
If we do allow ties on fields, this should SvGETMAGIC() before checking SvROK().
| SV* cvname = newSV_type_mortal(SVt_PV); | ||
| gv_fullname4(cvname, gv, NULL, TRUE); | ||
| croak("Too many arguments for subroutine '%" SVf "' (got %" UVuf "; expected %" UVuf ")", | ||
| cvname, items, expected); |
There was a problem hiding this comment.
items is never a UV, it is either I32 or SSize_t.
|
|
||
| SV* const fsv = fields[fieldix]; | ||
| /* Assigning magic to a field SV is currently unused and unsupported. */ | ||
| assert(!SvMAGICAL(fsv)); |
There was a problem hiding this comment.
Similar problem to the above:
$ ./perl -Ilib -MDevel::Peek -Mfeature=class -e 'class C { field $x:reader :writer; method f { length $x } method d { ::Dump($x) } } my $c = C->new; $c->set_x("\x{100}"); $c->f; $c->d; $c->set_x(1)'
class is experimental at -e line 1.
field is experimental at -e line 1.
method is experimental at -e line 1.
method is experimental at -e line 1.
SV = PVMG(0x55654e1dba28) at 0x55654e165900
REFCNT = 3
FLAGS = (SMG,POK,IsCOW,pPOK,UTF8)
IV = 0
NV = 0
PV = 0x55654e1c1c18 "\xC4\x80"\0 [UTF8 "\x{100}"]
CUR = 2
LEN = 16
COW_REFCNT = 1
MAGIC = 0x55654e1aa758
MG_VIRTUAL = &PL_vtbl_utf8
MG_TYPE = PERL_MAGIC_utf8(w)
MG_LEN = 1
perl: class.c:565: class_writer_sv_xsub: Assertion `!SvMAGICAL(fsv)' failed.
Aborted
| } | ||
| case G_LIST: | ||
| { | ||
| rpp_popfree_to(PL_stack_sp - 1); |
There was a problem hiding this comment.
For RCSTACK, what if this was the last reference?
Basic before/after benchmarks were run on a Linux VM:
Crudely comparing the outputs for
:reader:For
:writer: