aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-08-03 20:01:09 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-08-03 20:01:09 +0000
commitf177a3d139bd6ff92eef93e0e3559ad6793e956b (patch)
tree9b28758c6ec6f21969975d0f9bde402698d8e2f1
parentc7fdbdcdbd9f2ea3393ff6b3714394fa3922ab09 (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc21
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());