04-go数据类型内存结构-map

4. map

map变量只有8个字节,指向map对象自己。

var var_map map[int64]int64 = map[int64]int64{0x1234:0x1234};
1878 "".var_map SBSS size=8
var var2_map map[int64]int64 = map[int64]int64{0x1234:0x1234};

1、调用运行时runtime.makemap_small()创建一个hmap结构体。

// makehmap_small implements Go map creation for make(map[k]v) and
// make(map[k]v, hint) when hint is known to be at most bucketCnt
// at compile time and the map needs to be allocated on the heap.
func makemap_small() *hmap {
	h := new(hmap)
	h.hash0 = fastrand()
	return h
}

// A header for a Go map.
type hmap struct {
	// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
	// Make sure this stays in sync with the compiler's definition.
	count     int // # live cells == size of map.  Must be first (used by len() builtin)
	flags     uint8
	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	hash0     uint32 // hash seed

	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

	extra *mapextra // optional fields
}

2、mapassign_fast64获取key对应值位置

func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
src\runtime\type.go
type _type struct {
	size       uintptr  //8 字节
	ptrdata    uintptr  //8 字节 size of memory prefix holding all pointers
	hash       uint32   //4 字节
	tflag      tflag    //1 字节
	align      uint8    //1 字节  0x08 8字节对象
	fieldalign uint8    //1 字节  0x08 8字节对象 
	kind       uint8    //1 字节   0x14=20=RUNTIME_TYPE_KIND_INTERFACE
	alg        *typeAlg //8 字节
	// 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     //8
	str       nameOff   //4
	ptrToThis typeOff   //4
}

type maptype struct {  //80字节
	typ        _type    //48字节
	key        *_type   //8字节
	elem       *_type   //8字节
	bucket     *_type // 8字节 internal type representing a hash bucket
	keysize    uint8  // 1字节 size of key slot
	valuesize  uint8  // 1字节 size of value slot
	bucketsize uint16 // 2字节 size of bucket
	flags      uint32 // 4字节
}

map底层类型信息 maptype可以看出有80个字节
type.map[int64]int64 SRODATA dupok size=80

 type..namedata.*map[int64]int64- SRODATA dupok size=19
         0x0000 00 00 10 2a 6d 61 70 5b 69 6e 74 36 34 5d 69 6e  ...*map[int64]in
         0x0010 74 36 34                                         t64
 type.*map[int64]int64 SRODATA dupok size=56
         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
         0x0010 d1 14 ff d7 00 08 08 36 00 00 00 00 00 00 00 00  .......6........
         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
         0x0030 00 00 00 00 00 00 00 00                          ........
         rel 24+8 t=1 runtime.algarray+80
         rel 32+8 t=1 runtime.gcbits.01+0
         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
         rel 48+8 t=1 type.map[int64]int64+0
 type.map[int64]int64 SRODATA dupok size=80
         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
         0x0010 9c 10 d3 02 02 08 08 35 00 00 00 00 00 00 00 00  .......5........
         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
         0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
         0x0040 00 00 00 00 00 00 00 00 08 08 90 00 04 00 00 00  ................
         rel 24+8 t=1 runtime.algarray+0
         rel 32+8 t=1 runtime.gcbits.01+0
         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
         rel 44+4 t=6 type.*map[int64]int64+0
         rel 48+8 t=1 type.int64+0
         rel 56+8 t=1 type.int64+0
         rel 64+8 t=1 type.noalg.map.bucket[int64]int64+0

3、赋值

0x0040 00064 (type.go:41)       CALL    runtime.makemap_small(SB)   //创建hmap对象
0x0045 00069 (type.go:41)       PCDATA  $2, $1
0x0045 00069 (type.go:41)       MOVQ    (SP), AX    //将hmap对象地址赋值给AX
0x0049 00073 (type.go:41)       PCDATA  $2, $0
0x0049 00073 (type.go:41)       PCDATA  $0, $1
0x0049 00073 (type.go:41)       MOVQ    AX, "".var2_map+136(SP) //将hmap对象地址赋值给var2_map
0x0051 00081 (type.go:41)       MOVQ    $4660, ""..autotmp_27+104(SP)   //临时变量赋值为0x1234
0x005a 00090 (type.go:41)       MOVQ    $4660, ""..autotmp_28+96(SP)    //临时变量赋值为0x1234
0x0063 00099 (type.go:41)       PCDATA  $2, $1
0x0063 00099 (type.go:41)       LEAQ    type.map[int64]int64(SB), AX    //将map[int64]int64类型地址赋值给AX
0x006a 00106 (type.go:41)       PCDATA  $2, $0
0x006a 00106 (type.go:41)       MOVQ    AX, (SP)    //将map类型信息压入栈
0x006e 00110 (type.go:41)       PCDATA  $2, $1
0x006e 00110 (type.go:41)       MOVQ    "".var2_map+136(SP), AX 
0x0076 00118 (type.go:41)       PCDATA  $2, $0
0x0076 00118 (type.go:41)       MOVQ    AX, 8(SP)   //将map变量地址压入栈
0x007b 00123 (type.go:41)       MOVQ    ""..autotmp_27+104(SP), AX
0x0080 00128 (type.go:41)       MOVQ    AX, 16(SP)  //将临时变量压入栈
0x0085 00133 (type.go:41)       CALL    runtime.mapassign_fast64(SB) //获取key对应的值地址
0x008a 00138 (type.go:41)       PCDATA  $2, $1
0x008a 00138 (type.go:41)       MOVQ    24(SP), AX
0x008f 00143 (type.go:41)       MOVQ    AX, ""..autotmp_29+184(SP)  //返回值赋值给临时变量
0x0097 00151 (type.go:41)       TESTB   AL, (AX)
0x0099 00153 (type.go:41)       MOVQ    ""..autotmp_28+96(SP), CX   //将0x1234放到寄存器CX
0x009e 00158 (type.go:41)       PCDATA  $2, $0
0x009e 00158 (type.go:41)       MOVQ    CX, (AX)    //将值0x1234赋值给key对应的val指向地址

你可能感兴趣的:(Go,内存结构,map,实现原理,go,数据类型,内存结构,实现原理,map)