Commit 79711643 authored by Kirill Smelkov's avatar Kirill Smelkov

tracing: call/return overhead related to using trace functions is gone

As of Go1.12 the check for whether particular trace event is enabled or
not is inlined into caller. For example:

	---- 8< ---- (connection.go)
	//trace:event traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg)

	func (link *NodeLink) sendMsg(connId uint32, msg proto.Msg) error {
		traceMsgSendPre(link, connId, msg)

		buf := msgPack(connId, msg)
		return link.sendPkt(buf)
	}

	---- 8< ---- (ztrace.go)
	// traceevent: traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg)

	type _t_traceMsgSendPre struct {
	        tracing.Probe
	        probefunc     func(l *NodeLink, connId uint32, msg proto.Msg)
	}

	var _traceMsgSendPre *_t_traceMsgSendPre

	func traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg) {
	        if _traceMsgSendPre != nil {
	                _traceMsgSendPre_run(l, connId, msg)
	        }
	}

	func _traceMsgSendPre_run(l *NodeLink, connId uint32, msg proto.Msg) {
	        for p := _traceMsgSendPre; p != nil; p = (*_t_traceMsgSendPre)(unsafe.Pointer(p.Next())) {
	                p.probefunc(l, connId, msg)
	        }
	}

	---- 8< ---- (connection.o)
	TEXT lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·(*NodeLink).sendMsg(SB), ABIInternal, $40-48 // connection.go:1368
	        // MOVQ    (TLS), CX (stack growth prologue)
	        // CMPQ    SP, 16(CX)
	        // JLS     177
	        // SUBQ    $40, SP
	        // MOVQ    BP, 32(SP) (BP save)
	        // LEAQ    32(SP), BP (BP init)
	        // FUNCDATA $0, gclocals·dbae954985b577993f0eafab1347dd21(SB) (args)
	        FUNCDATA   $1, gclocals·f6bd6b3389b872033d462029172c8612(SB) (locals)
	        FUNCDATA   $3, gclocals·47f0f3578d0f16ef296c57af2564832c(SB)
	        PCDATA     $2, $0             // connection.go:1369
	        PCDATA     $0, $0
	        XCHGL      AX, AX
	        CMPQ       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·_traceMsgSendPre(SB), $0	<-- inlined traceMsgSendPre
	        JNE        pc130              // ztrace.go:50					<--
	pc44:
	        MOVL       connId+56(SP), AX  // connection.go:1371				<-- normal path
	        MOVL       AX, (SP)
	        MOVQ       msg+64(SP), AX
	        MOVQ       AX, 8(SP)
	        PCDATA     $2, $1
	        PCDATA     $0, $1
	        MOVQ       msg+72(SP), AX
	        PCDATA     $2, $0
	        MOVQ       AX, 16(SP)
	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·msgPack(SB)
	        PCDATA     $2, $1
	        MOVQ       24(SP), AX
	        PCDATA     $2, $2             // connection.go:1372
	        PCDATA     $0, $2
	        MOVQ       link+48(SP), CX
	        PCDATA     $2, $1
	        MOVQ       CX, (SP)
	        PCDATA     $2, $0
	        MOVQ       AX, 8(SP)
	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·(*NodeLink).sendPkt(SB)
	        PCDATA     $2, $1
	        MOVQ       24(SP), AX
	        MOVQ       16(SP), CX
	        PCDATA     $0, $3
	        MOVQ       CX, _r2+80(SP)
	        PCDATA     $2, $0
	        MOVQ       AX, _r2+88(SP)
	        // MOVQ    32(SP), BP (BP restore)
	        // ADDQ    $40, SP (SP restore)
	        RET
	pc130:											<-- slow path (tracepoint attached)
	        PCDATA     $2, $1             // ztrace.go:51
	        PCDATA     $0, $0
	        MOVQ       link+48(SP), AX
	        PCDATA     $2, $0
	        MOVQ       AX, (SP)
	        MOVL       connId+56(SP), CX
	        MOVL       CX, 8(SP)
	        MOVQ       msg+64(SP), DX
	        MOVQ       DX, 16(SP)
	        PCDATA     $2, $3
	        MOVQ       msg+72(SP), BX
	        PCDATA     $2, $0
	        MOVQ       BX, 24(SP)
	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·_traceMsgSendPre_run(SB)
	        JMP        pc44
	        // NOP (stack growth)
	        // PCDATA  $0, $-1            // connection.go:1368
	        // PCDATA  $2, $-1
	        // CALL    runtime.morestack_noctxt(SB)
	        // JMP     0
parent 5a2cf114
......@@ -37,7 +37,7 @@ function that is used to signal when the event happens. For example:
traceHello(who)
}
By default trace function does nothing and has very small overhead(*).
By default using trace function does nothing and has very small overhead(*).
Probes
......@@ -191,9 +191,7 @@ Please see `gotrace help` and lab.nexedi.com/kirr/go123/tracing/cmd/gotrace for
--------
(*) conditionally checking whether a pointer != nil. After
https://golang.org/issues/19348 is implemented the call/return overhead will be
also gone.
(*) inlined check whether a global pointer != nil.
*/
package tracing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment