...
Run Format

Source file test/fixedbugs/issue18902b.go

Documentation: test/fixedbugs

  // skip
  
  // Copyright 2016 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 foo
  
  import (
  	"unsafe"
  )
  
  type gcMaxTreeNodeVal uint64
  
  var work struct {
  	full         uint64    // lock-free list of full blocks workbuf
  	empty        uint64    // lock-free list of empty blocks workbuf
  	pad0         [64]uint8 // prevents false-sharing between full/empty and nproc/nwait
  	bytesMarked  uint64
  	markrootNext uint32 // next markroot job
  	markrootJobs uint32 // number of markroot jobs
  	nproc        uint32
  	tstart       int64
  	nwait        uint32
  	ndone        uint32
  }
  
  type gcShardQueue1 struct {
  	partial *workbuf
  	full    *workbuf
  	n       uintptr
  	maxTree gcMaxTreeNodeVal
  }
  type gcShardQueue struct {
  	gcShardQueue1
  	pad [64 - unsafe.Sizeof(gcShardQueue1{})]byte
  }
  
  const gcSortBufPointers = (64 << 10) / 8
  
  type gcSortBuf struct {
  	buf *gcSortArray
  	tmp *gcSortArray
  	n   uintptr
  }
  
  //go:notinheap
  type gcSortArray [gcSortBufPointers]uintptr
  
  const (
  	_DebugGC             = 0
  	_ConcurrentSweep     = true
  	_FinBlockSize        = 4 * 1024
  	sweepMinHeapDistance = 1024 * 1024
  	gcShardShift         = 2 + 20
  	gcShardBytes         = 1 << gcShardShift
  )
  
  //go:notinheap
  type mheap struct {
  	shardQueues       []gcShardQueue
  	_                 uint32     // align uint64 fields on 32-bit for atomics
  	pagesInUse        uint64     // pages of spans in stats _MSpanInUse; R/W with mheap.lock
  	spanBytesAlloc    uint64     // bytes of spans allocated this cycle; updated atomically
  	pagesSwept        uint64     // pages swept this cycle; updated atomically
  	sweepPagesPerByte float64    // proportional sweep ratio; written with lock, read without
  	largefree         uint64     // bytes freed for large objects (>maxsmallsize)
  	nlargefree        uint64     // number of frees for large objects (>maxsmallsize)
  	nsmallfree        [67]uint64 // number of frees for small objects (<=maxsmallsize)
  	bitmap            uintptr    // Points to one byte past the end of the bitmap
  	bitmap_mapped     uintptr
  	arena_start       uintptr
  	arena_used        uintptr // always mHeap_Map{Bits,Spans} before updating
  	arena_end         uintptr
  	arena_reserved    bool
  }
  
  var mheap_ mheap
  
  type lfnode struct {
  	next    uint64
  	pushcnt uintptr
  }
  type workbufhdr struct {
  	node lfnode // must be first
  	next *workbuf
  	nobj int
  }
  
  //go:notinheap
  type workbuf struct {
  	workbufhdr
  	obj [(2048 - unsafe.Sizeof(workbufhdr{})) / 8]uintptr
  }
  
  //go:noinline
  func (b *workbuf) checkempty() {
  	if b.nobj != 0 {
  		b.nobj = 0
  	}
  }
  func putempty(b *workbuf) {
  	b.checkempty()
  	lfstackpush(&work.empty, &b.node)
  }
  
  //go:noinline
  func lfstackpush(head *uint64, node *lfnode) {
  }
  
  //go:noinline
  func (q *gcShardQueue) add(qidx uintptr, ptrs []uintptr, spare *workbuf) *workbuf {
  	return spare
  }
  
  func (b *gcSortBuf) flush() {
  	if b.n == 0 {
  		return
  	}
  	const sortDigitBits = 11
  	buf, tmp := b.buf[:b.n], b.tmp[:b.n]
  	moreBits := true
  	for shift := uint(gcShardShift); moreBits; shift += sortDigitBits {
  		const k = 1 << sortDigitBits
  		var pos [k]uint16
  		nshift := shift + sortDigitBits
  		nbits := buf[0] >> nshift
  		moreBits = false
  		for _, v := range buf {
  			pos[(v>>shift)%k]++
  			moreBits = moreBits || v>>nshift != nbits
  		}
  		var sum uint16
  		for i, count := range &pos {
  			pos[i] = sum
  			sum += count
  		}
  		for _, v := range buf {
  			digit := (v >> shift) % k
  			tmp[pos[digit]] = v
  			pos[digit]++
  		}
  		buf, tmp = tmp, buf
  	}
  	start := mheap_.arena_start
  	i0 := 0
  	shard0 := (buf[0] - start) / gcShardBytes
  	var spare *workbuf
  	for i, p := range buf {
  		shard := (p - start) / gcShardBytes
  		if shard != shard0 {
  			spare = mheap_.shardQueues[shard0].add(shard0, buf[i0:i], spare)
  			i0, shard0 = i, shard
  		}
  	}
  	spare = mheap_.shardQueues[shard0].add(shard0, buf[i0:], spare)
  	b.n = 0
  	if spare != nil {
  		putempty(spare)
  	}
  }
  

View as plain text