diff --git a/src/cmd/compile/internal/test/inl_test.go b/src/cmd/compile/internal/test/inl_test.go index 5705c356e2..ea7f317ef5 100644 --- a/src/cmd/compile/internal/test/inl_test.go +++ b/src/cmd/compile/internal/test/inl_test.go @@ -88,7 +88,7 @@ func TestIntendedInlining(t *testing.T) { "(*mspan).base", "(*mspan).markBitsForBase", "(*mspan).markBitsForIndex", - "(*mspan).writeHeapBits", + "(*mspan).writeUserArenaHeapBits", "(*muintptr).set", "(*puintptr).set", "(*wbBuf).get1", diff --git a/src/runtime/mbitmap_allocheaders.go b/src/runtime/mbitmap_allocheaders.go index 9370d50b72..77f5b4c990 100644 --- a/src/runtime/mbitmap_allocheaders.go +++ b/src/runtime/mbitmap_allocheaders.go @@ -481,14 +481,26 @@ func (s *mspan) initHeapBits(forceClear bool) { } } -type writeHeapBits struct { +// bswapIfBigEndian swaps the byte order of the uintptr on goarch.BigEndian platforms, +// and leaves it alone elsewhere. +func bswapIfBigEndian(x uintptr) uintptr { + if goarch.BigEndian { + if goarch.PtrSize == 8 { + return uintptr(sys.Bswap64(uint64(x))) + } + return uintptr(sys.Bswap32(uint32(x))) + } + return x +} + +type writeUserArenaHeapBits struct { offset uintptr // offset in span that the low bit of mask represents the pointer state of. mask uintptr // some pointer bits starting at the address addr. valid uintptr // number of bits in buf that are valid (including low) low uintptr // number of low-order bits to not overwrite } -func (s *mspan) writeHeapBits(addr uintptr) (h writeHeapBits) { +func (s *mspan) writeUserArenaHeapBits(addr uintptr) (h writeUserArenaHeapBits) { offset := addr - s.base() // We start writing bits maybe in the middle of a heap bitmap word. @@ -508,7 +520,7 @@ func (s *mspan) writeHeapBits(addr uintptr) (h writeHeapBits) { // write appends the pointerness of the next valid pointer slots // using the low valid bits of bits. 1=pointer, 0=scalar. -func (h writeHeapBits) write(s *mspan, bits, valid uintptr) writeHeapBits { +func (h writeUserArenaHeapBits) write(s *mspan, bits, valid uintptr) writeUserArenaHeapBits { if h.valid+valid <= ptrBits { // Fast path - just accumulate the bits. h.mask |= bits << h.valid @@ -526,7 +538,7 @@ func (h writeHeapBits) write(s *mspan, bits, valid uintptr) writeHeapBits { idx := h.offset / (ptrBits * goarch.PtrSize) m := uintptr(1)< ptrBits { k = ptrBits } + // N.B. On big endian platforms we byte swap the data that we + // read from GCData, which is always stored in little-endian order + // by the compiler. writeUserArenaHeapBits handles data in + // a platform-ordered way for efficiency, but stores back the + // data in little endian order, since we expose the bitmap through + // a dummy type. h = h.write(s, readUintptr(addb(p, i/8)), k) } // Note: we call pad here to ensure we emit explicit 0 bits diff --git a/src/runtime/mbitmap_noallocheaders.go b/src/runtime/mbitmap_noallocheaders.go index 6097500fac..96c70a0970 100644 --- a/src/runtime/mbitmap_noallocheaders.go +++ b/src/runtime/mbitmap_noallocheaders.go @@ -916,7 +916,7 @@ func (tp typePointers) fastForward(n, limit uintptr) typePointers { } // For goexperiment.AllocHeaders, to pass TestIntendedInlining. -func (s *mspan) writeHeapBits() { +func (s *mspan) writeUserArenaHeapBits() { panic("not implemented") }