runtime: rotate map key seed on clearing up maps

Same thing as CL 253020 did for map clear idiom.

name                        old time/op  new time/op  delta
MapDelete/Int32/100-12      30.0ns ± 1%  30.7ns ± 3%   ~     (p=0.400 n=3+3)
MapDelete/Int32/1000-12     26.6ns ± 2%  28.1ns ± 3%   ~     (p=0.100 n=3+3)
MapDelete/Int32/10000-12    28.6ns ± 1%  31.9ns ± 1%   ~     (p=0.100 n=3+3)
MapDelete/Int64/100-12      30.2ns ± 0%  32.1ns ± 3%   ~     (p=0.100 n=3+3)
MapDelete/Int64/1000-12     26.5ns ± 1%  27.5ns ± 3%   ~     (p=0.100 n=3+3)
MapDelete/Int64/10000-12    29.6ns ± 1%  29.3ns ± 1%   ~     (p=0.300 n=3+3)
MapDelete/Str/100-12        19.5ns ± 3%  19.6ns ± 2%   ~     (p=0.800 n=3+3)
MapDelete/Str/1000-12       31.6ns ± 1%  31.4ns ± 1%   ~     (p=0.500 n=3+3)
MapDelete/Str/10000-12      37.8ns ± 1%  37.1ns ± 1%   ~     (p=0.100 n=3+3)
MapDelete/Pointer/100-12    15.9ns ± 1%  16.8ns ± 9%   ~     (p=0.200 n=3+3)
MapDelete/Pointer/1000-12   26.9ns ± 1%  26.2ns ± 2%   ~     (p=0.200 n=3+3)
MapDelete/Pointer/10000-12  30.6ns ± 1%  30.7ns ± 4%   ~     (p=0.700 n=3+3)

Fixes #25237

Change-Id: I353cf44a2f6158549f0ef563d867f0844fec7095
Reviewed-on: https://go-review.googlesource.com/c/go/+/252940
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 22a0241..8be1d39 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -780,6 +780,11 @@
 			}
 		notLast:
 			h.count--
+			// Reset the hash seed to make it more difficult for attackers to
+			// repeatedly trigger hash collisions. See issue 25237.
+			if h.count == 0 {
+				h.hash0 = fastrand()
+			}
 			break search
 		}
 	}
diff --git a/src/runtime/map_fast32.go b/src/runtime/map_fast32.go
index d035ed0..d80f5ea 100644
--- a/src/runtime/map_fast32.go
+++ b/src/runtime/map_fast32.go
@@ -344,6 +344,11 @@
 			}
 		notLast:
 			h.count--
+			// Reset the hash seed to make it more difficult for attackers to
+			// repeatedly trigger hash collisions. See issue 25237.
+			if h.count == 0 {
+				h.hash0 = fastrand()
+			}
 			break search
 		}
 	}
diff --git a/src/runtime/map_fast64.go b/src/runtime/map_fast64.go
index f1f3927..3bc84bb 100644
--- a/src/runtime/map_fast64.go
+++ b/src/runtime/map_fast64.go
@@ -346,6 +346,11 @@
 			}
 		notLast:
 			h.count--
+			// Reset the hash seed to make it more difficult for attackers to
+			// repeatedly trigger hash collisions. See issue 25237.
+			if h.count == 0 {
+				h.hash0 = fastrand()
+			}
 			break search
 		}
 	}
diff --git a/src/runtime/map_faststr.go b/src/runtime/map_faststr.go
index 069cda6..108c502 100644
--- a/src/runtime/map_faststr.go
+++ b/src/runtime/map_faststr.go
@@ -369,6 +369,11 @@
 			}
 		notLast:
 			h.count--
+			// Reset the hash seed to make it more difficult for attackers to
+			// repeatedly trigger hash collisions. See issue 25237.
+			if h.count == 0 {
+				h.hash0 = fastrand()
+			}
 			break search
 		}
 	}