Source File
presence.go
Belonging Package
google.golang.org/protobuf/internal/impl
// Copyright 2024 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 implimport ()// presenceSize represents the size of a presence set, which should be the largest index of the set+1type presenceSize uint32// presence is the internal representation of the bitmap array in a generated protobuftype presence struct {// This is a pointer to the beginning of an array of uint32P unsafe.Pointer}func ( presence) ( uint32) ( *uint32) {const (= 8= unsafe.Sizeof(*))// p.P points to an array of uint32, num is the bit in this array that the// caller wants to check/manipulate. Calculate the index in the array that// contains this specific bit. E.g.: 76 / 32 = 2 (integer division).:= uintptr() / ( * ) *return (*uint32)(unsafe.Pointer(uintptr(.P) + ))}// Present checks for the presence of a specific field number in a presence set.func ( presence) ( uint32) bool {return Export{}.Present(.toElem(), )}// SetPresent adds presence for a specific field number in a presence set.func ( presence) ( uint32, presenceSize) {Export{}.SetPresent(.toElem(), , uint32())}// SetPresentUnatomic adds presence for a specific field number in a presence set without using// atomic operations. Only to be called during unmarshaling.func ( presence) ( uint32, presenceSize) {Export{}.SetPresentNonAtomic(.toElem(), , uint32())}// ClearPresent removes presence for a specific field number in a presence set.func ( presence) ( uint32) {Export{}.ClearPresent(.toElem(), )}// LoadPresenceCache (together with PresentInCache) allows for a// cached version of checking for presence without re-reading the word// for every field. It is optimized for efficiency and assumes no// simltaneous mutation of the presence set (or at least does not have// a problem with simultaneous mutation giving inconsistent results).func ( presence) () ( uint32) {if .P == nil {return 0}return atomic.LoadUint32((*uint32)(.P))}// PresentInCache reads presence from a cached word in the presence// bitmap. It caches up a new word if the bit is outside the// word. This is for really fast iteration through bitmaps in cases// where we either know that the bitmap will not be altered, or we// don't care about inconsistencies caused by simultaneous writes.func ( presence) ( uint32, *uint32, *uint32) bool {if /32 != * {:= uintptr(/32) * unsafe.Sizeof(uint32(0)):= (*uint32)(unsafe.Pointer(uintptr(.P) + ))* = atomic.LoadUint32()* = / 32}return (* & (1 << ( % 32))) > 0}// AnyPresent checks if any field is marked as present in the bitmap.func ( presence) ( presenceSize) bool {:= uintptr(( + 31) / 32)for := uintptr(0); < ; ++ {:= * unsafe.Sizeof(uint32(0)):= (*uint32)(unsafe.Pointer(uintptr(.P) + )):= atomic.LoadUint32()if > 0 {return true}}return false}// toRaceDetectData finds the preceding RaceDetectHookData in a// message by using pointer arithmetic. As the type of the presence// set (bitmap) varies with the number of fields in the protobuf, we// can not have a struct type containing the array and the// RaceDetectHookData. instead the RaceDetectHookData is placed// immediately before the bitmap array, and we find it by walking// backwards in the struct.//// This method is only called from the race-detect version of the code,// so RaceDetectHookData is never an empty struct.func ( presence) () *RaceDetectHookData {var struct {RaceDetectHookData[1]uint32}:= (uintptr(unsafe.Pointer(&.)) - uintptr(unsafe.Pointer(&.)))return (*RaceDetectHookData)(unsafe.Pointer(uintptr(.P) - ))}func ( **[]byte) *[]byte {return (*[]byte)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer())))}func ( **[]byte, *[]byte) {atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer()), nil, unsafe.Pointer())}// findPointerToRaceDetectData finds the preceding RaceDetectHookData// in a message by using pointer arithmetic. For the methods called// directy from generated code, we don't have a pointer to the// beginning of the presence set, but a pointer inside the array. As// we know the index of the bit we're manipulating (num), we can// calculate which element of the array ptr is pointing to. With that// information we find the preceding RaceDetectHookData and can// manipulate the shadow bitmap.//// This method is only called from the race-detect version of the// code, so RaceDetectHookData is never an empty struct.func ( *uint32, uint32) *RaceDetectHookData {var struct {RaceDetectHookData[1]uint32}:= (uintptr(unsafe.Pointer(&.)) - uintptr(unsafe.Pointer(&.))) + uintptr(/32)*unsafe.Sizeof(uint32(0))return (*RaceDetectHookData)(unsafe.Pointer(uintptr(unsafe.Pointer()) - ))}
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64)