Skip to content

Commit 3009566

Browse files
committed
runtime: fix tag pointers on aix
Clean up tagged pointers a bit. I got the shifts wrong for the weird aix case. Change-Id: I21449fd5973f4651fd1103d3b8be9c2b9b93a490 Reviewed-on: https://go-review.googlesource.com/c/go/+/667715 Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Keith Randall <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 8a8f506 commit 3009566

File tree

3 files changed

+16
-36
lines changed

3 files changed

+16
-36
lines changed

src/runtime/malloc.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,8 @@ func mallocinit() {
455455
throw("max pointer/scan bitmap size for headerless objects is too large")
456456
}
457457

458-
if minTagBits > taggedPointerBits {
459-
throw("taggedPointerBits too small")
458+
if minTagBits > tagBits {
459+
throw("tagBits too small")
460460
}
461461

462462
// Initialize the heap.

src/runtime/netpoll.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ func (c *pollCache) free(pd *pollDesc) {
302302
// Increment the fdseq field, so that any currently
303303
// running netpoll calls will not mark pd as ready.
304304
fdseq := pd.fdseq.Load()
305-
fdseq = (fdseq + 1) & (1<<taggedPointerBits - 1)
305+
fdseq = (fdseq + 1) & (1<<tagBits - 1)
306306
pd.fdseq.Store(fdseq)
307307

308308
pd.publishInfo()

src/runtime/tagptr_64bit.go

+13-33
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,41 @@ const (
1717
//
1818
// See heapAddrBits for a table of address space sizes on
1919
// various architectures. 48 bits is enough for all
20-
// architectures except s390x.
20+
// arch/os combos except s390x, aix, and riscv64.
2121
//
22-
// On AMD64, virtual addresses are 48-bit (or 57-bit) numbers sign extended to 64.
23-
// We shift the address left 16 to eliminate the sign extended part and make
24-
// room in the bottom for the count.
22+
// On AMD64, virtual addresses are 48-bit (or 57-bit) sign-extended.
23+
// Other archs are 48-bit zero-extended.
2524
//
2625
// On s390x, virtual addresses are 64-bit. There's not much we
2726
// can do about this, so we just hope that the kernel doesn't
2827
// get to really high addresses and panic if it does.
29-
addrBits = 48
30-
31-
// In addition to the 16 bits taken from the top, we can take 9 from the
32-
// bottom, because we require pointers to be well-aligned (see tagptr.go:tagAlignBits).
33-
// That gives us a total of 25 bits for the tag.
34-
tagBits = 64 - addrBits + tagAlignBits
28+
defaultAddrBits = 48
3529

3630
// On AIX, 64-bit addresses are split into 36-bit segment number and 28-bit
3731
// offset in segment. Segment numbers in the range 0x0A0000000-0x0AFFFFFFF(LSA)
3832
// are available for mmap.
3933
// We assume all tagged addresses are from memory allocated with mmap.
4034
// We use one bit to distinguish between the two ranges.
4135
aixAddrBits = 57
42-
aixTagBits = 64 - aixAddrBits + tagAlignBits
4336

4437
// riscv64 SV57 mode gives 56 bits of userspace VA.
4538
// tagged pointer code supports it,
4639
// but broader support for SV57 mode is incomplete,
4740
// and there may be other issues (see #54104).
4841
riscv64AddrBits = 56
49-
riscv64TagBits = 64 - riscv64AddrBits + tagAlignBits
50-
)
5142

52-
// The number of bits stored in the numeric tag of a taggedPointer
53-
const taggedPointerBits = (goos.IsAix * aixTagBits) + (goarch.IsRiscv64 * riscv64TagBits) + ((1 - goos.IsAix) * (1 - goarch.IsRiscv64) * tagBits)
43+
addrBits = goos.IsAix*aixAddrBits + goarch.IsRiscv64*riscv64AddrBits + (1-goos.IsAix)*(1-goarch.IsRiscv64)*defaultAddrBits
44+
45+
// In addition to the 16 bits (or other, depending on arch/os) taken from the top,
46+
// we can take 9 from the bottom, because we require pointers to be well-aligned
47+
// (see tagptr.go:tagAlignBits). That gives us a total of 25 bits for the tag.
48+
tagBits = 64 - addrBits + tagAlignBits
49+
)
5450

5551
// taggedPointerPack created a taggedPointer from a pointer and a tag.
5652
// Tag bits that don't fit in the result are discarded.
5753
func taggedPointerPack(ptr unsafe.Pointer, tag uintptr) taggedPointer {
58-
var t taggedPointer
59-
if GOOS == "aix" {
60-
if GOARCH != "ppc64" {
61-
throw("check this code for aix on non-ppc64")
62-
}
63-
t = taggedPointer(uint64(uintptr(ptr))<<(64-aixAddrBits) | uint64(tag&(1<<aixTagBits-1)))
64-
} else if GOARCH == "riscv64" {
65-
t = taggedPointer(uint64(uintptr(ptr))<<(64-riscv64AddrBits) | uint64(tag&(1<<riscv64TagBits-1)))
66-
} else {
67-
t = taggedPointer(uint64(uintptr(ptr))<<(64-addrBits) | uint64(tag&(1<<tagBits-1)))
68-
}
54+
t := taggedPointer(uint64(uintptr(ptr))<<(tagBits-tagAlignBits) | uint64(tag&(1<<tagBits-1)))
6955
if t.pointer() != ptr || t.tag() != tag {
7056
print("runtime: taggedPointerPack invalid packing: ptr=", ptr, " tag=", hex(tag), " packed=", hex(t), " -> ptr=", t.pointer(), " tag=", hex(t.tag()), "\n")
7157
throw("taggedPointerPack")
@@ -80,16 +66,10 @@ func (tp taggedPointer) pointer() unsafe.Pointer {
8066
// val before unpacking.
8167
return unsafe.Pointer(uintptr(int64(tp) >> tagBits << tagAlignBits))
8268
}
83-
if GOOS == "aix" {
84-
return unsafe.Pointer(uintptr((tp >> aixTagBits << tagAlignBits) | 0xa<<56))
85-
}
86-
if GOARCH == "riscv64" {
87-
return unsafe.Pointer(uintptr(tp >> riscv64TagBits << tagAlignBits))
88-
}
8969
return unsafe.Pointer(uintptr(tp >> tagBits << tagAlignBits))
9070
}
9171

9272
// Tag returns the tag from a taggedPointer.
9373
func (tp taggedPointer) tag() uintptr {
94-
return uintptr(tp & (1<<taggedPointerBits - 1))
74+
return uintptr(tp & (1<<tagBits - 1))
9575
}

0 commit comments

Comments
 (0)