diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-08-03 20:01:09 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-08-03 20:01:09 +0000 |
commit | f177a3d139bd6ff92eef93e0e3559ad6793e956b (patch) | |
tree | 9b28758c6ec6f21969975d0f9bde402698d8e2f1 | |
parent | c7fdbdcdbd9f2ea3393ff6b3714394fa3922ab09 (diff) | |
download | gcc-f177a3d139bd6ff92eef93e0e3559ad6793e956b.zip gcc-f177a3d139bd6ff92eef93e0e3559ad6793e956b.tar.gz gcc-f177a3d139bd6ff92eef93e0e3559ad6793e956b.tar.bz2 |
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
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 21 |
2 files changed, 18 insertions, 5 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5009c89..1d83328 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7d6c53910e52b7db2a77c1c1c3bc2c170283a1fa +0fb416a7bed076bdfef168480789bb2994a58de3 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index ff2893f..71a84c7 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -14114,16 +14114,27 @@ Interface_info_expression::do_type() { 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(); - if (this->iface_->type()->interface_type()->is_empty()) - return pdt; + if (itype->is_empty()) + { + result_types[itype] = pdt; + return pdt; + } Location loc = this->location(); Struct_field_list* sfl = new Struct_field_list(); sfl->push_back( 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(); p != itype->methods()->end(); ++p) @@ -14156,7 +14167,9 @@ Interface_info_expression::do_type() 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: return Type::make_pointer_type(Type::make_void_type()); |