aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/mcache.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2010-12-03 04:34:57 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-12-03 04:34:57 +0000
commit7a9389330e91acc3ed05deac2d198af25d13cf3c (patch)
tree38fe54a4f38ede5d949c915d66191f24a6fe5153 /libgo/runtime/mcache.c
parent1aa6700378e5188a853c018256113ce6e1fb5c05 (diff)
downloadgcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.zip
gcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.tar.gz
gcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.tar.bz2
Add Go frontend, libgo library, and Go testsuite.
gcc/: * gcc.c (default_compilers): Add entry for ".go". * common.opt: Add -static-libgo as a driver option. * doc/install.texi (Configuration): Mention libgo as an option for --enable-shared. Mention go as an option for --enable-languages. * doc/invoke.texi (Overall Options): Mention .go as a file name suffix. Mention go as a -x option. * doc/frontends.texi (G++ and GCC): Mention Go as a supported language. * doc/sourcebuild.texi (Top Level): Mention libgo. * doc/standards.texi (Standards): Add section on Go language. Move references for other languages into their own section. * doc/contrib.texi (Contributors): Mention that I contributed the Go frontend. gcc/testsuite/: * lib/go.exp: New file. * lib/go-dg.exp: New file. * lib/go-torture.exp: New file. * lib/target-supports.exp (check_compile): Match // Go. From-SVN: r167407
Diffstat (limited to 'libgo/runtime/mcache.c')
-rw-r--r--libgo/runtime/mcache.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/libgo/runtime/mcache.c b/libgo/runtime/mcache.c
new file mode 100644
index 0000000..ce65757
--- /dev/null
+++ b/libgo/runtime/mcache.c
@@ -0,0 +1,131 @@
+// Copyright 2009 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.
+
+// Per-thread (in Go, per-M) malloc cache for small objects.
+//
+// See malloc.h for an overview.
+
+#include "runtime.h"
+#include "malloc.h"
+
+void*
+runtime_MCache_Alloc(MCache *c, int32 sizeclass, uintptr size, int32 zeroed)
+{
+ MCacheList *l;
+ MLink *first, *v;
+ int32 n;
+
+ // Allocate from list.
+ l = &c->list[sizeclass];
+ if(l->list == nil) {
+ // Replenish using central lists.
+ n = runtime_MCentral_AllocList(&runtime_mheap.central[sizeclass],
+ runtime_class_to_transfercount[sizeclass], &first);
+ l->list = first;
+ l->nlist = n;
+ c->size += n*size;
+ }
+ v = l->list;
+ l->list = v->next;
+ l->nlist--;
+ if(l->nlist < l->nlistmin)
+ l->nlistmin = l->nlist;
+ c->size -= size;
+
+ // v is zeroed except for the link pointer
+ // that we used above; zero that.
+ v->next = nil;
+ if(zeroed) {
+ // block is zeroed iff second word is zero ...
+ if(size > sizeof(uintptr) && ((uintptr*)v)[1] != 0)
+ runtime_memclr((byte*)v, size);
+ else {
+ // ... except for the link pointer
+ // that we used above; zero that.
+ v->next = nil;
+ }
+ }
+ c->local_alloc += size;
+ c->local_objects++;
+ return v;
+}
+
+// Take n elements off l and return them to the central free list.
+static void
+ReleaseN(MCache *c, MCacheList *l, int32 n, int32 sizeclass)
+{
+ MLink *first, **lp;
+ int32 i;
+
+ // Cut off first n elements.
+ first = l->list;
+ lp = &l->list;
+ for(i=0; i<n; i++)
+ lp = &(*lp)->next;
+ l->list = *lp;
+ *lp = nil;
+ l->nlist -= n;
+ if(l->nlist < l->nlistmin)
+ l->nlistmin = l->nlist;
+ c->size -= n*runtime_class_to_size[sizeclass];
+
+ // Return them to central free list.
+ runtime_MCentral_FreeList(&runtime_mheap.central[sizeclass], n, first);
+}
+
+void
+runtime_MCache_Free(MCache *c, void *v, int32 sizeclass, uintptr size)
+{
+ int32 i, n;
+ MCacheList *l;
+ MLink *p;
+
+ // Put back on list.
+ l = &c->list[sizeclass];
+ p = v;
+ p->next = l->list;
+ l->list = p;
+ l->nlist++;
+ c->size += size;
+ c->local_alloc -= size;
+ c->local_objects--;
+
+ if(l->nlist >= MaxMCacheListLen) {
+ // Release a chunk back.
+ ReleaseN(c, l, runtime_class_to_transfercount[sizeclass], sizeclass);
+ }
+
+ if(c->size >= MaxMCacheSize) {
+ // Scavenge.
+ for(i=0; i<NumSizeClasses; i++) {
+ l = &c->list[i];
+ n = l->nlistmin;
+
+ // n is the minimum number of elements we've seen on
+ // the list since the last scavenge. If n > 0, it means that
+ // we could have gotten by with n fewer elements
+ // without needing to consult the central free list.
+ // Move toward that situation by releasing n/2 of them.
+ if(n > 0) {
+ if(n > 1)
+ n /= 2;
+ ReleaseN(c, l, n, i);
+ }
+ l->nlistmin = l->nlist;
+ }
+ }
+}
+
+void
+runtime_MCache_ReleaseAll(MCache *c)
+{
+ int32 i;
+ MCacheList *l;
+
+ for(i=0; i<NumSizeClasses; i++) {
+ l = &c->list[i];
+ ReleaseN(c, l, l->nlist, i);
+ l->nlistmin = 0;
+ }
+}