[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