Bug 891209 (part 2) - Parse "detectably simple" expressions quickly. r=jorendorff.

--HG--
extra : rebase_source : c501dc470978a94898fd68311b776574034fb654
This commit is contained in:
Nicholas Nethercote 2013-07-08 19:09:34 -07:00
Родитель aa9f6934ee
Коммит b3c33ecb10
3 изменённых файлов: 42 добавлений и 4 удалений

Просмотреть файл

@ -5161,10 +5161,32 @@ Parser<ParseHandler>::assignExpr()
{
JS_CHECK_RECURSION(context, return null());
if (tokenStream.matchToken(TOK_YIELD, TSF_OPERAND))
// It's very common at this point to have a "detectably simple" expression,
// i.e. a name/number/string token followed by one of the following tokens
// that obviously isn't part of an expression: , ; : ) ] }
//
// (In Parsemark this happens 81.4% of the time; in code with large
// numeric arrays, such as some Kraken benchmarks, it happens more often.)
//
// In such cases, we can avoid the full expression parsing route through
// assignExpr(), condExpr1(), orExpr1(), unaryExpr(), memberExpr(), and
// primaryExpr().
TokenKind tt = tokenStream.getToken(TSF_OPERAND);
if (tt == TOK_NAME && tokenStream.nextTokenEndsExpr())
return identifierName();
if (tt == TOK_NUMBER && tokenStream.nextTokenEndsExpr())
return newNumber(tokenStream.currentToken());
if (tt == TOK_STRING && tokenStream.nextTokenEndsExpr())
return stringLiteral();
if (tt == TOK_YIELD)
return returnStatementOrYieldExpression();
if (tokenStream.hadError())
return null();
tokenStream.ungetToken();
// Save the tokenizer state in case we find an arrow function and have to
// rewind.

Просмотреть файл

@ -348,6 +348,15 @@ TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options,
maybeStrSpecial[unsigned(LINE_SEPARATOR & 0xff)] = true;
maybeStrSpecial[unsigned(PARA_SEPARATOR & 0xff)] = true;
maybeStrSpecial[unsigned(EOF & 0xff)] = true;
/* See Parser::assignExpr() for an explanation of isExprEnding[]. */
memset(isExprEnding, 0, sizeof(isExprEnding));
isExprEnding[TOK_COMMA] = 1;
isExprEnding[TOK_SEMI] = 1;
isExprEnding[TOK_COLON] = 1;
isExprEnding[TOK_RP] = 1;
isExprEnding[TOK_RB] = 1;
isExprEnding[TOK_RC] = 1;
}
#ifdef _MSC_VER

Просмотреть файл

@ -28,6 +28,8 @@
namespace js {
namespace frontend {
// Values of this type are used to index into arrays such as isExprEnding[],
// so the first value must be zero.
enum TokenKind {
TOK_ERROR = 0, /* well-known as the only code < EOF */
TOK_EOF, /* end of file */
@ -617,6 +619,10 @@ class MOZ_STACK_CLASS TokenStream
return false;
}
bool nextTokenEndsExpr() {
return isExprEnding[peekToken()];
}
class MOZ_STACK_CLASS Position {
public:
/*
@ -910,9 +916,10 @@ class MOZ_STACK_CLASS TokenStream
const char *filename; /* input filename or null */
jschar *sourceMap; /* source map's filename or null */
CharBuffer tokenbuf; /* current token string buffer */
int8_t oneCharTokens[128]; /* table of one-char tokens */
int8_t oneCharTokens[128]; /* table of one-char tokens, indexed by 7-bit char */
bool maybeEOL[256]; /* probabilistic EOL lookup table */
bool maybeStrSpecial[256];/* speeds up string scanning */
uint8_t isExprEnding[TOK_LIMIT]; /* which tokens definitely terminate exprs? */
ExclusiveContext *const cx;
JSPrincipals *const originPrincipals;
StrictModeGetter *strictModeGetter; /* used to test for strict mode */