Change RecordVals to get resized at time of RecordType redef

Opposed to unconditionally checking all RecordVals whether they need to
be resized after parsing ends.
This commit is contained in:
Jon Siwek 2020-03-12 15:51:37 -07:00
parent da5fca7163
commit a61ad9ea5c
4 changed files with 21 additions and 13 deletions

View file

@ -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;
}

View file

@ -2548,7 +2548,7 @@ HashKey* TableVal::ComputeHash(const Val* index) const
return table_hash->ComputeHash(index, 1);
}
vector<RecordVal*> 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();
}

View file

@ -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<RecordVal*> parse_time_records;
using RecordTypeValMap = std::unordered_map<RecordType*, std::vector<IntrusivePtr<RecordVal>>>;
static RecordTypeValMap parse_time_records;
};
class EnumVal : public Val {

View file

@ -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();