diff --git a/src/Type.cc b/src/Type.cc index b855e0cbde..531fea4e5b 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -874,6 +874,7 @@ const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) delete others; num_fields = types->length(); + RecordVal::ResizeParseTimeRecords(this); return 0; } diff --git a/src/Val.cc b/src/Val.cc index 4185e122e5..aa46f971f3 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2548,7 +2548,7 @@ HashKey* TableVal::ComputeHash(const Val* index) const return table_hash->ComputeHash(index, 1); } -vector RecordVal::parse_time_records; +RecordVal::RecordTypeValMap RecordVal::parse_time_records; RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) { @@ -2557,10 +2557,7 @@ RecordVal::RecordVal(RecordType* t, bool init_fields) : Val(t) val_list* vl = val.val_list_val = new val_list(n); if ( is_parsing ) - { - parse_time_records.emplace_back(this); - Ref(); - } + parse_time_records[t].emplace_back(NewRef{}, this); if ( ! init_fields ) return; @@ -2630,12 +2627,18 @@ Val* RecordVal::LookupWithDefault(int field) const return Type()->AsRecordType()->FieldDefault(field); } -void RecordVal::ResizeParseTimeRecords() +void RecordVal::ResizeParseTimeRecords(RecordType* rt) { - for ( auto& rv : parse_time_records ) + auto it = parse_time_records.find(rt); + + if ( it == parse_time_records.end() ) + return; + + auto& rvs = it->second; + + for ( auto& rv : rvs ) { auto vs = rv->val.val_list_val; - auto rt = rv->Type()->AsRecordType(); auto current_length = vs->length(); auto required_length = rt->NumFields(); @@ -2646,10 +2649,11 @@ void RecordVal::ResizeParseTimeRecords() for ( auto i = current_length; i < required_length; ++i ) vs->replace(i, nullptr); } - - Unref(rv); } + } +void RecordVal::DoneParsing() + { parse_time_records.clear(); } diff --git a/src/Val.h b/src/Val.h index ae8915fa08..0bb588d310 100644 --- a/src/Val.h +++ b/src/Val.h @@ -924,14 +924,17 @@ public: // Extend the underlying arrays of record instances created during // parsing to match the number of fields in the record type (they may // mismatch as a result of parse-time record type redefinitions. - static void ResizeParseTimeRecords(); + static void ResizeParseTimeRecords(RecordType* rt); + + static void DoneParsing(); protected: Val* DoClone(CloneState* state) override; BroObj* origin; - static vector parse_time_records; + using RecordTypeValMap = std::unordered_map>>; + static RecordTypeValMap parse_time_records; }; class EnumVal : public Val { diff --git a/src/main.cc b/src/main.cc index 30334c5b3e..09171ccb63 100644 --- a/src/main.cc +++ b/src/main.cc @@ -649,7 +649,7 @@ int main(int argc, char** argv) yyparse(); is_parsing = false; - RecordVal::ResizeParseTimeRecords(); + RecordVal::DoneParsing(); init_general_global_var(); init_net_var();