]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/noder: set ir.Name.DictIndex for unified IR
authorMatthew Dempsky <mdempsky@google.com>
Thu, 18 Aug 2022 10:53:58 +0000 (03:53 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 18 Aug 2022 17:26:17 +0000 (17:26 +0000)
For local variables of derived type, Delve relies on ir.Name.DictIndex
being set to the type's rtype index within the function's dictionary.
This CL implements that functionality within unified IR.

Manually double checked that Delve behaves correctly, at least as far
as I can tell from casual use. Specifically, I confirmed that running
the test program from TestDictIndex, stepping into testfn, and then
running `print mapvar` prints `map[int]main.CustomInt []`, which
matches the behavior under GOEXPERIMENT=nounified. (Also compare that
when ir.Name.DictIndex is *not* set by unified IR, `print mapvar`
instead prints `map[int]go.shape.int []`.)

Fixes #54514.

Change-Id: I90d443945895abfba04dc018f15e00217930091c
Reviewed-on: https://go-review.googlesource.com/c/go/+/424735
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go
src/cmd/link/internal/ld/dwarf_test.go

index 9280232fc9ee467538308ca86634d4af23522058..1acc8c7fb6eb1f04228ad9f35ff088eebba18713 100644 (file)
@@ -1490,7 +1490,7 @@ func (r *reader) addLocal(name *ir.Name, ctxt ir.Class) {
        if name.Sym().Name == dictParamName {
                r.dictParam = name
        } else {
-               if ctxt == ir.PAUTO {
+               if r.synthetic == nil {
                        r.Sync(pkgbits.SyncAddLocal)
                        if r.p.SyncMarkers() {
                                want := r.Int()
@@ -1498,12 +1498,10 @@ func (r *reader) addLocal(name *ir.Name, ctxt ir.Class) {
                                        base.FatalfAt(name.Pos(), "locals table has desynced")
                                }
                        }
+                       r.varDictIndex(name)
                }
 
                r.locals = append(r.locals, name)
-
-               // TODO(go.dev/issue/54514): Set name.DictIndex for variables of
-               // derived type and enable cmd/link/internal/ld.TestDictIndex.
        }
 
        name.SetUsed(true)
@@ -3062,6 +3060,17 @@ func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
        return
 }
 
+// varDictIndex populates name.DictIndex if name is a derived type.
+func (r *reader) varDictIndex(name *ir.Name) {
+       if r.Bool() {
+               idx := 1 + r.dict.rtypesOffset() + r.Len()
+               if int(uint16(idx)) != idx {
+                       base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
+               }
+               name.DictIndex = uint16(idx)
+       }
+}
+
 func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
        if r.Bool() { // derived types
                idx := r.Len()
index a90aec9fc8ca65bdb9b80d1936e62f68b7a2961e..6c2ef033f66c136e3b1d70c60de0eda382e17494 100644 (file)
@@ -1090,20 +1090,19 @@ func (w *writer) funcargs(sig *types2.Signature) {
 
 func (w *writer) funcarg(param *types2.Var, result bool) {
        if param.Name() != "" || result {
-               w.addLocal(param, true)
+               w.addLocal(param)
        }
 }
 
 // addLocal records the declaration of a new local variable.
-func (w *writer) addLocal(obj *types2.Var, isParam bool) {
+func (w *writer) addLocal(obj *types2.Var) {
        idx := len(w.localsIdx)
 
-       if !isParam {
-               w.Sync(pkgbits.SyncAddLocal)
-               if w.p.SyncMarkers() {
-                       w.Int(idx)
-               }
+       w.Sync(pkgbits.SyncAddLocal)
+       if w.p.SyncMarkers() {
+               w.Int(idx)
        }
+       w.varDictIndex(obj)
 
        if w.localsIdx == nil {
                w.localsIdx = make(map[*types2.Var]int)
@@ -1295,7 +1294,7 @@ func (w *writer) assign(expr syntax.Expr) {
 
                        // TODO(mdempsky): Minimize locals index size by deferring
                        // this until the variables actually come into scope.
-                       w.addLocal(obj, false)
+                       w.addLocal(obj)
                        return
                }
        }
@@ -1558,7 +1557,7 @@ func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
 
                        obj := obj.(*types2.Var)
                        w.typ(obj.Type())
-                       w.addLocal(obj, false)
+                       w.addLocal(obj)
                }
 
                w.stmts(clause.Body)
@@ -2177,6 +2176,15 @@ func (w *writer) rtype(typ types2.Type) {
        }
 }
 
+// varDictIndex writes out information for populating DictIndex for
+// the ir.Name that will represent obj.
+func (w *writer) varDictIndex(obj *types2.Var) {
+       info := w.p.typIdx(obj.Type(), w.dict)
+       if w.Bool(info.derived) {
+               w.Len(w.dict.rtypeIdx(info))
+       }
+}
+
 func isUntyped(typ types2.Type) bool {
        basic, ok := typ.(*types2.Basic)
        return ok && basic.Info()&types2.IsUntyped != 0
index 4ac3dbdcfded9f92e92ac073a16ed6a1d4624638..4b503711612d1ecfaffa4016f64a692b1d1c3d75 100644 (file)
@@ -11,7 +11,6 @@ import (
        "debug/dwarf"
        "debug/pe"
        "fmt"
-       "internal/buildcfg"
        "internal/testenv"
        "io"
        "io/ioutil"
@@ -1597,9 +1596,6 @@ func TestDictIndex(t *testing.T) {
        if runtime.GOOS == "plan9" {
                t.Skip("skipping on plan9; no DWARF symbol table in executables")
        }
-       if buildcfg.Experiment.Unified {
-               t.Skip("GOEXPERIMENT=unified does not emit dictionaries yet")
-       }
        t.Parallel()
 
        const prog = `