From: Josh Bleecher Snyder Date: Tue, 21 Sep 2021 20:48:23 +0000 (-0700) Subject: runtime: change funcinl sentinel value from 0 to ^0 X-Git-Tag: go1.18beta1~1166 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6c163e5ac9cdb258566f1287de7915a2fd30a0de;p=gostls13.git runtime: change funcinl sentinel value from 0 to ^0 _func and funcinl are type-punned. We distinguish them at runtime by inspecting the first word. Prior to this change, we used 0 as the sentinel value that means that a Func is a funcinl. That worked because _func's first word is the functions' entry PC, and 0 is not a valid PC. I plan to make *_func's entry PC relative to the containing module. As a result, 0 will be a valid value, for the first function in the module. Switch to ^0 as the new sentinel value, which is neither a valid entry PC nor a valid PC offset. Change-Id: I4c718523a083ed6edd57767c3548640681993522 Reviewed-on: https://go-review.googlesource.com/c/go/+/351459 Trust: Josh Bleecher Snyder Run-TryBot: Josh Bleecher Snyder TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 04bd5cb887..442042eb16 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -879,8 +879,8 @@ type _func struct { // A *Func can be either a *_func or a *funcinl, and they are distinguished // by the first uintptr. type funcinl struct { - zero uintptr // set to 0 to distinguish from _func - entry uintptr // entry of the real (the "outermost") frame. + ones uintptr // set to ^0 to distinguish from _func + entry uintptr // entry of the real (the "outermost") frame name string file string line int diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index 6236643ceb..0f4ad5ab95 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -650,6 +650,7 @@ func FuncForPC(pc uintptr) *Func { name := funcnameFromNameoff(f, inltree[ix].func_) file, line := funcline(f, pc) fi := &funcinl{ + ones: ^uintptr(0), entry: f.entry, // entry of the real (the outermost) function. name: name, file: file, @@ -667,7 +668,7 @@ func (f *Func) Name() string { return "" } fn := f.raw() - if fn.entry == 0 { // inlined version + if fn.isInlined() { // inlined version fi := (*funcinl)(unsafe.Pointer(fn)) return fi.name } @@ -677,7 +678,7 @@ func (f *Func) Name() string { // Entry returns the entry address of the function. func (f *Func) Entry() uintptr { fn := f.raw() - if fn.entry == 0 { // inlined version + if fn.isInlined() { // inlined version fi := (*funcinl)(unsafe.Pointer(fn)) return fi.entry } @@ -690,7 +691,7 @@ func (f *Func) Entry() uintptr { // counter within f. func (f *Func) FileLine(pc uintptr) (file string, line int) { fn := f.raw() - if fn.entry == 0 { // inlined version + if fn.isInlined() { // inlined version fi := (*funcinl)(unsafe.Pointer(fn)) return fi.file, fi.line } @@ -728,6 +729,11 @@ func (f funcInfo) _Func() *Func { return (*Func)(unsafe.Pointer(f._func)) } +// isInlined reports whether f should be re-interpreted as a *funcinl. +func (f *_func) isInlined() bool { + return f.entry == ^uintptr(0) // see comment for funcinl.ones +} + // findfunc looks up function metadata for a PC. // // It is nosplit because it's part of the isgoexception