compiler: improve type caching for interface types

Add a cached to Interface_info_expression::do_type() so as to reuse
    previously created interface types. This change reduces gccgo peak heap
    usage when compiling the "fmt" package from around 16mb to around 10mb.
    
    Fixes golang/go#16334
    
    Reviewed-on: https://go-review.googlesource.com/24890

From-SVN: r239095
This commit is contained in:
Ian Lance Taylor 2016-08-03 20:01:09 +00:00
parent c7fdbdcdbd
commit f177a3d139
2 changed files with 18 additions and 5 deletions

View File

@ -1,4 +1,4 @@
7d6c53910e52b7db2a77c1c1c3bc2c170283a1fa 0fb416a7bed076bdfef168480789bb2994a58de3
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -14114,16 +14114,27 @@ Interface_info_expression::do_type()
{ {
case INTERFACE_INFO_METHODS: case INTERFACE_INFO_METHODS:
{ {
typedef Unordered_map(Interface_type*, Type*) Hashtable;
static Hashtable result_types;
Interface_type* itype = this->iface_->type()->interface_type();
Hashtable::const_iterator p = result_types.find(itype);
if (p != result_types.end())
return p->second;
Type* pdt = Type::make_type_descriptor_ptr_type(); Type* pdt = Type::make_type_descriptor_ptr_type();
if (this->iface_->type()->interface_type()->is_empty()) if (itype->is_empty())
return pdt; {
result_types[itype] = pdt;
return pdt;
}
Location loc = this->location(); Location loc = this->location();
Struct_field_list* sfl = new Struct_field_list(); Struct_field_list* sfl = new Struct_field_list();
sfl->push_back( sfl->push_back(
Struct_field(Typed_identifier("__type_descriptor", pdt, loc))); Struct_field(Typed_identifier("__type_descriptor", pdt, loc)));
Interface_type* itype = this->iface_->type()->interface_type();
for (Typed_identifier_list::const_iterator p = itype->methods()->begin(); for (Typed_identifier_list::const_iterator p = itype->methods()->begin();
p != itype->methods()->end(); p != itype->methods()->end();
++p) ++p)
@ -14156,7 +14167,9 @@ Interface_info_expression::do_type()
sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc))); sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc)));
} }
return Type::make_pointer_type(Type::make_struct_type(sfl, loc)); Pointer_type *pt = Type::make_pointer_type(Type::make_struct_type(sfl, loc));
result_types[itype] = pt;
return pt;
} }
case INTERFACE_INFO_OBJECT: case INTERFACE_INFO_OBJECT:
return Type::make_pointer_type(Type::make_void_type()); return Type::make_pointer_type(Type::make_void_type());