diff options
author | Cherry Mui <cherryyz@google.com> | 2021-09-24 16:46:05 -0400 |
---|---|---|
committer | Cherry Mui <cherryyz@google.com> | 2021-10-27 20:27:02 +0000 |
commit | 30a82efcf403fed76bf1542e9477047660d5f54d (patch) | |
tree | 5de1ccb9abde5ff01289dc6e5855cdb9871e963b /src/cmd/internal | |
parent | bbc059572d599a414653e4ac659b4738d434e1f1 (diff) | |
download | go-30a82efcf403fed76bf1542e9477047660d5f54d.tar.gz go-30a82efcf403fed76bf1542e9477047660d5f54d.zip |
cmd/compile, runtime: track argument stack slot liveness
Currently, for stack traces (e.g. at panic or when runtime.Stack
is called), we print argument values from the stack. With register
ABI, we may never store the argument to stack therefore the
argument value on stack may be meaningless. This causes confusion.
This CL makes the compiler keep trace of which argument stack
slots are meaningful. If it is meaningful, it will be printed in
stack traces as before. If it may not be meaningful, it will be
printed as the stack value with a question mark ("?"). In general,
the value could be meaningful on some code paths but not others
depending on the execution, and the compiler couldn't know
statically, so we still print the stack value, instead of not
printing it at all. Also note that if the argument variable is
updated in the function body the printed value may be stale (like
before register ABI) but still considered meaningful.
Arguments passed on stack are always meaningful therefore always
printed without a question mark. Results are never printed, as
before.
(Due to a bug in the compiler we sometimes don't spill args into
their dedicated spill slots (as we should), causing it having
fewer meaningful values than it should be.)
This increases binary sizes a bit:
old new
hello 1129760 1142080 +1.09%
cmd/go 13932320 14088016 +1.12%
cmd/link 6267696 6329168 +0.98%
Fixes #45728.
Change-Id: I308a0402e5c5ab94ca0953f8bd85a56acd28f58c
Reviewed-on: https://go-review.googlesource.com/c/go/+/352057
Trust: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r-- | src/cmd/internal/obj/link.go | 1 | ||||
-rw-r--r-- | src/cmd/internal/obj/objfile.go | 4 | ||||
-rw-r--r-- | src/cmd/internal/objabi/funcdata.go | 2 |
3 files changed, 6 insertions, 1 deletions
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index abb37416cc..4bcfb05a5e 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -486,6 +486,7 @@ type FuncInfo struct { StackObjects *LSym OpenCodedDeferInfo *LSym ArgInfo *LSym // argument info for traceback + ArgLiveInfo *LSym // argument liveness info for traceback FuncInfoSym *LSym } diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index a590549f52..fa616691eb 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -347,7 +347,8 @@ func (w *writer) Sym(s *LSym) { strings.HasPrefix(name, "runtime.gcbits."), strings.HasSuffix(name, ".opendefer"), strings.HasSuffix(name, ".arginfo0"), - strings.HasSuffix(name, ".arginfo1"): + strings.HasSuffix(name, ".arginfo1"), + strings.HasSuffix(name, ".argliveinfo"): // These are just bytes, or varints. align = 1 case strings.HasPrefix(name, "gclocals·"): @@ -415,6 +416,7 @@ func contentHashSection(s *LSym) byte { strings.HasSuffix(name, ".opendefer") || strings.HasSuffix(name, ".arginfo0") || strings.HasSuffix(name, ".arginfo1") || + strings.HasSuffix(name, ".argliveinfo") || strings.HasSuffix(name, ".args_stackmap") || strings.HasSuffix(name, ".stkobj") { return 'F' // go.func.* or go.funcrel.* diff --git a/src/cmd/internal/objabi/funcdata.go b/src/cmd/internal/objabi/funcdata.go index 4ff0ebe13d..4d49a8d548 100644 --- a/src/cmd/internal/objabi/funcdata.go +++ b/src/cmd/internal/objabi/funcdata.go @@ -14,6 +14,7 @@ const ( PCDATA_UnsafePoint = 0 PCDATA_StackMapIndex = 1 PCDATA_InlTreeIndex = 2 + PCDATA_ArgLiveIndex = 3 FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_LocalsPointerMaps = 1 @@ -21,6 +22,7 @@ const ( FUNCDATA_InlTree = 3 FUNCDATA_OpenCodedDeferInfo = 4 FUNCDATA_ArgInfo = 5 + FUNCDATA_ArgLiveInfo = 6 // ArgsSizeUnknown is set in Func.argsize to mark all functions // whose argument size is unknown (C vararg functions, and |