aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/hashmap.go
AgeCommit message (Collapse)Author
2016-09-13runtime: limit the number of map overflow bucketsJosh Bleecher Snyder
Consider repeatedly adding many items to a map and then deleting them all, as in #16070. The map itself doesn't need to grow above the high water mark of number of items. However, due to random collisions, the map can accumulate overflow buckets. Prior to this CL, those overflow buckets were never removed, which led to a slow memory leak. The problem with removing overflow buckets is iterators. The obvious approach is to repack keys and values and eliminate unused overflow buckets. However, keys, values, and overflow buckets cannot be manipulated without disrupting iterators. This CL takes a different approach, which is to reuse the existing map growth mechanism, which is well established, well tested, and safe in the presence of iterators. When a map has accumulated enough overflow buckets we trigger map growth, but grow into a map of the same size as before. The old overflow buckets will be left behind for garbage collection. For the code in #16070, instead of climbing (very slowly) forever, memory usage now cycles between 264mb and 483mb every 15 minutes or so. To avoid increasing the size of maps, the overflow bucket counter is only 16 bits. For large maps, the counter is incremented stochastically. Fixes #16070 Change-Id: If551d77613ec6836907efca58bda3deee304297e Reviewed-on: https://go-review.googlesource.com/25049 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-08-30runtime: rename fastrand1 to fastrandJosh Bleecher Snyder
Change-Id: I37706ff0a3486827c5b072c95ad890ea87ede847 Reviewed-on: https://go-review.googlesource.com/28210 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-08-16runtime: fix map iterator concurrent map checkKeith Randall
We should check whether there is a concurrent writer at the start of every mapiternext, not just in mapaccessK (which is only called during certain map growth situations). Tests turned off by default because they are inherently flaky. Fixes #16278 Change-Id: I8b72cab1b8c59d1923bec6fa3eabc932e4e91542 Reviewed-on: https://go-review.googlesource.com/24749 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2016-04-21runtime: use type int to specify size for newarrayMartin Möhrmann
Consistently use type int for the size argument of runtime.newarray, runtime.reflect_unsafe_NewArray and reflect.unsafe_NewArray. Change-Id: Ic77bf2dde216c92ca8c49462f8eedc0385b6314e Reviewed-on: https://go-review.googlesource.com/22311 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Martin Möhrmann <martisch@uos.de> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-04-20cmd/compile: change the way we handle large map valuesKeith Randall
mapaccess{1,2} returns a pointer to the value. When the key is not in the map, it returns a pointer to zeroed memory. Currently, for large map values we have a complicated scheme which dynamically allocates zeroed memory for this purpose. It is ugly code and requires an atomic.Load in a bunch of places we'd rather not have it. Switch to a scheme where callsites of mapaccess{1,2} which expect large return values pass in a pointer to zeroed memory that mapaccess can return if the key is not found. This avoids the atomic.Load on all map accesses with a few extra instructions only for the large value acccesses, plus a bit of bss space. There was a time (1.4 & 1.5?) where we did something like this but all the tricks to make the right size zero value were done by the linker. That scheme broke in the presence of dyamic linking. The scheme in this CL works even when dynamic linking. Fixes #12337 Change-Id: Ic2d0319944af33bbb59785938d9ab80958d1b4b1 Reviewed-on: https://go-review.googlesource.com/22221 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
2016-04-13runtime/internal/atomic: rename Storep1 to StorepNoWBAustin Clements
Make it clear that the point of this function stores a pointer *without* a write barrier. sed -i -e 's/Storep1/StorepNoWB/' $(git grep -l Storep1) Updates #15270. Change-Id: Ifad7e17815e51a738070655fe3b178afdadaecf6 Reviewed-on: https://go-review.googlesource.com/21994 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org>
2016-04-10runtime: avoid unnecessary map iteration write barrierJosh Bleecher Snyder
Update #14921 Change-Id: I5c5816d0193757bf7465b1e09c27ca06897df4bf Reviewed-on: https://go-review.googlesource.com/21814 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-04-10runtime: make execution error panic values implement the Error interfaceEmmanuel Odeke
Make execution panics implement Error as mandated by https://golang.org/ref/spec#Run_time_panics, instead of panics with strings. Fixes #14965 Change-Id: I7827f898b9b9c08af541db922cc24fa0800ff18a Reviewed-on: https://go-review.googlesource.com/21214 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-07runtime: eliminate unnecessary type conversionsMatthew Dempsky
Automated refactoring produced using github.com/mdempsky/unconvert. Change-Id: Iacf871a4f221ef17f48999a464ab2858b2bbaa90 Reviewed-on: https://go-review.googlesource.com/20071 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-02all: single space after period.Brad Fitzpatrick
The tree's pretty inconsistent about single space vs double space after a period in documentation. Make it consistently a single space, per earlier decisions. This means contributors won't be confused by misleading precedence. This CL doesn't use go/doc to parse. It only addresses // comments. It was generated with: $ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])') $ go test go/doc -update Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7 Reviewed-on: https://go-review.googlesource.com/20022 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Dave Day <djd@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-02-23Revert "cmd/compile: move hiter, hmap, and scase definitions into builtin.go"Matthew Dempsky
This reverts commit f28bbb776a050cc3edca2bbe1241d81217a7a251. Change-Id: I82fb81dcff3ddcaefef72949f1ef3a41bcd22301 Reviewed-on: https://go-review.googlesource.com/19849 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-02-22cmd/compile: move hiter, hmap, and scase definitions into builtin.goMatthew Dempsky
Also eliminates per-maptype hiter and hmap types, since they're not really needed anyway. Update packages reflect and runtime accordingly. Reduces golang.org/x/tools/cmd/godoc's text segment by ~170kB: text data bss dec hex filename 13085702 140640 151520 13377862 cc2146 godoc.before 12915382 140640 151520 13207542 c987f6 godoc.after Updates #6853. Change-Id: I948b2bc1f22d477c1756204996b4e3e1fb568d81 Reviewed-on: https://go-review.googlesource.com/16610 Reviewed-by: Keith Randall <khr@golang.org>
2015-12-07runtime: best-effort detection of concurrent misuse of mapsRuss Cox
If reports like #13062 are really concurrent misuse of maps, we can detect that, at least some of the time, with a cheap check. There is an extra pair of memory writes for writing to a map, but to the same cache line as h.count, which is often being modified anyway, and there is an extra memory read for reading from a map, but to the same cache line as h.count, which is always being read anyway. So the check should be basically invisible and may help reduce the number of "mysterious runtime crash due to map misuse" reports. Change-Id: I0e71b0d92eaa3b7bef48bf41b0f5ab790092487e Reviewed-on: https://go-review.googlesource.com/17501 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Austin Clements <austin@google.com>
2015-11-12runtime: break out system-specific constants into package sysMichael Matloob
runtime/internal/sys will hold system-, architecture- and config- specific constants. Updates #11647 Change-Id: I6db29c312556087a42e8d2bdd9af40d157c56b54 Reviewed-on: https://go-review.googlesource.com/16817 Reviewed-by: Russ Cox <rsc@golang.org>
2015-11-10runtime: break atomics out into package runtime/internal/atomicMichael Matloob
This change breaks out most of the atomics functions in the runtime into package runtime/internal/atomic. It adds some basic support in the toolchain for runtime packages, and also modifies linux/arm atomics to remove the dependency on the runtime's mutex. The mutexes have been replaced with spinlocks. all trybots are happy! In addition to the trybots, I've tested on the darwin/arm64 builder, on the darwin/arm builder, and on a ppc64le machine. Change-Id: I6698c8e3cf3834f55ce5824059f44d00dc8e3c2f Reviewed-on: https://go-review.googlesource.com/14204 Run-TryBot: Michael Matloob <matloob@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
2015-10-21runtime, syscall: add calls to msan functionsIan Lance Taylor
Add explicit memory sanitizer instrumentation to the runtime and syscall packages. The compiler does not instrument the runtime package. It does instrument the syscall package, but we need to add a couple of cases that it can't see. Change-Id: I2d66073f713fe67e33a6720460d2bb8f72f31394 Reviewed-on: https://go-review.googlesource.com/16164 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-09-09runtime: on map update, don't overwrite key if we don't need to.Keith Randall
Keep track of which types of keys need an update and which don't. Strings need an update because the new key might pin a smaller backing store. Floats need an update because it might be +0/-0. Interfaces need an update because they may contain strings or floats. Fixes #11088 Change-Id: I9ade53c1dfb3c1a2870d68d07201bc8128e9f217 Reviewed-on: https://go-review.googlesource.com/10843 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-08-26cmd/compile, runtime: stop returning t.zero on hashmap missMichael Hudson-Doyle
Previously t.zero always pointed to runtime.zerovalue. Change the hashmap code to always return a runtime pointer directly, and change that pointer to point to a larger buffer if one is needed. (It might be better to only copy from the pointer returned by the mapaccess functions when the value type is small enough and have the compiler insert explicit zeroing for larger value types, but I tried and failed to do this). This removes all uses of the zero field of the type data; the field itself can be removed in a separate change. Fixes #11491 Change-Id: I5b81752ff4067d74a5a281c41e88f151bae0171e Reviewed-on: https://go-review.googlesource.com/13784 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-07-31cmd/compile, runtime: fix placement of map bucket overflow pointer on naclRuss Cox
On most systems, a pointer is the worst case alignment, so adding a pointer field at the end of a struct guarantees there will be no padding added after that field (to satisfy overall struct alignment due to some more-aligned field also present). In the runtime, the map implementation needs a quick way to get to the overflow pointer, which is last in the bucket struct, so it uses size - sizeof(pointer) as the offset. NaCl/amd64p32 is the exception, as always. The worst case alignment is 64 bits but pointers are 32 bits. There's a long history that is not worth going into, but when we moved the overflow pointer to the end of the struct, we didn't get the padding computation right. The compiler computed the regular struct size and then on amd64p32 added another 32-bit field. And the runtime assumed it could step back two 32-bit fields (one 64-bit register size) to get to the overflow pointer. But in fact if the struct needed 64-bit alignment, the computation of the regular struct size would have added a 32-bit pad already, and then the code unconditionally added a second 32-bit pad. This placed the overflow pointer three words from the end, not two. The last two were padding, and since the runtime was consistent about using the second-to-last word as the overflow pointer, no harm done in the sense of overwriting useful memory. But writing the overflow pointer to a non-pointer word of memory means that the GC can't see the overflow blocks, so it will collect them prematurely. Then bad things happen. Correct all this in a few steps: 1. Add an explicit check at the end of the bucket layout in the compiler that the overflow field is last in the struct, never followed by padding. 2. When padding is needed on nacl (not always, just when needed), insert it before the overflow pointer, to preserve the "last in the struct" property. 3. Let the compiler have the final word on the width of the struct, by inserting an explicit padding field instead of overwriting the results of the width computation it does. 4. For the same reason (tell the truth to the compiler), set the type of the overflow field when we're trying to pretend its not a pointer (in this case the runtime maintains a list of the overflow blocks elsewhere). 5. Make the runtime use "last in the struct" as its location algorithm. This fixes TestTraceStress on nacl/amd64p32. The 'bad map state' and 'invalid free list' failures no longer occur. Fixes #11838. Change-Id: If918887f8f252d988db0a35159944d2b36512f92 Reviewed-on: https://go-review.googlesource.com/12971 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
2015-05-15runtime: make mapzero not crash on armRuss Cox
Change-Id: I40e8a4a2e62253233b66f6a2e61e222437292c31 Reviewed-on: https://go-review.googlesource.com/10151 Reviewed-by: Minux Ma <minux@golang.org>
2015-05-15runtime: allocate map element zero values for reflect-created types on demandRuss Cox
Preallocating them in reflect means that (1) if you say _ = PtrTo(ArrayOf(1000000000, reflect.TypeOf(byte(0)))), you just allocated 1GB of data (2) if you say it again, that's *another* GB of data. The only use of t.zero in the runtime is for map elements. Delay the allocation until the creation of a map with that element type, and share the zeros. The one downside of the shared zero is that it's not garbage collected, but it's also never written, so the OS should be able to handle it fairly efficiently. Change-Id: I56b098a091abf3ac0945de28ebef9a6c08e76614 Reviewed-on: https://go-review.googlesource.com/10111 Reviewed-by: Keith Randall <khr@golang.org>
2015-04-02runtime: remove checkgc code from hashmapAustin Clements
Currently hashmap is riddled with code that attempts to force a GC on the next allocation if checkgc is set. This no longer works as originally intended with the concurrent collector, and is apparently no longer used anyway. Remove checkgc. Change-Id: Ia6c17c405fa8821dc2e6af28d506c1133ab1ca0c Reviewed-on: https://go-review.googlesource.com/8355 Reviewed-by: Keith Randall <khr@golang.org>
2015-03-11runtime,reflect,cmd/internal/gc: Fix comments referring to .c/.h filesKeith Randall
Everything has moved to Go, but comments still refer to .c/.h files. Fix all of those up, at least for these three directories. Fixes #10138 Change-Id: Ie5efe89b247841e0b3f82aac5256b2c606ef67dc Reviewed-on: https://go-review.googlesource.com/7431 Reviewed-by: Russ Cox <rsc@golang.org>
2015-02-15cmd/gc: fix noscan mapsDmitry Vyukov
Change 85e7bee introduced a bug: it marks map buckets as noscan when key and val do not contain pointers. However, buckets with large/outline key or val do contain pointers. This change takes key/val size into consideration when marking buckets as noscan. Change-Id: I7172a0df482657be39faa59e2579dd9f209cb54d Reviewed-on: https://go-review.googlesource.com/4901 Reviewed-by: Keith Randall <khr@golang.org>
2015-02-12cmd/gc: allocate non-escaping maps on stackDmitry Vyukov
Extend escape analysis to make(map[k]v). If it does not escape, allocate temp buffer for hmap and one bucket on stack. There are 75 cases of non-escaping maps in std lib. benchmark old allocs new allocs delta BenchmarkConcurrentStmtQuery 16161 15161 -6.19% BenchmarkConcurrentTxQuery 17658 16658 -5.66% BenchmarkConcurrentTxStmtQuery 16157 15156 -6.20% BenchmarkConcurrentRandom 13637 13114 -3.84% BenchmarkManyConcurrentQueries 22 20 -9.09% BenchmarkDecodeComplex128Slice 250 188 -24.80% BenchmarkDecodeFloat64Slice 250 188 -24.80% BenchmarkDecodeInt32Slice 250 188 -24.80% BenchmarkDecodeStringSlice 2250 2188 -2.76% BenchmarkNewEmptyMap 1 0 -100.00% BenchmarkNewSmallMap 2 0 -100.00% benchmark old ns/op new ns/op delta BenchmarkNewEmptyMap 124 55.7 -55.08% BenchmarkNewSmallMap 317 148 -53.31% benchmark old allocs new allocs delta BenchmarkNewEmptyMap 1 0 -100.00% BenchmarkNewSmallMap 2 0 -100.00% benchmark old bytes new bytes delta BenchmarkNewEmptyMap 48 0 -100.00% BenchmarkNewSmallMap 192 0 -100.00% Fixes #5449 Change-Id: I24fa66f949d2f138885d9e66a0d160240dc9e8fa Reviewed-on: https://go-review.googlesource.com/3508 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
2015-01-27runtime: do not scan maps when k/v do not contain pointersDmitry Vyukov
Currently we scan maps even if k/v does not contain pointers. This is required because overflow buckets are hanging off the main table. This change introduces a separate array that contains pointers to all overflow buckets and keeps them alive. Buckets themselves are marked as containing no pointers and are not scanned by GC (if k/v does not contain pointers). This brings maps in line with slices and chans -- GC does not scan their contents if elements do not contain pointers. Currently scanning of a map[int]int with 2e8 entries (~8GB heap) takes ~8 seconds. With this change scanning takes negligible time. Update #9477. Change-Id: Id8a04066a53d2f743474cad406afb9f30f00eaae Reviewed-on: https://go-review.googlesource.com/3288 Reviewed-by: Keith Randall <khr@golang.org>
2015-01-07runtime: remove size argument from hash and equal algorithmsKeith Randall
The equal algorithm used to take the size equal(p, q *T, size uintptr) bool With this change, it does not equal(p, q *T) bool Similarly for the hash algorithm. The size is rarely used, as most equal functions know the size of the thing they are comparing. For instance f32equal already knows its inputs are 4 bytes in size. For cases where the size is not known, we allocate a closure (one for each size needed) that points to an assembly stub that reads the size out of the closure and calls generic code that has a size argument. Reduces the size of the go binary by 0.07%. Performance impact is not measurable. Change-Id: I6e00adf3dde7ad2974adbcff0ee91e86d2194fec Reviewed-on: https://go-review.googlesource.com/2392 Reviewed-by: Russ Cox <rsc@golang.org>
2015-01-06runtime: use typed memmove (write barriers) for chan, map, interface contentRuss Cox
Found with GODEBUG=wbshadow=2 mode. Eventually that will run automatically, but right now it still detects other missing write barriers. Change-Id: Iea83d693480c2f3008b4e80d55821acff65970a6 Reviewed-on: https://go-review.googlesource.com/2277 Reviewed-by: Keith Randall <khr@golang.org>
2014-12-28runtime: get rid of goalg, no longer neededKeith Randall
The goalg function was a holdover from when we had algorithm tables in both C and Go. It is no longer needed. Change-Id: Ia0c1af35bef3497a899f22084a1a7b42daae72a0 Reviewed-on: https://go-review.googlesource.com/2099 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2014-12-28runtime: rename gothrow to throwKeith Randall
Rename "gothrow" to "throw" now that the C version of "throw" is no longer needed. This change is purely mechanical except in panic.go where the old version of "throw" has been deleted. sed -i "" 's/[[:<:]]gothrow[[:>:]]/throw/g' runtime/*.go Change-Id: Icf0752299c35958b92870a97111c67bcd9159dc3 Reviewed-on: https://go-review.googlesource.com/2150 Reviewed-by: Minux Ma <minux@golang.org> Reviewed-by: Dave Cheney <dave@cheney.net>
2014-12-26reflect, runtime: gofmtmattn
Change-Id: I5437b3a36181373d8ff33225d7520ab321459de9 Reviewed-on: https://go-review.googlesource.com/2084 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2014-12-23runtime: remove thunk.sRuss Cox
Replace with uses of //go:linkname in Go files, direct use of name in .s files. The only one that really truly needs a jump is reflect.call; the jump is now next to the runtime.reflectcall assembly implementations. Change-Id: Ie7ff3020a8f60a8e4c8645fe236e7883a3f23f46 Reviewed-on: https://go-review.googlesource.com/1962 Reviewed-by: Austin Clements <austin@google.com>
2014-12-22runtime: fix nacl build, hashmap overflow field offset was incorrect.Keith Randall
Change-Id: Ieb305b2a4d4ef28d70a8b8ece703f495c5af0529 Reviewed-on: https://go-review.googlesource.com/2051 Reviewed-by: Keith Randall <khr@golang.org>
2014-12-22runtime: hashmap: move overflow pointer to end of bucketKeith Randall
Pointers to zero-sized values may end up pointing to the next object in memory, and possibly off the end of a span. This can cause memory leaks and/or confuse the garbage collector. By putting the overflow pointer at the end of the bucket, we make sure that pointers to any zero-sized keys or values don't accidentally point to the next object in memory. fixes #9384 Change-Id: I5d434df176984cb0210b4d0195dd106d6eb28f73 Reviewed-on: https://go-review.googlesource.com/1869 Reviewed-by: Russ Cox <rsc@golang.org>
2014-12-15runtime: if key type is reflexive, don't call equal(k, k)Keith Randall
Most types are reflexive (k == k for all k of type t), so don't bother calling equal(k, k) when the key type is reflexive. Change-Id: Ia716b4198b8b298687843b94b878dbc5e8fc2c65 Reviewed-on: https://go-review.googlesource.com/1480 Reviewed-by: Russ Cox <rsc@golang.org>
2014-09-09runtime: map iterators: always use intrabucket randomessKeith Randall
Fixes #8688 LGTM=rsc R=golang-codereviews, bradfitz, rsc, khr CC=golang-codereviews https://golang.org/cl/135660043
2014-09-08runtime: on bigger maps, start iterator at a random bucket.Keith Randall
This change brings the iter/delete pattern down to O(n lgn) from O(n^2). Fixes #8412. before: BenchmarkMapPop100 50000 32498 ns/op BenchmarkMapPop1000 500 3244851 ns/op BenchmarkMapPop10000 5 270276855 ns/op after: BenchmarkMapPop100 100000 16169 ns/op BenchmarkMapPop1000 5000 300416 ns/op BenchmarkMapPop10000 300 5990814 ns/op LGTM=iant R=golang-codereviews, iant, khr CC=golang-codereviews https://golang.org/cl/141270043
2014-09-08build: move package sources from src/pkg to srcRuss Cox
Preparation was in CL 134570043. This CL contains only the effect of 'hg mv src/pkg/* src'. For more about the move, see golang.org/s/go14nopkg.