mirror of
https://github.com/Perl/perl5.git
synced 2026-01-26 16:39:36 +00:00
OP_AELEMFASTLEX_STORE - combined sassign/aelemfast_lex
This commit introduces a new OP to replace simple cases of OP_SASSIGN and OP_AELEMFAST_LEX. (Similar concept to GH #19943) For example, `my @ary; $ary[0] = "boo"` is currently implemented as: 7 <2> sassign vKS/2 ->8 5 <$> const[PV "boo"] s ->6 - <1> ex-aelem sKRM*/2 ->7 6 <0> aelemfast_lex[@ary:1,2] sRM ->7 - <0> ex-const s ->- But now will be turned into: 6 <1> aelemfastlex_store[@ary:1,2] vKS ->7 5 <$> const(PV "boo") s ->6 - <1> ex-aelem sKRM*/2 ->6 - <0> ex-aelemfast_lex sRM ->6 - <0> ex-const s ->- This is intended to be a transparent performance optimization. It should be applicable for RHS optrees of varying complexity.
This commit is contained in:
parent
ec18fac000
commit
aafefcb901
@ -305,7 +305,7 @@ invert_opset function.
|
||||
rv2sv sassign padsv_store
|
||||
|
||||
rv2av aassign aelem aelemfast aelemfast_lex aslice kvaslice
|
||||
av2arylen
|
||||
av2arylen aelemfastlex_store
|
||||
|
||||
rv2hv helem hslice kvhslice each values keys exists delete
|
||||
aeach akeys avalues multideref argelem argdefelem argcheck
|
||||
|
||||
@ -4305,6 +4305,17 @@ sub pp_gv {
|
||||
return $self->maybe_qualify("", $self->gv_name($gv));
|
||||
}
|
||||
|
||||
sub pp_aelemfastlex_store {
|
||||
my $self = shift;
|
||||
my($op, $cx) = @_;
|
||||
my $name = $self->padname($op->targ);
|
||||
$name =~ s/^@/\$/;
|
||||
my $i = $op->private;
|
||||
$i -= 256 if $i > 127;
|
||||
my $val = $self->deparse($op->first, 7);
|
||||
return $self->maybe_parens("${name}[$i] = $val", $cx, 7);
|
||||
}
|
||||
|
||||
sub pp_aelemfast_lex {
|
||||
my $self = shift;
|
||||
my($op, $cx) = @_;
|
||||
|
||||
@ -254,6 +254,7 @@ $bits{aeach}{0} = $bf[0];
|
||||
@{$bits{aelem}}{5,4,1,0} = ($bf[8], $bf[8], $bf[1], $bf[1]);
|
||||
@{$bits{aelemfast}}{7,6,5,4,3,2,1,0} = ($bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6]);
|
||||
@{$bits{aelemfast_lex}}{7,6,5,4,3,2,1,0} = ($bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6]);
|
||||
@{$bits{aelemfastlex_store}}{7,6,5,4,3,2,1,0} = ($bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6], $bf[6]);
|
||||
$bits{akeys}{0} = $bf[0];
|
||||
$bits{alarm}{0} = $bf[0];
|
||||
$bits{and}{0} = $bf[0];
|
||||
|
||||
9
opcode.h
9
opcode.h
@ -288,6 +288,7 @@ EXTCONST char* const PL_op_name[] = {
|
||||
"rv2av",
|
||||
"aelemfast",
|
||||
"aelemfast_lex",
|
||||
"aelemfastlex_store",
|
||||
"aelem",
|
||||
"aslice",
|
||||
"kvaslice",
|
||||
@ -712,6 +713,7 @@ EXTCONST char* const PL_op_desc[] = {
|
||||
"array dereference",
|
||||
"constant array element",
|
||||
"constant lexical array element",
|
||||
"const lexical array element store",
|
||||
"array element",
|
||||
"array slice",
|
||||
"index/value array slice",
|
||||
@ -1139,6 +1141,7 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
|
||||
Perl_pp_rv2av,
|
||||
Perl_pp_aelemfast,
|
||||
Perl_pp_aelemfast_lex, /* implemented by Perl_pp_aelemfast */
|
||||
Perl_pp_aelemfastlex_store,
|
||||
Perl_pp_aelem,
|
||||
Perl_pp_aslice,
|
||||
Perl_pp_kvaslice,
|
||||
@ -1562,6 +1565,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
|
||||
Perl_ck_rvconst, /* rv2av */
|
||||
Perl_ck_null, /* aelemfast */
|
||||
Perl_ck_null, /* aelemfast_lex */
|
||||
Perl_ck_null, /* aelemfastlex_store */
|
||||
Perl_ck_null, /* aelem */
|
||||
Perl_ck_null, /* aslice */
|
||||
Perl_ck_null, /* kvaslice */
|
||||
@ -1986,6 +1990,7 @@ EXTCONST U32 PL_opargs[] = {
|
||||
0x00000148, /* rv2av */
|
||||
0x00013644, /* aelemfast */
|
||||
0x00013040, /* aelemfast_lex */
|
||||
0x00013140, /* aelemfastlex_store */
|
||||
0x00013204, /* aelem */
|
||||
0x00023401, /* aslice */
|
||||
0x00023401, /* kvaslice */
|
||||
@ -2671,6 +2676,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
|
||||
118, /* rv2av */
|
||||
125, /* aelemfast */
|
||||
125, /* aelemfast_lex */
|
||||
125, /* aelemfastlex_store */
|
||||
126, /* aelem */
|
||||
131, /* aslice */
|
||||
134, /* kvaslice */
|
||||
@ -3003,7 +3009,7 @@ EXTCONST U16 PL_op_private_bitdefs[] = {
|
||||
0x32cc, 0x0067, /* vec */
|
||||
0x3438, 0x05b4, 0x4730, 0x018f, /* index, rindex */
|
||||
0x31dc, 0x3858, 0x05b4, 0x32cc, 0x40a8, 0x4384, 0x0003, /* rv2av */
|
||||
0x025f, /* aelemfast, aelemfast_lex */
|
||||
0x025f, /* aelemfast, aelemfast_lex, aelemfastlex_store */
|
||||
0x31dc, 0x30d8, 0x03d6, 0x32cc, 0x0067, /* aelem, helem */
|
||||
0x31dc, 0x32cc, 0x40a9, /* aslice, hslice */
|
||||
0x32cd, /* kvaslice, kvhslice */
|
||||
@ -3187,6 +3193,7 @@ EXTCONST U8 PL_op_private_valid[] = {
|
||||
/* RV2AV */ (OPpARG1_MASK|OPpHINT_STRICT_REFS|OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpTRUEBOOL|OPpOUR_INTRO|OPpLVAL_INTRO),
|
||||
/* AELEMFAST */ (255),
|
||||
/* AELEMFAST_LEX */ (255),
|
||||
/* AELEMFASTLEX_STORE */ (255),
|
||||
/* AELEM */ (OPpARG2_MASK|OPpMAYBE_LVSUB|OPpDEREF|OPpLVAL_DEFER|OPpLVAL_INTRO),
|
||||
/* ASLICE */ (OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpLVAL_INTRO),
|
||||
/* KVASLICE */ (OPpMAYBE_LVSUB),
|
||||
|
||||
557
opnames.h
557
opnames.h
@ -153,287 +153,288 @@ typedef enum opcode {
|
||||
OP_RV2AV = 136,
|
||||
OP_AELEMFAST = 137,
|
||||
OP_AELEMFAST_LEX = 138,
|
||||
OP_AELEM = 139,
|
||||
OP_ASLICE = 140,
|
||||
OP_KVASLICE = 141,
|
||||
OP_AEACH = 142,
|
||||
OP_AVALUES = 143,
|
||||
OP_AKEYS = 144,
|
||||
OP_EACH = 145,
|
||||
OP_VALUES = 146,
|
||||
OP_KEYS = 147,
|
||||
OP_DELETE = 148,
|
||||
OP_EXISTS = 149,
|
||||
OP_RV2HV = 150,
|
||||
OP_HELEM = 151,
|
||||
OP_HSLICE = 152,
|
||||
OP_KVHSLICE = 153,
|
||||
OP_MULTIDEREF = 154,
|
||||
OP_UNPACK = 155,
|
||||
OP_PACK = 156,
|
||||
OP_SPLIT = 157,
|
||||
OP_JOIN = 158,
|
||||
OP_LIST = 159,
|
||||
OP_LSLICE = 160,
|
||||
OP_ANONLIST = 161,
|
||||
OP_ANONHASH = 162,
|
||||
OP_SPLICE = 163,
|
||||
OP_PUSH = 164,
|
||||
OP_POP = 165,
|
||||
OP_SHIFT = 166,
|
||||
OP_UNSHIFT = 167,
|
||||
OP_SORT = 168,
|
||||
OP_REVERSE = 169,
|
||||
OP_GREPSTART = 170,
|
||||
OP_GREPWHILE = 171,
|
||||
OP_MAPSTART = 172,
|
||||
OP_MAPWHILE = 173,
|
||||
OP_RANGE = 174,
|
||||
OP_FLIP = 175,
|
||||
OP_FLOP = 176,
|
||||
OP_AND = 177,
|
||||
OP_OR = 178,
|
||||
OP_XOR = 179,
|
||||
OP_DOR = 180,
|
||||
OP_COND_EXPR = 181,
|
||||
OP_ANDASSIGN = 182,
|
||||
OP_ORASSIGN = 183,
|
||||
OP_DORASSIGN = 184,
|
||||
OP_ENTERSUB = 185,
|
||||
OP_LEAVESUB = 186,
|
||||
OP_LEAVESUBLV = 187,
|
||||
OP_ARGCHECK = 188,
|
||||
OP_ARGELEM = 189,
|
||||
OP_ARGDEFELEM = 190,
|
||||
OP_CALLER = 191,
|
||||
OP_WARN = 192,
|
||||
OP_DIE = 193,
|
||||
OP_RESET = 194,
|
||||
OP_LINESEQ = 195,
|
||||
OP_NEXTSTATE = 196,
|
||||
OP_DBSTATE = 197,
|
||||
OP_UNSTACK = 198,
|
||||
OP_ENTER = 199,
|
||||
OP_LEAVE = 200,
|
||||
OP_SCOPE = 201,
|
||||
OP_ENTERITER = 202,
|
||||
OP_ITER = 203,
|
||||
OP_ENTERLOOP = 204,
|
||||
OP_LEAVELOOP = 205,
|
||||
OP_RETURN = 206,
|
||||
OP_LAST = 207,
|
||||
OP_NEXT = 208,
|
||||
OP_REDO = 209,
|
||||
OP_DUMP = 210,
|
||||
OP_GOTO = 211,
|
||||
OP_EXIT = 212,
|
||||
OP_METHOD = 213,
|
||||
OP_METHOD_NAMED = 214,
|
||||
OP_METHOD_SUPER = 215,
|
||||
OP_METHOD_REDIR = 216,
|
||||
OP_METHOD_REDIR_SUPER = 217,
|
||||
OP_ENTERGIVEN = 218,
|
||||
OP_LEAVEGIVEN = 219,
|
||||
OP_ENTERWHEN = 220,
|
||||
OP_LEAVEWHEN = 221,
|
||||
OP_BREAK = 222,
|
||||
OP_CONTINUE = 223,
|
||||
OP_OPEN = 224,
|
||||
OP_CLOSE = 225,
|
||||
OP_PIPE_OP = 226,
|
||||
OP_FILENO = 227,
|
||||
OP_UMASK = 228,
|
||||
OP_BINMODE = 229,
|
||||
OP_TIE = 230,
|
||||
OP_UNTIE = 231,
|
||||
OP_TIED = 232,
|
||||
OP_DBMOPEN = 233,
|
||||
OP_DBMCLOSE = 234,
|
||||
OP_SSELECT = 235,
|
||||
OP_SELECT = 236,
|
||||
OP_GETC = 237,
|
||||
OP_READ = 238,
|
||||
OP_ENTERWRITE = 239,
|
||||
OP_LEAVEWRITE = 240,
|
||||
OP_PRTF = 241,
|
||||
OP_PRINT = 242,
|
||||
OP_SAY = 243,
|
||||
OP_SYSOPEN = 244,
|
||||
OP_SYSSEEK = 245,
|
||||
OP_SYSREAD = 246,
|
||||
OP_SYSWRITE = 247,
|
||||
OP_EOF = 248,
|
||||
OP_TELL = 249,
|
||||
OP_SEEK = 250,
|
||||
OP_TRUNCATE = 251,
|
||||
OP_FCNTL = 252,
|
||||
OP_IOCTL = 253,
|
||||
OP_FLOCK = 254,
|
||||
OP_SEND = 255,
|
||||
OP_RECV = 256,
|
||||
OP_SOCKET = 257,
|
||||
OP_SOCKPAIR = 258,
|
||||
OP_BIND = 259,
|
||||
OP_CONNECT = 260,
|
||||
OP_LISTEN = 261,
|
||||
OP_ACCEPT = 262,
|
||||
OP_SHUTDOWN = 263,
|
||||
OP_GSOCKOPT = 264,
|
||||
OP_SSOCKOPT = 265,
|
||||
OP_GETSOCKNAME = 266,
|
||||
OP_GETPEERNAME = 267,
|
||||
OP_LSTAT = 268,
|
||||
OP_STAT = 269,
|
||||
OP_FTRREAD = 270,
|
||||
OP_FTRWRITE = 271,
|
||||
OP_FTREXEC = 272,
|
||||
OP_FTEREAD = 273,
|
||||
OP_FTEWRITE = 274,
|
||||
OP_FTEEXEC = 275,
|
||||
OP_FTIS = 276,
|
||||
OP_FTSIZE = 277,
|
||||
OP_FTMTIME = 278,
|
||||
OP_FTATIME = 279,
|
||||
OP_FTCTIME = 280,
|
||||
OP_FTROWNED = 281,
|
||||
OP_FTEOWNED = 282,
|
||||
OP_FTZERO = 283,
|
||||
OP_FTSOCK = 284,
|
||||
OP_FTCHR = 285,
|
||||
OP_FTBLK = 286,
|
||||
OP_FTFILE = 287,
|
||||
OP_FTDIR = 288,
|
||||
OP_FTPIPE = 289,
|
||||
OP_FTSUID = 290,
|
||||
OP_FTSGID = 291,
|
||||
OP_FTSVTX = 292,
|
||||
OP_FTLINK = 293,
|
||||
OP_FTTTY = 294,
|
||||
OP_FTTEXT = 295,
|
||||
OP_FTBINARY = 296,
|
||||
OP_CHDIR = 297,
|
||||
OP_CHOWN = 298,
|
||||
OP_CHROOT = 299,
|
||||
OP_UNLINK = 300,
|
||||
OP_CHMOD = 301,
|
||||
OP_UTIME = 302,
|
||||
OP_RENAME = 303,
|
||||
OP_LINK = 304,
|
||||
OP_SYMLINK = 305,
|
||||
OP_READLINK = 306,
|
||||
OP_MKDIR = 307,
|
||||
OP_RMDIR = 308,
|
||||
OP_OPEN_DIR = 309,
|
||||
OP_READDIR = 310,
|
||||
OP_TELLDIR = 311,
|
||||
OP_SEEKDIR = 312,
|
||||
OP_REWINDDIR = 313,
|
||||
OP_CLOSEDIR = 314,
|
||||
OP_FORK = 315,
|
||||
OP_WAIT = 316,
|
||||
OP_WAITPID = 317,
|
||||
OP_SYSTEM = 318,
|
||||
OP_EXEC = 319,
|
||||
OP_KILL = 320,
|
||||
OP_GETPPID = 321,
|
||||
OP_GETPGRP = 322,
|
||||
OP_SETPGRP = 323,
|
||||
OP_GETPRIORITY = 324,
|
||||
OP_SETPRIORITY = 325,
|
||||
OP_TIME = 326,
|
||||
OP_TMS = 327,
|
||||
OP_LOCALTIME = 328,
|
||||
OP_GMTIME = 329,
|
||||
OP_ALARM = 330,
|
||||
OP_SLEEP = 331,
|
||||
OP_SHMGET = 332,
|
||||
OP_SHMCTL = 333,
|
||||
OP_SHMREAD = 334,
|
||||
OP_SHMWRITE = 335,
|
||||
OP_MSGGET = 336,
|
||||
OP_MSGCTL = 337,
|
||||
OP_MSGSND = 338,
|
||||
OP_MSGRCV = 339,
|
||||
OP_SEMOP = 340,
|
||||
OP_SEMGET = 341,
|
||||
OP_SEMCTL = 342,
|
||||
OP_REQUIRE = 343,
|
||||
OP_DOFILE = 344,
|
||||
OP_HINTSEVAL = 345,
|
||||
OP_ENTEREVAL = 346,
|
||||
OP_LEAVEEVAL = 347,
|
||||
OP_ENTERTRY = 348,
|
||||
OP_LEAVETRY = 349,
|
||||
OP_GHBYNAME = 350,
|
||||
OP_GHBYADDR = 351,
|
||||
OP_GHOSTENT = 352,
|
||||
OP_GNBYNAME = 353,
|
||||
OP_GNBYADDR = 354,
|
||||
OP_GNETENT = 355,
|
||||
OP_GPBYNAME = 356,
|
||||
OP_GPBYNUMBER = 357,
|
||||
OP_GPROTOENT = 358,
|
||||
OP_GSBYNAME = 359,
|
||||
OP_GSBYPORT = 360,
|
||||
OP_GSERVENT = 361,
|
||||
OP_SHOSTENT = 362,
|
||||
OP_SNETENT = 363,
|
||||
OP_SPROTOENT = 364,
|
||||
OP_SSERVENT = 365,
|
||||
OP_EHOSTENT = 366,
|
||||
OP_ENETENT = 367,
|
||||
OP_EPROTOENT = 368,
|
||||
OP_ESERVENT = 369,
|
||||
OP_GPWNAM = 370,
|
||||
OP_GPWUID = 371,
|
||||
OP_GPWENT = 372,
|
||||
OP_SPWENT = 373,
|
||||
OP_EPWENT = 374,
|
||||
OP_GGRNAM = 375,
|
||||
OP_GGRGID = 376,
|
||||
OP_GGRENT = 377,
|
||||
OP_SGRENT = 378,
|
||||
OP_EGRENT = 379,
|
||||
OP_GETLOGIN = 380,
|
||||
OP_SYSCALL = 381,
|
||||
OP_LOCK = 382,
|
||||
OP_ONCE = 383,
|
||||
OP_CUSTOM = 384,
|
||||
OP_COREARGS = 385,
|
||||
OP_AVHVSWITCH = 386,
|
||||
OP_RUNCV = 387,
|
||||
OP_FC = 388,
|
||||
OP_PADCV = 389,
|
||||
OP_INTROCV = 390,
|
||||
OP_CLONECV = 391,
|
||||
OP_PADRANGE = 392,
|
||||
OP_REFASSIGN = 393,
|
||||
OP_LVREF = 394,
|
||||
OP_LVREFSLICE = 395,
|
||||
OP_LVAVREF = 396,
|
||||
OP_ANONCONST = 397,
|
||||
OP_ISA = 398,
|
||||
OP_CMPCHAIN_AND = 399,
|
||||
OP_CMPCHAIN_DUP = 400,
|
||||
OP_ENTERTRYCATCH = 401,
|
||||
OP_LEAVETRYCATCH = 402,
|
||||
OP_POPTRY = 403,
|
||||
OP_CATCH = 404,
|
||||
OP_PUSHDEFER = 405,
|
||||
OP_IS_BOOL = 406,
|
||||
OP_IS_WEAK = 407,
|
||||
OP_WEAKEN = 408,
|
||||
OP_UNWEAKEN = 409,
|
||||
OP_BLESSED = 410,
|
||||
OP_REFADDR = 411,
|
||||
OP_REFTYPE = 412,
|
||||
OP_CEIL = 413,
|
||||
OP_FLOOR = 414,
|
||||
OP_IS_TAINTED = 415,
|
||||
OP_AELEMFASTLEX_STORE = 139,
|
||||
OP_AELEM = 140,
|
||||
OP_ASLICE = 141,
|
||||
OP_KVASLICE = 142,
|
||||
OP_AEACH = 143,
|
||||
OP_AVALUES = 144,
|
||||
OP_AKEYS = 145,
|
||||
OP_EACH = 146,
|
||||
OP_VALUES = 147,
|
||||
OP_KEYS = 148,
|
||||
OP_DELETE = 149,
|
||||
OP_EXISTS = 150,
|
||||
OP_RV2HV = 151,
|
||||
OP_HELEM = 152,
|
||||
OP_HSLICE = 153,
|
||||
OP_KVHSLICE = 154,
|
||||
OP_MULTIDEREF = 155,
|
||||
OP_UNPACK = 156,
|
||||
OP_PACK = 157,
|
||||
OP_SPLIT = 158,
|
||||
OP_JOIN = 159,
|
||||
OP_LIST = 160,
|
||||
OP_LSLICE = 161,
|
||||
OP_ANONLIST = 162,
|
||||
OP_ANONHASH = 163,
|
||||
OP_SPLICE = 164,
|
||||
OP_PUSH = 165,
|
||||
OP_POP = 166,
|
||||
OP_SHIFT = 167,
|
||||
OP_UNSHIFT = 168,
|
||||
OP_SORT = 169,
|
||||
OP_REVERSE = 170,
|
||||
OP_GREPSTART = 171,
|
||||
OP_GREPWHILE = 172,
|
||||
OP_MAPSTART = 173,
|
||||
OP_MAPWHILE = 174,
|
||||
OP_RANGE = 175,
|
||||
OP_FLIP = 176,
|
||||
OP_FLOP = 177,
|
||||
OP_AND = 178,
|
||||
OP_OR = 179,
|
||||
OP_XOR = 180,
|
||||
OP_DOR = 181,
|
||||
OP_COND_EXPR = 182,
|
||||
OP_ANDASSIGN = 183,
|
||||
OP_ORASSIGN = 184,
|
||||
OP_DORASSIGN = 185,
|
||||
OP_ENTERSUB = 186,
|
||||
OP_LEAVESUB = 187,
|
||||
OP_LEAVESUBLV = 188,
|
||||
OP_ARGCHECK = 189,
|
||||
OP_ARGELEM = 190,
|
||||
OP_ARGDEFELEM = 191,
|
||||
OP_CALLER = 192,
|
||||
OP_WARN = 193,
|
||||
OP_DIE = 194,
|
||||
OP_RESET = 195,
|
||||
OP_LINESEQ = 196,
|
||||
OP_NEXTSTATE = 197,
|
||||
OP_DBSTATE = 198,
|
||||
OP_UNSTACK = 199,
|
||||
OP_ENTER = 200,
|
||||
OP_LEAVE = 201,
|
||||
OP_SCOPE = 202,
|
||||
OP_ENTERITER = 203,
|
||||
OP_ITER = 204,
|
||||
OP_ENTERLOOP = 205,
|
||||
OP_LEAVELOOP = 206,
|
||||
OP_RETURN = 207,
|
||||
OP_LAST = 208,
|
||||
OP_NEXT = 209,
|
||||
OP_REDO = 210,
|
||||
OP_DUMP = 211,
|
||||
OP_GOTO = 212,
|
||||
OP_EXIT = 213,
|
||||
OP_METHOD = 214,
|
||||
OP_METHOD_NAMED = 215,
|
||||
OP_METHOD_SUPER = 216,
|
||||
OP_METHOD_REDIR = 217,
|
||||
OP_METHOD_REDIR_SUPER = 218,
|
||||
OP_ENTERGIVEN = 219,
|
||||
OP_LEAVEGIVEN = 220,
|
||||
OP_ENTERWHEN = 221,
|
||||
OP_LEAVEWHEN = 222,
|
||||
OP_BREAK = 223,
|
||||
OP_CONTINUE = 224,
|
||||
OP_OPEN = 225,
|
||||
OP_CLOSE = 226,
|
||||
OP_PIPE_OP = 227,
|
||||
OP_FILENO = 228,
|
||||
OP_UMASK = 229,
|
||||
OP_BINMODE = 230,
|
||||
OP_TIE = 231,
|
||||
OP_UNTIE = 232,
|
||||
OP_TIED = 233,
|
||||
OP_DBMOPEN = 234,
|
||||
OP_DBMCLOSE = 235,
|
||||
OP_SSELECT = 236,
|
||||
OP_SELECT = 237,
|
||||
OP_GETC = 238,
|
||||
OP_READ = 239,
|
||||
OP_ENTERWRITE = 240,
|
||||
OP_LEAVEWRITE = 241,
|
||||
OP_PRTF = 242,
|
||||
OP_PRINT = 243,
|
||||
OP_SAY = 244,
|
||||
OP_SYSOPEN = 245,
|
||||
OP_SYSSEEK = 246,
|
||||
OP_SYSREAD = 247,
|
||||
OP_SYSWRITE = 248,
|
||||
OP_EOF = 249,
|
||||
OP_TELL = 250,
|
||||
OP_SEEK = 251,
|
||||
OP_TRUNCATE = 252,
|
||||
OP_FCNTL = 253,
|
||||
OP_IOCTL = 254,
|
||||
OP_FLOCK = 255,
|
||||
OP_SEND = 256,
|
||||
OP_RECV = 257,
|
||||
OP_SOCKET = 258,
|
||||
OP_SOCKPAIR = 259,
|
||||
OP_BIND = 260,
|
||||
OP_CONNECT = 261,
|
||||
OP_LISTEN = 262,
|
||||
OP_ACCEPT = 263,
|
||||
OP_SHUTDOWN = 264,
|
||||
OP_GSOCKOPT = 265,
|
||||
OP_SSOCKOPT = 266,
|
||||
OP_GETSOCKNAME = 267,
|
||||
OP_GETPEERNAME = 268,
|
||||
OP_LSTAT = 269,
|
||||
OP_STAT = 270,
|
||||
OP_FTRREAD = 271,
|
||||
OP_FTRWRITE = 272,
|
||||
OP_FTREXEC = 273,
|
||||
OP_FTEREAD = 274,
|
||||
OP_FTEWRITE = 275,
|
||||
OP_FTEEXEC = 276,
|
||||
OP_FTIS = 277,
|
||||
OP_FTSIZE = 278,
|
||||
OP_FTMTIME = 279,
|
||||
OP_FTATIME = 280,
|
||||
OP_FTCTIME = 281,
|
||||
OP_FTROWNED = 282,
|
||||
OP_FTEOWNED = 283,
|
||||
OP_FTZERO = 284,
|
||||
OP_FTSOCK = 285,
|
||||
OP_FTCHR = 286,
|
||||
OP_FTBLK = 287,
|
||||
OP_FTFILE = 288,
|
||||
OP_FTDIR = 289,
|
||||
OP_FTPIPE = 290,
|
||||
OP_FTSUID = 291,
|
||||
OP_FTSGID = 292,
|
||||
OP_FTSVTX = 293,
|
||||
OP_FTLINK = 294,
|
||||
OP_FTTTY = 295,
|
||||
OP_FTTEXT = 296,
|
||||
OP_FTBINARY = 297,
|
||||
OP_CHDIR = 298,
|
||||
OP_CHOWN = 299,
|
||||
OP_CHROOT = 300,
|
||||
OP_UNLINK = 301,
|
||||
OP_CHMOD = 302,
|
||||
OP_UTIME = 303,
|
||||
OP_RENAME = 304,
|
||||
OP_LINK = 305,
|
||||
OP_SYMLINK = 306,
|
||||
OP_READLINK = 307,
|
||||
OP_MKDIR = 308,
|
||||
OP_RMDIR = 309,
|
||||
OP_OPEN_DIR = 310,
|
||||
OP_READDIR = 311,
|
||||
OP_TELLDIR = 312,
|
||||
OP_SEEKDIR = 313,
|
||||
OP_REWINDDIR = 314,
|
||||
OP_CLOSEDIR = 315,
|
||||
OP_FORK = 316,
|
||||
OP_WAIT = 317,
|
||||
OP_WAITPID = 318,
|
||||
OP_SYSTEM = 319,
|
||||
OP_EXEC = 320,
|
||||
OP_KILL = 321,
|
||||
OP_GETPPID = 322,
|
||||
OP_GETPGRP = 323,
|
||||
OP_SETPGRP = 324,
|
||||
OP_GETPRIORITY = 325,
|
||||
OP_SETPRIORITY = 326,
|
||||
OP_TIME = 327,
|
||||
OP_TMS = 328,
|
||||
OP_LOCALTIME = 329,
|
||||
OP_GMTIME = 330,
|
||||
OP_ALARM = 331,
|
||||
OP_SLEEP = 332,
|
||||
OP_SHMGET = 333,
|
||||
OP_SHMCTL = 334,
|
||||
OP_SHMREAD = 335,
|
||||
OP_SHMWRITE = 336,
|
||||
OP_MSGGET = 337,
|
||||
OP_MSGCTL = 338,
|
||||
OP_MSGSND = 339,
|
||||
OP_MSGRCV = 340,
|
||||
OP_SEMOP = 341,
|
||||
OP_SEMGET = 342,
|
||||
OP_SEMCTL = 343,
|
||||
OP_REQUIRE = 344,
|
||||
OP_DOFILE = 345,
|
||||
OP_HINTSEVAL = 346,
|
||||
OP_ENTEREVAL = 347,
|
||||
OP_LEAVEEVAL = 348,
|
||||
OP_ENTERTRY = 349,
|
||||
OP_LEAVETRY = 350,
|
||||
OP_GHBYNAME = 351,
|
||||
OP_GHBYADDR = 352,
|
||||
OP_GHOSTENT = 353,
|
||||
OP_GNBYNAME = 354,
|
||||
OP_GNBYADDR = 355,
|
||||
OP_GNETENT = 356,
|
||||
OP_GPBYNAME = 357,
|
||||
OP_GPBYNUMBER = 358,
|
||||
OP_GPROTOENT = 359,
|
||||
OP_GSBYNAME = 360,
|
||||
OP_GSBYPORT = 361,
|
||||
OP_GSERVENT = 362,
|
||||
OP_SHOSTENT = 363,
|
||||
OP_SNETENT = 364,
|
||||
OP_SPROTOENT = 365,
|
||||
OP_SSERVENT = 366,
|
||||
OP_EHOSTENT = 367,
|
||||
OP_ENETENT = 368,
|
||||
OP_EPROTOENT = 369,
|
||||
OP_ESERVENT = 370,
|
||||
OP_GPWNAM = 371,
|
||||
OP_GPWUID = 372,
|
||||
OP_GPWENT = 373,
|
||||
OP_SPWENT = 374,
|
||||
OP_EPWENT = 375,
|
||||
OP_GGRNAM = 376,
|
||||
OP_GGRGID = 377,
|
||||
OP_GGRENT = 378,
|
||||
OP_SGRENT = 379,
|
||||
OP_EGRENT = 380,
|
||||
OP_GETLOGIN = 381,
|
||||
OP_SYSCALL = 382,
|
||||
OP_LOCK = 383,
|
||||
OP_ONCE = 384,
|
||||
OP_CUSTOM = 385,
|
||||
OP_COREARGS = 386,
|
||||
OP_AVHVSWITCH = 387,
|
||||
OP_RUNCV = 388,
|
||||
OP_FC = 389,
|
||||
OP_PADCV = 390,
|
||||
OP_INTROCV = 391,
|
||||
OP_CLONECV = 392,
|
||||
OP_PADRANGE = 393,
|
||||
OP_REFASSIGN = 394,
|
||||
OP_LVREF = 395,
|
||||
OP_LVREFSLICE = 396,
|
||||
OP_LVAVREF = 397,
|
||||
OP_ANONCONST = 398,
|
||||
OP_ISA = 399,
|
||||
OP_CMPCHAIN_AND = 400,
|
||||
OP_CMPCHAIN_DUP = 401,
|
||||
OP_ENTERTRYCATCH = 402,
|
||||
OP_LEAVETRYCATCH = 403,
|
||||
OP_POPTRY = 404,
|
||||
OP_CATCH = 405,
|
||||
OP_PUSHDEFER = 406,
|
||||
OP_IS_BOOL = 407,
|
||||
OP_IS_WEAK = 408,
|
||||
OP_WEAKEN = 409,
|
||||
OP_UNWEAKEN = 410,
|
||||
OP_BLESSED = 411,
|
||||
OP_REFADDR = 412,
|
||||
OP_REFTYPE = 413,
|
||||
OP_CEIL = 414,
|
||||
OP_FLOOR = 415,
|
||||
OP_IS_TAINTED = 416,
|
||||
OP_max
|
||||
} opcode;
|
||||
|
||||
#define MAXO 416
|
||||
#define MAXO 417
|
||||
#define OP_FREED MAXO
|
||||
|
||||
/* the OP_IS_* macros are optimized to a simple range check because
|
||||
|
||||
49
peep.c
49
peep.c
@ -3951,6 +3951,55 @@ Perl_rpeep(pTHX_ OP *o)
|
||||
/* NULL the previous op ptrs, so rpeep can continue */
|
||||
oldoldop = NULL; oldop = NULL;
|
||||
}
|
||||
|
||||
/* Combine a simple SASSIGN OP with an AELEMFAST_LEX lvalue
|
||||
* into a single OP. This optimization covers arbitrarily
|
||||
* complicated RHS OP trees. */
|
||||
|
||||
if (!(o->op_private & (OPpASSIGN_BACKWARDS|OPpASSIGN_CV_TO_GV))
|
||||
&& (lval->op_type == OP_NULL) && (lval->op_private == 2) &&
|
||||
(cBINOPx(lval)->op_first->op_type == OP_AELEMFAST_LEX) &&
|
||||
((I8)(cBINOPx(lval)->op_first->op_private) >= 0)
|
||||
) {
|
||||
OP * lex = cBINOPx(lval)->op_first;
|
||||
/* SASSIGN's bitfield flags, such as op_moresib and
|
||||
* op_slabbed, will be carried over unchanged. */
|
||||
OpTYPE_set(o, OP_AELEMFASTLEX_STORE);
|
||||
|
||||
/* Explicitly craft the new OP's op_flags, carrying
|
||||
* some bits over from the SASSIGN */
|
||||
o->op_flags = (
|
||||
OPf_KIDS | OPf_STACKED |
|
||||
(o->op_flags & (OPf_WANT|OPf_PARENS))
|
||||
);
|
||||
|
||||
/* Copy the AELEMFAST_LEX op->private, which contains
|
||||
* the key index. */
|
||||
o->op_private = lex->op_private;
|
||||
|
||||
/* Take the targ from the AELEMFAST_LEX */
|
||||
o->op_targ = lex->op_targ; lex->op_targ = 0;
|
||||
|
||||
assert(oldop->op_type == OP_AELEMFAST_LEX);
|
||||
/* oldoldop can be arbitrarily deep in the RHS OP tree */
|
||||
oldoldop->op_next = o;
|
||||
|
||||
/* Even when (rhs != oldoldop), rhs might still have a
|
||||
* relevant op_next ptr to lex. (Updating it here can
|
||||
* also cause other ops in the RHS to get the desired
|
||||
* op_next pointer, presumably thanks to the finalizer.)
|
||||
* This is definitely truewhen rhs is OP_NULL with a
|
||||
* LOGOP kid (e.g. orassign). There may be other cases. */
|
||||
if (rhs->op_next == lex)
|
||||
rhs->op_next = o;
|
||||
|
||||
/* Now null-out the AELEMFAST_LEX */
|
||||
op_null(lex);
|
||||
|
||||
/* NULL the previous op ptrs, so rpeep can continue */
|
||||
oldop = oldoldop; oldoldop = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
50
pp_hot.c
50
pp_hot.c
@ -169,6 +169,56 @@ PP(pp_padsv_store)
|
||||
RETURN;
|
||||
}
|
||||
|
||||
/* A mashup of simplified AELEMFAST_LEX + SASSIGN OPs */
|
||||
|
||||
PP(pp_aelemfastlex_store)
|
||||
{
|
||||
dSP;
|
||||
OP * const op = PL_op;
|
||||
SV* const val = TOPs; /* RHS value to assign */
|
||||
AV * const av = MUTABLE_AV(PAD_SV(op->op_targ));
|
||||
const I8 key = (I8)PL_op->op_private;
|
||||
SV * targ = NULL;
|
||||
|
||||
/* !OPf_STACKED is not handled by this OP */
|
||||
assert(op->op_flags & OPf_STACKED);
|
||||
|
||||
/* Inlined, simplified pp_aelemfast here */
|
||||
assert(SvTYPE(av) == SVt_PVAV);
|
||||
assert(key >= 0);
|
||||
|
||||
/* inlined av_fetch() for simple cases ... */
|
||||
if (!SvRMAGICAL(av) && key <= AvFILLp(av)) {
|
||||
targ = AvARRAY(av)[key];
|
||||
}
|
||||
/* ... else do it the hard way */
|
||||
if (!targ) {
|
||||
SV **svp = av_fetch(av, key, 1);
|
||||
|
||||
if (svp)
|
||||
targ = *svp;
|
||||
else
|
||||
DIE(aTHX_ PL_no_aelem, (int)key);
|
||||
}
|
||||
|
||||
/* Inlined, simplified pp_sassign from here */
|
||||
assert(TAINTING_get || !TAINT_get);
|
||||
if (UNLIKELY(TAINT_get) && !SvTAINTED(val))
|
||||
TAINT_NOT;
|
||||
|
||||
if (
|
||||
UNLIKELY(SvTEMP(targ)) && !SvSMAGICAL(targ) && SvREFCNT(targ) == 1 &&
|
||||
(!isGV_with_GP(targ) || SvFAKE(targ)) && ckWARN(WARN_MISC)
|
||||
)
|
||||
Perl_warner(aTHX_
|
||||
packWARN(WARN_MISC), "Useless assignment to a temporary"
|
||||
);
|
||||
SvSetMagicSV(targ, val);
|
||||
|
||||
SETs(targ);
|
||||
RETURN;
|
||||
}
|
||||
|
||||
PP(pp_sassign)
|
||||
{
|
||||
dSP;
|
||||
|
||||
@ -12,6 +12,7 @@ PERL_CALLCONV OP *Perl_pp_add(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_aeach(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_aelem(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_aelemfast(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_aelemfastlex_store(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_akeys(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_alarm(pTHX) __attribute__visibility__("hidden");
|
||||
PERL_CALLCONV OP *Perl_pp_and(pTHX) __attribute__visibility__("hidden");
|
||||
|
||||
@ -199,7 +199,7 @@ use strict;
|
||||
# find which ops use 0,1,2,3 or 4 bits of op_private for arg count info
|
||||
|
||||
$args0{$_} = 1 for qw(entersub avhvswitch
|
||||
rv2hv); # UNOPs that usurp bit 0
|
||||
rv2hv aelemfastlex_store); # UNOPs that usurp bit 0
|
||||
|
||||
# Historically, bit ops used bit 0 to indicate 'use integer' in scope;
|
||||
# For now, ban use of bits 0..1 as an arg count, in order to detect
|
||||
@ -627,7 +627,7 @@ addbits('padrange',
|
||||
|
||||
|
||||
|
||||
for (qw(aelemfast aelemfast_lex)) {
|
||||
for (qw(aelemfast aelemfast_lex aelemfastlex_store)) {
|
||||
addbits($_,
|
||||
'0..7' => {
|
||||
label => 'key',
|
||||
|
||||
@ -223,6 +223,7 @@ quotemeta quotemeta ck_fun fstu% S?
|
||||
rv2av array dereference ck_rvconst dt1
|
||||
aelemfast constant array element ck_null ds$ A S
|
||||
aelemfast_lex constant lexical array element ck_null d0 A S
|
||||
aelemfastlex_store const lexical array element store ck_null d1 A S
|
||||
aelem array element ck_null s2 A S
|
||||
aslice array slice ck_null m@ A L
|
||||
kvaslice index/value array slice ck_null m@ A L
|
||||
|
||||
@ -1402,6 +1402,22 @@
|
||||
code => '$r = []; $r = $r1;',
|
||||
},
|
||||
|
||||
'expr::sassign::aelemfast_lex_assign' => {
|
||||
desc => 'lexical $x[0] = 1',
|
||||
setup => 'my @x',
|
||||
code => '$x[0] = 1',
|
||||
},
|
||||
'expr::sassign::aelemfast_lex_assign_ref' => {
|
||||
desc => 'lexical $x[0] = []',
|
||||
setup => 'my @x',
|
||||
code => '$x[0] = []',
|
||||
},
|
||||
'expr::sassign::aelemfast_lex_assign_deref' => {
|
||||
desc => 'lexical $x[0][1]',
|
||||
setup => 'my @x = ([1,2])',
|
||||
code => '$x[0][1] = 1',
|
||||
},
|
||||
|
||||
|
||||
'func::grep::bool0' => {
|
||||
desc => 'grep returning 0 items in boolean context',
|
||||
|
||||
@ -886,4 +886,36 @@ test_opcount(0, 'my $y= 1; my @x= \($y= undef);',
|
||||
srefgen => 1,
|
||||
});
|
||||
|
||||
# aelemfast_lex + sassign are replaced by a combined OP
|
||||
test_opcount(0, "simple aelemfast_lex + sassign replacement",
|
||||
sub { my @x; $x[0] = "foo" },
|
||||
{
|
||||
aelemfast_lex => 0,
|
||||
aelemfastlex_store => 1,
|
||||
padav => 1,
|
||||
sassign => 0,
|
||||
});
|
||||
|
||||
# aelemfast_lex + sassign are not replaced by a combined OP
|
||||
# when key <0 (not handled, to keep the pp_ function simple
|
||||
test_opcount(0, "no aelemfast_lex + sassign replacement with neg key",
|
||||
sub { my @x = (1,2); $x[-1] = 7 },
|
||||
{
|
||||
aelemfast_lex => 1,
|
||||
aelemfastlex_store => 0,
|
||||
padav => 1,
|
||||
sassign => 1,
|
||||
});
|
||||
|
||||
# aelemfast_lex + sassign optimization does not disrupt multideref
|
||||
test_opcount(0, "no aelemfast_lex + sassign replacement with multideref",
|
||||
sub { my @x = ([1,2]); $x[0][1] = 1; },
|
||||
{
|
||||
aelemfast_lex => 0,
|
||||
aelemfastlex_store => 0,
|
||||
multideref => 1,
|
||||
padav => 1,
|
||||
sassign => 1,
|
||||
});
|
||||
|
||||
done_testing();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user