3-数据类型内存结构-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

   2247 type..namedata.*map[int64]int64- SRODATA dupok size=19
   2248         0x0000 00 00 10 2a 6d 61 70 5b 69 6e 74 36 34 5d 69 6e  ...*map[int64]in
   2249         0x0010 74 36 34                                         t64
   2250 type.*map[int64]int64 SRODATA dupok size=56
   2251         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
   2252         0x0010 d1 14 ff d7 00 08 08 36 00 00 00 00 00 00 00 00  .......6........
   2253         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2254         0x0030 00 00 00 00 00 00 00 00                          ........
   2255         rel 24+8 t=1 runtime.algarray+80
   2256         rel 32+8 t=1 runtime.gcbits.01+0
   2257         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
   2258         rel 48+8 t=1 type.map[int64]int64+0
   2259 type.map[int64]int64 SRODATA dupok size=80
   2260         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
   2261         0x0010 9c 10 d3 02 02 08 08 35 00 00 00 00 00 00 00 00  .......5........
   2262         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2263         0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2264         0x0040 00 00 00 00 00 00 00 00 08 08 90 00 04 00 00 00  ................
   2265         rel 24+8 t=1 runtime.algarray+0
   2266         rel 32+8 t=1 runtime.gcbits.01+0
   2267         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
   2268         rel 44+4 t=6 type.*map[int64]int64+0
   2269         rel 48+8 t=1 type.int64+0
   2270         rel 56+8 t=1 type.int64+0
   2271         rel 64+8 t=1 type.noalg.map.bucket[int64]int64+0

3、赋值

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

转载于:https://www.jianshu.com/p/196b028041b4

猜你喜欢

转载自blog.csdn.net/weixin_34151004/article/details/91244345