Skip to content

Commit 0e26b70

Browse files
committed
runtime: add gc layout info for some basic types
1 parent b8fe75a commit 0e26b70

File tree

5 files changed

+63
-6
lines changed

5 files changed

+63
-6
lines changed

src/reflect/gclayout_none.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build !gc.precise
2+
3+
package reflect
4+
5+
func (r *rawType) gcLayout() unsafe.Pointer {
6+
return nil
7+
}

src/reflect/gclayout_precise.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//go:build gc.precise
2+
3+
package reflect
4+
5+
import "unsafe"
6+
7+
var (
8+
// Constants for use with alloc()
9+
// See runtime/gc_precise.go
10+
// pppppppp_pppppppp_pppppppp_ppsssss1
11+
gcLayoutNoPtrs = unsafe.Pointer(uintptr(0b0000_00001_1))
12+
gcLayoutPointer = unsafe.Pointer(uintptr(0b0001_00001_1))
13+
gcLayoutString = unsafe.Pointer(uintptr(0b0001_00010_1))
14+
gcLayoutSlice = unsafe.Pointer(uintptr(0b0001_00011_1))
15+
)
16+
17+
func (r *rawType) gcLayout() unsafe.Pointer {
18+
19+
if r.Kind() < String {
20+
return gcLayoutNoPtrs
21+
}
22+
23+
if r.Kind() == Pointer || r.Kind() == UnsafePointer {
24+
return gcLayoutPointer
25+
}
26+
27+
if r.Kind() == String {
28+
return gcLayoutString
29+
}
30+
31+
if r.Kind() == Slice {
32+
return gcLayoutSlice
33+
}
34+
35+
// Unknown (for now); less the conservative pointer scanning handle it
36+
return nil
37+
}

src/reflect/value.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,9 @@ func MakeSlice(typ Type, len, cap int) Value {
14931493
var slice sliceHeader
14941494
slice.cap = uintptr(ucap)
14951495
slice.len = uintptr(ulen)
1496-
slice.data = alloc(size, nil)
1496+
layout := rtype.elem.gcLayout()
1497+
1498+
slice.data = alloc(size, layout)
14971499

14981500
return Value{
14991501
typecode: rtype,

src/runtime/slice.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr)
4747
// memory allocators, this causes some difficult to debug issues.
4848
newCap = 1 << bits.Len(uint(newCap))
4949

50-
buf := alloc(newCap*elemSize, nil)
50+
var layout unsafe.Pointer
51+
if elemSize == 1 {
52+
// []byte
53+
layout = gcLayoutNoPtrs
54+
}
55+
56+
buf := alloc(newCap*elemSize, layout)
5157
if oldLen > 0 {
5258
// copy any data to new slice
5359
memmove(buf, oldBuf, oldLen*elemSize)

src/runtime/string.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ func stringEqual(x, y string) bool {
3232
return true
3333
}
3434

35+
var (
36+
// Constants for use with alloc()
37+
gcLayoutNoPtrs = unsafe.Pointer(uintptr(0x3))
38+
)
39+
3540
// Return true iff x < y.
3641
//
3742
//go:nobounds
@@ -59,7 +64,7 @@ func stringConcat(x, y _string) _string {
5964
return x
6065
} else {
6166
length := x.length + y.length
62-
buf := alloc(length, nil)
67+
buf := alloc(length, gcLayoutNoPtrs)
6368
memcpy(buf, unsafe.Pointer(x.ptr), x.length)
6469
memcpy(unsafe.Add(buf, x.length), unsafe.Pointer(y.ptr), y.length)
6570
return _string{ptr: (*byte)(buf), length: length}
@@ -72,7 +77,7 @@ func stringFromBytes(x struct {
7277
len uintptr
7378
cap uintptr
7479
}) _string {
75-
buf := alloc(x.len, nil)
80+
buf := alloc(x.len, gcLayoutNoPtrs)
7681
memcpy(buf, unsafe.Pointer(x.ptr), x.len)
7782
return _string{ptr: (*byte)(buf), length: x.len}
7883
}
@@ -83,7 +88,7 @@ func stringToBytes(x _string) (slice struct {
8388
len uintptr
8489
cap uintptr
8590
}) {
86-
buf := alloc(x.length, nil)
91+
buf := alloc(x.length, gcLayoutNoPtrs)
8792
memcpy(buf, unsafe.Pointer(x.ptr), x.length)
8893
slice.ptr = (*byte)(buf)
8994
slice.len = x.length
@@ -100,7 +105,7 @@ func stringFromRunes(runeSlice []rune) (s _string) {
100105
}
101106

102107
// Allocate memory for the string.
103-
s.ptr = (*byte)(alloc(s.length, nil))
108+
s.ptr = (*byte)(alloc(s.length, gcLayoutNoPtrs))
104109

105110
// Encode runes to UTF-8 and store the resulting bytes in the string.
106111
index := uintptr(0)

0 commit comments

Comments
 (0)