@@ -99,7 +99,7 @@ func (v Value) typ() *abi.Type {
99
99
// types, held in the central map). So there is no need to
100
100
// escape types. noescape here help avoid unnecessary escape
101
101
// of v.
102
- return (* abi .Type )(noescape (unsafe .Pointer (v .typ_ )))
102
+ return (* abi .Type )(abi . NoEscape (unsafe .Pointer (v .typ_ )))
103
103
}
104
104
105
105
// pointer returns the underlying pointer represented by v.
@@ -119,7 +119,7 @@ func (v Value) pointer() unsafe.Pointer {
119
119
func packEface (v Value ) any {
120
120
t := v .typ ()
121
121
var i any
122
- e := (* emptyInterface )(unsafe .Pointer (& i ))
122
+ e := (* abi . EmptyInterface )(unsafe .Pointer (& i ))
123
123
// First, fill in the data portion of the interface.
124
124
switch {
125
125
case t .IfaceIndir ():
@@ -133,36 +133,36 @@ func packEface(v Value) any {
133
133
typedmemmove (t , c , ptr )
134
134
ptr = c
135
135
}
136
- e .word = ptr
136
+ e .Data = ptr
137
137
case v .flag & flagIndir != 0 :
138
138
// Value is indirect, but interface is direct. We need
139
139
// to load the data at v.ptr into the interface data word.
140
- e .word = * (* unsafe .Pointer )(v .ptr )
140
+ e .Data = * (* unsafe .Pointer )(v .ptr )
141
141
default :
142
142
// Value is direct, and so is the interface.
143
- e .word = v .ptr
143
+ e .Data = v .ptr
144
144
}
145
145
// Now, fill in the type portion. We're very careful here not
146
146
// to have any operation between the e.word and e.typ assignments
147
147
// that would let the garbage collector observe the partially-built
148
148
// interface value.
149
- e .typ = t
149
+ e .Type = t
150
150
return i
151
151
}
152
152
153
153
// unpackEface converts the empty interface i to a Value.
154
154
func unpackEface (i any ) Value {
155
- e := (* emptyInterface )(unsafe .Pointer (& i ))
155
+ e := (* abi . EmptyInterface )(unsafe .Pointer (& i ))
156
156
// NOTE: don't read e.word until we know whether it is really a pointer or not.
157
- t := e .typ
157
+ t := e .Type
158
158
if t == nil {
159
159
return Value {}
160
160
}
161
161
f := flag (t .Kind ())
162
162
if t .IfaceIndir () {
163
163
f |= flagIndir
164
164
}
165
- return Value {t , e .word , f }
165
+ return Value {t , e .Data , f }
166
166
}
167
167
168
168
// A ValueError occurs when a Value method is invoked on
@@ -200,12 +200,6 @@ func valueMethodName() string {
200
200
return "unknown method"
201
201
}
202
202
203
- // emptyInterface is the header for an interface{} value.
204
- type emptyInterface struct {
205
- typ * abi.Type
206
- word unsafe.Pointer
207
- }
208
-
209
203
// nonEmptyInterface is the header for an interface value with methods.
210
204
type nonEmptyInterface struct {
211
205
itab * abi.ITab
@@ -1597,7 +1591,7 @@ func (v Value) IsZero() bool {
1597
1591
// v.ptr doesn't escape, as Equal functions are compiler generated
1598
1592
// and never escape. The escape analysis doesn't know, as it is a
1599
1593
// function pointer call.
1600
- return typ .Equal (noescape (v .ptr ), unsafe .Pointer (& zeroVal [0 ]))
1594
+ return typ .Equal (abi . NoEscape (v .ptr ), unsafe .Pointer (& zeroVal [0 ]))
1601
1595
}
1602
1596
if typ .TFlag & abi .TFlagRegularMemory != 0 {
1603
1597
// For some types where the zero value is a value where all bits of this type are 0
@@ -1623,7 +1617,7 @@ func (v Value) IsZero() bool {
1623
1617
// If the type is comparable, then compare directly with zero.
1624
1618
if typ .Equal != nil && typ .Size () <= abi .ZeroValSize {
1625
1619
// See noescape justification above.
1626
- return typ .Equal (noescape (v .ptr ), unsafe .Pointer (& zeroVal [0 ]))
1620
+ return typ .Equal (abi . NoEscape (v .ptr ), unsafe .Pointer (& zeroVal [0 ]))
1627
1621
}
1628
1622
if typ .TFlag & abi .TFlagRegularMemory != 0 {
1629
1623
// For some types where the zero value is a value where all bits of this type are 0
@@ -1736,7 +1730,7 @@ func (v Value) SetZero() {
1736
1730
case Slice :
1737
1731
* (* unsafeheader .Slice )(v .ptr ) = unsafeheader.Slice {}
1738
1732
case Interface :
1739
- * (* emptyInterface )(v .ptr ) = emptyInterface {}
1733
+ * (* abi . EmptyInterface )(v .ptr ) = abi. EmptyInterface {}
1740
1734
case Chan , Func , Map , Pointer , UnsafePointer :
1741
1735
* (* unsafe .Pointer )(v .ptr ) = nil
1742
1736
case Array , Struct :
@@ -4015,8 +4009,12 @@ func contentEscapes(x unsafe.Pointer) {
4015
4009
}
4016
4010
}
4017
4011
4012
+ // This is just a wrapper around abi.NoEscape. The inlining heuristics are
4013
+ // finnicky and for whatever reason treat the local call to noescape as much
4014
+ // lower cost with respect to the inliner budget. (That is, replacing calls to
4015
+ // noescape with abi.NoEscape will cause inlining tests to fail.)
4016
+ //
4018
4017
//go:nosplit
4019
4018
func noescape (p unsafe.Pointer ) unsafe.Pointer {
4020
- x := uintptr (p )
4021
- return unsafe .Pointer (x ^ 0 )
4019
+ return abi .NoEscape (p )
4022
4020
}
0 commit comments