Skip to content

Commit

Permalink
Big slowdown in 5.10 @_ parameter passing
Browse files Browse the repository at this point in the history
Message-ID: <20080106191439.GF13935@bort.ca>

p4raw-id: //depot/perl@32891
  • Loading branch information
Rick Delaney authored and rgs committed Jan 7, 2008
1 parent b7e0bd9 commit fafafba
Showing 1 changed file with 61 additions and 49 deletions.
110 changes: 61 additions & 49 deletions op.c
Expand Up @@ -3992,6 +3992,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
static const char no_list_state[] = "Initialization of state variables"
" in list context currently forbidden";
OP *curop;
bool maybe_common_vars = TRUE;

PL_modcount = 0;
/* Grandfathering $[ assignment here. Bletch.*/
Expand All @@ -4009,6 +4010,65 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
o = newBINOP(OP_AASSIGN, flags, list(force_list(right)), curop);
o->op_private = (U8)(0 | (flags >> 8));

if ((left->op_type == OP_LIST
|| (left->op_type == OP_NULL && left->op_targ == OP_LIST)))
{
OP* lop = ((LISTOP*)left)->op_first;
maybe_common_vars = FALSE;
while (lop) {
if (lop->op_type == OP_PADSV ||
lop->op_type == OP_PADAV ||
lop->op_type == OP_PADHV ||
lop->op_type == OP_PADANY) {
if (!(lop->op_private & OPpLVAL_INTRO))
maybe_common_vars = TRUE;

if (lop->op_private & OPpPAD_STATE) {
if (left->op_private & OPpLVAL_INTRO) {
/* Each variable in state($a, $b, $c) = ... */
}
else {
/* Each state variable in
(state $a, my $b, our $c, $d, undef) = ... */
}
yyerror(no_list_state);
} else {
/* Each my variable in
(state $a, my $b, our $c, $d, undef) = ... */
}
} else if (lop->op_type == OP_UNDEF ||
lop->op_type == OP_PUSHMARK) {
/* undef may be interesting in
(state $a, undef, state $c) */
} else {
/* Other ops in the list. */
maybe_common_vars = TRUE;
}
lop = lop->op_sibling;
}
}
else if ((left->op_private & OPpLVAL_INTRO)
&& ( left->op_type == OP_PADSV
|| left->op_type == OP_PADAV
|| left->op_type == OP_PADHV
|| left->op_type == OP_PADANY))
{
maybe_common_vars = FALSE;
if (left->op_private & OPpPAD_STATE) {
/* All single variable list context state assignments, hence
state ($a) = ...
(state $a) = ...
state @a = ...
state (@a) = ...
(state @a) = ...
state %a = ...
state (%a) = ...
(state %a) = ...
*/
yyerror(no_list_state);
}
}

/* PL_generation sorcery:
* an assignment like ($a,$b) = ($c,$d) is easier than
* ($a,$b) = ($c,$a), since there is no need for temporary vars.
Expand All @@ -4023,7 +4083,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
* to store these values, evil chicanery is done with SvUVX().
*/

{
if (maybe_common_vars) {
OP *lastop = o;
PL_generation++;
for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
Expand Down Expand Up @@ -4084,54 +4144,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
o->op_private |= OPpASSIGN_COMMON;
}

if ((left->op_type == OP_LIST
|| (left->op_type == OP_NULL && left->op_targ == OP_LIST))) {
OP* lop = ((LISTOP*)left)->op_first;
while (lop) {
if (lop->op_type == OP_PADSV ||
lop->op_type == OP_PADAV ||
lop->op_type == OP_PADHV ||
lop->op_type == OP_PADANY) {
if (lop->op_private & OPpPAD_STATE) {
if (left->op_private & OPpLVAL_INTRO) {
/* Each variable in state($a, $b, $c) = ... */
}
else {
/* Each state variable in
(state $a, my $b, our $c, $d, undef) = ... */
}
yyerror(no_list_state);
} else {
/* Each my variable in
(state $a, my $b, our $c, $d, undef) = ... */
}
} else {
/* Other ops in the list. undef may be interesting in
(state $a, undef, state $c) */
}
lop = lop->op_sibling;
}
}
else if (((left->op_private & (OPpLVAL_INTRO | OPpPAD_STATE))
== (OPpLVAL_INTRO | OPpPAD_STATE))
&& ( left->op_type == OP_PADSV
|| left->op_type == OP_PADAV
|| left->op_type == OP_PADHV
|| left->op_type == OP_PADANY))
{
/* All single variable list context state assignments, hence
state ($a) = ...
(state $a) = ...
state @a = ...
state (@a) = ...
(state @a) = ...
state %a = ...
state (%a) = ...
(state %a) = ...
*/
yyerror(no_list_state);
}

if (right && right->op_type == OP_SPLIT && !PL_madskills) {
OP* tmpop = ((LISTOP*)right)->op_first;
if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
Expand Down

0 comments on commit fafafba

Please sign in to comment.