aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2023-07-07 15:47:49 +0200
committerRon Evans <[email protected]>2023-08-04 11:59:11 +0200
commitf1e25a18d2584cda1d7b2d478e17a4358ee7daf0 (patch)
tree1cee732b73801015de741855ad047c71fcf3fa4a /src
parenta2f886a67a645add0c2e42289e20f89fe402294d (diff)
downloadtinygo-f1e25a18d2584cda1d7b2d478e17a4358ee7daf0.tar.gz
tinygo-f1e25a18d2584cda1d7b2d478e17a4358ee7daf0.zip
compiler: implement clear builtin for maps
Diffstat (limited to 'src')
-rw-r--r--src/runtime/hashmap.go29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go
index 8a902a55d..dfbec300e 100644
--- a/src/runtime/hashmap.go
+++ b/src/runtime/hashmap.go
@@ -91,6 +91,35 @@ func hashmapMakeUnsafePointer(keySize, valueSize uintptr, sizeHint uintptr, alg
return (unsafe.Pointer)(hashmapMake(keySize, valueSize, sizeHint, alg))
}
+// Remove all entries from the map, without actually deallocating the space for
+// it. This is used for the clear builtin, and can be used to reuse a map (to
+// avoid extra heap allocations).
+func hashmapClear(m *hashmap) {
+ if m == nil {
+ // Nothing to do. According to the spec:
+ // > If the map or slice is nil, clear is a no-op.
+ return
+ }
+
+ m.count = 0
+ numBuckets := uintptr(1) << m.bucketBits
+ bucketSize := hashmapBucketSize(m)
+ for i := uintptr(0); i < numBuckets; i++ {
+ bucket := hashmapBucketAddr(m, m.buckets, i)
+ for bucket != nil {
+ // Clear the tophash, to mark these keys/values as removed.
+ bucket.tophash = [8]uint8{}
+
+ // Clear the keys and values in the bucket so that the GC won't pin
+ // these allocations.
+ memzero(unsafe.Add(unsafe.Pointer(bucket), unsafe.Sizeof(hashmapBucket{})), bucketSize-unsafe.Sizeof(hashmapBucket{}))
+
+ // Move on to the next bucket in the chain.
+ bucket = bucket.next
+ }
+ }
+}
+
func hashmapKeyEqualAlg(alg hashmapAlgorithm) func(x, y unsafe.Pointer, n uintptr) bool {
switch alg {
case hashmapAlgorithmBinary: