Commit bee42067 authored by David Crawshaw's avatar David Crawshaw

runtime: have typelinksinit work forwards

For reasons I have forgotten typelinksinit processed modules backwards.
(I suspect this was an attempt to process types in the executing
binary first.)

It does not appear to be necessary, and it is not the order we want
when a module can be loaded at an arbitrary point during a program's
execution as a plugin. So reverse the order.

While here, make it safe to call typelinksinit multiple times.

Change-Id: Ie10587c55c8e5efa0542981efb6eb3c12dd59e8c
Reviewed-on: https://go-review.googlesource.com/27822Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 8f3c8a33
...@@ -446,14 +446,11 @@ func typelinksinit() { ...@@ -446,14 +446,11 @@ func typelinksinit() {
if firstmoduledata.next == nil { if firstmoduledata.next == nil {
return return
} }
typehash := make(map[uint32][]*_type) typehash := make(map[uint32][]*_type, len(firstmoduledata.typelinks))
modules := []*moduledata{} prev := &firstmoduledata
for md := &firstmoduledata; md != nil; md = md.next { md := firstmoduledata.next
modules = append(modules, md) for md != nil {
}
prev, modules := modules[len(modules)-1], modules[:len(modules)-1]
for len(modules) > 0 {
// Collect types from the previous module into typehash. // Collect types from the previous module into typehash.
collect: collect:
for _, tl := range prev.typelinks { for _, tl := range prev.typelinks {
...@@ -473,23 +470,25 @@ func typelinksinit() { ...@@ -473,23 +470,25 @@ func typelinksinit() {
typehash[t.hash] = append(tlist, t) typehash[t.hash] = append(tlist, t)
} }
// If any of this module's typelinks match a type from a if md.typemap == nil {
// prior module, prefer that prior type by adding the offset // If any of this module's typelinks match a type from a
// to this module's typemap. // prior module, prefer that prior type by adding the offset
md := modules[len(modules)-1] // to this module's typemap.
md.typemap = make(map[typeOff]*_type, len(md.typelinks)) md.typemap = make(map[typeOff]*_type, len(md.typelinks))
for _, tl := range md.typelinks { for _, tl := range md.typelinks {
t := (*_type)(unsafe.Pointer(md.types + uintptr(tl))) t := (*_type)(unsafe.Pointer(md.types + uintptr(tl)))
for _, candidate := range typehash[t.hash] { for _, candidate := range typehash[t.hash] {
if typesEqual(t, candidate) { if typesEqual(t, candidate) {
t = candidate t = candidate
break break
}
} }
md.typemap[typeOff(tl)] = t
} }
md.typemap[typeOff(tl)] = t
} }
prev, modules = md, modules[:len(modules)-1] prev = md
md = md.next
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment