aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc44
-rw-r--r--gcc/go/gofrontend/types.h14
3 files changed, 55 insertions, 5 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 8c49b2b..81e11d1 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-02f11a2d5cf0db2c2675c13d92bb69529f2175dd
+5fe998e4a18cc1dbbd4869be5c8202bda55adb33
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/types.cc b/gcc/go/gofrontend/types.cc
index 34edf76..eb04fe1 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -9096,6 +9096,8 @@ Interface_type::get_backend_empty_interface_type(Gogo* gogo)
return empty_interface_type;
}
+Interface_type::Bmethods_map Interface_type::bmethods_map;
+
// Return a pointer to the backend representation of the method table.
Btype*
@@ -9104,6 +9106,21 @@ Interface_type::get_backend_methods(Gogo* gogo)
if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_)
return this->bmethods_;
+ std::pair<Interface_type*, Bmethods_map_entry> val;
+ val.first = this;
+ val.second.btype = NULL;
+ val.second.is_placeholder = false;
+ std::pair<Bmethods_map::iterator, bool> ins =
+ Interface_type::bmethods_map.insert(val);
+ if (!ins.second
+ && ins.first->second.btype != NULL
+ && !ins.first->second.is_placeholder)
+ {
+ this->bmethods_ = ins.first->second.btype;
+ this->bmethods_is_placeholder_ = false;
+ return this->bmethods_;
+ }
+
Location loc = this->location();
std::vector<Backend::Btyped_identifier>
@@ -9160,10 +9177,14 @@ Interface_type::get_backend_methods(Gogo* gogo)
Btype* st = gogo->backend()->struct_type(mfields);
Btype* ret = gogo->backend()->pointer_type(st);
- if (this->bmethods_ != NULL && this->bmethods_is_placeholder_)
- gogo->backend()->set_placeholder_pointer_type(this->bmethods_, ret);
+ if (ins.first->second.btype != NULL
+ && ins.first->second.is_placeholder)
+ gogo->backend()->set_placeholder_pointer_type(ins.first->second.btype,
+ ret);
this->bmethods_ = ret;
+ ins.first->second.btype = ret;
this->bmethods_is_placeholder_ = false;
+ ins.first->second.is_placeholder = false;
return ret;
}
@@ -9174,10 +9195,25 @@ Interface_type::get_backend_methods_placeholder(Gogo* gogo)
{
if (this->bmethods_ == NULL)
{
+ std::pair<Interface_type*, Bmethods_map_entry> val;
+ val.first = this;
+ val.second.btype = NULL;
+ val.second.is_placeholder = false;
+ std::pair<Bmethods_map::iterator, bool> ins =
+ Interface_type::bmethods_map.insert(val);
+ if (!ins.second && ins.first->second.btype != NULL)
+ {
+ this->bmethods_ = ins.first->second.btype;
+ this->bmethods_is_placeholder_ = ins.first->second.is_placeholder;
+ return this->bmethods_;
+ }
+
Location loc = this->location();
- this->bmethods_ = gogo->backend()->placeholder_pointer_type("", loc,
- false);
+ Btype* bt = gogo->backend()->placeholder_pointer_type("", loc, false);
+ this->bmethods_ = bt;
+ ins.first->second.btype = bt;
this->bmethods_is_placeholder_ = true;
+ ins.first->second.is_placeholder = true;
}
return this->bmethods_;
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 6487731..234e0a6 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -3185,6 +3185,20 @@ class Interface_type : public Type
bool
assume_identical(const Interface_type*, const Interface_type*) const;
+ struct Bmethods_map_entry
+ {
+ Btype *btype;
+ bool is_placeholder;
+ };
+
+ // A mapping from Interface_type to the backend type of its bmethods_,
+ // used to ensure that the backend representation of identical types
+ // is identical.
+ typedef Unordered_map_hash(const Interface_type*, Bmethods_map_entry,
+ Type_hash_identical, Type_identical) Bmethods_map;
+
+ static Bmethods_map bmethods_map;
+
// The list of methods associated with the interface from the
// parser. This will be NULL for the empty interface. This may
// include unnamed interface types.