Browse Source

cppparser: Minor performance improvements

rdb 1 year ago
parent
commit
4430f16cda
2 changed files with 125 additions and 91 deletions
  1. 120 87
      dtool/src/cppparser/cppPreprocessor.cxx
  2. 5 4
      dtool/src/cppparser/cppPreprocessor.h

+ 120 - 87
dtool/src/cppparser/cppPreprocessor.cxx

@@ -439,10 +439,11 @@ get_verbose() const {
  */
  */
 void CPPPreprocessor::
 void CPPPreprocessor::
 copy_filepos(const CPPPreprocessor &other) {
 copy_filepos(const CPPPreprocessor &other) {
-  assert(!_files.empty());
-  _files.back()._file = other.get_file();
-  _files.back()._line_number = other.get_line_number();
-  _files.back()._col_number = other.get_col_number();
+  InputFile *infile = _infile;
+  assert(infile != nullptr);
+  infile->_file = other.get_file();
+  infile->_line_number = other.get_line_number();
+  infile->_col_number = other.get_col_number();
 }
 }
 
 
 /**
 /**
@@ -450,10 +451,12 @@ copy_filepos(const CPPPreprocessor &other) {
  */
  */
 CPPFile CPPPreprocessor::
 CPPFile CPPPreprocessor::
 get_file() const {
 get_file() const {
-  if (_files.empty()) {
+  InputFile *infile = _infile;
+  if (infile != nullptr) {
+    return infile->_file;
+  } else {
     return CPPFile("");
     return CPPFile("");
   }
   }
-  return _files.back()._file;
 }
 }
 
 
 /**
 /**
@@ -461,10 +464,12 @@ get_file() const {
  */
  */
 int CPPPreprocessor::
 int CPPPreprocessor::
 get_line_number() const {
 get_line_number() const {
-  if (_files.empty()) {
+  InputFile *infile = _infile;
+  if (infile != nullptr) {
+    return infile->_line_number;
+  } else {
     return 0;
     return 0;
   }
   }
-  return _files.back()._line_number;
 }
 }
 
 
 /**
 /**
@@ -472,10 +477,12 @@ get_line_number() const {
  */
  */
 int CPPPreprocessor::
 int CPPPreprocessor::
 get_col_number() const {
 get_col_number() const {
-  if (_files.empty()) {
+  InputFile *infile = _infile;
+  if (infile != nullptr) {
+    return infile->_col_number;
+  } else {
     return 0;
     return 0;
   }
   }
-  return _files.back()._col_number;
 }
 }
 
 
 /**
 /**
@@ -486,7 +493,7 @@ get_next_token() {
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
   CPPToken tok = get_next_token0();
   CPPToken tok = get_next_token0();
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << _token_index++ << ". " << tok << "\n";
     << _token_index++ << ". " << tok << "\n";
   return tok;
   return tok;
 }
 }
@@ -668,7 +675,7 @@ void CPPPreprocessor::
 warning(const string &message, const YYLTYPE &loc) const {
 warning(const string &message, const YYLTYPE &loc) const {
   if (_verbose >= 2) {
   if (_verbose >= 2) {
     if (_verbose >= 3) {
     if (_verbose >= 3) {
-      indent(cerr, _files.size() * 2);
+      indent(cerr, get_file_depth() * 2);
     }
     }
 
 
     if (!loc.file.empty()) {
     if (!loc.file.empty()) {
@@ -717,7 +724,7 @@ error(const string &message, const YYLTYPE &loc) const {
 
 
   if (_verbose >= 1) {
   if (_verbose >= 1) {
     if (_verbose >= 3) {
     if (_verbose >= 3) {
-      indent(cerr, _files.size() * 2);
+      indent(cerr, get_file_depth() * 2);
     }
     }
 
 
     if (!loc.file.empty()) {
     if (!loc.file.empty()) {
@@ -734,31 +741,31 @@ error(const string &message, const YYLTYPE &loc) const {
     cerr << " error: " << message << "\n";
     cerr << " error: " << message << "\n";
     show_line(loc);
     show_line(loc);
 
 
-    if (!_files.empty() && !loc.file.empty()) {
-      Files::const_reverse_iterator rit;
-      for (rit = _files.rbegin();
-           rit != _files.rend() && (*rit)._file == loc.file && (*rit)._manifest != nullptr;
-           ++rit) {
+    InputFile *infile = _infile;
+    if (infile != nullptr && !loc.file.empty()) {
+      // Add all the expansions to a vector for easy reverse iteration.
+      std::vector<InputFile *> infiles;
+      while (infile != nullptr && infile->_file == loc.file && infile->_manifest != nullptr) {
+        infiles.push_back(infile);
+        infile = infile->_parent;
       }
       }
-      if (rit != _files.rbegin() && rit != _files.rend()) {
-        --rit;
-        const InputFile &infile = *rit;
+      if (!infiles.empty()) {
+        auto rit = infiles.rbegin();
         if (_verbose >= 3) {
         if (_verbose >= 3) {
-          cerr << "Expansion of " << infile._manifest->_name << ":\n";
-          cerr << " -> " << trim_blanks(infile._input) << "\n";
-          while (rit != _files.rbegin()) {
-            --rit;
-            const InputFile &infile = *rit;
-            cerr << " -> " << trim_blanks(infile._input) << "\n";
+          cerr << "Expansion of " << (*rit)->_manifest->_name << ":\n";
+          while (rit != infiles.rend()) {
+            cerr << " -> " << trim_blanks((*rit)->_input) << "\n";
+            ++rit;
           }
           }
         }
         }
         else {
         else {
-          cerr << "with " << infile._manifest->_name;
-          if (infile._manifest->_has_parameters) {
+          cerr << "with " << (*rit)->_manifest->_name;
+          if ((*rit)->_manifest->_has_parameters) {
             cerr << "()";
             cerr << "()";
           }
           }
-          cerr << " expanded to: " << trim_blanks(_files.back()._input) << "\n";
+          cerr << " expanded to: " << trim_blanks(_infile->_input) << "\n";
         }
         }
+        cerr << std::endl;
       }
       }
     }
     }
 
 
@@ -781,7 +788,7 @@ show_line(const YYLTYPE &loc) const {
 
 
   int indent_level = 0;
   int indent_level = 0;
   if (_verbose >= 3) {
   if (_verbose >= 3) {
-    indent_level = _files.size() * 2;
+    indent_level = get_file_depth() * 2;
   }
   }
 
 
   // Seek to the offending line in the file.
   // Seek to the offending line in the file.
@@ -940,25 +947,26 @@ init_type(const string &type) {
 bool CPPPreprocessor::
 bool CPPPreprocessor::
 push_file(const CPPFile &file) {
 push_file(const CPPFile &file) {
   if (_verbose >= 3) {
   if (_verbose >= 3) {
-    indent(cerr, _files.size() * 2)
+    indent(cerr, get_file_depth() * 2)
       << "Reading " << file << "\n";
       << "Reading " << file << "\n";
   }
   }
   assert(_last_c == 0);
   assert(_last_c == 0);
 
 
-  _files.push_back(InputFile());
-  InputFile &infile = _files.back();
+  InputFile *infile = new InputFile;
+  if (infile->open(file)) {
+    infile->_parent = _infile;
+    _infile = infile;
 
 
-  if (infile.open(file)) {
     // Record the fact that we opened the file for the benefit of user code.
     // Record the fact that we opened the file for the benefit of user code.
     _parsed_files.insert(file);
     _parsed_files.insert(file);
 
 
-    infile._prev_last_c = _last_c;
+    infile->_prev_last_c = _last_c;
     _last_c = '\0';
     _last_c = '\0';
     _start_of_line = true;
     _start_of_line = true;
     return true;
     return true;
   }
   }
 
 
-  _files.pop_back();
+  delete infile;
   return false;
   return false;
 }
 }
 
 
@@ -968,25 +976,26 @@ push_file(const CPPFile &file) {
 bool CPPPreprocessor::
 bool CPPPreprocessor::
 push_string(const string &input) {
 push_string(const string &input) {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Pushing to string \"" << input
     << "Pushing to string \"" << input
     << "\"\n";
     << "\"\n";
 #endif
 #endif
-  _files.push_back(InputFile());
-  InputFile &infile = _files.back();
 
 
-  if (infile.connect_input(input)) {
-    infile._prev_last_c = _last_c;
+  InputFile *infile = new InputFile;
+  if (infile->connect_input(input)) {
+    infile->_prev_last_c = _last_c;
+    infile->_parent = _infile;
+    _infile = infile;
     _last_c = '\0';
     _last_c = '\0';
     return true;
     return true;
   }
   }
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Unable to read string\n";
     << "Unable to read string\n";
 #endif
 #endif
 
 
-  _files.pop_back();
+  delete infile;
   return false;
   return false;
 }
 }
 
 
@@ -996,37 +1005,38 @@ push_string(const string &input) {
 bool CPPPreprocessor::
 bool CPPPreprocessor::
 push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &loc) {
 push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &loc) {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Pushing to expansion \"" << input
     << "Pushing to expansion \"" << input
     << "\"\n";
     << "\"\n";
 #endif
 #endif
-  _files.push_back(InputFile());
-  InputFile &infile = _files.back();
 
 
-  if (infile.connect_input(input)) {
-    infile._manifest = manifest;
-    infile._file = loc.file;
-    infile._line_number = loc.first_line;
-    infile._col_number = loc.first_column;
-    infile._lock_position = true;
+  InputFile *infile = new InputFile;
+  if (infile->connect_input(input)) {
+    infile->_manifest = manifest;
+    infile->_file = loc.file;
+    infile->_line_number = loc.first_line;
+    infile->_col_number = loc.first_column;
+    infile->_lock_position = true;
 
 
     if (!manifest->_has_parameters) {
     if (!manifest->_has_parameters) {
       // If the manifest does not use arguments, then disallow recursive
       // If the manifest does not use arguments, then disallow recursive
       // expansion.
       // expansion.
-      infile._ignore_manifest = true;
+      infile->_ignore_manifest = true;
     }
     }
 
 
-    infile._prev_last_c = _last_c;
+    infile->_prev_last_c = _last_c;
+    infile->_parent = _infile;
+    _infile = infile;
     _last_c = '\0';
     _last_c = '\0';
     return true;
     return true;
   }
   }
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Unable to read expansion\n";
     << "Unable to read expansion\n";
 #endif
 #endif
 
 
-  _files.pop_back();
+  delete infile;
   return false;
   return false;
 }
 }
 
 
@@ -1647,7 +1657,7 @@ process_directive(int c) {
   loc.last_column = 0;
   loc.last_column = 0;
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "#" << command << " " << args << "\n";
     << "#" << command << " " << args << "\n";
 #endif
 #endif
 
 
@@ -1870,7 +1880,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
     if (expr[0] == '"' && expr[expr.size() - 1] == '"') {
     if (expr[0] == '"' && expr[expr.size() - 1] == '"') {
       filename = expr.substr(1, expr.size() - 2);
       filename = expr.substr(1, expr.size() - 2);
 
 
-      if (_files.size() == 1) {
+      if (_infile->_parent == nullptr) {
         // If we're currently processing a top-level file, record the include
         // If we're currently processing a top-level file, record the include
         // directive.  We don't need to record includes from included files.
         // directive.  We don't need to record includes from included files.
         _quote_includes.insert(filename);
         _quote_includes.insert(filename);
@@ -1884,7 +1894,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
         angle_quotes = true;
         angle_quotes = true;
       }
       }
 
 
-      if (_files.size() == 1) {
+      if (_infile->_parent == nullptr) {
         // If we're currently processing a top-level file, record the include
         // If we're currently processing a top-level file, record the include
         // directive.  We don't need to record includes from included files.
         // directive.  We don't need to record includes from included files.
         _angle_includes.insert(filename);
         _angle_includes.insert(filename);
@@ -2470,17 +2480,19 @@ expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc) {
   CPPManifest::Ignores ignores;
   CPPManifest::Ignores ignores;
   ignores.insert(manifest);
   ignores.insert(manifest);
 
 
-  for (const InputFile &infile : _files) {
-    if (infile._ignore_manifest) {
-      ignores.insert(infile._manifest);
+  InputFile *infile = _infile;
+  while (infile != nullptr) {
+    if (infile->_ignore_manifest) {
+      ignores.insert(infile->_manifest);
     }
     }
+    infile = infile->_parent;
   }
   }
 
 
   string expanded = " " + manifest->expand(args, false, ignores) + " ";
   string expanded = " " + manifest->expand(args, false, ignores) + " ";
   push_expansion(expanded, manifest, loc);
   push_expansion(expanded, manifest, loc);
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Expanding " << manifest->_name << " to " << expanded << "\n";
     << "Expanding " << manifest->_name << " to " << expanded << "\n";
 #endif
 #endif
 
 
@@ -3006,10 +3018,12 @@ scan_raw(int c) {
  */
  */
 bool CPPPreprocessor::
 bool CPPPreprocessor::
 should_ignore_manifest(const CPPManifest *manifest) const {
 should_ignore_manifest(const CPPManifest *manifest) const {
-  for (const InputFile &infile : _files) {
-    if (infile._ignore_manifest && infile._manifest == manifest) {
+  InputFile *infile = _infile;
+  while (infile != nullptr) {
+    if (infile->_ignore_manifest && infile->_manifest == manifest) {
       return true;
       return true;
     }
     }
+    infile = infile->_parent;
   }
   }
 
 
   return false;
   return false;
@@ -3021,10 +3035,12 @@ should_ignore_manifest(const CPPManifest *manifest) const {
  */
  */
 bool CPPPreprocessor::
 bool CPPPreprocessor::
 should_ignore_preprocessor() const {
 should_ignore_preprocessor() const {
-  for (const InputFile &infile : _files) {
-    if (infile._ignore_manifest) {
+  InputFile *infile = _infile;
+  while (infile != nullptr) {
+    if (infile->_ignore_manifest) {
       return true;
       return true;
     }
     }
+    infile = infile->_parent;
   }
   }
 
 
   return false;
   return false;
@@ -3041,18 +3057,21 @@ get() {
     return c;
     return c;
   }
   }
 
 
-  if (_files.empty()) {
+  if (UNLIKELY(_infile == nullptr)) {
     return EOF;
     return EOF;
   }
   }
 
 
-  int c = _files.back().get();
+  int c = _infile->get();
 
 
-  while (c == EOF && !_files.empty()) {
+  while (UNLIKELY(c == EOF && _infile != nullptr)) {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-    indent(cerr, _files.size() * 2)
+    indent(cerr, get_file_depth() * 2)
       << "End of input stream, restoring to previous input\n";
       << "End of input stream, restoring to previous input\n";
 #endif
 #endif
-    _files.pop_back();
+    // Pop the last file off the end.
+    InputFile *infile = _infile;
+    _infile = infile->_parent;
+    delete infile;
 
 
     // Synthesize a newline, just in case the file doesn't already end with
     // Synthesize a newline, just in case the file doesn't already end with
     // one.
     // one.
@@ -3077,21 +3096,21 @@ peek() {
     return _unget;
     return _unget;
   }
   }
 
 
-  if (_files.empty()) {
+  InputFile *infile = _infile;
+  if (UNLIKELY(infile == nullptr)) {
     return EOF;
     return EOF;
   }
   }
 
 
-  Files::reverse_iterator it = _files.rbegin();
-  int c = (*it).peek();
+  int c = infile->peek();
 
 
-  while (c == EOF && it != _files.rend()) {
-    int last_c = (*it)._prev_last_c;
-    ++it;
+  while (UNLIKELY(c == EOF && infile != nullptr)) {
+    int last_c = infile->_prev_last_c;
+    infile = infile->_parent;
 
 
     if (last_c != '\0') {
     if (last_c != '\0') {
       c = last_c;
       c = last_c;
-    } else if (it != _files.rend()) {
-      c = (*it).peek();
+    } else if (infile != nullptr) {
+      c = infile->peek();
     }
     }
   }
   }
 
 
@@ -3117,7 +3136,7 @@ unget(int c) {
 CPPTemplateParameterList *CPPPreprocessor::
 CPPTemplateParameterList *CPPPreprocessor::
 nested_parse_template_instantiation(CPPTemplateScope *scope) {
 nested_parse_template_instantiation(CPPTemplateScope *scope) {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Beginning nested parse\n";
     << "Beginning nested parse\n";
 #endif
 #endif
   assert(scope != nullptr);
   assert(scope != nullptr);
@@ -3206,7 +3225,7 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
   _parsing_template_params = old_parsing_params;
   _parsing_template_params = old_parsing_params;
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Ending nested parse\n";
     << "Ending nested parse\n";
 #endif
 #endif
   return actual_params;
   return actual_params;
@@ -3222,7 +3241,7 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
 void CPPPreprocessor::
 void CPPPreprocessor::
 skip_to_end_nested() {
 skip_to_end_nested() {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Skipping tokens:\n";
     << "Skipping tokens:\n";
 #endif
 #endif
 
 
@@ -3236,7 +3255,7 @@ skip_to_end_nested() {
   }
   }
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Done skipping tokens.\n";
     << "Done skipping tokens.\n";
 #endif
 #endif
 }
 }
@@ -3249,7 +3268,7 @@ skip_to_end_nested() {
 void CPPPreprocessor::
 void CPPPreprocessor::
 skip_to_angle_bracket() {
 skip_to_angle_bracket() {
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Skipping tokens:\n";
     << "Skipping tokens:\n";
 #endif
 #endif
 
 
@@ -3266,7 +3285,21 @@ skip_to_angle_bracket() {
   }
   }
 
 
 #ifdef CPP_VERBOSE_LEX
 #ifdef CPP_VERBOSE_LEX
-  indent(cerr, _files.size() * 2)
+  indent(cerr, get_file_depth() * 2)
     << "Done skipping tokens.\n";
     << "Done skipping tokens.\n";
 #endif
 #endif
 }
 }
+
+/**
+ * Returns the number of files on the _infile list.
+ */
+int CPPPreprocessor::
+get_file_depth() const{
+  int depth = 0;
+  InputFile *infile = _infile;
+  while (infile != nullptr) {
+    ++depth;
+    infile = infile->_parent;
+  }
+  return depth;
+}

+ 5 - 4
dtool/src/cppparser/cppPreprocessor.h

@@ -182,6 +182,8 @@ private:
   void skip_to_end_nested();
   void skip_to_end_nested();
   void skip_to_angle_bracket();
   void skip_to_angle_bracket();
 
 
+  int get_file_depth() const;
+
   class InputFile {
   class InputFile {
   public:
   public:
     InputFile();
     InputFile();
@@ -203,12 +205,11 @@ private:
     bool _lock_position;
     bool _lock_position;
     bool _ignore_manifest;
     bool _ignore_manifest;
     int _prev_last_c;
     int _prev_last_c;
+
+    InputFile *_parent = nullptr;
   };
   };
 
 
-  // This must be a list and not a vector because we don't have a good copy
-  // constructor defined for InputFile.
-  typedef std::list<InputFile> Files;
-  Files _files;
+  InputFile *_infile = nullptr;
 
 
   enum State {
   enum State {
     S_normal, S_eof, S_nested, S_end_nested
     S_normal, S_eof, S_nested, S_end_nested