mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: make symbol's global index unique
Currently, when mapping symbol's local index to global index, for duplicated and overwriting/overwritten symbols, each appearance of the symbol gets a global index, with one being the "primary", and others "redirect" to it through the overwrite map. Basically, the local-global index mapping is one to one, with overwrite/ dedup happening in global index level. This has a few drawbacks: - All symbol accesses effectively need to query the overwrite map. This may hurt performance. - For multi-level overwrites, (Y overwrites X, Z overwrites Y), this can get quite complicated, and we have to follow the redirection recursively. - Failed to follow or to update the overwrite map leads to bugs. In this CL, we change the index mapping mechanism so that each symbol get a unique global index. Multiple appearances of the same symbol get the same index. Now the local-global index mapping is N to one. Overwrite/dedup happens directly in the local-global mapping. We keep both mapping directions in arrays. Each object carries an array for its local-global mapping. The loader carries an array mapping global index to the "primary" local index, which is the one we should load from. This way, we can get rid of the overwrite map, and index conversions are simply array accesses. TODO: we still make reservation of the index space upfront, and leave holes for dup symbols. Maybe get rid of the reservation and holes. Change-Id: Ia251489d5f2ff16a0b3156a71d141a70cdf03a4e Reviewed-on: https://go-review.googlesource.com/c/go/+/217064 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
ee04d45b8f
commit
8e2b5d3e71
3 changed files with 197 additions and 281 deletions
|
|
@ -28,7 +28,7 @@ func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
|||
panic("can't build if sym.Symbol already present")
|
||||
}
|
||||
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
||||
sb.extSymPayload = l.payloads[symIdx-l.extStart]
|
||||
sb.extSymPayload = l.getPayload(symIdx)
|
||||
return sb
|
||||
}
|
||||
|
||||
|
|
@ -42,10 +42,9 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) (*SymbolBuilder, Sym) {
|
|||
if symIdx == 0 {
|
||||
panic("can't update the null symbol")
|
||||
}
|
||||
symIdx = l.getOverwrite(symIdx)
|
||||
if !l.IsExternal(symIdx) {
|
||||
// Create a clone with the same name/version/kind etc.
|
||||
symIdx = l.cloneToExternal(symIdx)
|
||||
l.cloneToExternal(symIdx)
|
||||
}
|
||||
if l.Syms[symIdx] != nil {
|
||||
panic(fmt.Sprintf("can't build if sym.Symbol %q already present", l.RawSymName(symIdx)))
|
||||
|
|
@ -53,7 +52,7 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) (*SymbolBuilder, Sym) {
|
|||
|
||||
// Construct updater and return.
|
||||
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
||||
sb.extSymPayload = l.payloads[symIdx-l.extStart]
|
||||
sb.extSymPayload = l.getPayload(symIdx)
|
||||
return sb, symIdx
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue