1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package main
import (
"fmt"
"unsafe"
)
type tpe struct {
size uintptr
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32
tflag uint8
align uint8
fieldAlign uint8
kind uint8
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
equal func(unsafe.Pointer, unsafe.Pointer) bool
// gcdata stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, gcdata is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
gcdata *byte
str int32
ptrToThis int32
}
type maptype struct {
typ tpe // map类型
key *tpe // key类型
elem *tpe // elem类型
// 桶的类型,桶包含tophashs、keys、elems、overflow这四块
// 由于key/elem是不确定的类型,所以bucket也是不同的类型
// bucket是否包含指针类型,是取决于该结构中是否存在指针
// 1. tophashs 是非指针
// 2. keys、elems 是根据具体情况的
// 3. overflow 是个指针,那么是否意味则bucket是否包含指针类型?
// 其实bucket是否包含指针类型是根据keys、elems决定的
bucket *tpe // internal type representing a hash bucket
// function for hashing keys (ptr to key, seed) -> hash
// hash函数,用于(key, h.hash0)
hasher func(unsafe.Pointer, uintptr) uintptr
keysize uint8 // size of key slot // key值大小
elemsize uint8 // size of elem slot // value值大小
bucketsize uint16 // size of bucket // 桶大小
flags uint32 // map的标志位
}
type e struct {
i *tpe
d uintptr
}
func main() {
m := make(map[string]uint8, 8)
var d any = m
dd1 := **(**maptype)(unsafe.Pointer(&d))
dd := *(**(**maptype)(unsafe.Pointer(&d))).bucket
// 8 + 16*8 + 8 + 8
// 8 + 128 + 8 + 8
// 98 -> 152
fmt.Printf("%#v\n", dd1)
fmt.Printf("%#v\n", dd)
// Output:
// main.maptype{
// typ:main.tpe{
// size:0x8,
// ptrdata:0x8,
// hash:0xfc5c9caf,
// tflag:0x2,
// align:0x8,
// fieldAlign:0x8,
// kind:0x35, // 0x35 = 53 = 32 + 21
// equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(nil),
// gcdata:(*uint8)(0x71b448),
// str:13639,
// ptrToThis:0
// },
// key:(*main.tpe)(0x6e8140),
// elem:(*main.tpe)(0x6e82c0),
// bucket:(*main.tpe)(0x6f1d40),
// hasher:(func(unsafe.Pointer, uintptr) uintptr)(0x6adf40),
// keysize:0x10, // string 大小 16 byte
// elemsize:0x1, // uint8 大小 1 byte
// bucketsize:0x98, // 桶大小 tophash + 8key + 8elem + 1overflow
// flags:0xc
//}
//
// kind:0x35:32.间接存储在接口中; 21.map类型
//main.tpe{
// size:0x98,
// ptrdata:0x98,
// hash:0x9f98cd28,
// tflag:0x2,
// align:0x8,
// fieldAlign:0x8,
// kind:0x19,
// equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(nil),
// gcdata:(*uint8)(0x71b5f8),
// str:17051,
// ptrToThis:0
//}
}
|