// addb returns the byte pointer p+n.
//go:nowritebarrier
func addb(p *byte, n uintptr) *byte {
- return (*byte)(add(unsafe.Pointer(p), n))
+ // Note: wrote out full expression instead of calling add(p, n)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + n))
}
// subtractb returns the byte pointer p-n.
//go:nowritebarrier
func subtractb(p *byte, n uintptr) *byte {
- return (*byte)(add(unsafe.Pointer(p), -n))
+ // Note: wrote out full expression instead of calling add(p, -n)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - n))
+}
+
+// add1 returns the byte pointer p+1.
+//go:nowritebarrier
+func add1(p *byte) *byte {
+ // Note: wrote out full expression instead of calling addb(p, 1)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + 1))
+}
+
+// subtract1 returns the byte pointer p-1.
+//go:nowritebarrier
+func subtract1(p *byte) *byte {
+ // Note: wrote out full expression instead of calling subtractb(p, 1)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - 1))
}
// mHeap_MapBits is called each time arena_used is extended.
if h.shift < 3*heapBitsShift {
return heapBits{h.bitp, h.shift + heapBitsShift}
}
- return heapBits{subtractb(h.bitp, 1), 0}
+ return heapBits{subtract1(h.bitp), 0}
}
// forward returns the heapBits describing n pointer-sized words ahead of h in memory.
if h.shift == 0 {
return b&(bitMarked<<(2*heapBitsShift)) != 0
}
- return uint32(*subtractb(h.bitp, 1))&bitMarked != 0
+ return uint32(*subtract1(h.bitp))&bitMarked != 0
}
// isCheckmarked reports whether the heap bits have the checkmarked bit set.
bitp := h.bitp
for i := uintptr(0); i < n; i += 4 {
*bitp &^= bitPointerAll
- bitp = subtractb(bitp, 1)
+ bitp = subtract1(bitp)
}
return
}
bitp := h.bitp
for i := uintptr(0); i < n; i += 4 {
*bitp |= bitPointerAll
- bitp = subtractb(bitp, 1)
+ bitp = subtract1(bitp)
}
}
}
f(base + (i+3)*ptrSize)
}
*bitp = uint8(x)
- bitp = subtractb(bitp, 1)
+ bitp = subtract1(bitp)
}
case size%(4*ptrSize) == 0:
x &^= (bitMarked|bitPointer)<<(2*heapBitsShift) | (bitMarked|bitPointer)<<(3*heapBitsShift)
f(base + (i+1)*size)
if size > 2*ptrSize {
- *subtractb(bitp, 1) = 0
+ *subtract1(bitp) = 0
}
}
*bitp = uint8(x)
unrollgcprog_m(typ)
})
}
- ptrmask = addb(ptrmask, 1) // skip the unroll flag byte
+ ptrmask = add1(ptrmask) // skip the unroll flag byte
}
// Heap bitmap bits for 2-word object are only 4 bits,
nb = typ.ptrdata / ptrSize
for i := uintptr(0); i < nb; i += 8 {
b |= uintptr(*p) << i
- p = addb(p, 1)
+ p = add1(p)
}
nb = typ.size / ptrSize
}
if p != nil {
b = uintptr(*p)
- p = addb(p, 1)
+ p = add1(p)
nb = 8
}
goto Phase3
}
*hbitp = uint8(hb)
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
b >>= 4
nb -= 4
} else {
atomicor8(hbitp, uint8(hb))
}
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
if w += 2; w >= nw {
// We know that there is more data, because we handled 2-word objects above.
// This must be at least a 6-word object. If we're out of pointer words,
break
}
*hbitp = uint8(hb)
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
b >>= 4
// Load more bits. b has nb right now.
// and the next iteration will consume 8 bits,
// leaving us with the same nb the next time we're here.
b |= uintptr(*p) << nb
- p = addb(p, 1)
+ p = add1(p)
} else if p == nil {
// Almost as fast path: track bit count and refill from pbits.
// For short repetitions.
nb += endnb
if nb < 8 {
b |= uintptr(*ptrmask) << nb
- p = addb(ptrmask, 1)
+ p = add1(ptrmask)
} else {
nb -= 8
p = ptrmask
break
}
*hbitp = uint8(hb)
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
b >>= 4
}
// The first is hb, the rest are zero.
if w <= nw {
*hbitp = uint8(hb)
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
hb = 0 // for possible final half-byte below
for w += 4; w <= nw; w += 4 {
*hbitp = 0
- hbitp = subtractb(hbitp, 1)
+ hbitp = subtract1(hbitp)
}
}
throw("unrollgcprog: unknown instruction")
case insData:
- prog = addb(prog, 1)
+ prog = add1(prog)
siz := int(*prog)
- prog = addb(prog, 1)
+ prog = add1(prog)
p := (*[1 << 30]byte)(unsafe.Pointer(prog))
for i := 0; i < siz; i++ {
v := p[i/8] >> (uint(i) % 8) & 1