mirror of
https://github.com/golang/go
synced 2024-11-19 13:04:45 -07:00
699175a11a
In order to generate accurate tracebacks, the runtime needs to know the inlined call stack for a given PC. This creates two tables per function for this purpose. The first table is the inlining tree (stored in the function's funcdata), which has a node containing the file, line, and function name for every inlined call. The second table is a PC-value table that maps each PC to a node in the inlining tree (or -1 if the PC is not the result of inlining). To give the appearance that inlining hasn't happened, the runtime also needs the original source position information of inlined AST nodes. Previously the compiler plastered over the line numbers of inlined AST nodes with the line number of the call. This meant that the PC-line table mapped each PC to line number of the outermost call in its inlined call stack, with no way to access the innermost line number. Now the compiler retains line numbers of inlined AST nodes and writes the innermost source position information to the PC-line and PC-file tables. Some tools and tests expect to see outermost line numbers, so we provide the OutermostLine function for displaying line info. To keep track of the inlined call stack for an AST node, we extend the src.PosBase type with an index into a global inlining tree. Every time the compiler inlines a call, it creates a node in the global inlining tree for the call, and writes its index to the PosBase of every inlined AST node. The parent of this node is the inlining tree index of the call. -1 signifies no parent. For each function, the compiler creates a local inlining tree and a PC-value table mapping each PC to an index in the local tree. These are written to an object file, which is read by the linker. The linker re-encodes these tables compactly by deduplicating function names and file names. This change increases the size of binaries by 4-5%. For example, this is how the go1 benchmark binary is impacted by this change: section old bytes new bytes delta .text 3.49M ± 0% 3.49M ± 0% +0.06% .rodata 1.12M ± 0% 1.21M ± 0% +8.21% .gopclntab 1.50M ± 0% 1.68M ± 0% +11.89% .debug_line 338k ± 0% 435k ± 0% +28.78% Total 9.21M ± 0% 9.58M ± 0% +4.01% Updates #19348. Change-Id: Ic4f180c3b516018138236b0c35e0218270d957d3 Reviewed-on: https://go-review.googlesource.com/37231 Run-TryBot: David Lazar <lazard@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
50 lines
2.3 KiB
C
50 lines
2.3 KiB
C
// Copyright 2013 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.
|
|
|
|
// This file defines the IDs for PCDATA and FUNCDATA instructions
|
|
// in Go binaries. It is included by assembly sources, so it must
|
|
// be written using #defines.
|
|
//
|
|
// These must agree with symtab.go and ../cmd/internal/obj/funcdata.go.
|
|
|
|
#define PCDATA_StackMapIndex 0
|
|
#define PCDATA_InlTreeIndex 1
|
|
|
|
#define FUNCDATA_ArgsPointerMaps 0 /* garbage collector blocks */
|
|
#define FUNCDATA_LocalsPointerMaps 1
|
|
#define FUNCDATA_InlTree 2
|
|
|
|
// Pseudo-assembly statements.
|
|
|
|
// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
|
|
// that communicate to the runtime information about the location and liveness
|
|
// of pointers in an assembly function's arguments, results, and stack frame.
|
|
// This communication is only required in assembly functions that make calls
|
|
// to other functions that might be preempted or grow the stack.
|
|
// NOSPLIT functions that make no calls do not need to use these macros.
|
|
|
|
// GO_ARGS indicates that the Go prototype for this assembly function
|
|
// defines the pointer map for the function's arguments.
|
|
// GO_ARGS should be the first instruction in a function that uses it.
|
|
// It can be omitted if there are no arguments at all.
|
|
// GO_ARGS is inserted implicitly by the linker for any function
|
|
// that also has a Go prototype and therefore is usually not necessary
|
|
// to write explicitly.
|
|
#define GO_ARGS FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB)
|
|
|
|
// GO_RESULTS_INITIALIZED indicates that the assembly function
|
|
// has initialized the stack space for its results and that those results
|
|
// should be considered live for the remainder of the function.
|
|
#define GO_RESULTS_INITIALIZED PCDATA $PCDATA_StackMapIndex, $1
|
|
|
|
// NO_LOCAL_POINTERS indicates that the assembly function stores
|
|
// no pointers to heap objects in its local stack variables.
|
|
#define NO_LOCAL_POINTERS FUNCDATA $FUNCDATA_LocalsPointerMaps, runtime·no_pointers_stackmap(SB)
|
|
|
|
// ArgsSizeUnknown is set in Func.argsize to mark all functions
|
|
// whose argument size is unknown (C vararg functions, and
|
|
// assembly code without an explicit specification).
|
|
// This value is generated by the compiler, assembler, or linker.
|
|
#define ArgsSizeUnknown 0x80000000
|