aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/gc/builtin.go242
-rw-r--r--src/cmd/compile/internal/gc/builtin/runtime.go3
-rw-r--r--src/cmd/compile/internal/gc/walk.go19
-rw-r--r--src/runtime/hashmap.go19
-rw-r--r--src/runtime/hashmap_fast.go6
-rw-r--r--test/makemap.go34
6 files changed, 191 insertions, 132 deletions
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index fb3fdf90df..79e1a51a4b 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -72,83 +72,84 @@ var runtimeDecls = [...]struct {
{"panicnildottype", funcTag, 55},
{"ifaceeq", funcTag, 58},
{"efaceeq", funcTag, 58},
- {"makemap", funcTag, 60},
- {"mapaccess1", funcTag, 61},
- {"mapaccess1_fast32", funcTag, 62},
- {"mapaccess1_fast64", funcTag, 62},
- {"mapaccess1_faststr", funcTag, 62},
- {"mapaccess1_fat", funcTag, 63},
- {"mapaccess2", funcTag, 64},
- {"mapaccess2_fast32", funcTag, 65},
- {"mapaccess2_fast64", funcTag, 65},
- {"mapaccess2_faststr", funcTag, 65},
- {"mapaccess2_fat", funcTag, 66},
- {"mapassign", funcTag, 61},
- {"mapassign_fast32", funcTag, 62},
- {"mapassign_fast64", funcTag, 62},
- {"mapassign_faststr", funcTag, 62},
- {"mapiterinit", funcTag, 67},
- {"mapdelete", funcTag, 67},
- {"mapdelete_fast32", funcTag, 68},
- {"mapdelete_fast64", funcTag, 68},
- {"mapdelete_faststr", funcTag, 68},
- {"mapiternext", funcTag, 69},
- {"makechan64", funcTag, 71},
- {"makechan", funcTag, 72},
- {"chanrecv1", funcTag, 74},
- {"chanrecv2", funcTag, 75},
- {"chansend1", funcTag, 77},
+ {"makemap64", funcTag, 60},
+ {"makemap", funcTag, 61},
+ {"mapaccess1", funcTag, 62},
+ {"mapaccess1_fast32", funcTag, 63},
+ {"mapaccess1_fast64", funcTag, 63},
+ {"mapaccess1_faststr", funcTag, 63},
+ {"mapaccess1_fat", funcTag, 64},
+ {"mapaccess2", funcTag, 65},
+ {"mapaccess2_fast32", funcTag, 66},
+ {"mapaccess2_fast64", funcTag, 66},
+ {"mapaccess2_faststr", funcTag, 66},
+ {"mapaccess2_fat", funcTag, 67},
+ {"mapassign", funcTag, 62},
+ {"mapassign_fast32", funcTag, 63},
+ {"mapassign_fast64", funcTag, 63},
+ {"mapassign_faststr", funcTag, 63},
+ {"mapiterinit", funcTag, 68},
+ {"mapdelete", funcTag, 68},
+ {"mapdelete_fast32", funcTag, 69},
+ {"mapdelete_fast64", funcTag, 69},
+ {"mapdelete_faststr", funcTag, 69},
+ {"mapiternext", funcTag, 70},
+ {"makechan64", funcTag, 72},
+ {"makechan", funcTag, 73},
+ {"chanrecv1", funcTag, 75},
+ {"chanrecv2", funcTag, 76},
+ {"chansend1", funcTag, 78},
{"closechan", funcTag, 23},
- {"writeBarrier", varTag, 79},
- {"writebarrierptr", funcTag, 80},
- {"typedmemmove", funcTag, 81},
- {"typedmemclr", funcTag, 82},
- {"typedslicecopy", funcTag, 83},
- {"selectnbsend", funcTag, 84},
- {"selectnbrecv", funcTag, 85},
- {"selectnbrecv2", funcTag, 87},
- {"newselect", funcTag, 88},
- {"selectsend", funcTag, 89},
- {"selectrecv", funcTag, 90},
+ {"writeBarrier", varTag, 80},
+ {"writebarrierptr", funcTag, 81},
+ {"typedmemmove", funcTag, 82},
+ {"typedmemclr", funcTag, 83},
+ {"typedslicecopy", funcTag, 84},
+ {"selectnbsend", funcTag, 85},
+ {"selectnbrecv", funcTag, 86},
+ {"selectnbrecv2", funcTag, 88},
+ {"newselect", funcTag, 89},
+ {"selectsend", funcTag, 90},
+ {"selectrecv", funcTag, 91},
{"selectdefault", funcTag, 55},
- {"selectgo", funcTag, 91},
+ {"selectgo", funcTag, 92},
{"block", funcTag, 5},
- {"makeslice", funcTag, 93},
- {"makeslice64", funcTag, 94},
- {"growslice", funcTag, 95},
- {"memmove", funcTag, 96},
- {"memclrNoHeapPointers", funcTag, 97},
- {"memclrHasPointers", funcTag, 97},
- {"memequal", funcTag, 98},
- {"memequal8", funcTag, 99},
- {"memequal16", funcTag, 99},
- {"memequal32", funcTag, 99},
- {"memequal64", funcTag, 99},
- {"memequal128", funcTag, 99},
- {"int64div", funcTag, 100},
- {"uint64div", funcTag, 101},
- {"int64mod", funcTag, 100},
- {"uint64mod", funcTag, 101},
- {"float64toint64", funcTag, 102},
- {"float64touint64", funcTag, 103},
- {"float64touint32", funcTag, 105},
- {"int64tofloat64", funcTag, 106},
- {"uint64tofloat64", funcTag, 107},
- {"uint32tofloat64", funcTag, 108},
- {"complex128div", funcTag, 109},
- {"racefuncenter", funcTag, 110},
+ {"makeslice", funcTag, 94},
+ {"makeslice64", funcTag, 95},
+ {"growslice", funcTag, 96},
+ {"memmove", funcTag, 97},
+ {"memclrNoHeapPointers", funcTag, 98},
+ {"memclrHasPointers", funcTag, 98},
+ {"memequal", funcTag, 99},
+ {"memequal8", funcTag, 100},
+ {"memequal16", funcTag, 100},
+ {"memequal32", funcTag, 100},
+ {"memequal64", funcTag, 100},
+ {"memequal128", funcTag, 100},
+ {"int64div", funcTag, 101},
+ {"uint64div", funcTag, 102},
+ {"int64mod", funcTag, 101},
+ {"uint64mod", funcTag, 102},
+ {"float64toint64", funcTag, 103},
+ {"float64touint64", funcTag, 104},
+ {"float64touint32", funcTag, 106},
+ {"int64tofloat64", funcTag, 107},
+ {"uint64tofloat64", funcTag, 108},
+ {"uint32tofloat64", funcTag, 109},
+ {"complex128div", funcTag, 110},
+ {"racefuncenter", funcTag, 111},
{"racefuncexit", funcTag, 5},
- {"raceread", funcTag, 110},
- {"racewrite", funcTag, 110},
- {"racereadrange", funcTag, 111},
- {"racewriterange", funcTag, 111},
- {"msanread", funcTag, 111},
- {"msanwrite", funcTag, 111},
+ {"raceread", funcTag, 111},
+ {"racewrite", funcTag, 111},
+ {"racereadrange", funcTag, 112},
+ {"racewriterange", funcTag, 112},
+ {"msanread", funcTag, 112},
+ {"msanwrite", funcTag, 112},
{"support_popcnt", varTag, 11},
}
func runtimeTypes() []*types.Type {
- var typs [112]*types.Type
+ var typs [113]*types.Type
typs[0] = types.Bytetype
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[TANY]
@@ -210,56 +211,57 @@ func runtimeTypes() []*types.Type {
typs[58] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[57]), anonfield(typs[57])}, []*Node{anonfield(typs[11])})
typs[59] = types.NewMap(typs[2], typs[2])
typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[59])})
- typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
- typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
- typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
- typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
- typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
- typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
- typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, nil)
- typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, nil)
- typs[69] = functype(nil, []*Node{anonfield(typs[3])}, nil)
- typs[70] = types.NewChan(typs[2], types.Cboth)
- typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[70])})
- typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[70])})
- typs[73] = types.NewChan(typs[2], types.Crecv)
- typs[74] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, nil)
- typs[75] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
- typs[76] = types.NewChan(typs[2], types.Csend)
- typs[77] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, nil)
- typs[78] = types.NewArray(typs[0], 3)
- typs[79] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[78]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
- typs[80] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
- typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
- typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
- typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
- typs[84] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
- typs[85] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[73])}, []*Node{anonfield(typs[11])})
- typs[86] = types.NewPtr(typs[11])
- typs[87] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[86]), anonfield(typs[73])}, []*Node{anonfield(typs[11])})
- typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil)
- typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[76]), anonfield(typs[3])}, nil)
- typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3]), anonfield(typs[86])}, nil)
- typs[91] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
- typs[92] = types.NewSlice(typs[2])
- typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[92])})
- typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[92])})
- typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[92]), anonfield(typs[32])}, []*Node{anonfield(typs[92])})
- typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, nil)
- typs[97] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[48])}, nil)
- typs[98] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, []*Node{anonfield(typs[11])})
- typs[99] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
- typs[100] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
- typs[101] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
- typs[102] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
- typs[103] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
- typs[104] = types.Types[TUINT32]
- typs[105] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[104])})
- typs[106] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
- typs[107] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
- typs[108] = functype(nil, []*Node{anonfield(typs[104])}, []*Node{anonfield(typs[13])})
- typs[109] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
- typs[110] = functype(nil, []*Node{anonfield(typs[48])}, nil)
- typs[111] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[48])}, nil)
+ typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[3])}, []*Node{anonfield(typs[59])})
+ typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
+ typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
+ typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
+ typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+ typs[66] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+ typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
+ typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[3])}, nil)
+ typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[59]), anonfield(typs[2])}, nil)
+ typs[70] = functype(nil, []*Node{anonfield(typs[3])}, nil)
+ typs[71] = types.NewChan(typs[2], types.Cboth)
+ typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[71])})
+ typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[71])})
+ typs[74] = types.NewChan(typs[2], types.Crecv)
+ typs[75] = functype(nil, []*Node{anonfield(typs[74]), anonfield(typs[3])}, nil)
+ typs[76] = functype(nil, []*Node{anonfield(typs[74]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+ typs[77] = types.NewChan(typs[2], types.Csend)
+ typs[78] = functype(nil, []*Node{anonfield(typs[77]), anonfield(typs[3])}, nil)
+ typs[79] = types.NewArray(typs[0], 3)
+ typs[80] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[79]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
+ typs[81] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
+ typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+ typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
+ typs[84] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
+ typs[85] = functype(nil, []*Node{anonfield(typs[77]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+ typs[86] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[74])}, []*Node{anonfield(typs[11])})
+ typs[87] = types.NewPtr(typs[11])
+ typs[88] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[87]), anonfield(typs[74])}, []*Node{anonfield(typs[11])})
+ typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil)
+ typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[77]), anonfield(typs[3])}, nil)
+ typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3]), anonfield(typs[87])}, nil)
+ typs[92] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
+ typs[93] = types.NewSlice(typs[2])
+ typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[93])})
+ typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[93])})
+ typs[96] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[93]), anonfield(typs[32])}, []*Node{anonfield(typs[93])})
+ typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, nil)
+ typs[98] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[48])}, nil)
+ typs[99] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[48])}, []*Node{anonfield(typs[11])})
+ typs[100] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
+ typs[101] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
+ typs[102] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
+ typs[103] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
+ typs[104] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
+ typs[105] = types.Types[TUINT32]
+ typs[106] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[105])})
+ typs[107] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
+ typs[108] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
+ typs[109] = functype(nil, []*Node{anonfield(typs[105])}, []*Node{anonfield(typs[13])})
+ typs[110] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
+ typs[111] = functype(nil, []*Node{anonfield(typs[48])}, nil)
+ typs[112] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[48])}, nil)
return typs[:]
}
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index 6313b1a44c..1fb42e7223 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -92,7 +92,8 @@ func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
// *byte is really *runtime.Type
-func makemap(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
+func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 3ed4bc3edd..83c82a6a84 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -1484,9 +1484,24 @@ opswitch:
h = nodnil()
}
- fn := syslook("makemap")
+ // When hint fits into int, use makemap instead of
+ // makemap64, which is faster and shorter on 32 bit platforms.
+ hint := n.Left
+ fnname := "makemap64"
+ argtype := types.Types[TINT64]
+
+ // Type checking guarantees that TIDEAL hint is positive and fits in an int.
+ // See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function.
+ // The case of hint overflow when converting TUINT or TUINTPTR to TINT
+ // will be handled by the negative range checks in makemap during runtime.
+ if hint.Type.IsKind(TIDEAL) || maxintval[hint.Type.Etype].Cmp(maxintval[TUINT]) <= 0 {
+ fnname = "makemap"
+ argtype = types.Types[TINT]
+ }
+
+ fn := syslook(fnname)
fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
- n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), h)
+ n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
case OMAKESLICE:
l := n.Left
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go
index 852b65d1db..d4d02388db 100644
--- a/src/runtime/hashmap.go
+++ b/src/runtime/hashmap.go
@@ -255,18 +255,25 @@ func (h *hmap) createOverflow() {
}
}
+func makemap64(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {
+ if int64(int(hint)) != hint {
+ hint = 0
+ }
+ return makemap(t, int(hint), h)
+}
+
// makemap implements a Go map creation make(map[k]v, hint)
// If the compiler has determined that the map or the first bucket
// can be created on the stack, h and/or bucket may be non-nil.
// If h != nil, the map can be created directly in h.
// If h.buckets != nil, bucket pointed to can be used as the first bucket.
-func makemap(t *maptype, hint int64, h *hmap) *hmap {
+func makemap(t *maptype, hint int, h *hmap) *hmap {
if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != t.hmap.size {
println("runtime: sizeof(hmap) =", sz, ", t.hmap.size =", t.hmap.size)
throw("bad hmap size")
}
- if hint < 0 || hint > int64(maxSliceCap(t.bucket.size)) {
+ if hint < 0 || hint > int(maxSliceCap(t.bucket.size)) {
hint = 0
}
@@ -589,7 +596,7 @@ again:
// If we hit the max load factor or we have too many overflow buckets,
// and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ if !h.growing() && (overLoadFactor(h.count, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
hashGrow(t, h)
goto again // Growing the table invalidates everything, so try again
}
@@ -920,7 +927,7 @@ func hashGrow(t *maptype, h *hmap) {
// Otherwise, there are too many overflow buckets,
// so keep the same number of buckets and "grow" laterally.
bigger := uint8(1)
- if !overLoadFactor(int64(h.count), h.B) {
+ if !overLoadFactor(h.count, h.B) {
bigger = 0
h.flags |= sameSizeGrow
}
@@ -959,7 +966,7 @@ func hashGrow(t *maptype, h *hmap) {
}
// overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor.
-func overLoadFactor(count int64, B uint8) bool {
+func overLoadFactor(count int, B uint8) bool {
return count >= bucketCnt && uint64(count) >= loadFactorNum*((uint64(1)<<B)/loadFactorDen)
}
@@ -1168,7 +1175,7 @@ func ismapkey(t *_type) bool {
//go:linkname reflect_makemap reflect.makemap
func reflect_makemap(t *maptype, cap int) *hmap {
- return makemap(t, int64(cap), nil)
+ return makemap(t, cap, nil)
}
//go:linkname reflect_mapaccess reflect.mapaccess
diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go
index c3ce5ae150..e83c72d0f9 100644
--- a/src/runtime/hashmap_fast.go
+++ b/src/runtime/hashmap_fast.go
@@ -462,7 +462,7 @@ again:
// If we hit the max load factor or we have too many overflow buckets,
// and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ if !h.growing() && (overLoadFactor(h.count, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
hashGrow(t, h)
goto again // Growing the table invalidates everything, so try again
}
@@ -547,7 +547,7 @@ again:
// If we hit the max load factor or we have too many overflow buckets,
// and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ if !h.growing() && (overLoadFactor(h.count, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
hashGrow(t, h)
goto again // Growing the table invalidates everything, so try again
}
@@ -637,7 +637,7 @@ again:
// If we hit the max load factor or we have too many overflow buckets,
// and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(int64(h.count), h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ if !h.growing() && (overLoadFactor(h.count, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
hashGrow(t, h)
goto again // Growing the table invalidates everything, so try again
}
diff --git a/test/makemap.go b/test/makemap.go
new file mode 100644
index 0000000000..60983c0d47
--- /dev/null
+++ b/test/makemap.go
@@ -0,0 +1,34 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that typed non-integer, negative and too large
+// values are not accepted as size argument in make for
+// maps.
+
+package main
+
+type T map[int]int
+
+var sink T
+
+func main() {
+ sink = make(T, -1) // ERROR "negative size argument in make.*"
+ sink = make(T, uint64(1<<63)) // ERROR "size argument too large in make.*"
+
+ sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+}