Source File
symtabinl.go
Belonging Package
runtime
// Copyright 2023 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package runtimeimport// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.type inlinedCall struct {funcID abi.FuncID // type of the called function_ [3]bytenameOff int32 // offset into pclntab for name of called functionparentPc int32 // position of an instruction whose source position is the call site (offset from entry)startLine int32 // line number of start of function (func keyword/TEXT directive)}// An inlineUnwinder iterates over the stack of inlined calls at a PC by// decoding the inline table. The last step of iteration is always the frame of// the physical function, so there's always at least one frame.//// This is typically used as://// for u, uf := newInlineUnwinder(...); uf.valid(); uf = u.next(uf) { ... }//// Implementation note: This is used in contexts that disallow write barriers.// Hence, the constructor returns this by value and pointer receiver methods// must not mutate pointer fields. Also, we keep the mutable state in a separate// struct mostly to keep both structs SSA-able, which generates much better// code.type inlineUnwinder struct {f funcInfocache *pcvalueCacheinlTree *[1 << 20]inlinedCall}// An inlineFrame is a position in an inlineUnwinder.type inlineFrame struct {// pc is the PC giving the file/line metadata of the current frame. This is// always a "call PC" (not a "return PC"). This is 0 when the iterator is// exhausted.pc uintptr// index is the index of the current record in inlTree, or -1 if we are in// the outermost function.index int32}// newInlineUnwinder creates an inlineUnwinder initially set to the inner-most// inlined frame at PC. PC should be a "call PC" (not a "return PC").//// This unwinder uses non-strict handling of PC because it's assumed this is// only ever used for symbolic debugging. If things go really wrong, it'll just// fall back to the outermost frame.func ( funcInfo, uintptr, *pcvalueCache) (inlineUnwinder, inlineFrame) {:= funcdata(, abi.FUNCDATA_InlTree)if == nil {return inlineUnwinder{f: }, inlineFrame{pc: , index: -1}}:= (*[1 << 20]inlinedCall)():= inlineUnwinder{f: , cache: , inlTree: }return , .resolveInternal()}func ( *inlineUnwinder) ( uintptr) inlineFrame {return inlineFrame{pc: ,// Conveniently, this returns -1 if there's an error, which is the same// value we use for the outermost frame.index: pcdatavalue1(.f, abi.PCDATA_InlTreeIndex, , .cache, false),}}func ( inlineFrame) () bool {return .pc != 0}// next returns the frame representing uf's logical caller.func ( *inlineUnwinder) ( inlineFrame) inlineFrame {if .index < 0 {.pc = 0return}:= .inlTree[.index].parentPcreturn .resolveInternal(.f.entry() + uintptr())}// isInlined returns whether uf is an inlined frame.func ( *inlineUnwinder) ( inlineFrame) bool {return .index >= 0}// srcFunc returns the srcFunc representing the given frame.func ( *inlineUnwinder) ( inlineFrame) srcFunc {if .index < 0 {return .f.srcFunc()}:= &.inlTree[.index]return srcFunc{.f.datap,.nameOff,.startLine,.funcID,}}// fileLine returns the file name and line number of the call within the given// frame. As a convenience, for the innermost frame, it returns the file and// line of the PC this unwinder was started at (often this is a call to another// physical function).//// It returns "?", 0 if something goes wrong.func ( *inlineUnwinder) ( inlineFrame) ( string, int) {, := funcline1(.f, .pc, false)return , int()}
![]() |
The pages are generated with Golds v0.6.7. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |