Use local var for $stackPos

We're accessing $this->stackPos a lot, and property accesses are
much more expensive than local variable acesses. Its cheaper to
use a local var and pass it as an argument to semantic actions.
This commit is contained in:
Nikita Popov 2017-02-04 20:18:56 +01:00
parent 90b6d7cb5b
commit 3bbf8d8f7a
4 changed files with 2045 additions and 2047 deletions

View File

@ -2,8 +2,8 @@
$meta # $meta #
#semval($) $this->semValue #semval($) $this->semValue
#semval($,%t) $this->semValue #semval($,%t) $this->semValue
#semval(%n) $this->stackPos-(%l-%n) #semval(%n) $stackPos-(%l-%n)
#semval(%n,%t) $this->stackPos-(%l-%n) #semval(%n,%t) $stackPos-(%l-%n)
namespace PhpParser\Parser; namespace PhpParser\Parser;
@ -90,13 +90,13 @@ class #(-p) extends \PhpParser\ParserAbstract
#endif #endif
#reduce #reduce
protected function reduceRule%n() { protected function reduceRule%n($stackPos) {
%b %b
} }
#noact #noact
protected function reduceRule%n() { protected function reduceRule%n($stackPos) {
$this->semValue = $this->semStack[$this->stackPos]; $this->semValue = $this->semStack[$stackPos];
} }
#endreduce #endreduce
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -92,8 +92,6 @@ abstract class ParserAbstract implements Parser
protected $lexer; protected $lexer;
/** @var mixed Temporary value containing the result of last semantic action (reduction) */ /** @var mixed Temporary value containing the result of last semantic action (reduction) */
protected $semValue; protected $semValue;
/** @var int Position in stacks (state stack, semantic value stack, attribute stack) */
protected $stackPos;
/** @var array Semantic value stack (contains values of tokens and semantic action results) */ /** @var array Semantic value stack (contains values of tokens and semantic action results) */
protected $semStack; protected $semStack;
/** @var array[] Start attribute stack */ /** @var array[] Start attribute stack */
@ -177,7 +175,7 @@ abstract class ParserAbstract implements Parser
$this->semStack = array(); $this->semStack = array();
// Current position in the stack(s) // Current position in the stack(s)
$this->stackPos = 0; $stackPos = 0;
$this->errorState = 0; $this->errorState = 0;
@ -208,8 +206,8 @@ abstract class ParserAbstract implements Parser
// This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get
// the attributes of the next token, even though they don't contain it themselves. // the attributes of the next token, even though they don't contain it themselves.
$this->startAttributeStack[$this->stackPos+1] = $startAttributes; $this->startAttributeStack[$stackPos+1] = $startAttributes;
$this->endAttributeStack[$this->stackPos+1] = $endAttributes; $this->endAttributeStack[$stackPos+1] = $endAttributes;
$this->lookaheadStartAttributes = $startAttributes; $this->lookaheadStartAttributes = $startAttributes;
//$this->traceRead($symbol); //$this->traceRead($symbol);
@ -232,11 +230,11 @@ abstract class ParserAbstract implements Parser
/* shift */ /* shift */
//$this->traceShift($symbol); //$this->traceShift($symbol);
++$this->stackPos; ++$stackPos;
$stateStack[$this->stackPos] = $state = $action; $stateStack[$stackPos] = $state = $action;
$this->semStack[$this->stackPos] = $tokenValue; $this->semStack[$stackPos] = $tokenValue;
$this->startAttributeStack[$this->stackPos] = $startAttributes; $this->startAttributeStack[$stackPos] = $startAttributes;
$this->endAttributeStack[$this->stackPos] = $endAttributes; $this->endAttributeStack[$stackPos] = $endAttributes;
$this->endAttributes = $endAttributes; $this->endAttributes = $endAttributes;
$symbol = self::SYMBOL_NONE; $symbol = self::SYMBOL_NONE;
@ -268,7 +266,7 @@ abstract class ParserAbstract implements Parser
//$this->traceReduce($rule); //$this->traceReduce($rule);
try { try {
$this->{'reduceRule' . $rule}(); $this->{'reduceRule' . $rule}($stackPos);
} catch (Error $e) { } catch (Error $e) {
if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) {
$e->setStartLine($startAttributes['startLine']); $e->setStartLine($startAttributes['startLine']);
@ -280,20 +278,20 @@ abstract class ParserAbstract implements Parser
} }
/* Goto - shift nonterminal */ /* Goto - shift nonterminal */
$lastEndAttributes = $this->endAttributeStack[$this->stackPos]; $lastEndAttributes = $this->endAttributeStack[$stackPos];
$this->stackPos -= $this->ruleToLength[$rule]; $stackPos -= $this->ruleToLength[$rule];
$nonTerminal = $this->ruleToNonTerminal[$rule]; $nonTerminal = $this->ruleToNonTerminal[$rule];
$idx = $this->gotoBase[$nonTerminal] + $stateStack[$this->stackPos]; $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos];
if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) { if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) {
$state = $this->goto[$idx]; $state = $this->goto[$idx];
} else { } else {
$state = $this->gotoDefault[$nonTerminal]; $state = $this->gotoDefault[$nonTerminal];
} }
++$this->stackPos; ++$stackPos;
$stateStack[$this->stackPos] = $state; $stateStack[$stackPos] = $state;
$this->semStack[$this->stackPos] = $this->semValue; $this->semStack[$stackPos] = $this->semValue;
$this->endAttributeStack[$this->stackPos] = $lastEndAttributes; $this->endAttributeStack[$stackPos] = $lastEndAttributes;
} else { } else {
/* error */ /* error */
switch ($this->errorState) { switch ($this->errorState) {
@ -313,18 +311,18 @@ abstract class ParserAbstract implements Parser
&& ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0 && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0
&& $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol)
) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this ) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this
if ($this->stackPos <= 0) { if ($stackPos <= 0) {
// Could not recover from error // Could not recover from error
return null; return null;
} }
$state = $stateStack[--$this->stackPos]; $state = $stateStack[--$stackPos];
//$this->tracePop($state); //$this->tracePop($state);
} }
//$this->traceShift($this->errorSymbol); //$this->traceShift($this->errorSymbol);
++$this->stackPos; ++$stackPos;
$stateStack[$this->stackPos] = $state = $action; $stateStack[$stackPos] = $state = $action;
$this->endAttributes = $this->endAttributeStack[$this->stackPos]; $this->endAttributes = $this->endAttributeStack[$stackPos];
break; break;
case 3: case 3: