2010-03-31 15:55:10 -07:00
|
|
|
// Copyright 2010 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 runtime
|
|
|
|
|
|
2024-04-02 13:08:24 +00:00
|
|
|
import (
|
|
|
|
|
"internal/abi"
|
|
|
|
|
"internal/bytealg"
|
2024-09-16 14:07:43 -04:00
|
|
|
"internal/runtime/sys"
|
2024-04-02 13:08:24 +00:00
|
|
|
)
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
|
2025-05-07 14:00:37 -04:00
|
|
|
// Error identifies a runtime error used in panic.
|
|
|
|
|
//
|
|
|
|
|
// The Go runtime triggers panics for a variety of cases, as described by the
|
|
|
|
|
// Go Language Spec, such as out-of-bounds slice/array access, close of nil
|
|
|
|
|
// channels, type assertion failures, etc.
|
|
|
|
|
//
|
|
|
|
|
// When these cases occur, the Go runtime panics with an error that implements
|
|
|
|
|
// Error. This can be useful when recovering from panics to distinguish between
|
|
|
|
|
// custom application panics and fundamental runtime panics.
|
|
|
|
|
//
|
|
|
|
|
// Packages outside of the Go standard library should not implement Error.
|
2010-03-31 15:55:10 -07:00
|
|
|
type Error interface {
|
2011-11-01 21:48:27 -04:00
|
|
|
error
|
2010-04-01 22:31:27 -07:00
|
|
|
|
|
|
|
|
// RuntimeError is a no-op function but
|
2025-05-07 14:00:37 -04:00
|
|
|
// serves to distinguish types that are runtime
|
2011-11-01 22:58:09 -04:00
|
|
|
// errors from ordinary errors: a type is a
|
2025-05-07 14:00:37 -04:00
|
|
|
// runtime error if it has a RuntimeError method.
|
2010-04-01 22:31:27 -07:00
|
|
|
RuntimeError()
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A TypeAssertionError explains a failed type assertion.
|
|
|
|
|
type TypeAssertionError struct {
|
2018-07-11 13:51:39 -07:00
|
|
|
_interface *_type
|
|
|
|
|
concrete *_type
|
|
|
|
|
asserted *_type
|
|
|
|
|
missingMethod string // one method needed by Interface, missing from Concrete
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
|
2010-04-01 22:31:27 -07:00
|
|
|
func (*TypeAssertionError) RuntimeError() {}
|
|
|
|
|
|
2011-11-01 21:48:27 -04:00
|
|
|
func (e *TypeAssertionError) Error() string {
|
2018-07-11 13:51:39 -07:00
|
|
|
inter := "interface"
|
|
|
|
|
if e._interface != nil {
|
2023-04-24 15:45:33 -04:00
|
|
|
inter = toRType(e._interface).string()
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
2023-04-24 15:45:33 -04:00
|
|
|
as := toRType(e.asserted).string()
|
2018-07-11 13:51:39 -07:00
|
|
|
if e.concrete == nil {
|
|
|
|
|
return "interface conversion: " + inter + " is nil, not " + as
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
2023-04-24 15:45:33 -04:00
|
|
|
cs := toRType(e.concrete).string()
|
2010-03-31 15:55:10 -07:00
|
|
|
if e.missingMethod == "" {
|
2018-07-11 13:51:39 -07:00
|
|
|
msg := "interface conversion: " + inter + " is " + cs + ", not " + as
|
|
|
|
|
if cs == as {
|
2018-06-04 16:32:07 -07:00
|
|
|
// provide slightly clearer error message
|
2023-04-24 15:45:33 -04:00
|
|
|
if toRType(e.concrete).pkgpath() != toRType(e.asserted).pkgpath() {
|
2018-07-11 13:51:39 -07:00
|
|
|
msg += " (types from different packages)"
|
|
|
|
|
} else {
|
|
|
|
|
msg += " (types from different scopes)"
|
|
|
|
|
}
|
2018-06-04 16:32:07 -07:00
|
|
|
}
|
|
|
|
|
return msg
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
2018-07-11 13:51:39 -07:00
|
|
|
return "interface conversion: " + cs + " is not " + as +
|
2010-03-31 15:55:10 -07:00
|
|
|
": missing method " + e.missingMethod
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 14:12:36 -08:00
|
|
|
// itoa converts val to a decimal representation. The result is
|
|
|
|
|
// written somewhere within buf and the location of the result is returned.
|
|
|
|
|
// buf must be at least 20 bytes.
|
2022-02-03 14:12:08 -05:00
|
|
|
//
|
|
|
|
|
//go:nosplit
|
2019-02-06 14:12:36 -08:00
|
|
|
func itoa(buf []byte, val uint64) []byte {
|
|
|
|
|
i := len(buf) - 1
|
|
|
|
|
for val >= 10 {
|
|
|
|
|
buf[i] = byte(val%10 + '0')
|
|
|
|
|
i--
|
|
|
|
|
val /= 10
|
|
|
|
|
}
|
|
|
|
|
buf[i] = byte(val + '0')
|
|
|
|
|
return buf[i:]
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-01 22:31:27 -07:00
|
|
|
// An errorString represents a runtime error described by a single string.
|
|
|
|
|
type errorString string
|
|
|
|
|
|
|
|
|
|
func (e errorString) RuntimeError() {}
|
|
|
|
|
|
2011-11-01 21:48:27 -04:00
|
|
|
func (e errorString) Error() string {
|
2010-04-01 22:31:27 -07:00
|
|
|
return "runtime error: " + string(e)
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-20 14:22:30 -07:00
|
|
|
type errorAddressString struct {
|
|
|
|
|
msg string // error message
|
|
|
|
|
addr uintptr // memory address where the error occurred
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (e errorAddressString) RuntimeError() {}
|
|
|
|
|
|
|
|
|
|
func (e errorAddressString) Error() string {
|
|
|
|
|
return "runtime error: " + e.msg
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Addr returns the memory address where a fault occurred.
|
|
|
|
|
// The address provided is best-effort.
|
|
|
|
|
// The veracity of the result may depend on the platform.
|
|
|
|
|
// Errors providing this method will only be returned as
|
2023-11-07 17:35:46 +08:00
|
|
|
// a result of using [runtime/debug.SetPanicOnFault].
|
2020-08-20 14:22:30 -07:00
|
|
|
func (e errorAddressString) Addr() uintptr {
|
|
|
|
|
return e.addr
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-27 17:29:53 -07:00
|
|
|
// plainError represents a runtime error described a string without
|
|
|
|
|
// the prefix "runtime error: " after invoking errorString.Error().
|
|
|
|
|
// See Issue #14965.
|
|
|
|
|
type plainError string
|
|
|
|
|
|
|
|
|
|
func (e plainError) RuntimeError() {}
|
|
|
|
|
|
|
|
|
|
func (e plainError) Error() string {
|
|
|
|
|
return string(e)
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-15 19:49:30 +00:00
|
|
|
// A boundsError represents an indexing or slicing operation gone wrong.
|
2019-02-06 14:12:36 -08:00
|
|
|
type boundsError struct {
|
|
|
|
|
x int64
|
|
|
|
|
y int
|
|
|
|
|
// Values in an index or slice expression can be signed or unsigned.
|
|
|
|
|
// That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1.
|
|
|
|
|
// Instead, we keep track of whether x should be interpreted as signed or unsigned.
|
|
|
|
|
// y is known to be nonnegative and to fit in an int.
|
|
|
|
|
signed bool
|
2025-06-17 14:44:56 -07:00
|
|
|
code abi.BoundsErrorCode
|
2019-02-06 14:12:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// boundsErrorFmts provide error text for various out-of-bounds panics.
|
|
|
|
|
// Note: if you change these strings, you should adjust the size of the buffer
|
|
|
|
|
// in boundsError.Error below as well.
|
|
|
|
|
var boundsErrorFmts = [...]string{
|
2025-06-17 14:44:56 -07:00
|
|
|
abi.BoundsIndex: "index out of range [%x] with length %y",
|
|
|
|
|
abi.BoundsSliceAlen: "slice bounds out of range [:%x] with length %y",
|
|
|
|
|
abi.BoundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
|
|
|
|
|
abi.BoundsSliceB: "slice bounds out of range [%x:%y]",
|
|
|
|
|
abi.BoundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
|
|
|
|
|
abi.BoundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
|
|
|
|
|
abi.BoundsSlice3B: "slice bounds out of range [:%x:%y]",
|
|
|
|
|
abi.BoundsSlice3C: "slice bounds out of range [%x:%y:]",
|
|
|
|
|
abi.BoundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
|
2019-02-06 14:12:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
|
|
|
|
|
var boundsNegErrorFmts = [...]string{
|
2025-06-17 14:44:56 -07:00
|
|
|
abi.BoundsIndex: "index out of range [%x]",
|
|
|
|
|
abi.BoundsSliceAlen: "slice bounds out of range [:%x]",
|
|
|
|
|
abi.BoundsSliceAcap: "slice bounds out of range [:%x]",
|
|
|
|
|
abi.BoundsSliceB: "slice bounds out of range [%x:]",
|
|
|
|
|
abi.BoundsSlice3Alen: "slice bounds out of range [::%x]",
|
|
|
|
|
abi.BoundsSlice3Acap: "slice bounds out of range [::%x]",
|
|
|
|
|
abi.BoundsSlice3B: "slice bounds out of range [:%x:]",
|
|
|
|
|
abi.BoundsSlice3C: "slice bounds out of range [%x::]",
|
2019-02-06 14:12:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (e boundsError) RuntimeError() {}
|
|
|
|
|
|
|
|
|
|
func appendIntStr(b []byte, v int64, signed bool) []byte {
|
|
|
|
|
if signed && v < 0 {
|
|
|
|
|
b = append(b, '-')
|
|
|
|
|
v = -v
|
|
|
|
|
}
|
|
|
|
|
var buf [20]byte
|
|
|
|
|
b = append(b, itoa(buf[:], uint64(v))...)
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (e boundsError) Error() string {
|
|
|
|
|
fmt := boundsErrorFmts[e.code]
|
|
|
|
|
if e.signed && e.x < 0 {
|
|
|
|
|
fmt = boundsNegErrorFmts[e.code]
|
|
|
|
|
}
|
|
|
|
|
// max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y"
|
|
|
|
|
// x can be at most 20 characters. y can be at most 19.
|
|
|
|
|
b := make([]byte, 0, 100)
|
|
|
|
|
b = append(b, "runtime error: "...)
|
|
|
|
|
for i := 0; i < len(fmt); i++ {
|
|
|
|
|
c := fmt[i]
|
|
|
|
|
if c != '%' {
|
|
|
|
|
b = append(b, c)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
i++
|
|
|
|
|
switch fmt[i] {
|
|
|
|
|
case 'x':
|
|
|
|
|
b = appendIntStr(b, e.x, e.signed)
|
|
|
|
|
case 'y':
|
|
|
|
|
b = appendIntStr(b, int64(e.y), true)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return string(b)
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-31 15:55:10 -07:00
|
|
|
type stringer interface {
|
|
|
|
|
String() string
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 12:44:54 -04:00
|
|
|
// printpanicval prints an argument passed to panic.
|
2018-02-23 10:34:01 -08:00
|
|
|
// If panic is called with a value that has a String or Error method,
|
|
|
|
|
// it has already been converted into a string by preprintpanics.
|
2024-04-23 12:44:54 -04:00
|
|
|
//
|
|
|
|
|
// To ensure that the traceback can be unambiguously parsed even when
|
|
|
|
|
// the panic value contains "\ngoroutine" and other stack-like
|
|
|
|
|
// strings, newlines in the string representation of v are replaced by
|
|
|
|
|
// "\n\t".
|
|
|
|
|
func printpanicval(v any) {
|
|
|
|
|
switch v := v.(type) {
|
2010-03-31 15:55:10 -07:00
|
|
|
case nil:
|
|
|
|
|
print("nil")
|
2017-04-07 15:41:19 -05:00
|
|
|
case bool:
|
|
|
|
|
print(v)
|
2010-03-31 15:55:10 -07:00
|
|
|
case int:
|
|
|
|
|
print(v)
|
2017-04-07 15:41:19 -05:00
|
|
|
case int8:
|
|
|
|
|
print(v)
|
|
|
|
|
case int16:
|
|
|
|
|
print(v)
|
|
|
|
|
case int32:
|
|
|
|
|
print(v)
|
|
|
|
|
case int64:
|
|
|
|
|
print(v)
|
|
|
|
|
case uint:
|
|
|
|
|
print(v)
|
|
|
|
|
case uint8:
|
|
|
|
|
print(v)
|
|
|
|
|
case uint16:
|
|
|
|
|
print(v)
|
|
|
|
|
case uint32:
|
|
|
|
|
print(v)
|
|
|
|
|
case uint64:
|
|
|
|
|
print(v)
|
|
|
|
|
case uintptr:
|
|
|
|
|
print(v)
|
|
|
|
|
case float32:
|
|
|
|
|
print(v)
|
|
|
|
|
case float64:
|
|
|
|
|
print(v)
|
|
|
|
|
case complex64:
|
|
|
|
|
print(v)
|
|
|
|
|
case complex128:
|
|
|
|
|
print(v)
|
2010-03-31 15:55:10 -07:00
|
|
|
case string:
|
2024-04-23 12:44:54 -04:00
|
|
|
printindented(v)
|
2010-03-31 15:55:10 -07:00
|
|
|
default:
|
2024-04-23 12:44:54 -04:00
|
|
|
printanycustomtype(v)
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 12:44:54 -04:00
|
|
|
// Invariant: each newline in the string representation is followed by a tab.
|
2021-12-01 12:15:45 -05:00
|
|
|
func printanycustomtype(i any) {
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
eface := efaceOf(&i)
|
2023-04-24 15:45:33 -04:00
|
|
|
typestring := toRType(eface._type).string()
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
|
2023-01-20 16:41:57 -05:00
|
|
|
switch eface._type.Kind_ {
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.String:
|
2024-04-23 12:44:54 -04:00
|
|
|
print(typestring, `("`)
|
|
|
|
|
printindented(*(*string)(eface.data))
|
|
|
|
|
print(`")`)
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Bool:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*bool)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Int:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*int)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Int8:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*int8)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Int16:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*int16)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Int32:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*int32)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Int64:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*int64)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uint:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uint)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uint8:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uint8)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uint16:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uint16)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uint32:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uint32)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uint64:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uint64)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Uintptr:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*uintptr)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Float32:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*float32)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Float64:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, "(", *(*float64)(eface.data), ")")
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Complex64:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, *(*complex64)(eface.data))
|
2024-04-02 13:08:24 +00:00
|
|
|
case abi.Complex128:
|
runtime: during panic, print value instead of address, if kind is printable
Make panics more useful by printing values, if their
underlying kind is printable, instead of just their memory address.
Thus now given any custom type derived from any of:
float*, int*, string, uint*
if we have panic with such a result, its value will be printed.
Thus given any of:
type MyComplex128 complex128
type MyFloat64 float64
type MyString string
type MyUintptr uintptr
panic(MyComplex128(32.1 + 10i))
panic(MyFloat64(-93.7))
panic(MyString("This one"))
panic(MyUintptr(93))
They will now print in the panic:
panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)
panic: main.MyFloat64(-9.370000e+001)
panic: main.MyString("This one")
panic: main.MyUintptr(93)
instead of:
panic: (main.MyComplex128) (0xe0100,0x138cc0)
panic: (main.MyFloat64) (0xe0100,0x138068)
panic: (main.MyString) (0x48aa00,0x4c0840)
panic: (main.MyUintptr) (0xe0100,0x137e58)
and anything else will be printed as in the past with:
panic: (main.MyStruct) (0xe4ee0,0x40a0e0)
Also while here, updated the Go1.15 release notes.
Fixes #37531
Change-Id: Ia486424344a386014f2869ab3483e42a9ef48ac4
Reviewed-on: https://go-review.googlesource.com/c/go/+/221779
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-01 17:41:44 -08:00
|
|
|
print(typestring, *(*complex128)(eface.data))
|
|
|
|
|
default:
|
|
|
|
|
print("(", typestring, ") ", eface.data)
|
2010-03-31 15:55:10 -07:00
|
|
|
}
|
|
|
|
|
}
|
2011-06-17 15:23:27 -04:00
|
|
|
|
2024-04-23 12:44:54 -04:00
|
|
|
// printindented prints s, replacing "\n" with "\n\t".
|
|
|
|
|
func printindented(s string) {
|
|
|
|
|
for {
|
|
|
|
|
i := bytealg.IndexByteString(s, '\n')
|
|
|
|
|
if i < 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
i += len("\n")
|
|
|
|
|
print(s[:i])
|
|
|
|
|
print("\t")
|
|
|
|
|
s = s[i:]
|
|
|
|
|
}
|
|
|
|
|
print(s)
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-12 14:24:16 -04:00
|
|
|
// panicwrap generates a panic for a call to a wrapped value method
|
|
|
|
|
// with a nil pointer receiver.
|
|
|
|
|
//
|
|
|
|
|
// It is called from the generated wrapper code.
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
func panicwrap() {
|
2024-09-16 14:07:43 -04:00
|
|
|
pc := sys.GetCallerPC()
|
2023-05-02 16:46:20 -04:00
|
|
|
name := funcNameForPrint(funcname(findfunc(pc)))
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
// name is something like "main.(*T).F".
|
|
|
|
|
// We want to extract pkg ("main"), typ ("T"), and meth ("F").
|
|
|
|
|
// Do it by finding the parens.
|
2018-03-01 16:38:41 -08:00
|
|
|
i := bytealg.IndexByteString(name, '(')
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
if i < 0 {
|
2017-06-12 14:24:16 -04:00
|
|
|
throw("panicwrap: no ( in " + name)
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
}
|
|
|
|
|
pkg := name[:i-1]
|
|
|
|
|
if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
|
2017-06-12 14:24:16 -04:00
|
|
|
throw("panicwrap: unexpected string after package name: " + name)
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
}
|
|
|
|
|
name = name[i+2:]
|
2018-03-01 16:38:41 -08:00
|
|
|
i = bytealg.IndexByteString(name, ')')
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
if i < 0 {
|
2017-06-12 14:24:16 -04:00
|
|
|
throw("panicwrap: no ) in " + name)
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
}
|
|
|
|
|
if i+2 >= len(name) || name[i:i+2] != ")." {
|
2017-06-12 14:24:16 -04:00
|
|
|
throw("panicwrap: unexpected string after type name: " + name)
|
cmd/compile: make panicwrap argument-free
When code defines a method on T,
the compiler generates a corresponding wrapper method on *T.
The first thing the wrapper does is check whether
the pointer is nil and if so, call panicwrap.
This is done to provide a useful error message.
The existing implementation gets its information
from arguments set up by the compiler.
However, with some trouble, this information can
be extracted from the name of the wrapper method itself.
Removing the arguments to panicwrap simplifies and
shrinks the wrapper method.
It also means that the call to panicwrap does not
require any stack space.
This enables a further optimization on amd64/x86,
which is to skip the function prologue if nothing
else in the method requires stack space.
This is frequently the case in simple, hot methods,
such as Less and Swap in sort.Interface implementations.
Fixes #19040.
Benchmarks for package sort on amd64:
name old time/op new time/op delta
SearchWrappers-8 104ns ± 1% 104ns ± 1% ~ (p=0.286 n=27+27)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.44% (p=0.004 n=30+30)
SortString1K_Slice-8 118µs ± 2% 117µs ± 1% ~ (p=0.106 n=30+30)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.446 n=28+26)
SortInt1K-8 65.9µs ± 1% 60.7µs ± 1% -7.96% (p=0.000 n=28+30)
StableInt1K-8 75.3µs ± 2% 72.8µs ± 1% -3.41% (p=0.000 n=30+30)
StableInt1K_Slice-8 57.7µs ± 1% 57.7µs ± 1% ~ (p=0.515 n=30+30)
SortInt64K-8 6.28ms ± 1% 6.01ms ± 1% -4.19% (p=0.000 n=28+28)
SortInt64K_Slice-8 5.04ms ± 1% 5.04ms ± 1% ~ (p=0.927 n=28+27)
StableInt64K-8 6.65ms ± 1% 6.38ms ± 1% -3.97% (p=0.000 n=26+30)
Sort1e2-8 37.9µs ± 1% 37.2µs ± 1% -1.89% (p=0.000 n=29+27)
Stable1e2-8 77.0µs ± 1% 74.7µs ± 1% -3.06% (p=0.000 n=27+30)
Sort1e4-8 8.21ms ± 2% 7.98ms ± 1% -2.77% (p=0.000 n=29+30)
Stable1e4-8 24.8ms ± 1% 24.3ms ± 1% -2.31% (p=0.000 n=28+30)
Sort1e6-8 1.27s ± 4% 1.22s ± 1% -3.42% (p=0.000 n=30+29)
Stable1e6-8 5.06s ± 1% 4.92s ± 1% -2.77% (p=0.000 n=25+29)
[Geo mean] 731µs 714µs -2.29%
Before/after assembly for sort.(*intPairs).Less follows.
It can be optimized further, but that's for a follow-up CL.
Before:
"".(*intPairs).Less t=1 size=214 args=0x20 locals=0x38
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Less(SB), $56-32
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) CMPQ SP, 16(CX)
0x000d 00013 (<autogenerated>:1) JLS 204
0x0013 00019 (<autogenerated>:1) SUBQ $56, SP
0x0017 00023 (<autogenerated>:1) MOVQ BP, 48(SP)
0x001c 00028 (<autogenerated>:1) LEAQ 48(SP), BP
0x0021 00033 (<autogenerated>:1) MOVQ 32(CX), BX
0x0025 00037 (<autogenerated>:1) TESTQ BX, BX
0x0028 00040 (<autogenerated>:1) JEQ 55
0x002a 00042 (<autogenerated>:1) LEAQ 64(SP), DI
0x002f 00047 (<autogenerated>:1) CMPQ (BX), DI
0x0032 00050 (<autogenerated>:1) JNE 55
0x0034 00052 (<autogenerated>:1) MOVQ SP, (BX)
0x0037 00055 (<autogenerated>:1) NOP
0x0037 00055 (<autogenerated>:1) FUNCDATA $0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
0x0037 00055 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0037 00055 (<autogenerated>:1) MOVQ ""..this+64(FP), AX
0x003c 00060 (<autogenerated>:1) TESTQ AX, AX
0x003f 00063 (<autogenerated>:1) JEQ $0, 135
0x0041 00065 (<autogenerated>:1) MOVQ (AX), CX
0x0044 00068 (<autogenerated>:1) MOVQ 8(AX), AX
0x0048 00072 (<autogenerated>:1) MOVQ "".i+72(FP), DX
0x004d 00077 (<autogenerated>:1) CMPQ DX, AX
0x0050 00080 (<autogenerated>:1) JCC $0, 128
0x0052 00082 (<autogenerated>:1) SHLQ $4, DX
0x0056 00086 (<autogenerated>:1) MOVQ (CX)(DX*1), DX
0x005a 00090 (<autogenerated>:1) MOVQ "".j+80(FP), BX
0x005f 00095 (<autogenerated>:1) CMPQ BX, AX
0x0062 00098 (<autogenerated>:1) JCC $0, 128
0x0064 00100 (<autogenerated>:1) SHLQ $4, BX
0x0068 00104 (<autogenerated>:1) MOVQ (CX)(BX*1), AX
0x006c 00108 (<autogenerated>:1) CMPQ DX, AX
0x006f 00111 (<autogenerated>:1) SETLT AL
0x0072 00114 (<autogenerated>:1) MOVB AL, "".~r2+88(FP)
0x0076 00118 (<autogenerated>:1) MOVQ 48(SP), BP
0x007b 00123 (<autogenerated>:1) ADDQ $56, SP
0x007f 00127 (<autogenerated>:1) RET
0x0080 00128 (<autogenerated>:1) PCDATA $0, $1
0x0080 00128 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x0085 00133 (<autogenerated>:1) UNDEF
0x0087 00135 (<autogenerated>:1) LEAQ go.string."sort_test"(SB), AX
0x008e 00142 (<autogenerated>:1) MOVQ AX, (SP)
0x0092 00146 (<autogenerated>:1) MOVQ $9, 8(SP)
0x009b 00155 (<autogenerated>:1) LEAQ go.string."intPairs"(SB), AX
0x00a2 00162 (<autogenerated>:1) MOVQ AX, 16(SP)
0x00a7 00167 (<autogenerated>:1) MOVQ $8, 24(SP)
0x00b0 00176 (<autogenerated>:1) LEAQ go.string."Less"(SB), AX
0x00b7 00183 (<autogenerated>:1) MOVQ AX, 32(SP)
0x00bc 00188 (<autogenerated>:1) MOVQ $4, 40(SP)
0x00c5 00197 (<autogenerated>:1) PCDATA $0, $1
0x00c5 00197 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x00ca 00202 (<autogenerated>:1) UNDEF
0x00cc 00204 (<autogenerated>:1) NOP
0x00cc 00204 (<autogenerated>:1) PCDATA $0, $-1
0x00cc 00204 (<autogenerated>:1) CALL runtime.morestack_noctxt(SB)
0x00d1 00209 (<autogenerated>:1) JMP 0
After:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
Change-Id: I15bb8435f0690badb868799f313ed8817335efd3
Reviewed-on: https://go-review.googlesource.com/36809
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-10 21:49:07 -08:00
|
|
|
}
|
|
|
|
|
typ := name[:i]
|
|
|
|
|
meth := name[i+2:]
|
2016-03-27 17:29:53 -07:00
|
|
|
panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
|
2011-06-17 15:23:27 -04:00
|
|
|
}
|