diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-06-03 23:37:04 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-06-03 23:37:04 +0000 |
commit | 39c0aa5f74be114ec472a97a12409067b74ac0dc (patch) | |
tree | 19c16f5db5a78699200253d35ce390c429f76126 /gcc/go/gofrontend/names.cc | |
parent | 8535d5aa16a895ba54ddb9c9453f093ad42f505e (diff) | |
download | gcc-39c0aa5f74be114ec472a97a12409067b74ac0dc.zip gcc-39c0aa5f74be114ec472a97a12409067b74ac0dc.tar.gz gcc-39c0aa5f74be114ec472a97a12409067b74ac0dc.tar.bz2 |
compiler, runtime, reflect: generate unique type descriptors
Currently, the compiler already generates common symbols for type
descriptors, so the type descriptors are unique. However, when a
type is created through reflection, it is not deduplicated with
compiler-generated types. As a consequence, we cannot assume type
descriptors are unique, and cannot use pointer equality to
compare them. Also, when constructing a reflect.Type, it has to
go through a canonicalization map, which introduces overhead to
reflect.TypeOf, and lock contentions in concurrent programs.
In order for the reflect package to deduplicate types with
compiler-created types, we register all the compiler-created type
descriptors at startup time. The reflect package, when it needs
to create a type, looks up the registry of compiler-created types
before creates a new one. There is no lock contention since the
registry is read-only after initialization.
This lets us get rid of the canonicalization map, and also makes
it possible to compare type descriptors with pointer equality.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/179598
From-SVN: r271894
Diffstat (limited to 'gcc/go/gofrontend/names.cc')
-rw-r--r-- | gcc/go/gofrontend/names.cc | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/names.cc b/gcc/go/gofrontend/names.cc index d9ae5910..e109cfc 100644 --- a/gcc/go/gofrontend/names.cc +++ b/gcc/go/gofrontend/names.cc @@ -146,6 +146,12 @@ // and is named __go_init_main. For other packages it is // PKGPATH..import. // +// In each pacakge there is a list of all the type descriptors defined +// in this package. The name of the list is PKGPATH..types. +// +// In the main package it gathers all the type descriptor lists in a +// single list, named go..typelists. +// // The type literal encoding is essentially a single line version of // the type literal, such as "struct { pkgpath.i int; J int }". In // this representation unexported names use their pkgpath, exported @@ -985,6 +991,23 @@ Gogo::type_descriptor_name(Type* type, Named_type* nt) return ret; } +// Return the name of the type descriptor list symbol of a package. + +std::string +Gogo::type_descriptor_list_symbol(Package* pkg) +{ + return pkg->pkgpath_symbol() + "..types"; +} + +// Return the name of the list of all type descriptor lists. This is +// only used in the main package. + +std::string +Gogo::typelists_symbol() +{ + return "go..typelists"; +} + // Return the name for the GC symbol for a type. This is used to // initialize the gcdata field of a type descriptor. This is a local // name never referenced outside of this assembly file. (Note that |