X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fruntime%2Fmbitmap_allocheaders.go;h=77f5b4c990378b5ab7593c9846ca4be3192c3384;hb=f7c5cbb82087c55aa82081e931e0142783700ce8;hp=9370d50b727058c0cb6eff9ccf0ac3d6c5472c41;hpb=1fc45e9a2b7f457451106d5bf7a40d86257d639e;p=gostls13.git 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