// "Portable" code generation.
-var makefuncdatasym_nsym int
+func makefuncdatasym(pp *Progs, nameprefix string, funcdatakind int64, curfn *Node) *Sym {
+ // This symbol requires a unique, reproducible name;
+ // unique to avoid duplicate symbols,
+ // and reproducible for reproducible builds and toolstash.
+ // The function name will usually suffice.
+ suffix := curfn.Func.Nname.Sym.Name
+ if suffix == "_" {
+ // It is possible to have multiple functions called _,
+ // so in this rare case, use instead the function's position.
+ // This formatted string will be meaningless gibberish, but that's ok.
+ // It will be unique and reproducible, and it is rare anyway.
+ // Note that we can't just always use the position;
+ // it is possible to have multiple autogenerated functions at the same position.
+ // Fortunately, no autogenerated functions are called _.
+ if curfn.Pos == autogeneratedPos {
+ Fatalf("autogenerated func _")
+ }
+ suffix = fmt.Sprintf("%v", curfn.Pos)
+ }
+ // Add in the package path as well.
+ // When generating wrappers, we can end up compiling a function belonging
+ // to other packages, which might have a name that collides with one in our package.
+ symname := nameprefix + curfn.Func.Nname.Sym.Pkg.Path + "." + suffix
-func makefuncdatasym(pp *Progs, nameprefix string, funcdatakind int64) *Sym {
- sym := lookupN(nameprefix, makefuncdatasym_nsym)
- makefuncdatasym_nsym++
+ sym := lookup(symname)
p := pp.Prog(obj.AFUNCDATA)
Addrconst(&p.From, funcdatakind)
p.To.Type = obj.TYPE_MEM
e := f.Frontend().(*ssafn)
// Generate GC bitmaps.
- gcargs := makefuncdatasym(pp, "gcargs·", obj.FUNCDATA_ArgsPointerMaps)
- gclocals := makefuncdatasym(pp, "gclocals·", obj.FUNCDATA_LocalsPointerMaps)
+ gcargs := makefuncdatasym(pp, "gcargs·", obj.FUNCDATA_ArgsPointerMaps, e.curfn)
+ gclocals := makefuncdatasym(pp, "gclocals·", obj.FUNCDATA_LocalsPointerMaps, e.curfn)
s.stackMapIndex = liveness(e, f, gcargs, gclocals)
// Remember where each block starts.