[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: extragear/sdk/kdevelop/languages/cpp/parser
From: Alexander Dymo <adymo () kdevelop ! org>
Date: 2009-12-22 23:37:48
Message-ID: 1261525068.797097.538.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 1065301 by dymo:
Reduce C++ parser memory consumption (up to 35% in some cases).
Parser sometimes creates AST nodes in the memory pool which aren't used later
for example, it may try to parse simple type specifier, create a SimpleTypeSpecifierAST
and then decide that the thing under the cursor isn't a type specifier and return
leaving the AST node orphaned.
Usually that's ok, but not for autogenerated or preprocessed cpp files
with lots of numerals, strings or constants. I have a 4M file in Ruby interpreter sources,
which makes KDevelop take 550M during parsing.
Performance and memory consumption investigation:
parsing my test file
before: 552M 3.84 sec
after: 364M 3.59 sec
parsing the whole kdevplatform
before: 299M 92.93 sec
after: 291M 92.75 sec
Result: memory consumption is decreased by 35% in my case and by 3% in case of kdevplatform.
As a side effect, the parser became a bit faster.
This doesn't fix all such places in the parser, just the most important ones.
Others will be fixed later.
M +36 -11 parser.cpp
--- trunk/extragear/sdk/kdevelop/languages/cpp/parser/parser.cpp #1065300:1065301
@@ -535,11 +535,12 @@
WinDeclSpecAST *winDeclSpec = 0;
parseWinDeclSpec(winDeclSpec);
- NameAST *ast = CreateNode<NameAST>(session->mempool);
+ NameAST *ast = 0;
+ bool setGlobal = false;
if (session->token_stream->lookAhead() == Token_scope)
{
- ast->global = true;
+ setGlobal = true;
advance();
}
@@ -552,6 +553,9 @@
return false;
}
+ if (!ast)
+ ast = CreateNode<NameAST>(session->mempool);
+
if (session->token_stream->lookAhead() == Token_scope)
{
advance();
@@ -584,6 +588,8 @@
if (idx == session->token_stream->cursor())
return false;
+ if (setGlobal)
+ ast->global = true;
UPDATE_POS(ast, start, _M_last_valid_token+1);
node = ast;
@@ -1222,14 +1228,16 @@
}
}
- SimpleTypeSpecifierAST *ast = CreateNode<SimpleTypeSpecifierAST>(session->mempool);
+ SimpleTypeSpecifierAST *ast = 0;
if (isIntegral)
{
+ ast = CreateNode<SimpleTypeSpecifierAST>(session->mempool);
ast->integrals = integrals;
}
else if (session->token_stream->lookAhead() == Token___typeof)
{
+ ast = CreateNode<SimpleTypeSpecifierAST>(session->mempool);
ast->type_of = session->token_stream->cursor();
advance();
@@ -1259,12 +1267,14 @@
}
else
{
- if (!parseName(ast->name, AcceptTemplate))
+ NameAST *name = 0;
+ if (!parseName(name, AcceptTemplate))
{
- ast->name = 0;
rewind(start);
return false;
}
+ ast = CreateNode<SimpleTypeSpecifierAST>(session->mempool);
+ ast->name = name;
}
UPDATE_POS(ast, start, _M_last_valid_token+1);
@@ -2571,7 +2581,7 @@
{
std::size_t start = session->token_stream->cursor();
- InitializerClauseAST *ast = CreateNode<InitializerClauseAST>(session->mempool);
+ InitializerClauseAST *ast = 0;
if (session->token_stream->lookAhead() == '{')
{
@@ -2584,15 +2594,19 @@
}
ADVANCE('}',"}");
+ ast = CreateNode<InitializerClauseAST>(session->mempool);
ast->initializer_list = initializer_list;
}
else
{
- if (!parseAssignmentExpression(ast->expression))
+ ExpressionAST *expression = 0;
+ if (!parseAssignmentExpression(expression))
{
reportError("Expression expected");
return false;
}
+ ast = CreateNode<InitializerClauseAST>(session->mempool);
+ ast->expression = expression;
}
UPDATE_POS(ast, start, _M_last_valid_token+1);
@@ -3677,11 +3691,12 @@
{
std::size_t start = session->token_stream->cursor();
- PrimaryExpressionAST *ast = CreateNode<PrimaryExpressionAST>(session->mempool);
+ PrimaryExpressionAST *ast = 0;
switch(session->token_stream->lookAhead())
{
case Token_string_literal:
+ ast = CreateNode<PrimaryExpressionAST>(session->mempool);
parseStringLiteral(ast->literal);
break;
@@ -3690,6 +3705,7 @@
case Token_true:
case Token_false:
case Token_this:
+ ast = CreateNode<PrimaryExpressionAST>(session->mempool);
ast->token = session->token_stream->cursor();
advance();
break;
@@ -3699,21 +3715,30 @@
if (session->token_stream->lookAhead() == '{')
{
- if (!parseCompoundStatement(ast->expression_statement))
+ StatementAST *expressionStatement = 0;
+ if (!parseCompoundStatement(expressionStatement))
return false;
+ ast = CreateNode<PrimaryExpressionAST>(session->mempool);
+ ast->expression_statement = expressionStatement;
}
else
{
- if (!parseExpression(ast->sub_expression))
+ ExpressionAST *expression = 0;
+ if (!parseExpression(expression))
return false;
+ ast = CreateNode<PrimaryExpressionAST>(session->mempool);
+ ast->sub_expression = expression;
}
CHECK(')');
break;
default:
- if (!parseName(ast->name, EventuallyAcceptTemplate))
+ NameAST *name = 0;
+ if (!parseName(name, EventuallyAcceptTemplate))
return false;
+ ast = CreateNode<PrimaryExpressionAST>(session->mempool);
+ ast->name = name;
break;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic