Move some temp vectors into parser state
authorChris Forbes <chrisforbes@google.com>
Tue, 27 Jun 2017 18:00:06 +0000 (11:00 -0700)
committerDavid Neto <dneto@google.com>
Wed, 28 Jun 2017 15:13:26 +0000 (11:13 -0400)
We don't need to churn the allocations for these every instruction.

source/binary.cpp

index a803def..df75632 100644 (file)
@@ -198,6 +198,10 @@ class Parser {
     // Maps an ExtInstImport id to the extended instruction type.
     std::unordered_map<uint32_t, spv_ext_inst_type_t>
         import_id_to_ext_inst_type;
+
+    // Used by parseOperand
+    std::vector<spv_parsed_operand_t> operands;
+    std::vector<uint32_t> endian_converted_words;
   } _;
 };
 
@@ -269,17 +273,18 @@ spv_result_t Parser::parseInstruction() {
   // If the module's endianness is different from the host native endianness,
   // then converted_words contains the the endian-translated words in the
   // instruction.
-  std::vector<uint32_t> endian_converted_words = {first_word};
+  _.endian_converted_words.clear();
+  _.endian_converted_words.push_back(first_word);
   if (_.requires_endian_conversion) {
     // Most instructions have fewer than 25 words.
-    endian_converted_words.reserve(25);
+    _.endian_converted_words.reserve(25);
   }
 
   // After a successful parse of the instruction, the inst.operands member
   // will point to this vector's storage.
-  std::vector<spv_parsed_operand_t> operands;
   // Most instructions have fewer than 25 logical operands.
-  operands.reserve(25);
+  _.operands.clear();
+  _.operands.reserve(25);
 
   assert(_.word_index < _.num_words);
   // Decompose and check the first word.
@@ -323,8 +328,8 @@ spv_result_t Parser::parseInstruction() {
     spv_operand_type_t type = spvTakeFirstMatchableOperand(&expected_operands);
 
     if (auto error =
-            parseOperand(inst_offset, &inst, type, &endian_converted_words,
-                         &operands, &expected_operands)) {
+            parseOperand(inst_offset, &inst, type, &_.endian_converted_words,
+                         &_.operands, &expected_operands)) {
       return error;
     }
   }
@@ -351,15 +356,15 @@ spv_result_t Parser::parseInstruction() {
   // performed, then the vector only contains the initial opcode/word-count
   // word.
   assert(!_.requires_endian_conversion ||
-         (inst_word_count == endian_converted_words.size()));
-  assert(_.requires_endian_conversion || (endian_converted_words.size() == 1));
+         (inst_word_count == _.endian_converted_words.size()));
+  assert(_.requires_endian_conversion || (_.endian_converted_words.size() == 1));
 
   recordNumberType(inst_offset, &inst);
 
   if (_.requires_endian_conversion) {
     // We must wait until here to set this pointer, because the vector might
     // have been be resized while we accumulated its elements.
-    inst.words = endian_converted_words.data();
+    inst.words = _.endian_converted_words.data();
   } else {
     // If no conversion is required, then just point to the underlying binary.
     // This saves time and space.
@@ -369,8 +374,8 @@ spv_result_t Parser::parseInstruction() {
 
   // We must wait until here to set this pointer, because the vector might
   // have been be resized while we accumulated its elements.
-  inst.operands = operands.data();
-  inst.num_operands = uint16_t(operands.size());
+  inst.operands = _.operands.data();
+  inst.num_operands = uint16_t(_.operands.size());
 
   // Issue the callback.  The callee should know that all the storage in inst
   // is transient, and will disappear immediately afterward.