From 4c589d93ad6f77e31cccc237c20133f0d8d8492f Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 21 May 2024 23:04:21 -0400 Subject: [PATCH] runtime: revert "move zeroVal to internal/abi" This reverts CL 581395, commit 2f5b420fb5984842afab37a9c2e66e6599107483. It breaks a linkname from github.com/ugorji/go/codec. For #67401. A followup CL will document this dependence. Change-Id: I66d6c39c03e769ab829ca4c3f4f61277b93380d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/587216 TryBot-Bypass: Russ Cox Auto-Submit: Russ Cox Reviewed-by: Cherry Mui --- src/internal/abi/runtime.go | 5 +---- src/reflect/value.go | 11 +++++++---- src/runtime/iface.go | 4 ++-- src/runtime/map.go | 12 ++++++------ src/runtime/map_fast32.go | 8 ++++---- src/runtime/map_fast64.go | 8 ++++---- src/runtime/map_faststr.go | 16 ++++++++-------- src/runtime/runtime.go | 6 ++++++ 8 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/internal/abi/runtime.go b/src/internal/abi/runtime.go index 2a3181a48d..9b91cdf5ef 100644 --- a/src/internal/abi/runtime.go +++ b/src/internal/abi/runtime.go @@ -4,8 +4,5 @@ package abi -// ZeroValSize is the size in bytes of [ZeroVal]. +// ZeroValSize is the size in bytes of runtime.zeroVal. const ZeroValSize = 1024 - -// ZeroVal is a region containing all zero bytes. -var ZeroVal [ZeroValSize]byte diff --git a/src/reflect/value.go b/src/reflect/value.go index c93afb99eb..56d8ba708c 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1591,7 +1591,7 @@ func (v Value) IsZero() bool { // v.ptr doesn't escape, as Equal functions are compiler generated // and never escape. The escape analysis doesn't know, as it is a // function pointer call. - return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&abi.ZeroVal[0])) + return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0])) } if typ.TFlag&abi.TFlagRegularMemory != 0 { // For some types where the zero value is a value where all bits of this type are 0 @@ -1617,7 +1617,7 @@ func (v Value) IsZero() bool { // If the type is comparable, then compare directly with zero. if typ.Equal != nil && typ.Size() <= abi.ZeroValSize { // See noescape justification above. - return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&abi.ZeroVal[0])) + return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0])) } if typ.TFlag&abi.TFlagRegularMemory != 0 { // For some types where the zero value is a value where all bits of this type are 0 @@ -2312,7 +2312,7 @@ func (v Value) Set(x Value) { } x = x.assignTo("reflect.Set", v.typ(), target) if x.flag&flagIndir != 0 { - if x.ptr == unsafe.Pointer(&abi.ZeroVal[0]) { + if x.ptr == unsafe.Pointer(&zeroVal[0]) { typedmemclr(v.typ(), v.ptr) } else { typedmemmove(v.typ(), v.ptr, x.ptr) @@ -3280,7 +3280,7 @@ func Zero(typ Type) Value { if t.IfaceIndir() { var p unsafe.Pointer if t.Size() <= abi.ZeroValSize { - p = unsafe.Pointer(&abi.ZeroVal[0]) + p = unsafe.Pointer(&zeroVal[0]) } else { p = unsafe_New(t) } @@ -3289,6 +3289,9 @@ func Zero(typ Type) Value { return Value{t, nil, fl} } +//go:linkname zeroVal runtime.zeroVal +var zeroVal [abi.ZeroValSize]byte + // New returns a Value representing a pointer to a new zero value // for the specified type. That is, the returned Value's Type is [PointerTo](typ). func New(typ Type) Value { diff --git a/src/runtime/iface.go b/src/runtime/iface.go index f9c4c8e42d..67e7038691 100644 --- a/src/runtime/iface.go +++ b/src/runtime/iface.go @@ -391,7 +391,7 @@ func convT64(val uint64) (x unsafe.Pointer) { func convTstring(val string) (x unsafe.Pointer) { if val == "" { - x = unsafe.Pointer(&abi.ZeroVal[0]) + x = unsafe.Pointer(&zeroVal[0]) } else { x = mallocgc(unsafe.Sizeof(val), stringType, true) *(*string)(x) = val @@ -402,7 +402,7 @@ func convTstring(val string) (x unsafe.Pointer) { func convTslice(val []byte) (x unsafe.Pointer) { // Note: this must work for any element type, not just byte. if (*slice)(unsafe.Pointer(&val)).array == nil { - x = unsafe.Pointer(&abi.ZeroVal[0]) + x = unsafe.Pointer(&zeroVal[0]) } else { x = mallocgc(unsafe.Sizeof(val), sliceType, true) *(*[]byte)(x) = val diff --git a/src/runtime/map.go b/src/runtime/map.go index ebfe3b6707..7be27fd569 100644 --- a/src/runtime/map.go +++ b/src/runtime/map.go @@ -402,7 +402,7 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { if err := mapKeyError(t, key); err != nil { panic(err) // see issue 23734 } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -443,7 +443,7 @@ bucketloop: } } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) { @@ -463,7 +463,7 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) if err := mapKeyError(t, key); err != nil { panic(err) // see issue 23734 } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -504,7 +504,7 @@ bucketloop: } } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } // returns both key and elem. Used by map iterator. @@ -553,7 +553,7 @@ bucketloop: func mapaccess1_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) unsafe.Pointer { e := mapaccess1(t, h, key) - if e == unsafe.Pointer(&abi.ZeroVal[0]) { + if e == unsafe.Pointer(&zeroVal[0]) { return zero } return e @@ -561,7 +561,7 @@ func mapaccess1_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) unsafe.Pointe func mapaccess2_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) (unsafe.Pointer, bool) { e := mapaccess1(t, h, key) - if e == unsafe.Pointer(&abi.ZeroVal[0]) { + if e == unsafe.Pointer(&zeroVal[0]) { return zero, false } return e, true diff --git a/src/runtime/map_fast32.go b/src/runtime/map_fast32.go index 06dcbcabc4..7e52240e77 100644 --- a/src/runtime/map_fast32.go +++ b/src/runtime/map_fast32.go @@ -16,7 +16,7 @@ func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast32)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -47,7 +47,7 @@ func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer { } } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) { @@ -56,7 +56,7 @@ func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast32)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -87,7 +87,7 @@ func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) { } } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } func mapassign_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer { diff --git a/src/runtime/map_fast64.go b/src/runtime/map_fast64.go index c8b34dd41b..2c365183cb 100644 --- a/src/runtime/map_fast64.go +++ b/src/runtime/map_fast64.go @@ -16,7 +16,7 @@ func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast64)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -47,7 +47,7 @@ func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer { } } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) { @@ -56,7 +56,7 @@ func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast64)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -87,7 +87,7 @@ func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) { } } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer { diff --git a/src/runtime/map_faststr.go b/src/runtime/map_faststr.go index 38841aee4b..d989190f71 100644 --- a/src/runtime/map_faststr.go +++ b/src/runtime/map_faststr.go @@ -16,7 +16,7 @@ func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_faststr)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -39,7 +39,7 @@ func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer { return add(unsafe.Pointer(b), dataOffset+abi.MapBucketCount*2*goarch.PtrSize+i*uintptr(t.ValueSize)) } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } // long key, try not to do more comparisons than necessary keymaybe := uintptr(abi.MapBucketCount) @@ -74,7 +74,7 @@ func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer { return add(unsafe.Pointer(b), dataOffset+abi.MapBucketCount*2*goarch.PtrSize+keymaybe*uintptr(t.ValueSize)) } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } dohash: hash := t.Hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0)) @@ -102,7 +102,7 @@ dohash: } } } - return unsafe.Pointer(&abi.ZeroVal[0]) + return unsafe.Pointer(&zeroVal[0]) } func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) { @@ -111,7 +111,7 @@ func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) { racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_faststr)) } if h == nil || h.count == 0 { - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } if h.flags&hashWriting != 0 { fatal("concurrent map read and map write") @@ -134,7 +134,7 @@ func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) { return add(unsafe.Pointer(b), dataOffset+abi.MapBucketCount*2*goarch.PtrSize+i*uintptr(t.ValueSize)), true } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } // long key, try not to do more comparisons than necessary keymaybe := uintptr(abi.MapBucketCount) @@ -169,7 +169,7 @@ func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) { return add(unsafe.Pointer(b), dataOffset+abi.MapBucketCount*2*goarch.PtrSize+keymaybe*uintptr(t.ValueSize)), true } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } dohash: hash := t.Hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0)) @@ -197,7 +197,7 @@ dohash: } } } - return unsafe.Pointer(&abi.ZeroVal[0]), false + return unsafe.Pointer(&zeroVal[0]), false } func mapassign_faststr(t *maptype, h *hmap, s string) unsafe.Pointer { diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index f854fd5e41..6cf903d2c1 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -5,6 +5,7 @@ package runtime import ( + "internal/abi" "internal/runtime/atomic" "unsafe" ) @@ -301,3 +302,8 @@ var auxv []uintptr // //go:linkname getAuxv func getAuxv() []uintptr { return auxv } + +// zeroVal is used by reflect via linkname. +// +//go:linkname zeroVal +var zeroVal [abi.ZeroValSize]byte -- 2.48.1