aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/libgo/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/libgo/runtime')
-rw-r--r--gcc-4.8.1/libgo/runtime/arch.h8
-rw-r--r--gcc-4.8.1/libgo/runtime/array.h28
-rw-r--r--gcc-4.8.1/libgo/runtime/chan.c1430
-rw-r--r--gcc-4.8.1/libgo/runtime/cpuprof.c447
-rw-r--r--gcc-4.8.1/libgo/runtime/defs.h12
-rw-r--r--gcc-4.8.1/libgo/runtime/env_posix.c37
-rw-r--r--gcc-4.8.1/libgo/runtime/getncpu-bsd.c24
-rw-r--r--gcc-4.8.1/libgo/runtime/getncpu-irix.c16
-rw-r--r--gcc-4.8.1/libgo/runtime/getncpu-linux.c36
-rw-r--r--gcc-4.8.1/libgo/runtime/getncpu-none.c12
-rw-r--r--gcc-4.8.1/libgo/runtime/getncpu-solaris.c16
-rw-r--r--gcc-4.8.1/libgo/runtime/go-alloc.h11
-rw-r--r--gcc-4.8.1/libgo/runtime/go-append.c71
-rw-r--r--gcc-4.8.1/libgo/runtime/go-assert-interface.c45
-rw-r--r--gcc-4.8.1/libgo/runtime/go-assert.c19
-rw-r--r--gcc-4.8.1/libgo/runtime/go-assert.h18
-rw-r--r--gcc-4.8.1/libgo/runtime/go-breakpoint.c17
-rw-r--r--gcc-4.8.1/libgo/runtime/go-byte-array-to-string.c24
-rw-r--r--gcc-4.8.1/libgo/runtime/go-caller.c230
-rw-r--r--gcc-4.8.1/libgo/runtime/go-callers.c126
-rw-r--r--gcc-4.8.1/libgo/runtime/go-can-convert-interface.c78
-rw-r--r--gcc-4.8.1/libgo/runtime/go-cgo.c167
-rw-r--r--gcc-4.8.1/libgo/runtime/go-check-interface.c46
-rw-r--r--gcc-4.8.1/libgo/runtime/go-construct-map.c35
-rw-r--r--gcc-4.8.1/libgo/runtime/go-convert-interface.c132
-rw-r--r--gcc-4.8.1/libgo/runtime/go-copy.c22
-rw-r--r--gcc-4.8.1/libgo/runtime/go-defer.c77
-rw-r--r--gcc-4.8.1/libgo/runtime/go-defer.h37
-rw-r--r--gcc-4.8.1/libgo/runtime/go-deferred-recover.c94
-rw-r--r--gcc-4.8.1/libgo/runtime/go-eface-compare.c39
-rw-r--r--gcc-4.8.1/libgo/runtime/go-eface-val-compare.c35
-rw-r--r--gcc-4.8.1/libgo/runtime/go-fieldtrack.c101
-rw-r--r--gcc-4.8.1/libgo/runtime/go-getgoroot.c26
-rw-r--r--gcc-4.8.1/libgo/runtime/go-int-array-to-string.c85
-rw-r--r--gcc-4.8.1/libgo/runtime/go-int-to-string.c69
-rw-r--r--gcc-4.8.1/libgo/runtime/go-interface-compare.c35
-rw-r--r--gcc-4.8.1/libgo/runtime/go-interface-eface-compare.c36
-rw-r--r--gcc-4.8.1/libgo/runtime/go-interface-val-compare.c33
-rw-r--r--gcc-4.8.1/libgo/runtime/go-main.c54
-rw-r--r--gcc-4.8.1/libgo/runtime/go-make-slice.c96
-rw-r--r--gcc-4.8.1/libgo/runtime/go-map-delete.c56
-rw-r--r--gcc-4.8.1/libgo/runtime/go-map-index.c135
-rw-r--r--gcc-4.8.1/libgo/runtime/go-map-len.c25
-rw-r--r--gcc-4.8.1/libgo/runtime/go-map-range.c103
-rw-r--r--gcc-4.8.1/libgo/runtime/go-matherr.c88
-rw-r--r--gcc-4.8.1/libgo/runtime/go-memcmp.c13
-rw-r--r--gcc-4.8.1/libgo/runtime/go-nanotime.c21
-rw-r--r--gcc-4.8.1/libgo/runtime/go-new-map.c142
-rw-r--r--gcc-4.8.1/libgo/runtime/go-new.c22
-rw-r--r--gcc-4.8.1/libgo/runtime/go-nosys.c393
-rw-r--r--gcc-4.8.1/libgo/runtime/go-now.c33
-rw-r--r--gcc-4.8.1/libgo/runtime/go-panic.c106
-rw-r--r--gcc-4.8.1/libgo/runtime/go-panic.h43
-rw-r--r--gcc-4.8.1/libgo/runtime/go-print.c36
-rw-r--r--gcc-4.8.1/libgo/runtime/go-recover.c80
-rw-r--r--gcc-4.8.1/libgo/runtime/go-reflect-call.c535
-rw-r--r--gcc-4.8.1/libgo/runtime/go-reflect-map.c240
-rw-r--r--gcc-4.8.1/libgo/runtime/go-rune.c97
-rw-r--r--gcc-4.8.1/libgo/runtime/go-runtime-error.c90
-rw-r--r--gcc-4.8.1/libgo/runtime/go-setenv.c70
-rw-r--r--gcc-4.8.1/libgo/runtime/go-signal.c485
-rw-r--r--gcc-4.8.1/libgo/runtime/go-strcmp.c25
-rw-r--r--gcc-4.8.1/libgo/runtime/go-string-to-byte-array.c24
-rw-r--r--gcc-4.8.1/libgo/runtime/go-string-to-int-array.c51
-rw-r--r--gcc-4.8.1/libgo/runtime/go-string.h31
-rw-r--r--gcc-4.8.1/libgo/runtime/go-strplus.c30
-rw-r--r--gcc-4.8.1/libgo/runtime/go-strslice.c26
-rw-r--r--gcc-4.8.1/libgo/runtime/go-traceback.c37
-rw-r--r--gcc-4.8.1/libgo/runtime/go-trampoline.c113
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-complex.c128
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-eface.c59
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-error.c28
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-float.c106
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-identity.c56
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-interface.c56
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type-string.c43
-rw-r--r--gcc-4.8.1/libgo/runtime/go-type.h334
-rw-r--r--gcc-4.8.1/libgo/runtime/go-typedesc-equal.c39
-rw-r--r--gcc-4.8.1/libgo/runtime/go-typestring.c17
-rw-r--r--gcc-4.8.1/libgo/runtime/go-unsafe-new.c34
-rw-r--r--gcc-4.8.1/libgo/runtime/go-unsafe-newarray.c41
-rw-r--r--gcc-4.8.1/libgo/runtime/go-unsafe-pointer.c101
-rw-r--r--gcc-4.8.1/libgo/runtime/go-unwind.c440
-rw-r--r--gcc-4.8.1/libgo/runtime/goc2c.c676
-rw-r--r--gcc-4.8.1/libgo/runtime/iface.goc138
-rw-r--r--gcc-4.8.1/libgo/runtime/interface.h57
-rw-r--r--gcc-4.8.1/libgo/runtime/lfstack.c79
-rw-r--r--gcc-4.8.1/libgo/runtime/lock_futex.c157
-rw-r--r--gcc-4.8.1/libgo/runtime/lock_sema.c237
-rw-r--r--gcc-4.8.1/libgo/runtime/malloc.goc784
-rw-r--r--gcc-4.8.1/libgo/runtime/malloc.h508
-rw-r--r--gcc-4.8.1/libgo/runtime/map.goc72
-rw-r--r--gcc-4.8.1/libgo/runtime/map.h87
-rw-r--r--gcc-4.8.1/libgo/runtime/mcache.c129
-rw-r--r--gcc-4.8.1/libgo/runtime/mcentral.c227
-rw-r--r--gcc-4.8.1/libgo/runtime/mem.c185
-rw-r--r--gcc-4.8.1/libgo/runtime/mem_posix_memalign.c48
-rw-r--r--gcc-4.8.1/libgo/runtime/mfinal.c213
-rw-r--r--gcc-4.8.1/libgo/runtime/mfixalloc.c63
-rw-r--r--gcc-4.8.1/libgo/runtime/mgc0.c1956
-rw-r--r--gcc-4.8.1/libgo/runtime/mgc0.h42
-rw-r--r--gcc-4.8.1/libgo/runtime/mheap.c504
-rw-r--r--gcc-4.8.1/libgo/runtime/mprof.goc533
-rw-r--r--gcc-4.8.1/libgo/runtime/msize.c169
-rw-r--r--gcc-4.8.1/libgo/runtime/panic.c121
-rw-r--r--gcc-4.8.1/libgo/runtime/parfor.c232
-rw-r--r--gcc-4.8.1/libgo/runtime/print.c315
-rw-r--r--gcc-4.8.1/libgo/runtime/proc.c1815
-rw-r--r--gcc-4.8.1/libgo/runtime/race.h31
-rw-r--r--gcc-4.8.1/libgo/runtime/reflect.goc27
-rw-r--r--gcc-4.8.1/libgo/runtime/rtems-task-variable-add.c24
-rw-r--r--gcc-4.8.1/libgo/runtime/runtime.c183
-rw-r--r--gcc-4.8.1/libgo/runtime/runtime.h656
-rw-r--r--gcc-4.8.1/libgo/runtime/runtime1.goc14
-rw-r--r--gcc-4.8.1/libgo/runtime/sema.goc197
-rw-r--r--gcc-4.8.1/libgo/runtime/signal_unix.c64
-rw-r--r--gcc-4.8.1/libgo/runtime/sigqueue.goc161
-rw-r--r--gcc-4.8.1/libgo/runtime/string.goc109
-rw-r--r--gcc-4.8.1/libgo/runtime/thread-linux.c85
-rw-r--r--gcc-4.8.1/libgo/runtime/thread-sema.c148
-rw-r--r--gcc-4.8.1/libgo/runtime/thread.c182
-rw-r--r--gcc-4.8.1/libgo/runtime/time.goc263
-rw-r--r--gcc-4.8.1/libgo/runtime/yield.c52
123 files changed, 0 insertions, 20099 deletions
diff --git a/gcc-4.8.1/libgo/runtime/arch.h b/gcc-4.8.1/libgo/runtime/arch.h
deleted file mode 100644
index 0546a5da1..000000000
--- a/gcc-4.8.1/libgo/runtime/arch.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 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.
-
-// FIXME: Ideally CacheLineSize would be dependent on the host architecture.
-enum {
- CacheLineSize = 64
-};
diff --git a/gcc-4.8.1/libgo/runtime/array.h b/gcc-4.8.1/libgo/runtime/array.h
deleted file mode 100644
index 14a9bb48f..000000000
--- a/gcc-4.8.1/libgo/runtime/array.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* array.h -- the open array type for Go.
-
- 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. */
-
-#ifndef LIBGO_ARRAY_H
-#define LIBGO_ARRAY_H
-
-/* An open array is an instance of this structure. */
-
-struct __go_open_array
-{
- /* The elements of the array. In use in the compiler this is a
- pointer to the element type. */
- void* __values;
- /* The number of elements in the array. Note that this is "int",
- not "size_t". The language definition says that "int" is large
- enough to hold the size of any allocated object. Using "int"
- saves 8 bytes per slice header on a 64-bit system with 32-bit
- ints. */
- intgo __count;
- /* The capacity of the array--the number of elements that can fit in
- the __VALUES field. */
- intgo __capacity;
-};
-
-#endif /* !defined(LIBGO_ARRAY_H) */
diff --git a/gcc-4.8.1/libgo/runtime/chan.c b/gcc-4.8.1/libgo/runtime/chan.c
deleted file mode 100644
index a79ee9e18..000000000
--- a/gcc-4.8.1/libgo/runtime/chan.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "arch.h"
-#include "go-type.h"
-#include "race.h"
-#include "malloc.h"
-
-#define NOSELGEN 1
-
-static int32 debug = 0;
-
-typedef struct WaitQ WaitQ;
-typedef struct SudoG SudoG;
-typedef struct Select Select;
-typedef struct Scase Scase;
-
-typedef struct __go_type_descriptor Type;
-typedef struct __go_channel_type ChanType;
-
-struct SudoG
-{
- G* g; // g and selgen constitute
- uint32 selgen; // a weak pointer to g
- SudoG* link;
- int64 releasetime;
- byte* elem; // data element
-};
-
-struct WaitQ
-{
- SudoG* first;
- SudoG* last;
-};
-
-struct Hchan
-{
- uintgo qcount; // total data in the q
- uintgo dataqsiz; // size of the circular q
- uint16 elemsize;
- bool closed;
- uint8 elemalign;
- uintgo sendx; // send index
- uintgo recvx; // receive index
- WaitQ recvq; // list of recv waiters
- WaitQ sendq; // list of send waiters
- Lock;
-};
-
-// Buffer follows Hchan immediately in memory.
-// chanbuf(c, i) is pointer to the i'th slot in the buffer.
-#define chanbuf(c, i) ((byte*)((c)+1)+(uintptr)(c)->elemsize*(i))
-
-enum
-{
- // Scase.kind
- CaseRecv,
- CaseSend,
- CaseDefault,
-};
-
-struct Scase
-{
- SudoG sg; // must be first member (cast to Scase)
- Hchan* chan; // chan
- uint16 kind;
- uint16 index; // index to return
- bool* receivedp; // pointer to received bool (recv2)
-};
-
-struct Select
-{
- uint16 tcase; // total count of scase[]
- uint16 ncase; // currently filled scase[]
- uint16* pollorder; // case poll order
- Hchan** lockorder; // channel lock order
- Scase scase[1]; // one per case (in order of appearance)
-};
-
-static void dequeueg(WaitQ*);
-static SudoG* dequeue(WaitQ*);
-static void enqueue(WaitQ*, SudoG*);
-static void racesync(Hchan*, SudoG*);
-
-Hchan*
-runtime_makechan_c(ChanType *t, int64 hint)
-{
- Hchan *c;
- uintptr n;
- const Type *elem;
-
- elem = t->__element_type;
-
- // compiler checks this but be safe.
- if(elem->__size >= (1<<16))
- runtime_throw("makechan: invalid channel element type");
-
- if(hint < 0 || (intgo)hint != hint || (elem->__size > 0 && (uintptr)hint > MaxMem / elem->__size))
- runtime_panicstring("makechan: size out of range");
-
- n = sizeof(*c);
-
- // allocate memory in one call
- c = (Hchan*)runtime_mal(n + hint*elem->__size);
- c->elemsize = elem->__size;
- c->elemalign = elem->__align;
- c->dataqsiz = hint;
-
- if(debug)
- runtime_printf("makechan: chan=%p; elemsize=%D; elemalign=%d; dataqsiz=%D\n",
- c, (int64)elem->__size, elem->__align, (int64)c->dataqsiz);
-
- return c;
-}
-
-// For reflect
-// func makechan(typ *ChanType, size uint64) (chan)
-uintptr reflect_makechan(ChanType *, uint64)
- __asm__ (GOSYM_PREFIX "reflect.makechan");
-
-uintptr
-reflect_makechan(ChanType *t, uint64 size)
-{
- void *ret;
- Hchan *c;
-
- c = runtime_makechan_c(t, size);
- ret = runtime_mal(sizeof(void*));
- __builtin_memcpy(ret, &c, sizeof(void*));
- return (uintptr)ret;
-}
-
-// makechan(t *ChanType, hint int64) (hchan *chan any);
-Hchan*
-__go_new_channel(ChanType *t, uintptr hint)
-{
- return runtime_makechan_c(t, hint);
-}
-
-Hchan*
-__go_new_channel_big(ChanType *t, uint64 hint)
-{
- return runtime_makechan_c(t, hint);
-}
-
-/*
- * generic single channel send/recv
- * if the bool pointer is nil,
- * then the full exchange will
- * occur. if pres is not nil,
- * then the protocol will not
- * sleep but return if it could
- * not complete.
- *
- * sleep can wake up with g->param == nil
- * when a channel involved in the sleep has
- * been closed. it is easiest to loop and re-run
- * the operation; we'll see that it's now closed.
- */
-void
-runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
-{
- SudoG *sg;
- SudoG mysg;
- G* gp;
- int64 t0;
- G* g;
-
- g = runtime_g();
-
- if(c == nil) {
- USED(t);
- if(pres != nil) {
- *pres = false;
- return;
- }
- runtime_park(nil, nil, "chan send (nil chan)");
- return; // not reached
- }
-
- if(runtime_gcwaiting)
- runtime_gosched();
-
- if(debug) {
- runtime_printf("chansend: chan=%p\n", c);
- }
-
- t0 = 0;
- mysg.releasetime = 0;
- if(runtime_blockprofilerate > 0) {
- t0 = runtime_cputicks();
- mysg.releasetime = -1;
- }
-
- runtime_lock(c);
- // TODO(dvyukov): add similar instrumentation to select.
- if(raceenabled)
- runtime_racereadpc(c, pc, runtime_chansend);
- if(c->closed)
- goto closed;
-
- if(c->dataqsiz > 0)
- goto asynch;
-
- sg = dequeue(&c->recvq);
- if(sg != nil) {
- if(raceenabled)
- racesync(c, sg);
- runtime_unlock(c);
-
- gp = sg->g;
- gp->param = sg;
- if(sg->elem != nil)
- runtime_memmove(sg->elem, ep, c->elemsize);
- if(sg->releasetime)
- sg->releasetime = runtime_cputicks();
- runtime_ready(gp);
-
- if(pres != nil)
- *pres = true;
- return;
- }
-
- if(pres != nil) {
- runtime_unlock(c);
- *pres = false;
- return;
- }
-
- mysg.elem = ep;
- mysg.g = g;
- mysg.selgen = NOSELGEN;
- g->param = nil;
- enqueue(&c->sendq, &mysg);
- runtime_park(runtime_unlock, c, "chan send");
-
- if(g->param == nil) {
- runtime_lock(c);
- if(!c->closed)
- runtime_throw("chansend: spurious wakeup");
- goto closed;
- }
-
- if(mysg.releasetime > 0)
- runtime_blockevent(mysg.releasetime - t0, 2);
-
- return;
-
-asynch:
- if(c->closed)
- goto closed;
-
- if(c->qcount >= c->dataqsiz) {
- if(pres != nil) {
- runtime_unlock(c);
- *pres = false;
- return;
- }
- mysg.g = g;
- mysg.elem = nil;
- mysg.selgen = NOSELGEN;
- enqueue(&c->sendq, &mysg);
- runtime_park(runtime_unlock, c, "chan send");
-
- runtime_lock(c);
- goto asynch;
- }
-
- if(raceenabled)
- runtime_racerelease(chanbuf(c, c->sendx));
-
- runtime_memmove(chanbuf(c, c->sendx), ep, c->elemsize);
- if(++c->sendx == c->dataqsiz)
- c->sendx = 0;
- c->qcount++;
-
- sg = dequeue(&c->recvq);
- if(sg != nil) {
- gp = sg->g;
- runtime_unlock(c);
- if(sg->releasetime)
- sg->releasetime = runtime_cputicks();
- runtime_ready(gp);
- } else
- runtime_unlock(c);
- if(pres != nil)
- *pres = true;
- if(mysg.releasetime > 0)
- runtime_blockevent(mysg.releasetime - t0, 2);
- return;
-
-closed:
- runtime_unlock(c);
- runtime_panicstring("send on closed channel");
-}
-
-
-void
-runtime_chanrecv(ChanType *t, Hchan* c, byte *ep, bool *selected, bool *received)
-{
- SudoG *sg;
- SudoG mysg;
- G *gp;
- int64 t0;
- G *g;
-
- if(runtime_gcwaiting)
- runtime_gosched();
-
- if(debug)
- runtime_printf("chanrecv: chan=%p\n", c);
-
- g = runtime_g();
-
- if(c == nil) {
- USED(t);
- if(selected != nil) {
- *selected = false;
- return;
- }
- runtime_park(nil, nil, "chan receive (nil chan)");
- return; // not reached
- }
-
- t0 = 0;
- mysg.releasetime = 0;
- if(runtime_blockprofilerate > 0) {
- t0 = runtime_cputicks();
- mysg.releasetime = -1;
- }
-
- runtime_lock(c);
- if(c->dataqsiz > 0)
- goto asynch;
-
- if(c->closed)
- goto closed;
-
- sg = dequeue(&c->sendq);
- if(sg != nil) {
- if(raceenabled)
- racesync(c, sg);
- runtime_unlock(c);
-
- if(ep != nil)
- runtime_memmove(ep, sg->elem, c->elemsize);
- gp = sg->g;
- gp->param = sg;
- if(sg->releasetime)
- sg->releasetime = runtime_cputicks();
- runtime_ready(gp);
-
- if(selected != nil)
- *selected = true;
- if(received != nil)
- *received = true;
- return;
- }
-
- if(selected != nil) {
- runtime_unlock(c);
- *selected = false;
- return;
- }
-
- mysg.elem = ep;
- mysg.g = g;
- mysg.selgen = NOSELGEN;
- g->param = nil;
- enqueue(&c->recvq, &mysg);
- runtime_park(runtime_unlock, c, "chan receive");
-
- if(g->param == nil) {
- runtime_lock(c);
- if(!c->closed)
- runtime_throw("chanrecv: spurious wakeup");
- goto closed;
- }
-
- if(received != nil)
- *received = true;
- if(mysg.releasetime > 0)
- runtime_blockevent(mysg.releasetime - t0, 2);
- return;
-
-asynch:
- if(c->qcount <= 0) {
- if(c->closed)
- goto closed;
-
- if(selected != nil) {
- runtime_unlock(c);
- *selected = false;
- if(received != nil)
- *received = false;
- return;
- }
- mysg.g = g;
- mysg.elem = nil;
- mysg.selgen = NOSELGEN;
- enqueue(&c->recvq, &mysg);
- runtime_park(runtime_unlock, c, "chan receive");
-
- runtime_lock(c);
- goto asynch;
- }
-
- if(raceenabled)
- runtime_raceacquire(chanbuf(c, c->recvx));
-
- if(ep != nil)
- runtime_memmove(ep, chanbuf(c, c->recvx), c->elemsize);
- runtime_memclr(chanbuf(c, c->recvx), c->elemsize);
- if(++c->recvx == c->dataqsiz)
- c->recvx = 0;
- c->qcount--;
-
- sg = dequeue(&c->sendq);
- if(sg != nil) {
- gp = sg->g;
- runtime_unlock(c);
- if(sg->releasetime)
- sg->releasetime = runtime_cputicks();
- runtime_ready(gp);
- } else
- runtime_unlock(c);
-
- if(selected != nil)
- *selected = true;
- if(received != nil)
- *received = true;
- if(mysg.releasetime > 0)
- runtime_blockevent(mysg.releasetime - t0, 2);
- return;
-
-closed:
- if(ep != nil)
- runtime_memclr(ep, c->elemsize);
- if(selected != nil)
- *selected = true;
- if(received != nil)
- *received = false;
- if(raceenabled)
- runtime_raceacquire(c);
- runtime_unlock(c);
- if(mysg.releasetime > 0)
- runtime_blockevent(mysg.releasetime - t0, 2);
-}
-
-// The compiler generates a call to __go_send_small to send a value 8
-// bytes or smaller.
-void
-__go_send_small(ChanType *t, Hchan* c, uint64 val)
-{
- union
- {
- byte b[sizeof(uint64)];
- uint64 v;
- } u;
- byte *p;
-
- u.v = val;
-#ifndef WORDS_BIGENDIAN
- p = u.b;
-#else
- p = u.b + sizeof(uint64) - t->__element_type->__size;
-#endif
- runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t));
-}
-
-// The compiler generates a call to __go_send_big to send a value
-// larger than 8 bytes or smaller.
-void
-__go_send_big(ChanType *t, Hchan* c, byte* p)
-{
- runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t));
-}
-
-// The compiler generates a call to __go_receive_small to receive a
-// value 8 bytes or smaller.
-uint64
-__go_receive_small(ChanType *t, Hchan* c)
-{
- union {
- byte b[sizeof(uint64)];
- uint64 v;
- } u;
- byte *p;
-
- u.v = 0;
-#ifndef WORDS_BIGENDIAN
- p = u.b;
-#else
- p = u.b + sizeof(uint64) - t->__element_type->__size;
-#endif
- runtime_chanrecv(t, c, p, nil, nil);
- return u.v;
-}
-
-// The compiler generates a call to __go_receive_big to receive a
-// value larger than 8 bytes.
-void
-__go_receive_big(ChanType *t, Hchan* c, byte* p)
-{
- runtime_chanrecv(t, c, p, nil, nil);
-}
-
-_Bool runtime_chanrecv2(ChanType *t, Hchan* c, byte* p)
- __asm__ (GOSYM_PREFIX "runtime.chanrecv2");
-
-_Bool
-runtime_chanrecv2(ChanType *t, Hchan* c, byte* p)
-{
- bool received;
-
- runtime_chanrecv(t, c, p, nil, &received);
- return received;
-}
-
-// func selectnbsend(c chan any, elem any) bool
-//
-// compiler implements
-//
-// select {
-// case c <- v:
-// ... foo
-// default:
-// ... bar
-// }
-//
-// as
-//
-// if selectnbsend(c, v) {
-// ... foo
-// } else {
-// ... bar
-// }
-//
-_Bool
-runtime_selectnbsend(ChanType *t, Hchan *c, byte *p)
-{
- bool res;
-
- runtime_chansend(t, c, p, &res, runtime_getcallerpc(&t));
- return res;
-}
-
-// func selectnbrecv(elem *any, c chan any) bool
-//
-// compiler implements
-//
-// select {
-// case v = <-c:
-// ... foo
-// default:
-// ... bar
-// }
-//
-// as
-//
-// if selectnbrecv(&v, c) {
-// ... foo
-// } else {
-// ... bar
-// }
-//
-_Bool
-runtime_selectnbrecv(ChanType *t, byte *v, Hchan *c)
-{
- bool selected;
-
- runtime_chanrecv(t, c, v, &selected, nil);
- return selected;
-}
-
-// func selectnbrecv2(elem *any, ok *bool, c chan any) bool
-//
-// compiler implements
-//
-// select {
-// case v, ok = <-c:
-// ... foo
-// default:
-// ... bar
-// }
-//
-// as
-//
-// if c != nil && selectnbrecv2(&v, &ok, c) {
-// ... foo
-// } else {
-// ... bar
-// }
-//
-_Bool
-runtime_selectnbrecv2(ChanType *t, byte *v, _Bool *received, Hchan *c)
-{
- bool selected;
- bool r;
-
- r = false;
- runtime_chanrecv(t, c, v, &selected, received == nil ? nil : &r);
- if(received != nil)
- *received = r;
- return selected;
-}
-
-// For reflect:
-// func chansend(c chan, val iword, nb bool) (selected bool)
-// where an iword is the same word an interface value would use:
-// the actual data if it fits, or else a pointer to the data.
-
-_Bool reflect_chansend(ChanType *, Hchan *, uintptr, _Bool)
- __asm__ (GOSYM_PREFIX "reflect.chansend");
-
-_Bool
-reflect_chansend(ChanType *t, Hchan *c, uintptr val, _Bool nb)
-{
- bool selected;
- bool *sp;
- byte *vp;
-
- if(nb) {
- selected = false;
- sp = (bool*)&selected;
- } else {
- selected = true;
- sp = nil;
- }
- if(__go_is_pointer_type(t->__element_type))
- vp = (byte*)&val;
- else
- vp = (byte*)val;
- runtime_chansend(t, c, vp, sp, runtime_getcallerpc(&t));
- return selected;
-}
-
-// For reflect:
-// func chanrecv(c chan, nb bool) (val iword, selected, received bool)
-// where an iword is the same word an interface value would use:
-// the actual data if it fits, or else a pointer to the data.
-
-struct chanrecv_ret
-{
- uintptr val;
- _Bool selected;
- _Bool received;
-};
-
-struct chanrecv_ret reflect_chanrecv(ChanType *, Hchan *, _Bool)
- __asm__ (GOSYM_PREFIX "reflect.chanrecv");
-
-struct chanrecv_ret
-reflect_chanrecv(ChanType *t, Hchan *c, _Bool nb)
-{
- struct chanrecv_ret ret;
- byte *vp;
- bool *sp;
- bool selected;
- bool received;
-
- if(nb) {
- selected = false;
- sp = &selected;
- } else {
- ret.selected = true;
- sp = nil;
- }
- received = false;
- if(__go_is_pointer_type(t->__element_type)) {
- vp = (byte*)&ret.val;
- } else {
- vp = runtime_mal(t->__element_type->__size);
- ret.val = (uintptr)vp;
- }
- runtime_chanrecv(t, c, vp, sp, &received);
- if(nb)
- ret.selected = selected;
- ret.received = received;
- return ret;
-}
-
-static void newselect(int32, Select**);
-
-// newselect(size uint32) (sel *byte);
-
-void* runtime_newselect(int32) __asm__ (GOSYM_PREFIX "runtime.newselect");
-
-void*
-runtime_newselect(int32 size)
-{
- Select *sel;
-
- newselect(size, &sel);
- return (void*)sel;
-}
-
-static void
-newselect(int32 size, Select **selp)
-{
- int32 n;
- Select *sel;
-
- n = 0;
- if(size > 1)
- n = size-1;
-
- // allocate all the memory we need in a single allocation
- // start with Select with size cases
- // then lockorder with size entries
- // then pollorder with size entries
- sel = runtime_mal(sizeof(*sel) +
- n*sizeof(sel->scase[0]) +
- size*sizeof(sel->lockorder[0]) +
- size*sizeof(sel->pollorder[0]));
-
- sel->tcase = size;
- sel->ncase = 0;
- sel->lockorder = (void*)(sel->scase + size);
- sel->pollorder = (void*)(sel->lockorder + size);
- *selp = sel;
-
- if(debug)
- runtime_printf("newselect s=%p size=%d\n", sel, size);
-}
-
-// cut in half to give stack a chance to split
-static void selectsend(Select *sel, Hchan *c, int index, void *elem);
-
-// selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
-
-void runtime_selectsend(Select *, Hchan *, void *, int32)
- __asm__ (GOSYM_PREFIX "runtime.selectsend");
-
-void
-runtime_selectsend(Select *sel, Hchan *c, void *elem, int32 index)
-{
- // nil cases do not compete
- if(c == nil)
- return;
-
- selectsend(sel, c, index, elem);
-}
-
-static void
-selectsend(Select *sel, Hchan *c, int index, void *elem)
-{
- int32 i;
- Scase *cas;
-
- i = sel->ncase;
- if(i >= sel->tcase)
- runtime_throw("selectsend: too many cases");
- sel->ncase = i+1;
- cas = &sel->scase[i];
-
- cas->index = index;
- cas->chan = c;
- cas->kind = CaseSend;
- cas->sg.elem = elem;
-
- if(debug)
- runtime_printf("selectsend s=%p index=%d chan=%p\n",
- sel, cas->index, cas->chan);
-}
-
-// cut in half to give stack a chance to split
-static void selectrecv(Select *sel, Hchan *c, int index, void *elem, bool*);
-
-// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
-
-void runtime_selectrecv(Select *, Hchan *, void *, int32)
- __asm__ (GOSYM_PREFIX "runtime.selectrecv");
-
-void
-runtime_selectrecv(Select *sel, Hchan *c, void *elem, int32 index)
-{
- // nil cases do not compete
- if(c == nil)
- return;
-
- selectrecv(sel, c, index, elem, nil);
-}
-
-// selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool);
-
-void runtime_selectrecv2(Select *, Hchan *, void *, bool *, int32)
- __asm__ (GOSYM_PREFIX "runtime.selectrecv2");
-
-void
-runtime_selectrecv2(Select *sel, Hchan *c, void *elem, bool *received, int32 index)
-{
- // nil cases do not compete
- if(c == nil)
- return;
-
- selectrecv(sel, c, index, elem, received);
-}
-
-static void
-selectrecv(Select *sel, Hchan *c, int index, void *elem, bool *received)
-{
- int32 i;
- Scase *cas;
-
- i = sel->ncase;
- if(i >= sel->tcase)
- runtime_throw("selectrecv: too many cases");
- sel->ncase = i+1;
- cas = &sel->scase[i];
- cas->index = index;
- cas->chan = c;
-
- cas->kind = CaseRecv;
- cas->sg.elem = elem;
- cas->receivedp = received;
-
- if(debug)
- runtime_printf("selectrecv s=%p index=%d chan=%p\n",
- sel, cas->index, cas->chan);
-}
-
-// cut in half to give stack a chance to split
-static void selectdefault(Select*, int);
-
-// selectdefault(sel *byte) (selected bool);
-
-void runtime_selectdefault(Select *, int32) __asm__ (GOSYM_PREFIX "runtime.selectdefault");
-
-void
-runtime_selectdefault(Select *sel, int32 index)
-{
- selectdefault(sel, index);
-}
-
-static void
-selectdefault(Select *sel, int32 index)
-{
- int32 i;
- Scase *cas;
-
- i = sel->ncase;
- if(i >= sel->tcase)
- runtime_throw("selectdefault: too many cases");
- sel->ncase = i+1;
- cas = &sel->scase[i];
- cas->index = index;
- cas->chan = nil;
-
- cas->kind = CaseDefault;
-
- if(debug)
- runtime_printf("selectdefault s=%p index=%d\n",
- sel, cas->index);
-}
-
-static void
-sellock(Select *sel)
-{
- uint32 i;
- Hchan *c, *c0;
-
- c = nil;
- for(i=0; i<sel->ncase; i++) {
- c0 = sel->lockorder[i];
- if(c0 && c0 != c) {
- c = sel->lockorder[i];
- runtime_lock(c);
- }
- }
-}
-
-static void
-selunlock(Select *sel)
-{
- uint32 i;
- Hchan *c, *c0;
-
- c = nil;
- for(i=sel->ncase; i-->0;) {
- c0 = sel->lockorder[i];
- if(c0 && c0 != c) {
- c = c0;
- runtime_unlock(c);
- }
- }
-}
-
-void
-runtime_block(void)
-{
- runtime_park(nil, nil, "select (no cases)"); // forever
-}
-
-static int selectgo(Select**);
-
-// selectgo(sel *byte);
-
-int runtime_selectgo(Select *) __asm__ (GOSYM_PREFIX "runtime.selectgo");
-
-int
-runtime_selectgo(Select *sel)
-{
- return selectgo(&sel);
-}
-
-static int
-selectgo(Select **selp)
-{
- Select *sel;
- uint32 o, i, j;
- Scase *cas, *dfl;
- Hchan *c;
- SudoG *sg;
- G *gp;
- int index;
- G *g;
-
- sel = *selp;
- if(runtime_gcwaiting)
- runtime_gosched();
-
- if(debug)
- runtime_printf("select: sel=%p\n", sel);
-
- g = runtime_g();
-
- // The compiler rewrites selects that statically have
- // only 0 or 1 cases plus default into simpler constructs.
- // The only way we can end up with such small sel->ncase
- // values here is for a larger select in which most channels
- // have been nilled out. The general code handles those
- // cases correctly, and they are rare enough not to bother
- // optimizing (and needing to test).
-
- // generate permuted order
- for(i=0; i<sel->ncase; i++)
- sel->pollorder[i] = i;
- for(i=1; i<sel->ncase; i++) {
- o = sel->pollorder[i];
- j = runtime_fastrand1()%(i+1);
- sel->pollorder[i] = sel->pollorder[j];
- sel->pollorder[j] = o;
- }
-
- // sort the cases by Hchan address to get the locking order.
- for(i=0; i<sel->ncase; i++) {
- c = sel->scase[i].chan;
- for(j=i; j>0 && sel->lockorder[j-1] >= c; j--)
- sel->lockorder[j] = sel->lockorder[j-1];
- sel->lockorder[j] = c;
- }
- sellock(sel);
-
-loop:
- // pass 1 - look for something already waiting
- dfl = nil;
- for(i=0; i<sel->ncase; i++) {
- o = sel->pollorder[i];
- cas = &sel->scase[o];
- c = cas->chan;
-
- switch(cas->kind) {
- case CaseRecv:
- if(c->dataqsiz > 0) {
- if(c->qcount > 0)
- goto asyncrecv;
- } else {
- sg = dequeue(&c->sendq);
- if(sg != nil)
- goto syncrecv;
- }
- if(c->closed)
- goto rclose;
- break;
-
- case CaseSend:
- if(c->closed)
- goto sclose;
- if(c->dataqsiz > 0) {
- if(c->qcount < c->dataqsiz)
- goto asyncsend;
- } else {
- sg = dequeue(&c->recvq);
- if(sg != nil)
- goto syncsend;
- }
- break;
-
- case CaseDefault:
- dfl = cas;
- break;
- }
- }
-
- if(dfl != nil) {
- selunlock(sel);
- cas = dfl;
- goto retc;
- }
-
-
- // pass 2 - enqueue on all chans
- for(i=0; i<sel->ncase; i++) {
- o = sel->pollorder[i];
- cas = &sel->scase[o];
- c = cas->chan;
- sg = &cas->sg;
- sg->g = g;
- sg->selgen = g->selgen;
-
- switch(cas->kind) {
- case CaseRecv:
- enqueue(&c->recvq, sg);
- break;
-
- case CaseSend:
- enqueue(&c->sendq, sg);
- break;
- }
- }
-
- g->param = nil;
- runtime_park((void(*)(Lock*))selunlock, (Lock*)sel, "select");
-
- sellock(sel);
- sg = g->param;
-
- // pass 3 - dequeue from unsuccessful chans
- // otherwise they stack up on quiet channels
- for(i=0; i<sel->ncase; i++) {
- cas = &sel->scase[i];
- if(cas != (Scase*)sg) {
- c = cas->chan;
- if(cas->kind == CaseSend)
- dequeueg(&c->sendq);
- else
- dequeueg(&c->recvq);
- }
- }
-
- if(sg == nil)
- goto loop;
-
- cas = (Scase*)sg;
- c = cas->chan;
-
- if(c->dataqsiz > 0)
- runtime_throw("selectgo: shouldnt happen");
-
- if(debug)
- runtime_printf("wait-return: sel=%p c=%p cas=%p kind=%d\n",
- sel, c, cas, cas->kind);
-
- if(cas->kind == CaseRecv) {
- if(cas->receivedp != nil)
- *cas->receivedp = true;
- }
-
- selunlock(sel);
- goto retc;
-
-asyncrecv:
- // can receive from buffer
- if(raceenabled)
- runtime_raceacquire(chanbuf(c, c->recvx));
- if(cas->receivedp != nil)
- *cas->receivedp = true;
- if(cas->sg.elem != nil)
- runtime_memmove(cas->sg.elem, chanbuf(c, c->recvx), c->elemsize);
- runtime_memclr(chanbuf(c, c->recvx), c->elemsize);
- if(++c->recvx == c->dataqsiz)
- c->recvx = 0;
- c->qcount--;
- sg = dequeue(&c->sendq);
- if(sg != nil) {
- gp = sg->g;
- selunlock(sel);
- runtime_ready(gp);
- } else {
- selunlock(sel);
- }
- goto retc;
-
-asyncsend:
- // can send to buffer
- if(raceenabled)
- runtime_racerelease(chanbuf(c, c->sendx));
- runtime_memmove(chanbuf(c, c->sendx), cas->sg.elem, c->elemsize);
- if(++c->sendx == c->dataqsiz)
- c->sendx = 0;
- c->qcount++;
- sg = dequeue(&c->recvq);
- if(sg != nil) {
- gp = sg->g;
- selunlock(sel);
- runtime_ready(gp);
- } else {
- selunlock(sel);
- }
- goto retc;
-
-syncrecv:
- // can receive from sleeping sender (sg)
- if(raceenabled)
- racesync(c, sg);
- selunlock(sel);
- if(debug)
- runtime_printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
- if(cas->receivedp != nil)
- *cas->receivedp = true;
- if(cas->sg.elem != nil)
- runtime_memmove(cas->sg.elem, sg->elem, c->elemsize);
- gp = sg->g;
- gp->param = sg;
- runtime_ready(gp);
- goto retc;
-
-rclose:
- // read at end of closed channel
- selunlock(sel);
- if(cas->receivedp != nil)
- *cas->receivedp = false;
- if(cas->sg.elem != nil)
- runtime_memclr(cas->sg.elem, c->elemsize);
- if(raceenabled)
- runtime_raceacquire(c);
- goto retc;
-
-syncsend:
- // can send to sleeping receiver (sg)
- if(raceenabled)
- racesync(c, sg);
- selunlock(sel);
- if(debug)
- runtime_printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
- if(sg->elem != nil)
- runtime_memmove(sg->elem, cas->sg.elem, c->elemsize);
- gp = sg->g;
- gp->param = sg;
- runtime_ready(gp);
-
-retc:
- // return index corresponding to chosen case
- index = cas->index;
- runtime_free(sel);
- return index;
-
-sclose:
- // send on closed channel
- selunlock(sel);
- runtime_panicstring("send on closed channel");
- return 0; // not reached
-}
-
-// This struct must match ../reflect/value.go:/runtimeSelect.
-typedef struct runtimeSelect runtimeSelect;
-struct runtimeSelect
-{
- uintptr dir;
- ChanType *typ;
- Hchan *ch;
- uintptr val;
-};
-
-// This enum must match ../reflect/value.go:/SelectDir.
-enum SelectDir {
- SelectSend = 1,
- SelectRecv,
- SelectDefault,
-};
-
-struct rselect_ret {
- intgo chosen;
- uintptr word;
- bool recvOK;
-};
-
-// func rselect(cases []runtimeSelect) (chosen int, word uintptr, recvOK bool)
-
-struct rselect_ret reflect_rselect(Slice)
- __asm__ (GOSYM_PREFIX "reflect.rselect");
-
-struct rselect_ret
-reflect_rselect(Slice cases)
-{
- struct rselect_ret ret;
- int32 i;
- Select *sel;
- runtimeSelect* rcase, *rc;
- void *elem;
- void *recvptr;
- uintptr maxsize;
- bool onlyptr;
-
- ret.chosen = -1;
- ret.word = 0;
- ret.recvOK = false;
-
- maxsize = 0;
- onlyptr = true;
- rcase = (runtimeSelect*)cases.__values;
- for(i=0; i<cases.__count; i++) {
- rc = &rcase[i];
- if(rc->dir == SelectRecv && rc->ch != nil) {
- if(maxsize < rc->typ->__element_type->__size)
- maxsize = rc->typ->__element_type->__size;
- if(!__go_is_pointer_type(rc->typ->__element_type))
- onlyptr = false;
- }
- }
-
- recvptr = nil;
- if(!onlyptr)
- recvptr = runtime_mal(maxsize);
-
- newselect(cases.__count, &sel);
- for(i=0; i<cases.__count; i++) {
- rc = &rcase[i];
- switch(rc->dir) {
- case SelectDefault:
- selectdefault(sel, i);
- break;
- case SelectSend:
- if(rc->ch == nil)
- break;
- if(!__go_is_pointer_type(rc->typ->__element_type))
- elem = (void*)rc->val;
- else
- elem = (void*)&rc->val;
- selectsend(sel, rc->ch, i, elem);
- break;
- case SelectRecv:
- if(rc->ch == nil)
- break;
- if(!__go_is_pointer_type(rc->typ->__element_type))
- elem = recvptr;
- else
- elem = &ret.word;
- selectrecv(sel, rc->ch, i, elem, &ret.recvOK);
- break;
- }
- }
-
- ret.chosen = (intgo)(uintptr)selectgo(&sel);
- if(rcase[ret.chosen].dir == SelectRecv && !__go_is_pointer_type(rcase[ret.chosen].typ->__element_type))
- ret.word = (uintptr)recvptr;
-
- return ret;
-}
-
-// closechan(sel *byte);
-void
-runtime_closechan(Hchan *c)
-{
- SudoG *sg;
- G* gp;
-
- if(c == nil)
- runtime_panicstring("close of nil channel");
-
- if(runtime_gcwaiting)
- runtime_gosched();
-
- runtime_lock(c);
- if(c->closed) {
- runtime_unlock(c);
- runtime_panicstring("close of closed channel");
- }
-
- if(raceenabled) {
- runtime_racewritepc(c, runtime_getcallerpc(&c), runtime_closechan);
- runtime_racerelease(c);
- }
-
- c->closed = true;
-
- // release all readers
- for(;;) {
- sg = dequeue(&c->recvq);
- if(sg == nil)
- break;
- gp = sg->g;
- gp->param = nil;
- runtime_ready(gp);
- }
-
- // release all writers
- for(;;) {
- sg = dequeue(&c->sendq);
- if(sg == nil)
- break;
- gp = sg->g;
- gp->param = nil;
- runtime_ready(gp);
- }
-
- runtime_unlock(c);
-}
-
-void
-__go_builtin_close(Hchan *c)
-{
- runtime_closechan(c);
-}
-
-// For reflect
-// func chanclose(c chan)
-
-void reflect_chanclose(uintptr) __asm__ (GOSYM_PREFIX "reflect.chanclose");
-
-void
-reflect_chanclose(uintptr c)
-{
- runtime_closechan((Hchan*)c);
-}
-
-// For reflect
-// func chanlen(c chan) (len int)
-
-intgo reflect_chanlen(uintptr) __asm__ (GOSYM_PREFIX "reflect.chanlen");
-
-intgo
-reflect_chanlen(uintptr ca)
-{
- Hchan *c;
- intgo len;
-
- c = (Hchan*)ca;
- if(c == nil)
- len = 0;
- else
- len = c->qcount;
- return len;
-}
-
-intgo
-__go_chan_len(Hchan *c)
-{
- return reflect_chanlen((uintptr)c);
-}
-
-// For reflect
-// func chancap(c chan) (cap intgo)
-
-intgo reflect_chancap(uintptr) __asm__ (GOSYM_PREFIX "reflect.chancap");
-
-intgo
-reflect_chancap(uintptr ca)
-{
- Hchan *c;
- intgo cap;
-
- c = (Hchan*)ca;
- if(c == nil)
- cap = 0;
- else
- cap = c->dataqsiz;
- return cap;
-}
-
-intgo
-__go_chan_cap(Hchan *c)
-{
- return reflect_chancap((uintptr)c);
-}
-
-static SudoG*
-dequeue(WaitQ *q)
-{
- SudoG *sgp;
-
-loop:
- sgp = q->first;
- if(sgp == nil)
- return nil;
- q->first = sgp->link;
-
- // if sgp is stale, ignore it
- if(sgp->selgen != NOSELGEN &&
- (sgp->selgen != sgp->g->selgen ||
- !runtime_cas(&sgp->g->selgen, sgp->selgen, sgp->selgen + 2))) {
- //prints("INVALID PSEUDOG POINTER\n");
- goto loop;
- }
-
- return sgp;
-}
-
-static void
-dequeueg(WaitQ *q)
-{
- SudoG **l, *sgp, *prevsgp;
- G *g;
-
- g = runtime_g();
- prevsgp = nil;
- for(l=&q->first; (sgp=*l) != nil; l=&sgp->link, prevsgp=sgp) {
- if(sgp->g == g) {
- *l = sgp->link;
- if(q->last == sgp)
- q->last = prevsgp;
- break;
- }
- }
-}
-
-static void
-enqueue(WaitQ *q, SudoG *sgp)
-{
- sgp->link = nil;
- if(q->first == nil) {
- q->first = sgp;
- q->last = sgp;
- return;
- }
- q->last->link = sgp;
- q->last = sgp;
-}
-
-static void
-racesync(Hchan *c, SudoG *sg)
-{
- runtime_racerelease(chanbuf(c, 0));
- runtime_raceacquireg(sg->g, chanbuf(c, 0));
- runtime_racereleaseg(sg->g, chanbuf(c, 0));
- runtime_raceacquire(chanbuf(c, 0));
-}
diff --git a/gcc-4.8.1/libgo/runtime/cpuprof.c b/gcc-4.8.1/libgo/runtime/cpuprof.c
deleted file mode 100644
index 3ef08ef51..000000000
--- a/gcc-4.8.1/libgo/runtime/cpuprof.c
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright 2011 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.
-
-// CPU profiling.
-// Based on algorithms and data structures used in
-// http://code.google.com/p/google-perftools/.
-//
-// The main difference between this code and the google-perftools
-// code is that this code is written to allow copying the profile data
-// to an arbitrary io.Writer, while the google-perftools code always
-// writes to an operating system file.
-//
-// The signal handler for the profiling clock tick adds a new stack trace
-// to a hash table tracking counts for recent traces. Most clock ticks
-// hit in the cache. In the event of a cache miss, an entry must be
-// evicted from the hash table, copied to a log that will eventually be
-// written as profile data. The google-perftools code flushed the
-// log itself during the signal handler. This code cannot do that, because
-// the io.Writer might block or need system calls or locks that are not
-// safe to use from within the signal handler. Instead, we split the log
-// into two halves and let the signal handler fill one half while a goroutine
-// is writing out the other half. When the signal handler fills its half, it
-// offers to swap with the goroutine. If the writer is not done with its half,
-// we lose the stack trace for this clock tick (and record that loss).
-// The goroutine interacts with the signal handler by calling getprofile() to
-// get the next log piece to write, implicitly handing back the last log
-// piece it obtained.
-//
-// The state of this dance between the signal handler and the goroutine
-// is encoded in the Profile.handoff field. If handoff == 0, then the goroutine
-// is not using either log half and is waiting (or will soon be waiting) for
-// a new piece by calling notesleep(&p->wait). If the signal handler
-// changes handoff from 0 to non-zero, it must call notewakeup(&p->wait)
-// to wake the goroutine. The value indicates the number of entries in the
-// log half being handed off. The goroutine leaves the non-zero value in
-// place until it has finished processing the log half and then flips the number
-// back to zero. Setting the high bit in handoff means that the profiling is over,
-// and the goroutine is now in charge of flushing the data left in the hash table
-// to the log and returning that data.
-//
-// The handoff field is manipulated using atomic operations.
-// For the most part, the manipulation of handoff is orderly: if handoff == 0
-// then the signal handler owns it and can change it to non-zero.
-// If handoff != 0 then the goroutine owns it and can change it to zero.
-// If that were the end of the story then we would not need to manipulate
-// handoff using atomic operations. The operations are needed, however,
-// in order to let the log closer set the high bit to indicate "EOF" safely
-// in the situation when normally the goroutine "owns" handoff.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-#include "array.h"
-typedef struct __go_open_array Slice;
-#define array __values
-#define len __count
-#define cap __capacity
-
-enum
-{
- HashSize = 1<<10,
- LogSize = 1<<17,
- Assoc = 4,
- MaxStack = 64,
-};
-
-typedef struct Profile Profile;
-typedef struct Bucket Bucket;
-typedef struct Entry Entry;
-
-struct Entry {
- uintptr count;
- uintptr depth;
- uintptr stack[MaxStack];
-};
-
-struct Bucket {
- Entry entry[Assoc];
-};
-
-struct Profile {
- bool on; // profiling is on
- Note wait; // goroutine waits here
- uintptr count; // tick count
- uintptr evicts; // eviction count
- uintptr lost; // lost ticks that need to be logged
- uintptr totallost; // total lost ticks
-
- // Active recent stack traces.
- Bucket hash[HashSize];
-
- // Log of traces evicted from hash.
- // Signal handler has filled log[toggle][:nlog].
- // Goroutine is writing log[1-toggle][:handoff].
- uintptr log[2][LogSize/2];
- uintptr nlog;
- int32 toggle;
- uint32 handoff;
-
- // Writer state.
- // Writer maintains its own toggle to avoid races
- // looking at signal handler's toggle.
- uint32 wtoggle;
- bool wholding; // holding & need to release a log half
- bool flushing; // flushing hash table - profile is over
- bool eod_sent; // special end-of-data record sent; => flushing
-};
-
-static Lock lk;
-static Profile *prof;
-
-static void tick(uintptr*, int32);
-static void add(Profile*, uintptr*, int32);
-static bool evict(Profile*, Entry*);
-static bool flushlog(Profile*);
-
-static uintptr eod[3] = {0, 1, 0};
-
-// LostProfileData is a no-op function used in profiles
-// to mark the number of profiling stack traces that were
-// discarded due to slow data writers.
-static void LostProfileData(void) {
-}
-
-extern void runtime_SetCPUProfileRate(intgo)
- __asm__ (GOSYM_PREFIX "runtime.SetCPUProfileRate");
-
-// SetCPUProfileRate sets the CPU profiling rate.
-// The user documentation is in debug.go.
-void
-runtime_SetCPUProfileRate(intgo hz)
-{
- uintptr *p;
- uintptr n;
-
- // Clamp hz to something reasonable.
- if(hz < 0)
- hz = 0;
- if(hz > 1000000)
- hz = 1000000;
-
- runtime_lock(&lk);
- if(hz > 0) {
- if(prof == nil) {
- prof = runtime_SysAlloc(sizeof *prof);
- if(prof == nil) {
- runtime_printf("runtime: cpu profiling cannot allocate memory\n");
- runtime_unlock(&lk);
- return;
- }
- }
- if(prof->on || prof->handoff != 0) {
- runtime_printf("runtime: cannot set cpu profile rate until previous profile has finished.\n");
- runtime_unlock(&lk);
- return;
- }
-
- prof->on = true;
- p = prof->log[0];
- // pprof binary header format.
- // http://code.google.com/p/google-perftools/source/browse/trunk/src/profiledata.cc#117
- *p++ = 0; // count for header
- *p++ = 3; // depth for header
- *p++ = 0; // version number
- *p++ = 1000000 / hz; // period (microseconds)
- *p++ = 0;
- prof->nlog = p - prof->log[0];
- prof->toggle = 0;
- prof->wholding = false;
- prof->wtoggle = 0;
- prof->flushing = false;
- prof->eod_sent = false;
- runtime_noteclear(&prof->wait);
-
- runtime_setcpuprofilerate(tick, hz);
- } else if(prof->on) {
- runtime_setcpuprofilerate(nil, 0);
- prof->on = false;
-
- // Now add is not running anymore, and getprofile owns the entire log.
- // Set the high bit in prof->handoff to tell getprofile.
- for(;;) {
- n = prof->handoff;
- if(n&0x80000000)
- runtime_printf("runtime: setcpuprofile(off) twice");
- if(runtime_cas(&prof->handoff, n, n|0x80000000))
- break;
- }
- if(n == 0) {
- // we did the transition from 0 -> nonzero so we wake getprofile
- runtime_notewakeup(&prof->wait);
- }
- }
- runtime_unlock(&lk);
-}
-
-static void
-tick(uintptr *pc, int32 n)
-{
- add(prof, pc, n);
-}
-
-// add adds the stack trace to the profile.
-// It is called from signal handlers and other limited environments
-// and cannot allocate memory or acquire locks that might be
-// held at the time of the signal, nor can it use substantial amounts
-// of stack. It is allowed to call evict.
-static void
-add(Profile *p, uintptr *pc, int32 n)
-{
- int32 i, j;
- uintptr h, x;
- Bucket *b;
- Entry *e;
-
- if(n > MaxStack)
- n = MaxStack;
-
- // Compute hash.
- h = 0;
- for(i=0; i<n; i++) {
- h = h<<8 | (h>>(8*(sizeof(h)-1)));
- x = pc[i];
- h += x*31 + x*7 + x*3;
- }
- p->count++;
-
- // Add to entry count if already present in table.
- b = &p->hash[h%HashSize];
- for(i=0; i<Assoc; i++) {
- e = &b->entry[i];
- if(e->depth != (uintptr)n)
- continue;
- for(j=0; j<n; j++)
- if(e->stack[j] != pc[j])
- goto ContinueAssoc;
- e->count++;
- return;
- ContinueAssoc:;
- }
-
- // Evict entry with smallest count.
- e = &b->entry[0];
- for(i=1; i<Assoc; i++)
- if(b->entry[i].count < e->count)
- e = &b->entry[i];
- if(e->count > 0) {
- if(!evict(p, e)) {
- // Could not evict entry. Record lost stack.
- p->lost++;
- p->totallost++;
- return;
- }
- p->evicts++;
- }
-
- // Reuse the newly evicted entry.
- e->depth = n;
- e->count = 1;
- for(i=0; i<n; i++)
- e->stack[i] = pc[i];
-}
-
-// evict copies the given entry's data into the log, so that
-// the entry can be reused. evict is called from add, which
-// is called from the profiling signal handler, so it must not
-// allocate memory or block. It is safe to call flushLog.
-// evict returns true if the entry was copied to the log,
-// false if there was no room available.
-static bool
-evict(Profile *p, Entry *e)
-{
- int32 i, d, nslot;
- uintptr *log, *q;
-
- d = e->depth;
- nslot = d+2;
- log = p->log[p->toggle];
- if(p->nlog+nslot > nelem(p->log[0])) {
- if(!flushlog(p))
- return false;
- log = p->log[p->toggle];
- }
-
- q = log+p->nlog;
- *q++ = e->count;
- *q++ = d;
- for(i=0; i<d; i++)
- *q++ = e->stack[i];
- p->nlog = q - log;
- e->count = 0;
- return true;
-}
-
-// flushlog tries to flush the current log and switch to the other one.
-// flushlog is called from evict, called from add, called from the signal handler,
-// so it cannot allocate memory or block. It can try to swap logs with
-// the writing goroutine, as explained in the comment at the top of this file.
-static bool
-flushlog(Profile *p)
-{
- uintptr *log, *q;
-
- if(!runtime_cas(&p->handoff, 0, p->nlog))
- return false;
- runtime_notewakeup(&p->wait);
-
- p->toggle = 1 - p->toggle;
- log = p->log[p->toggle];
- q = log;
- if(p->lost > 0) {
- *q++ = p->lost;
- *q++ = 1;
- *q++ = (uintptr)LostProfileData;
- }
- p->nlog = q - log;
- return true;
-}
-
-// getprofile blocks until the next block of profiling data is available
-// and returns it as a []byte. It is called from the writing goroutine.
-Slice
-getprofile(Profile *p)
-{
- uint32 i, j, n;
- Slice ret;
- Bucket *b;
- Entry *e;
-
- ret.array = nil;
- ret.len = 0;
- ret.cap = 0;
-
- if(p == nil)
- return ret;
-
- if(p->wholding) {
- // Release previous log to signal handling side.
- // Loop because we are racing against setprofile(off).
- for(;;) {
- n = p->handoff;
- if(n == 0) {
- runtime_printf("runtime: phase error during cpu profile handoff\n");
- return ret;
- }
- if(n & 0x80000000) {
- p->wtoggle = 1 - p->wtoggle;
- p->wholding = false;
- p->flushing = true;
- goto flush;
- }
- if(runtime_cas(&p->handoff, n, 0))
- break;
- }
- p->wtoggle = 1 - p->wtoggle;
- p->wholding = false;
- }
-
- if(p->flushing)
- goto flush;
-
- if(!p->on && p->handoff == 0)
- return ret;
-
- // Wait for new log.
- runtime_entersyscall();
- runtime_notesleep(&p->wait);
- runtime_exitsyscall();
- runtime_noteclear(&p->wait);
-
- n = p->handoff;
- if(n == 0) {
- runtime_printf("runtime: phase error during cpu profile wait\n");
- return ret;
- }
- if(n == 0x80000000) {
- p->flushing = true;
- goto flush;
- }
- n &= ~0x80000000;
-
- // Return new log to caller.
- p->wholding = true;
-
- ret.array = (byte*)p->log[p->wtoggle];
- ret.len = n*sizeof(uintptr);
- ret.cap = ret.len;
- return ret;
-
-flush:
- // In flush mode.
- // Add is no longer being called. We own the log.
- // Also, p->handoff is non-zero, so flushlog will return false.
- // Evict the hash table into the log and return it.
- for(i=0; i<HashSize; i++) {
- b = &p->hash[i];
- for(j=0; j<Assoc; j++) {
- e = &b->entry[j];
- if(e->count > 0 && !evict(p, e)) {
- // Filled the log. Stop the loop and return what we've got.
- goto breakflush;
- }
- }
- }
-breakflush:
-
- // Return pending log data.
- if(p->nlog > 0) {
- // Note that we're using toggle now, not wtoggle,
- // because we're working on the log directly.
- ret.array = (byte*)p->log[p->toggle];
- ret.len = p->nlog*sizeof(uintptr);
- ret.cap = ret.len;
- p->nlog = 0;
- return ret;
- }
-
- // Made it through the table without finding anything to log.
- if(!p->eod_sent) {
- // We may not have space to append this to the partial log buf,
- // so we always return a new slice for the end-of-data marker.
- p->eod_sent = true;
- ret.array = (byte*)eod;
- ret.len = sizeof eod;
- ret.cap = ret.len;
- return ret;
- }
-
- // Finally done. Clean up and return nil.
- p->flushing = false;
- if(!runtime_cas(&p->handoff, p->handoff, 0))
- runtime_printf("runtime: profile flush racing with something\n");
- return ret; // set to nil at top of function
-}
-
-extern Slice runtime_CPUProfile(void)
- __asm__ (GOSYM_PREFIX "runtime.CPUProfile");
-
-// CPUProfile returns the next cpu profile block as a []byte.
-// The user documentation is in debug.go.
-Slice
-runtime_CPUProfile(void)
-{
- return getprofile(prof);
-}
diff --git a/gcc-4.8.1/libgo/runtime/defs.h b/gcc-4.8.1/libgo/runtime/defs.h
deleted file mode 100644
index 67ad212b8..000000000
--- a/gcc-4.8.1/libgo/runtime/defs.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* defs.h -- runtime definitions for Go.
-
- 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. */
-
-/* The gc library uses this file for system defines, and generates it
- automatically using the godefs program. The logical thing to put
- here for gccgo would be #include statements for system header
- files. We can't do that, though, because runtime.h #define's the
- standard types. So we #include the system headers from runtime.h
- instead. */
diff --git a/gcc-4.8.1/libgo/runtime/env_posix.c b/gcc-4.8.1/libgo/runtime/env_posix.c
deleted file mode 100644
index 7f3fa0d8e..000000000
--- a/gcc-4.8.1/libgo/runtime/env_posix.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2012 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.
-
-// +build darwin freebsd linux netbsd openbsd windows
-
-#include "runtime.h"
-#include "array.h"
-
-extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
-
-const byte*
-runtime_getenv(const char *s)
-{
- int32 i, j, len;
- const byte *v, *bs;
- String* envv;
- int32 envc;
-
- bs = (const byte*)s;
- len = runtime_findnull(bs);
- envv = (String*)syscall_Envs.__values;
- envc = syscall_Envs.__count;
- for(i=0; i<envc; i++){
- if(envv[i].len <= len)
- continue;
- v = (const byte*)envv[i].str;
- for(j=0; j<len; j++)
- if(bs[j] != v[j])
- goto nomatch;
- if(v[len] != '=')
- goto nomatch;
- return v+len+1;
- nomatch:;
- }
- return nil;
-}
diff --git a/gcc-4.8.1/libgo/runtime/getncpu-bsd.c b/gcc-4.8.1/libgo/runtime/getncpu-bsd.c
deleted file mode 100644
index 00a81d1dd..000000000
--- a/gcc-4.8.1/libgo/runtime/getncpu-bsd.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 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.
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int mib[2], out;
- size_t len;
-
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(out);
- if(sysctl(mib, 2, &out, &len, NULL, 0) >= 0)
- return (int32)out;
- else
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/getncpu-irix.c b/gcc-4.8.1/libgo/runtime/getncpu-irix.c
deleted file mode 100644
index a65ca63d2..000000000
--- a/gcc-4.8.1/libgo/runtime/getncpu-irix.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 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.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int32 n;
- n = (int32)sysconf(_SC_NPROC_ONLN);
- return n > 1 ? n : 1;
-}
diff --git a/gcc-4.8.1/libgo/runtime/getncpu-linux.c b/gcc-4.8.1/libgo/runtime/getncpu-linux.c
deleted file mode 100644
index 0122b77c9..000000000
--- a/gcc-4.8.1/libgo/runtime/getncpu-linux.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 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.
-
-#include <features.h>
-#include <sched.h>
-
-// CPU_COUNT is only provided by glibc 2.6 or higher
-#if !defined(__GLIBC_PREREQ) || !__GLIBC_PREREQ(2, 6)
-#define CPU_COUNT(set) _CPU_COUNT((unsigned int *)(set), sizeof(*(set))/sizeof(unsigned int))
-static int _CPU_COUNT(unsigned int *set, size_t len) {
- int cnt;
-
- cnt = 0;
- while (len--)
- cnt += __builtin_popcount(*set++);
- return cnt;
-}
-#endif
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- cpu_set_t set;
- int32 r, cnt;
-
- cnt = 0;
- r = sched_getaffinity(0, sizeof(set), &set);
- if(r == 0)
- cnt += CPU_COUNT(&set);
-
- return cnt ? cnt : 1;
-}
diff --git a/gcc-4.8.1/libgo/runtime/getncpu-none.c b/gcc-4.8.1/libgo/runtime/getncpu-none.c
deleted file mode 100644
index ba6fd4e68..000000000
--- a/gcc-4.8.1/libgo/runtime/getncpu-none.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 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.
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/getncpu-solaris.c b/gcc-4.8.1/libgo/runtime/getncpu-solaris.c
deleted file mode 100644
index 5d5d7025d..000000000
--- a/gcc-4.8.1/libgo/runtime/getncpu-solaris.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 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.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int32 n;
- n = (int32)sysconf(_SC_NPROCESSORS_ONLN);
- return n > 1 ? n : 1;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-alloc.h b/gcc-4.8.1/libgo/runtime/go-alloc.h
deleted file mode 100644
index c880a043e..000000000
--- a/gcc-4.8.1/libgo/runtime/go-alloc.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* go-alloc.h -- allocate memory for Go.
-
- 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. */
-
-#include <stddef.h>
-#include <stdint.h>
-
-extern void *__go_alloc (unsigned int __attribute__ ((mode (pointer))));
-extern void __go_free (void *);
diff --git a/gcc-4.8.1/libgo/runtime/go-append.c b/gcc-4.8.1/libgo/runtime/go-append.c
deleted file mode 100644
index 12fe876cb..000000000
--- a/gcc-4.8.1/libgo/runtime/go-append.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* go-append.c -- the go builtin append function.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-panic.h"
-#include "go-type.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-/* We should be OK if we don't split the stack here, since the only
- libc functions we call are memcpy and memmove. If we don't do
- this, we will always split the stack, because of memcpy and
- memmove. */
-extern struct __go_open_array
-__go_append (struct __go_open_array, void *, uintptr_t, uintptr_t)
- __attribute__ ((no_split_stack));
-
-struct __go_open_array
-__go_append (struct __go_open_array a, void *bvalues, uintptr_t bcount,
- uintptr_t element_size)
-{
- uintptr_t ucount;
- int count;
-
- if (bvalues == NULL || bcount == 0)
- return a;
-
- ucount = (uintptr_t) a.__count + bcount;
- count = (int) ucount;
- if ((uintptr_t) count != ucount || count <= a.__count)
- runtime_panicstring ("append: slice overflow");
-
- if (count > a.__capacity)
- {
- int m;
- void *n;
-
- m = a.__capacity;
- if (m == 0)
- m = (int) bcount;
- else
- {
- do
- {
- if (a.__count < 1024)
- m += m;
- else
- m += m / 4;
- }
- while (m < count);
- }
-
- if ((uintptr) m > MaxMem / element_size)
- runtime_panicstring ("growslice: cap out of range");
-
- n = __go_alloc (m * element_size);
- __builtin_memcpy (n, a.__values, a.__count * element_size);
-
- a.__values = n;
- a.__capacity = m;
- }
-
- __builtin_memmove ((char *) a.__values + a.__count * element_size,
- bvalues, bcount * element_size);
- a.__count = count;
- return a;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-assert-interface.c b/gcc-4.8.1/libgo/runtime/go-assert-interface.c
deleted file mode 100644
index 2510f9aef..000000000
--- a/gcc-4.8.1/libgo/runtime/go-assert-interface.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* go-assert-interface.c -- interface type assertion for Go.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "go-panic.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* This is called by the compiler to implement a type assertion from
- one interface type to another. This returns the value that should
- go in the first field of the result tuple. The result may be an
- empty or a non-empty interface. */
-
-const void *
-__go_assert_interface (const struct __go_type_descriptor *lhs_descriptor,
- const struct __go_type_descriptor *rhs_descriptor)
-{
- const struct __go_interface_type *lhs_interface;
-
- if (rhs_descriptor == NULL)
- {
- struct __go_empty_interface panic_arg;
-
- /* A type assertion is not permitted with a nil interface. */
-
- runtime_newTypeAssertionError (NULL, NULL, lhs_descriptor->__reflection,
- NULL, &panic_arg);
- __go_panic (panic_arg);
- }
-
- /* A type assertion to an empty interface just returns the object
- descriptor. */
-
- __go_assert (lhs_descriptor->__code == GO_INTERFACE);
- lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
- if (lhs_interface->__methods.__count == 0)
- return rhs_descriptor;
-
- return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-assert.c b/gcc-4.8.1/libgo/runtime/go-assert.c
deleted file mode 100644
index a36f43a75..000000000
--- a/gcc-4.8.1/libgo/runtime/go-assert.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* go-assert.c -- libgo specific assertions
-
- Copyright 2010 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. */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "go-assert.h"
-
-void
-__go_assert_fail (const char *file, unsigned int lineno)
-{
- /* FIXME: Eventually we should dump a stack trace here. */
- runtime_printf ("%s:%U: libgo assertion failure\n", file, (uint64) lineno);
- abort ();
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-assert.h b/gcc-4.8.1/libgo/runtime/go-assert.h
deleted file mode 100644
index 636559597..000000000
--- a/gcc-4.8.1/libgo/runtime/go-assert.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* go-assert.h -- libgo specific assertions
-
- Copyright 2010 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. */
-
-#ifndef LIBGO_GO_ASSERT_H
-#define LIBGO_GO_ASSERT_H
-
-/* We use a Go specific assert function so that functions which call
- assert aren't required to always split the stack. */
-
-extern void __go_assert_fail (const char *file, unsigned int lineno)
- __attribute__ ((noreturn));
-
-#define __go_assert(e) ((e) ? (void) 0 : __go_assert_fail (__FILE__, __LINE__))
-
-#endif /* !defined(LIBGO_GO_ASSERT_H) */
diff --git a/gcc-4.8.1/libgo/runtime/go-breakpoint.c b/gcc-4.8.1/libgo/runtime/go-breakpoint.c
deleted file mode 100644
index e403a2a96..000000000
--- a/gcc-4.8.1/libgo/runtime/go-breakpoint.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* go-breakpoint.c -- the runtime.Breakpoint function.
-
- 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. */
-
-#include <sched.h>
-
-#include "runtime.h"
-
-void Breakpoint (void) __asm__ (GOSYM_PREFIX "runtime.Breakpoint");
-
-void
-Breakpoint (void)
-{
- __builtin_trap ();
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-byte-array-to-string.c b/gcc-4.8.1/libgo/runtime/go-byte-array-to-string.c
deleted file mode 100644
index 0cd63c76d..000000000
--- a/gcc-4.8.1/libgo/runtime/go-byte-array-to-string.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* go-byte-array-to-string.c -- convert an array of bytes to a string in Go.
-
- 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. */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_byte_array_to_string (const void* p, intgo len)
-{
- const unsigned char *bytes;
- unsigned char *retdata;
- String ret;
-
- bytes = (const unsigned char *) p;
- retdata = runtime_mallocgc ((uintptr) len, FlagNoPointers, 1, 0);
- __builtin_memcpy (retdata, bytes, len);
- ret.str = retdata;
- ret.len = len;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-caller.c b/gcc-4.8.1/libgo/runtime/go-caller.c
deleted file mode 100644
index d84580fa5..000000000
--- a/gcc-4.8.1/libgo/runtime/go-caller.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* go-caller.c -- runtime.Caller and runtime.FuncForPC for Go.
-
- 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. */
-
-/* Implement runtime.Caller. */
-
-#include <stdint.h>
-
-#include "backtrace.h"
-
-#include "runtime.h"
-
-/* Get the function name, file name, and line number for a PC value.
- We use the backtrace library to get this. */
-
-/* Data structure to gather file/line information. */
-
-struct caller
-{
- String fn;
- String file;
- intgo line;
-};
-
-/* Collect file/line information for a PC value. If this is called
- more than once, due to inlined functions, we use the last call, as
- that is usually the most useful one. */
-
-static int
-callback (void *data, uintptr_t pc __attribute__ ((unused)),
- const char *filename, int lineno, const char *function)
-{
- struct caller *c = (struct caller *) data;
-
- if (function == NULL)
- {
- c->fn.str = NULL;
- c->fn.len = 0;
- }
- else
- {
- byte *s;
-
- c->fn.len = __builtin_strlen (function);
- s = runtime_malloc (c->fn.len);
- __builtin_memcpy (s, function, c->fn.len);
- c->fn.str = s;
- }
-
- if (filename == NULL)
- {
- c->file.str = NULL;
- c->file.len = 0;
- }
- else
- {
- byte *s;
-
- c->file.len = __builtin_strlen (filename);
- s = runtime_malloc (c->file.len);
- __builtin_memcpy (s, filename, c->file.len);
- c->file.str = s;
- }
-
- c->line = lineno;
-
- return 0;
-}
-
-/* The error callback for backtrace_pcinfo and backtrace_syminfo. */
-
-static void
-error_callback (void *data __attribute__ ((unused)),
- const char *msg, int errnum)
-{
- if (errnum == -1)
- return;
- if (errnum > 0)
- runtime_printf ("%s errno %d\n", msg, errnum);
- runtime_throw (msg);
-}
-
-/* The backtrace library state. */
-
-static void *back_state;
-
-/* A lock to control creating back_state. */
-
-static Lock back_state_lock;
-
-/* Fetch back_state, creating it if necessary. */
-
-struct backtrace_state *
-__go_get_backtrace_state ()
-{
- runtime_lock (&back_state_lock);
- if (back_state == NULL)
- {
- const char *filename;
-
- filename = (const char *) runtime_progname ();
- back_state = backtrace_create_state (filename, 1, error_callback, NULL);
- }
- runtime_unlock (&back_state_lock);
- return back_state;
-}
-
-/* Return function/file/line information for PC. */
-
-_Bool
-__go_file_line (uintptr pc, String *fn, String *file, intgo *line)
-{
- struct caller c;
-
- runtime_memclr (&c, sizeof c);
- backtrace_pcinfo (__go_get_backtrace_state (), pc, callback,
- error_callback, &c);
- *fn = c.fn;
- *file = c.file;
- *line = c.line;
- return c.file.len > 0;
-}
-
-/* Collect symbol information. */
-
-static void
-syminfo_callback (void *data, uintptr_t pc __attribute__ ((unused)),
- const char *symname __attribute__ ((unused)),
- uintptr_t address)
-{
- uintptr_t *pval = (uintptr_t *) data;
-
- *pval = address;
-}
-
-/* Set *VAL to the value of the symbol for PC. */
-
-static _Bool
-__go_symbol_value (uintptr_t pc, uintptr_t *val)
-{
- *val = 0;
- backtrace_syminfo (__go_get_backtrace_state (), pc, syminfo_callback,
- error_callback, val);
- return *val != 0;
-}
-
-/* The values returned by runtime.Caller. */
-
-struct caller_ret
-{
- uintptr_t pc;
- String file;
- intgo line;
- _Bool ok;
-};
-
-struct caller_ret Caller (int n) __asm__ (GOSYM_PREFIX "runtime.Caller");
-
-Func *FuncForPC (uintptr_t) __asm__ (GOSYM_PREFIX "runtime.FuncForPC");
-
-/* Implement runtime.Caller. */
-
-struct caller_ret
-Caller (int skip)
-{
- struct caller_ret ret;
- Location loc;
- int32 n;
-
- runtime_memclr (&ret, sizeof ret);
- n = runtime_callers (skip + 1, &loc, 1);
- if (n < 1)
- return ret;
- ret.pc = loc.pc;
- ret.file = loc.filename;
- ret.line = loc.lineno;
- ret.ok = 1;
- return ret;
-}
-
-/* Implement runtime.FuncForPC. */
-
-Func *
-FuncForPC (uintptr_t pc)
-{
- Func *ret;
- String fn;
- String file;
- intgo line;
- uintptr_t val;
-
- if (!__go_file_line (pc, &fn, &file, &line))
- return NULL;
-
- ret = (Func *) runtime_malloc (sizeof (*ret));
- ret->name = fn;
-
- if (__go_symbol_value (pc, &val))
- ret->entry = val;
- else
- ret->entry = 0;
-
- return ret;
-}
-
-/* Look up the file and line information for a PC within a
- function. */
-
-struct funcline_go_return
-{
- String retfile;
- intgo retline;
-};
-
-struct funcline_go_return
-runtime_funcline_go (Func *f, uintptr targetpc)
- __asm__ (GOSYM_PREFIX "runtime.funcline_go");
-
-struct funcline_go_return
-runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
-{
- struct funcline_go_return ret;
- String fn;
-
- if (!__go_file_line (targetpc, &fn, &ret.retfile, &ret.retline))
- runtime_memclr (&ret, sizeof ret);
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-callers.c b/gcc-4.8.1/libgo/runtime/go-callers.c
deleted file mode 100644
index dd1cf7909..000000000
--- a/gcc-4.8.1/libgo/runtime/go-callers.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* go-callers.c -- get callers for Go.
-
- Copyright 2012 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. */
-
-#include "config.h"
-
-#include "backtrace.h"
-
-#include "runtime.h"
-#include "array.h"
-
-/* Argument passed to callback function. */
-
-struct callers_data
-{
- Location *locbuf;
- int skip;
- int index;
- int max;
-};
-
-/* Callback function for backtrace_full. Just collect the locations.
- Return zero to continue, non-zero to stop. */
-
-static int
-callback (void *data, uintptr_t pc, const char *filename, int lineno,
- const char *function)
-{
- struct callers_data *arg = (struct callers_data *) data;
- Location *loc;
-
- /* Skip split stack functions. */
- if (function != NULL)
- {
- const char *p;
-
- p = function;
- if (__builtin_strncmp (p, "___", 3) == 0)
- ++p;
- if (__builtin_strncmp (p, "__morestack_", 12) == 0)
- return 0;
- }
- else if (filename != NULL)
- {
- const char *p;
-
- p = strrchr (filename, '/');
- if (p == NULL)
- p = filename;
- if (__builtin_strncmp (p, "/morestack.S", 12) == 0)
- return 0;
- }
-
- if (arg->skip > 0)
- {
- --arg->skip;
- return 0;
- }
-
- loc = &arg->locbuf[arg->index];
- loc->pc = pc;
-
- /* The libbacktrace library says that these strings might disappear,
- but with the current implementation they won't. We can't easily
- allocate memory here, so for now assume that we can save a
- pointer to the strings. */
- loc->filename = runtime_gostringnocopy ((const byte *) filename);
- loc->function = runtime_gostringnocopy ((const byte *) function);
-
- loc->lineno = lineno;
- ++arg->index;
- return arg->index >= arg->max;
-}
-
-/* Error callback. */
-
-static void
-error_callback (void *data __attribute__ ((unused)),
- const char *msg, int errnum)
-{
- if (errnum != 0)
- runtime_printf ("%s errno %d\n", msg, errnum);
- runtime_throw (msg);
-}
-
-/* Gather caller PC's. */
-
-int32
-runtime_callers (int32 skip, Location *locbuf, int32 m)
-{
- struct callers_data data;
-
- data.locbuf = locbuf;
- data.skip = skip + 1;
- data.index = 0;
- data.max = m;
- backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
- &data);
- return data.index;
-}
-
-int Callers (int, struct __go_open_array)
- __asm__ (GOSYM_PREFIX "runtime.Callers");
-
-int
-Callers (int skip, struct __go_open_array pc)
-{
- Location *locbuf;
- int ret;
- int i;
-
- locbuf = (Location *) runtime_mal (pc.__count * sizeof (Location));
-
- /* In the Go 1 release runtime.Callers has an off-by-one error,
- which we can not correct because it would break backward
- compatibility. Normally we would add 1 to SKIP here, but we
- don't so that we are compatible. */
- ret = runtime_callers (skip, locbuf, pc.__count);
-
- for (i = 0; i < ret; i++)
- ((uintptr *) pc.__values)[i] = locbuf[i].pc;
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-can-convert-interface.c b/gcc-4.8.1/libgo/runtime/go-can-convert-interface.c
deleted file mode 100644
index 4de558077..000000000
--- a/gcc-4.8.1/libgo/runtime/go-can-convert-interface.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* go-can-convert-interface.c -- can we convert to an interface?
-
- 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. */
-
-#include "runtime.h"
-#include "go-assert.h"
-#include "go-string.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Return whether we can convert from the type in FROM_DESCRIPTOR to
- the interface in TO_DESCRIPTOR. This is used for type
- switches. */
-
-_Bool
-__go_can_convert_to_interface (
- const struct __go_type_descriptor *to_descriptor,
- const struct __go_type_descriptor *from_descriptor)
-{
- const struct __go_interface_type *to_interface;
- int to_method_count;
- const struct __go_interface_method *to_method;
- const struct __go_uncommon_type *from_uncommon;
- int from_method_count;
- const struct __go_method *from_method;
- int i;
-
- /* In a type switch FROM_DESCRIPTOR can be NULL. */
- if (from_descriptor == NULL)
- return 0;
-
- __go_assert (to_descriptor->__code == GO_INTERFACE);
- to_interface = (const struct __go_interface_type *) to_descriptor;
- to_method_count = to_interface->__methods.__count;
- to_method = ((const struct __go_interface_method *)
- to_interface->__methods.__values);
-
- from_uncommon = from_descriptor->__uncommon;
- if (from_uncommon == NULL)
- {
- from_method_count = 0;
- from_method = NULL;
- }
- else
- {
- from_method_count = from_uncommon->__methods.__count;
- from_method = ((const struct __go_method *)
- from_uncommon->__methods.__values);
- }
-
- for (i = 0; i < to_method_count; ++i)
- {
- while (from_method_count > 0
- && (!__go_ptr_strings_equal (from_method->__name,
- to_method->__name)
- || !__go_ptr_strings_equal (from_method->__pkg_path,
- to_method->__pkg_path)))
- {
- ++from_method;
- --from_method_count;
- }
-
- if (from_method_count == 0)
- return 0;
-
- if (!__go_type_descriptors_equal (from_method->__mtype,
- to_method->__type))
- return 0;
-
- ++to_method;
- ++from_method;
- --from_method_count;
- }
-
- return 1;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-cgo.c b/gcc-4.8.1/libgo/runtime/go-cgo.c
deleted file mode 100644
index 46eb1827a..000000000
--- a/gcc-4.8.1/libgo/runtime/go-cgo.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* go-cgo.c -- SWIG support routines for libgo.
-
- Copyright 2011 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. */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "interface.h"
-#include "go-panic.h"
-
-/* Prepare to call from code written in Go to code written in C or
- C++. This takes the current goroutine out of the Go scheduler, as
- though it were making a system call. Otherwise the program can
- lock up if the C code goes to sleep on a mutex or for some other
- reason. This idea is to call this function, then immediately call
- the C/C++ function. After the C/C++ function returns, call
- syscall_cgocalldone. The usual Go code would look like
-
- syscall.Cgocall()
- defer syscall.Cgocalldone()
- cfunction()
-
- */
-
-/* We let Go code call these via the syscall package. */
-void syscall_cgocall(void) __asm__ (GOSYM_PREFIX "syscall.Cgocall");
-void syscall_cgocalldone(void) __asm__ (GOSYM_PREFIX "syscall.CgocallDone");
-void syscall_cgocallback(void) __asm__ (GOSYM_PREFIX "syscall.CgocallBack");
-void syscall_cgocallbackdone(void) __asm__ (GOSYM_PREFIX "syscall.CgocallBackDone");
-
-void
-syscall_cgocall ()
-{
- M* m;
- G* g;
-
- m = runtime_m ();
- ++m->ncgocall;
- g = runtime_g ();
- ++g->ncgo;
- runtime_entersyscall ();
-}
-
-/* Prepare to return to Go code from C/C++ code. */
-
-void
-syscall_cgocalldone ()
-{
- G* g;
-
- g = runtime_g ();
- __go_assert (g != NULL);
- --g->ncgo;
- if (g->ncgo == 0)
- {
- /* We are going back to Go, and we are not in a recursive call.
- Let the garbage collector clean up any unreferenced
- memory. */
- g->cgomal = NULL;
- }
-
- /* If we are invoked because the C function called _cgo_panic, then
- _cgo_panic will already have exited syscall mode. */
- if (g->status == Gsyscall)
- runtime_exitsyscall ();
-}
-
-/* Call back from C/C++ code to Go code. */
-
-void
-syscall_cgocallback ()
-{
- runtime_exitsyscall ();
-}
-
-/* Prepare to return to C/C++ code from a callback to Go code. */
-
-void
-syscall_cgocallbackdone ()
-{
- runtime_entersyscall ();
-}
-
-/* Allocate memory and save it in a list visible to the Go garbage
- collector. */
-
-void *
-alloc_saved (size_t n)
-{
- void *ret;
- G *g;
- CgoMal *c;
-
- ret = __go_alloc (n);
-
- g = runtime_g ();
- c = (CgoMal *) __go_alloc (sizeof (CgoMal));
- c->next = g->cgomal;
- c->alloc = ret;
- g->cgomal = c;
-
- return ret;
-}
-
-/* These are routines used by SWIG. The gc runtime library provides
- the same routines under the same name, though in that case the code
- is required to import runtime/cgo. */
-
-void *
-_cgo_allocate (size_t n)
-{
- void *ret;
-
- runtime_exitsyscall ();
- ret = alloc_saved (n);
- runtime_entersyscall ();
- return ret;
-}
-
-extern const struct __go_type_descriptor string_type_descriptor
- __asm__ (GOSYM_PREFIX "__go_tdn_string");
-
-void
-_cgo_panic (const char *p)
-{
- intgo len;
- unsigned char *data;
- String *ps;
- struct __go_empty_interface e;
-
- runtime_exitsyscall ();
- len = __builtin_strlen (p);
- data = alloc_saved (len);
- __builtin_memcpy (data, p, len);
- ps = alloc_saved (sizeof *ps);
- ps->str = data;
- ps->len = len;
- e.__type_descriptor = &string_type_descriptor;
- e.__object = ps;
-
- /* We don't call runtime_entersyscall here, because normally what
- will happen is that we will walk up the stack to a Go deferred
- function that calls recover. However, this will do the wrong
- thing if this panic is recovered and the stack unwinding is
- caught by a C++ exception handler. It might be possible to
- handle this by calling runtime_entersyscall in the personality
- function in go-unwind.c. FIXME. */
-
- __go_panic (e);
-}
-
-/* Return the number of CGO calls. */
-
-int64 runtime_NumCgoCall (void) __asm__ (GOSYM_PREFIX "runtime.NumCgoCall");
-
-int64
-runtime_NumCgoCall (void)
-{
- int64 ret;
- M* m;
-
- ret = 0;
- for (m = runtime_atomicloadp (&runtime_allm); m != NULL; m = m->alllink)
- ret += m->ncgocall;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-check-interface.c b/gcc-4.8.1/libgo/runtime/go-check-interface.c
deleted file mode 100644
index c29971ada..000000000
--- a/gcc-4.8.1/libgo/runtime/go-check-interface.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* go-check-interface.c -- check an interface type for a conversion
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-panic.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Check that an interface type matches for a conversion to a
- non-interface type. This panics if the types are bad. The actual
- extraction of the object is inlined. */
-
-void
-__go_check_interface_type (
- const struct __go_type_descriptor *lhs_descriptor,
- const struct __go_type_descriptor *rhs_descriptor,
- const struct __go_type_descriptor *rhs_inter_descriptor)
-{
- if (rhs_descriptor == NULL)
- {
- struct __go_empty_interface panic_arg;
-
- runtime_newTypeAssertionError(NULL, NULL, lhs_descriptor->__reflection,
- NULL, &panic_arg);
- __go_panic(panic_arg);
- }
-
- if (lhs_descriptor != rhs_descriptor
- && !__go_type_descriptors_equal (lhs_descriptor, rhs_descriptor)
- && (lhs_descriptor->__code != GO_UNSAFE_POINTER
- || !__go_is_pointer_type (rhs_descriptor))
- && (rhs_descriptor->__code != GO_UNSAFE_POINTER
- || !__go_is_pointer_type (lhs_descriptor)))
- {
- struct __go_empty_interface panic_arg;
-
- runtime_newTypeAssertionError(rhs_inter_descriptor->__reflection,
- rhs_descriptor->__reflection,
- lhs_descriptor->__reflection,
- NULL, &panic_arg);
- __go_panic(panic_arg);
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-construct-map.c b/gcc-4.8.1/libgo/runtime/go-construct-map.c
deleted file mode 100644
index 4bd79d200..000000000
--- a/gcc-4.8.1/libgo/runtime/go-construct-map.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* go-construct-map.c -- construct a map from an initializer.
-
- 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. */
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "map.h"
-
-struct __go_map *
-__go_construct_map (const struct __go_map_descriptor *descriptor,
- uintptr_t count, uintptr_t entry_size,
- uintptr_t val_offset, uintptr_t val_size,
- const void *ventries)
-{
- struct __go_map *ret;
- const unsigned char *entries;
- uintptr_t i;
-
- ret = __go_new_map (descriptor, count);
-
- entries = (const unsigned char *) ventries;
- for (i = 0; i < count; ++i)
- {
- void *val = __go_map_index (ret, entries, 1);
- __builtin_memcpy (val, entries + val_offset, val_size);
- entries += entry_size;
- }
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-convert-interface.c b/gcc-4.8.1/libgo/runtime/go-convert-interface.c
deleted file mode 100644
index 3eee6bf4a..000000000
--- a/gcc-4.8.1/libgo/runtime/go-convert-interface.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* go-convert-interface.c -- convert interfaces for Go.
-
- 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. */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "go-panic.h"
-#include "go-string.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* This is called when converting one interface type into another
- interface type. LHS_DESCRIPTOR is the type descriptor of the
- resulting interface. RHS_DESCRIPTOR is the type descriptor of the
- object being converted. This builds and returns a new interface
- method table. If any method in the LHS_DESCRIPTOR interface is not
- implemented by the object, the conversion fails. If the conversion
- fails, then if MAY_FAIL is true this returns NULL; otherwise, it
- panics. */
-
-void *
-__go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor,
- const struct __go_type_descriptor *rhs_descriptor,
- _Bool may_fail)
-{
- const struct __go_interface_type *lhs_interface;
- int lhs_method_count;
- const struct __go_interface_method* lhs_methods;
- const void **methods;
- const struct __go_uncommon_type *rhs_uncommon;
- int rhs_method_count;
- const struct __go_method *p_rhs_method;
- int i;
-
- if (rhs_descriptor == NULL)
- {
- /* A nil value always converts to nil. */
- return NULL;
- }
-
- __go_assert (lhs_descriptor->__code == GO_INTERFACE);
- lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
- lhs_method_count = lhs_interface->__methods.__count;
- lhs_methods = ((const struct __go_interface_method *)
- lhs_interface->__methods.__values);
-
- /* This should not be called for an empty interface. */
- __go_assert (lhs_method_count > 0);
-
- rhs_uncommon = rhs_descriptor->__uncommon;
- if (rhs_uncommon == NULL || rhs_uncommon->__methods.__count == 0)
- {
- struct __go_empty_interface panic_arg;
-
- if (may_fail)
- return NULL;
-
- runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
- lhs_descriptor->__reflection,
- lhs_methods[0].__name,
- &panic_arg);
- __go_panic (panic_arg);
- }
-
- rhs_method_count = rhs_uncommon->__methods.__count;
- p_rhs_method = ((const struct __go_method *)
- rhs_uncommon->__methods.__values);
-
- methods = NULL;
-
- for (i = 0; i < lhs_method_count; ++i)
- {
- const struct __go_interface_method *p_lhs_method;
-
- p_lhs_method = &lhs_methods[i];
-
- while (rhs_method_count > 0
- && (!__go_ptr_strings_equal (p_lhs_method->__name,
- p_rhs_method->__name)
- || !__go_ptr_strings_equal (p_lhs_method->__pkg_path,
- p_rhs_method->__pkg_path)))
- {
- ++p_rhs_method;
- --rhs_method_count;
- }
-
- if (rhs_method_count == 0
- || !__go_type_descriptors_equal (p_lhs_method->__type,
- p_rhs_method->__mtype))
- {
- struct __go_empty_interface panic_arg;
-
- if (methods != NULL)
- __go_free (methods);
-
- if (may_fail)
- return NULL;
-
- runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
- lhs_descriptor->__reflection,
- p_lhs_method->__name, &panic_arg);
- __go_panic (panic_arg);
- }
-
- if (methods == NULL)
- {
- methods = (const void **) __go_alloc ((lhs_method_count + 1)
- * sizeof (void *));
-
- /* The first field in the method table is always the type of
- the object. */
- methods[0] = rhs_descriptor;
- }
-
- methods[i + 1] = p_rhs_method->__function;
- }
-
- return methods;
-}
-
-/* This is called by the compiler to convert a value from one
- interface type to another. */
-
-void *
-__go_convert_interface (const struct __go_type_descriptor *lhs_descriptor,
- const struct __go_type_descriptor *rhs_descriptor)
-{
- return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-copy.c b/gcc-4.8.1/libgo/runtime/go-copy.c
deleted file mode 100644
index 05e16acbf..000000000
--- a/gcc-4.8.1/libgo/runtime/go-copy.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* go-append.c -- the go builtin copy function.
-
- Copyright 2010 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. */
-
-#include <stddef.h>
-#include <stdint.h>
-
-/* We should be OK if we don't split the stack here, since we are just
- calling memmove which shouldn't need much stack. If we don't do
- this we will always split the stack, because of memmove. */
-
-extern void
-__go_copy (void *, void *, uintptr_t)
- __attribute__ ((no_split_stack));
-
-void
-__go_copy (void *a, void *b, uintptr_t len)
-{
- __builtin_memmove (a, b, len);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-defer.c b/gcc-4.8.1/libgo/runtime/go-defer.c
deleted file mode 100644
index c27de6ab4..000000000
--- a/gcc-4.8.1/libgo/runtime/go-defer.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* go-defer.c -- manage the defer stack.
-
- 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-panic.h"
-#include "go-defer.h"
-
-/* This function is called each time we need to defer a call. */
-
-void
-__go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
-{
- G *g;
- struct __go_defer_stack *n;
-
- g = runtime_g ();
- n = (struct __go_defer_stack *) __go_alloc (sizeof (struct __go_defer_stack));
- n->__next = g->defer;
- n->__frame = frame;
- n->__panic = g->panic;
- n->__pfn = pfn;
- n->__arg = arg;
- n->__retaddr = NULL;
- g->defer = n;
-}
-
-/* This function is called when we want to undefer the stack. */
-
-void
-__go_undefer (_Bool *frame)
-{
- G *g;
-
- g = runtime_g ();
- while (g->defer != NULL && g->defer->__frame == frame)
- {
- struct __go_defer_stack *d;
- void (*pfn) (void *);
-
- d = g->defer;
- pfn = d->__pfn;
- d->__pfn = NULL;
-
- if (pfn != NULL)
- (*pfn) (d->__arg);
-
- g->defer = d->__next;
- __go_free (d);
-
- /* Since we are executing a defer function here, we know we are
- returning from the calling function. If the calling
- function, or one of its callees, paniced, then the defer
- functions would be executed by __go_panic. */
- *frame = 1;
- }
-}
-
-/* This function is called to record the address to which the deferred
- function returns. This may in turn be checked by __go_can_recover.
- The frontend relies on this function returning false. */
-
-_Bool
-__go_set_defer_retaddr (void *retaddr)
-{
- G *g;
-
- g = runtime_g ();
- if (g->defer != NULL)
- g->defer->__retaddr = retaddr;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-defer.h b/gcc-4.8.1/libgo/runtime/go-defer.h
deleted file mode 100644
index 0b20e8f6e..000000000
--- a/gcc-4.8.1/libgo/runtime/go-defer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* go-defer.h -- the defer stack.
-
- Copyright 2010 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. */
-
-struct __go_panic_stack;
-
-/* The defer stack is a list of these structures. */
-
-struct __go_defer_stack
-{
- /* The next entry in the stack. */
- struct __go_defer_stack *__next;
-
- /* The stack variable for the function which called this defer
- statement. This is set to 1 if we are returning from that
- function, 0 if we are panicing through it. */
- _Bool *__frame;
-
- /* The value of the panic stack when this function is deferred.
- This function can not recover this value from the panic stack.
- This can happen if a deferred function uses its own defer
- statement. */
- struct __go_panic_stack *__panic;
-
- /* The function to call. */
- void (*__pfn) (void *);
-
- /* The argument to pass to the function. */
- void *__arg;
-
- /* The return address that a recover thunk matches against. This is
- set by __go_set_defer_retaddr which is called by the thunks
- created by defer statements. */
- const void *__retaddr;
-};
diff --git a/gcc-4.8.1/libgo/runtime/go-deferred-recover.c b/gcc-4.8.1/libgo/runtime/go-deferred-recover.c
deleted file mode 100644
index 78ef287cf..000000000
--- a/gcc-4.8.1/libgo/runtime/go-deferred-recover.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* go-deferred-recover.c -- support for a deferred recover function.
-
- Copyright 2010 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-panic.h"
-#include "go-defer.h"
-
-/* This is called when a call to recover is deferred. That is,
- something like
- defer recover()
-
- We need to handle this specially. In 6g/8g, the recover function
- looks up the stack frame. In particular, that means that a
- deferred recover will not recover a panic thrown in the same
- function that defers the recover. It will only recover a panic
- thrown in a function that defers the deferred call to recover.
-
- In other words:
-
- func f1() {
- defer recover() // does not stop panic
- panic(0)
- }
-
- func f2() {
- defer func() {
- defer recover() // stops panic(0)
- }()
- panic(0)
- }
-
- func f3() {
- defer func() {
- defer recover() // does not stop panic
- panic(0)
- }()
- panic(1)
- }
-
- func f4() {
- defer func() {
- defer func() {
- defer recover() // stops panic(0)
- }()
- panic(0)
- }()
- panic(1)
- }
-
- The interesting case here is f3. As can be seen from f2, the
- deferred recover could pick up panic(1). However, this does not
- happen because it is blocked by the panic(0).
-
- When a function calls recover, then when we invoke it we pass a
- hidden parameter indicating whether it should recover something.
- This parameter is set based on whether the function is being
- invoked directly from defer. The parameter winds up determining
- whether __go_recover or __go_deferred_recover is called at all.
-
- In the case of a deferred recover, the hidden parameter which
- controls the call is actually the one set up for the function which
- runs the defer recover() statement. That is the right thing in all
- the cases above except for f3. In f3 the function is permitted to
- call recover, but the deferred recover call is not. We address
- that here by checking for that specific case before calling
- recover. If this function was deferred when there is already a
- panic on the panic stack, then we can only recover that panic, not
- any other.
-
- Note that we can get away with using a special function here
- because you are not permitted to take the address of a predeclared
- function like recover. */
-
-struct __go_empty_interface
-__go_deferred_recover ()
-{
- G *g;
-
- g = runtime_g ();
- if (g->defer == NULL || g->defer->__panic != g->panic)
- {
- struct __go_empty_interface ret;
-
- ret.__type_descriptor = NULL;
- ret.__object = NULL;
- return ret;
- }
- return __go_recover ();
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-eface-compare.c b/gcc-4.8.1/libgo/runtime/go-eface-compare.c
deleted file mode 100644
index e738efced..000000000
--- a/gcc-4.8.1/libgo/runtime/go-eface-compare.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* go-eface-compare.c -- compare two empty values.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Compare two interface values. Return 0 for equal, not zero for not
- equal (return value is like strcmp). */
-
-intgo
-__go_empty_interface_compare (struct __go_empty_interface left,
- struct __go_empty_interface right)
-{
- const struct __go_type_descriptor *left_descriptor;
-
- left_descriptor = left.__type_descriptor;
-
- if (((uintptr_t) left_descriptor & reflectFlags) != 0
- || ((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
- runtime_panicstring ("invalid interface value");
-
- if (left_descriptor == NULL && right.__type_descriptor == NULL)
- return 0;
- if (left_descriptor == NULL || right.__type_descriptor == NULL)
- return 1;
- if (!__go_type_descriptors_equal (left_descriptor,
- right.__type_descriptor))
- return 1;
- if (__go_is_pointer_type (left_descriptor))
- return left.__object == right.__object ? 0 : 1;
- if (!left_descriptor->__equalfn (left.__object, right.__object,
- left_descriptor->__size))
- return 1;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-eface-val-compare.c b/gcc-4.8.1/libgo/runtime/go-eface-val-compare.c
deleted file mode 100644
index 454ea3eba..000000000
--- a/gcc-4.8.1/libgo/runtime/go-eface-val-compare.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* go-eface-val-compare.c -- compare an empty interface with a value.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Compare an empty interface with a value. Return 0 for equal, not
- zero for not equal (return value is like strcmp). */
-
-intgo
-__go_empty_interface_value_compare (
- struct __go_empty_interface left,
- const struct __go_type_descriptor *right_descriptor,
- const void *val)
-{
- const struct __go_type_descriptor *left_descriptor;
-
- left_descriptor = left.__type_descriptor;
- if (((uintptr_t) left_descriptor & reflectFlags) != 0)
- runtime_panicstring ("invalid interface value");
- if (left_descriptor == NULL)
- return 1;
- if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
- return 1;
- if (__go_is_pointer_type (left_descriptor))
- return left.__object == val ? 0 : 1;
- if (!left_descriptor->__equalfn (left.__object, val,
- left_descriptor->__size))
- return 1;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-fieldtrack.c b/gcc-4.8.1/libgo/runtime/go-fieldtrack.c
deleted file mode 100644
index a7e2c1334..000000000
--- a/gcc-4.8.1/libgo/runtime/go-fieldtrack.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* go-fieldtrack.c -- structure field data analysis.
-
- Copyright 2012 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "map.h"
-
-/* The compiler will track fields that have the tag go:"track". Any
- function that refers to such a field will call this function with a
- string
- fieldtrack "package.type.field"
-
- This function does not actually do anything. Instead, we gather
- the field tracking information by looking for strings of that form
- in the read-only data section. This is, of course, a horrible
- hack, but it's good enough for now. We can improve it, e.g., by a
- linker plugin, if this turns out to be useful. */
-
-void
-__go_fieldtrack (byte *p __attribute__ ((unused)))
-{
-}
-
-/* A runtime function to add all the tracked fields to a
- map[string]bool. */
-
-extern const char _etext[] __attribute__ ((weak));
-extern const char __etext[] __attribute__ ((weak));
-extern const char __data_start[] __attribute__ ((weak));
-extern const char _edata[] __attribute__ ((weak));
-extern const char __edata[] __attribute__ ((weak));
-extern const char __bss_start[] __attribute__ ((weak));
-
-void runtime_Fieldtrack (struct __go_map *) __asm__ (GOSYM_PREFIX "runtime.Fieldtrack");
-
-void
-runtime_Fieldtrack (struct __go_map *m)
-{
- const char *p;
- const char *pend;
- const char *prefix;
- size_t prefix_len;
-
- p = __data_start;
- if (p == NULL)
- p = __etext;
- if (p == NULL)
- p = _etext;
- if (p == NULL)
- return;
-
- pend = __edata;
- if (pend == NULL)
- pend = _edata;
- if (pend == NULL)
- pend = __bss_start;
- if (pend == NULL)
- return;
-
- prefix = "fieldtrack ";
- prefix_len = __builtin_strlen (prefix);
-
- while (p < pend)
- {
- const char *q1;
- const char *q2;
-
- q1 = __builtin_memchr (p + prefix_len, '"', pend - (p + prefix_len));
- if (q1 == NULL)
- break;
-
- if (__builtin_memcmp (q1 - prefix_len, prefix, prefix_len) != 0)
- {
- p = q1 + 1;
- continue;
- }
-
- q1++;
- q2 = __builtin_memchr (q1, '"', pend - q1);
- if (q2 == NULL)
- break;
-
- if (__builtin_memchr (q1, '\0', q2 - q1) == NULL)
- {
- String s;
- void *v;
- _Bool *pb;
-
- s.str = (const byte *) q1;
- s.len = q2 - q1;
- v = __go_map_index (m, &s, 1);
- pb = (_Bool *) v;
- *pb = 1;
- }
-
- p = q2;
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-getgoroot.c b/gcc-4.8.1/libgo/runtime/go-getgoroot.c
deleted file mode 100644
index 1b52d4404..000000000
--- a/gcc-4.8.1/libgo/runtime/go-getgoroot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* go-getgoroot.c -- getgoroot function for runtime package.
-
- Copyright 2010 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. */
-
-#include <stdlib.h>
-
-#include "runtime.h"
-
-String getgoroot (void) __asm__ (GOSYM_PREFIX "runtime.getgoroot");
-
-String
-getgoroot ()
-{
- const char *p;
- String ret;
-
- p = getenv ("GOROOT");
- ret.str = (const byte *) p;
- if (ret.str == NULL)
- ret.len = 0;
- else
- ret.len = __builtin_strlen (p);
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-int-array-to-string.c b/gcc-4.8.1/libgo/runtime/go-int-array-to-string.c
deleted file mode 100644
index 6cae2fd8c..000000000
--- a/gcc-4.8.1/libgo/runtime/go-int-array-to-string.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* go-int-array-to-string.c -- convert an array of ints to a string in Go.
-
- 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. */
-
-#include "go-assert.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_int_array_to_string (const void* p, intgo len)
-{
- const int32 *ints;
- intgo slen;
- intgo i;
- unsigned char *retdata;
- String ret;
- unsigned char *s;
-
- ints = (const int32 *) p;
-
- slen = 0;
- for (i = 0; i < len; ++i)
- {
- int32 v;
-
- v = ints[i];
-
- if (v < 0 || v > 0x10ffff)
- v = 0xfffd;
-
- if (v <= 0x7f)
- slen += 1;
- else if (v <= 0x7ff)
- slen += 2;
- else if (v <= 0xffff)
- slen += 3;
- else
- slen += 4;
- }
-
- retdata = runtime_mallocgc ((uintptr) slen, FlagNoPointers, 1, 0);
- ret.str = retdata;
- ret.len = slen;
-
- s = retdata;
- for (i = 0; i < len; ++i)
- {
- int32 v;
-
- v = ints[i];
-
- /* If V is out of range for UTF-8, substitute the replacement
- character. */
- if (v < 0 || v > 0x10ffff)
- v = 0xfffd;
-
- if (v <= 0x7f)
- *s++ = v;
- else if (v <= 0x7ff)
- {
- *s++ = 0xc0 | ((v >> 6) & 0x1f);
- *s++ = 0x80 | (v & 0x3f);
- }
- else if (v <= 0xffff)
- {
- *s++ = 0xe0 | ((v >> 12) & 0xf);
- *s++ = 0x80 | ((v >> 6) & 0x3f);
- *s++ = 0x80 | (v & 0x3f);
- }
- else
- {
- *s++ = 0xf0 | ((v >> 18) & 0x7);
- *s++ = 0x80 | ((v >> 12) & 0x3f);
- *s++ = 0x80 | ((v >> 6) & 0x3f);
- *s++ = 0x80 | (v & 0x3f);
- }
- }
-
- __go_assert (s - retdata == slen);
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-int-to-string.c b/gcc-4.8.1/libgo/runtime/go-int-to-string.c
deleted file mode 100644
index eb441674b..000000000
--- a/gcc-4.8.1/libgo/runtime/go-int-to-string.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* go-int-to-string.c -- convert an integer to a string in Go.
-
- 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. */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_int_to_string (intgo v)
-{
- char buf[4];
- int len;
- unsigned char *retdata;
- String ret;
-
- /* A negative value is not valid UTF-8; turn it into the replacement
- character. */
- if (v < 0)
- v = 0xfffd;
-
- if (v <= 0x7f)
- {
- buf[0] = v;
- len = 1;
- }
- else if (v <= 0x7ff)
- {
- buf[0] = 0xc0 + (v >> 6);
- buf[1] = 0x80 + (v & 0x3f);
- len = 2;
- }
- else
- {
- /* If the value is out of range for UTF-8, turn it into the
- "replacement character". */
- if (v > 0x10ffff)
- v = 0xfffd;
- /* If the value is a surrogate pair, which is invalid in UTF-8,
- turn it into the replacement character. */
- if (v >= 0xd800 && v < 0xe000)
- v = 0xfffd;
-
- if (v <= 0xffff)
- {
- buf[0] = 0xe0 + (v >> 12);
- buf[1] = 0x80 + ((v >> 6) & 0x3f);
- buf[2] = 0x80 + (v & 0x3f);
- len = 3;
- }
- else
- {
- buf[0] = 0xf0 + (v >> 18);
- buf[1] = 0x80 + ((v >> 12) & 0x3f);
- buf[2] = 0x80 + ((v >> 6) & 0x3f);
- buf[3] = 0x80 + (v & 0x3f);
- len = 4;
- }
- }
-
- retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
- __builtin_memcpy (retdata, buf, len);
- ret.str = retdata;
- ret.len = len;
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-interface-compare.c b/gcc-4.8.1/libgo/runtime/go-interface-compare.c
deleted file mode 100644
index 6374bd2fb..000000000
--- a/gcc-4.8.1/libgo/runtime/go-interface-compare.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* go-interface-compare.c -- compare two interface values.
-
- 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Compare two interface values. Return 0 for equal, not zero for not
- equal (return value is like strcmp). */
-
-int
-__go_interface_compare (struct __go_interface left,
- struct __go_interface right)
-{
- const struct __go_type_descriptor *left_descriptor;
-
- if (left.__methods == NULL && right.__methods == NULL)
- return 0;
- if (left.__methods == NULL || right.__methods == NULL)
- return 1;
- left_descriptor = left.__methods[0];
- if (!__go_type_descriptors_equal (left_descriptor, right.__methods[0]))
- return 1;
- if (__go_is_pointer_type (left_descriptor))
- return left.__object == right.__object ? 0 : 1;
- if (!left_descriptor->__equalfn (left.__object, right.__object,
- left_descriptor->__size))
- return 1;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-interface-eface-compare.c b/gcc-4.8.1/libgo/runtime/go-interface-eface-compare.c
deleted file mode 100644
index bb81ff813..000000000
--- a/gcc-4.8.1/libgo/runtime/go-interface-eface-compare.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* go-interface-eface-compare.c -- compare non-empty and empty interface.
-
- Copyright 2011 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Compare a non-empty interface value with an empty interface value.
- Return 0 for equal, not zero for not equal (return value is like
- strcmp). */
-
-intgo
-__go_interface_empty_compare (struct __go_interface left,
- struct __go_empty_interface right)
-{
- const struct __go_type_descriptor *left_descriptor;
-
- if (((uintptr_t) right.__type_descriptor & reflectFlags) != 0)
- runtime_panicstring ("invalid interface value");
- if (left.__methods == NULL && right.__type_descriptor == NULL)
- return 0;
- if (left.__methods == NULL || right.__type_descriptor == NULL)
- return 1;
- left_descriptor = left.__methods[0];
- if (!__go_type_descriptors_equal (left_descriptor, right.__type_descriptor))
- return 1;
- if (__go_is_pointer_type (left_descriptor))
- return left.__object == right.__object ? 0 : 1;
- if (!left_descriptor->__equalfn (left.__object, right.__object,
- left_descriptor->__size))
- return 1;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-interface-val-compare.c b/gcc-4.8.1/libgo/runtime/go-interface-val-compare.c
deleted file mode 100644
index e2dae6a18..000000000
--- a/gcc-4.8.1/libgo/runtime/go-interface-val-compare.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* go-interface-val-compare.c -- compare an interface to a value.
-
- 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Compare two interface values. Return 0 for equal, not zero for not
- equal (return value is like strcmp). */
-
-intgo
-__go_interface_value_compare (
- struct __go_interface left,
- const struct __go_type_descriptor *right_descriptor,
- const void *val)
-{
- const struct __go_type_descriptor *left_descriptor;
-
- if (left.__methods == NULL)
- return 1;
- left_descriptor = left.__methods[0];
- if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
- return 1;
- if (__go_is_pointer_type (left_descriptor))
- return left.__object == val ? 0 : 1;
- if (!left_descriptor->__equalfn (left.__object, val,
- left_descriptor->__size))
- return 1;
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-main.c b/gcc-4.8.1/libgo/runtime/go-main.c
deleted file mode 100644
index 97d140583..000000000
--- a/gcc-4.8.1/libgo/runtime/go-main.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* go-main.c -- the main function for a Go program.
-
- 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. */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-
-#ifdef HAVE_FPU_CONTROL_H
-#include <fpu_control.h>
-#endif
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-#undef int
-#undef char
-#undef unsigned
-
-/* The main function for a Go program. This records the command line
- parameters, calls the real main function, and returns a zero status
- if the real main function returns. */
-
-extern char **environ;
-
-extern void runtime_main (void);
-static void mainstart (void *);
-
-/* The main function. */
-
-int
-main (int argc, char **argv)
-{
- runtime_check ();
- runtime_args (argc, (byte **) argv);
- runtime_osinit ();
- runtime_schedinit ();
- __go_go (mainstart, NULL);
- runtime_mstart (runtime_m ());
- abort ();
-}
-
-static void
-mainstart (void *arg __attribute__ ((unused)))
-{
- runtime_main ();
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-make-slice.c b/gcc-4.8.1/libgo/runtime/go-make-slice.c
deleted file mode 100644
index 591ab37e0..000000000
--- a/gcc-4.8.1/libgo/runtime/go-make-slice.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* go-make-slice.c -- make a slice.
-
- Copyright 2011 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. */
-
-#include <stdint.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "go-panic.h"
-#include "go-type.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-/* Dummy word to use as base pointer for make([]T, 0).
- Since you cannot take the address of such a slice,
- you can't tell that they all have the same base pointer. */
-uintptr runtime_zerobase;
-
-struct __go_open_array
-__go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len,
- uintptr_t cap)
-{
- const struct __go_slice_type* std;
- intgo ilen;
- intgo icap;
- uintptr_t size;
- struct __go_open_array ret;
-
- __go_assert (td->__code == GO_SLICE);
- std = (const struct __go_slice_type *) td;
-
- ilen = (intgo) len;
- if (ilen < 0 || (uintptr_t) ilen != len)
- runtime_panicstring ("makeslice: len out of range");
-
- icap = (intgo) cap;
- if (cap < len
- || (uintptr_t) icap != cap
- || (std->__element_type->__size > 0
- && cap > MaxMem / std->__element_type->__size))
- runtime_panicstring ("makeslice: cap out of range");
-
- ret.__count = ilen;
- ret.__capacity = icap;
-
- size = cap * std->__element_type->__size;
-
- if (size == 0)
- ret.__values = &runtime_zerobase;
- else if ((std->__element_type->__code & GO_NO_POINTERS) != 0)
- ret.__values = runtime_mallocgc (size, FlagNoPointers, 1, 1);
- else
- {
- ret.__values = runtime_mallocgc (size, 0, 1, 1);
-
- if (UseSpanType)
- runtime_settype (ret.__values,
- (uintptr) std->__element_type | TypeInfo_Array);
- }
-
- return ret;
-}
-
-struct __go_open_array
-__go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
-{
- return __go_make_slice2 (td, len, len);
-}
-
-struct __go_open_array
-__go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len,
- uint64_t cap)
-{
- uintptr_t slen;
- uintptr_t scap;
-
- slen = (uintptr_t) len;
- if ((uint64_t) slen != len)
- runtime_panicstring ("makeslice: len out of range");
-
- scap = (uintptr_t) cap;
- if ((uint64_t) scap != cap)
- runtime_panicstring ("makeslice: cap out of range");
-
- return __go_make_slice2 (td, slen, scap);
-}
-
-struct __go_open_array
-__go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len)
-{
- return __go_make_slice2_big (td, len, len);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-map-delete.c b/gcc-4.8.1/libgo/runtime/go-map-delete.c
deleted file mode 100644
index f8f8907c3..000000000
--- a/gcc-4.8.1/libgo/runtime/go-map-delete.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* go-map-delete.c -- delete an entry from a map.
-
- 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. */
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "map.h"
-
-/* Delete the entry matching KEY from MAP. */
-
-void
-__go_map_delete (struct __go_map *map, const void *key)
-{
- const struct __go_map_descriptor *descriptor;
- const struct __go_type_descriptor *key_descriptor;
- uintptr_t key_offset;
- _Bool (*equalfn) (const void*, const void*, uintptr_t);
- size_t key_hash;
- size_t key_size;
- size_t bucket_index;
- void **pentry;
-
- if (map == NULL)
- return;
-
- descriptor = map->__descriptor;
-
- key_descriptor = descriptor->__map_descriptor->__key_type;
- key_offset = descriptor->__key_offset;
- key_size = key_descriptor->__size;
- __go_assert (key_size != 0 && key_size != -1UL);
- equalfn = key_descriptor->__equalfn;
-
- key_hash = key_descriptor->__hashfn (key, key_size);
- bucket_index = key_hash % map->__bucket_count;
-
- pentry = map->__buckets + bucket_index;
- while (*pentry != NULL)
- {
- char *entry = (char *) *pentry;
- if (equalfn (key, entry + key_offset, key_size))
- {
- *pentry = *(void **) entry;
- __go_free (entry);
- map->__element_count -= 1;
- break;
- }
- pentry = (void **) entry;
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-map-index.c b/gcc-4.8.1/libgo/runtime/go-map-index.c
deleted file mode 100644
index a602d2ad0..000000000
--- a/gcc-4.8.1/libgo/runtime/go-map-index.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* go-map-index.c -- find or insert an entry in a map.
-
- 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. */
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "map.h"
-
-/* Rehash MAP to a larger size. */
-
-static void
-__go_map_rehash (struct __go_map *map)
-{
- const struct __go_map_descriptor *descriptor;
- const struct __go_type_descriptor *key_descriptor;
- uintptr_t key_offset;
- size_t key_size;
- uintptr_t (*hashfn) (const void *, uintptr_t);
- uintptr_t old_bucket_count;
- void **old_buckets;
- uintptr_t new_bucket_count;
- void **new_buckets;
- uintptr_t i;
-
- descriptor = map->__descriptor;
-
- key_descriptor = descriptor->__map_descriptor->__key_type;
- key_offset = descriptor->__key_offset;
- key_size = key_descriptor->__size;
- hashfn = key_descriptor->__hashfn;
-
- old_bucket_count = map->__bucket_count;
- old_buckets = map->__buckets;
-
- new_bucket_count = __go_map_next_prime (old_bucket_count * 2);
- new_buckets = (void **) __go_alloc (new_bucket_count * sizeof (void *));
- __builtin_memset (new_buckets, 0, new_bucket_count * sizeof (void *));
-
- for (i = 0; i < old_bucket_count; ++i)
- {
- char* entry;
- char* next;
-
- for (entry = old_buckets[i]; entry != NULL; entry = next)
- {
- size_t key_hash;
- size_t new_bucket_index;
-
- /* We could speed up rehashing at the cost of memory space
- by caching the hash code. */
- key_hash = hashfn (entry + key_offset, key_size);
- new_bucket_index = key_hash % new_bucket_count;
-
- next = *(char **) entry;
- *(char **) entry = new_buckets[new_bucket_index];
- new_buckets[new_bucket_index] = entry;
- }
- }
-
- __go_free (old_buckets);
-
- map->__bucket_count = new_bucket_count;
- map->__buckets = new_buckets;
-}
-
-/* Find KEY in MAP, return a pointer to the value. If KEY is not
- present, then if INSERT is false, return NULL, and if INSERT is
- true, insert a new value and zero-initialize it before returning a
- pointer to it. */
-
-void *
-__go_map_index (struct __go_map *map, const void *key, _Bool insert)
-{
- const struct __go_map_descriptor *descriptor;
- const struct __go_type_descriptor *key_descriptor;
- uintptr_t key_offset;
- _Bool (*equalfn) (const void*, const void*, uintptr_t);
- size_t key_hash;
- size_t key_size;
- size_t bucket_index;
- char *entry;
-
- if (map == NULL)
- {
- if (insert)
- runtime_panicstring ("assignment to entry in nil map");
- return NULL;
- }
-
- descriptor = map->__descriptor;
-
- key_descriptor = descriptor->__map_descriptor->__key_type;
- key_offset = descriptor->__key_offset;
- key_size = key_descriptor->__size;
- __go_assert (key_size != 0 && key_size != -1UL);
- equalfn = key_descriptor->__equalfn;
-
- key_hash = key_descriptor->__hashfn (key, key_size);
- bucket_index = key_hash % map->__bucket_count;
-
- entry = (char *) map->__buckets[bucket_index];
- while (entry != NULL)
- {
- if (equalfn (key, entry + key_offset, key_size))
- return entry + descriptor->__val_offset;
- entry = *(char **) entry;
- }
-
- if (!insert)
- return NULL;
-
- if (map->__element_count >= map->__bucket_count)
- {
- __go_map_rehash (map);
- bucket_index = key_hash % map->__bucket_count;
- }
-
- entry = (char *) __go_alloc (descriptor->__entry_size);
- __builtin_memset (entry, 0, descriptor->__entry_size);
-
- __builtin_memcpy (entry + key_offset, key, key_size);
-
- *(char **) entry = map->__buckets[bucket_index];
- map->__buckets[bucket_index] = entry;
-
- map->__element_count += 1;
-
- return entry + descriptor->__val_offset;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-map-len.c b/gcc-4.8.1/libgo/runtime/go-map-len.c
deleted file mode 100644
index 7da10c249..000000000
--- a/gcc-4.8.1/libgo/runtime/go-map-len.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* go-map-len.c -- return the length of a map.
-
- 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-assert.h"
-#include "map.h"
-
-/* Return the length of a map. This could be done inline, of course,
- but I'm doing it as a function for now to make it easy to change
- the map structure. */
-
-intgo
-__go_map_len (struct __go_map *map)
-{
- if (map == NULL)
- return 0;
- __go_assert (map->__element_count
- == (uintptr_t) (intgo) map->__element_count);
- return map->__element_count;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-map-range.c b/gcc-4.8.1/libgo/runtime/go-map-range.c
deleted file mode 100644
index 5dbb92ccb..000000000
--- a/gcc-4.8.1/libgo/runtime/go-map-range.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* go-map-range.c -- implement a range clause over a map.
-
- Copyright 2009, 2010 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. */
-
-#include "runtime.h"
-#include "go-assert.h"
-#include "map.h"
-
-/* Initialize a range over a map. */
-
-void
-__go_mapiterinit (const struct __go_map *h, struct __go_hash_iter *it)
-{
- it->entry = NULL;
- if (h != NULL)
- {
- it->map = h;
- it->next_entry = NULL;
- it->bucket = 0;
- --it->bucket;
- __go_mapiternext(it);
- }
-}
-
-/* Move to the next iteration, updating *HITER. */
-
-void
-__go_mapiternext (struct __go_hash_iter *it)
-{
- const void *entry;
-
- entry = it->next_entry;
- if (entry == NULL)
- {
- const struct __go_map *map;
- uintptr_t bucket;
-
- map = it->map;
- bucket = it->bucket;
- while (1)
- {
- ++bucket;
- if (bucket >= map->__bucket_count)
- {
- /* Map iteration is complete. */
- it->entry = NULL;
- return;
- }
- entry = map->__buckets[bucket];
- if (entry != NULL)
- break;
- }
- it->bucket = bucket;
- }
- it->entry = entry;
- it->next_entry = *(const void * const *) entry;
-}
-
-/* Get the key of the current iteration. */
-
-void
-__go_mapiter1 (struct __go_hash_iter *it, unsigned char *key)
-{
- const struct __go_map *map;
- const struct __go_map_descriptor *descriptor;
- const struct __go_type_descriptor *key_descriptor;
- const char *p;
-
- map = it->map;
- descriptor = map->__descriptor;
- key_descriptor = descriptor->__map_descriptor->__key_type;
- p = it->entry;
- __go_assert (p != NULL);
- __builtin_memcpy (key, p + descriptor->__key_offset, key_descriptor->__size);
-}
-
-/* Get the key and value of the current iteration. */
-
-void
-__go_mapiter2 (struct __go_hash_iter *it, unsigned char *key,
- unsigned char *val)
-{
- const struct __go_map *map;
- const struct __go_map_descriptor *descriptor;
- const struct __go_map_type *map_descriptor;
- const struct __go_type_descriptor *key_descriptor;
- const struct __go_type_descriptor *val_descriptor;
- const char *p;
-
- map = it->map;
- descriptor = map->__descriptor;
- map_descriptor = descriptor->__map_descriptor;
- key_descriptor = map_descriptor->__key_type;
- val_descriptor = map_descriptor->__val_type;
- p = it->entry;
- __go_assert (p != NULL);
- __builtin_memcpy (key, p + descriptor->__key_offset,
- key_descriptor->__size);
- __builtin_memcpy (val, p + descriptor->__val_offset,
- val_descriptor->__size);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-matherr.c b/gcc-4.8.1/libgo/runtime/go-matherr.c
deleted file mode 100644
index d620ba08b..000000000
--- a/gcc-4.8.1/libgo/runtime/go-matherr.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* go-matherr.c -- a Go version of the matherr function.
-
- Copyright 2012 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. */
-
-/* The gccgo version of the math library calls libc functions. On
- some systems, such as Solaris, those functions will call matherr on
- exceptional conditions. This is a version of matherr appropriate
- for Go, one which returns the values that the Go math library
- expects. This is fine for pure Go programs. For mixed Go and C
- programs this will be problematic if the C programs themselves use
- matherr. Normally the C version of matherr will override this, and
- the Go code will just have to cope. If this turns out to be too
- problematic we can change to run pure Go code in the math library
- on systems that use matherr. */
-
-#include <math.h>
-#include <stdint.h>
-
-#include "config.h"
-
-#if defined(HAVE_MATHERR) && defined(HAVE_STRUCT_EXCEPTION)
-
-#define PI 3.14159265358979323846264338327950288419716939937510582097494459
-
-int
-matherr (struct exception* e)
-{
- const char *n;
-
- if (e->type != DOMAIN)
- return 0;
-
- n = e->name;
- if (__builtin_strcmp (n, "acos") == 0
- || __builtin_strcmp (n, "asin") == 0)
- e->retval = __builtin_nan ("");
- else if (__builtin_strcmp (n, "atan2") == 0)
- {
- if (e->arg1 == 0 && e->arg2 == 0)
- {
- double nz;
-
- nz = -0.0;
- if (__builtin_memcmp (&e->arg2, &nz, sizeof (double)) != 0)
- e->retval = e->arg1;
- else
- e->retval = copysign (PI, e->arg1);
- }
- else
- return 0;
- }
- else if (__builtin_strcmp (n, "log") == 0
- || __builtin_strcmp (n, "log10") == 0)
- e->retval = __builtin_nan ("");
- else if (__builtin_strcmp (n, "pow") == 0)
- {
- if (e->arg1 < 0)
- e->retval = __builtin_nan ("");
- else if (e->arg1 == 0 && e->arg2 == 0)
- e->retval = 1.0;
- else if (e->arg1 == 0 && e->arg2 < 0)
- {
- double i;
-
- if (modf (e->arg2, &i) == 0 && ((int64_t) i & 1) == 1)
- e->retval = copysign (__builtin_inf (), e->arg1);
- else
- e->retval = __builtin_inf ();
- }
- else
- return 0;
- }
- else if (__builtin_strcmp (n, "sqrt") == 0)
- {
- if (e->arg1 < 0)
- e->retval = __builtin_nan ("");
- else
- return 0;
- }
- else
- return 0;
-
- return 1;
-}
-
-#endif
diff --git a/gcc-4.8.1/libgo/runtime/go-memcmp.c b/gcc-4.8.1/libgo/runtime/go-memcmp.c
deleted file mode 100644
index 78a356b08..000000000
--- a/gcc-4.8.1/libgo/runtime/go-memcmp.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* go-memcmp.c -- the go memory comparison function.
-
- Copyright 2012 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. */
-
-#include "runtime.h"
-
-intgo
-__go_memcmp (const void *p1, const void *p2, uintptr len)
-{
- return __builtin_memcmp (p1, p2, len);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-nanotime.c b/gcc-4.8.1/libgo/runtime/go-nanotime.c
deleted file mode 100644
index 7e5e3e098..000000000
--- a/gcc-4.8.1/libgo/runtime/go-nanotime.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.
-
-// Return current time in nanoseconds.
-
-#include <sys/time.h>
-
-#include "runtime.h"
-
-int64 runtime_nanotime (void)
- __attribute__ ((no_split_stack));
-
-int64
-runtime_nanotime (void)
-{
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
- return (int64) tv.tv_sec * 1000000000 + (int64) tv.tv_usec * 1000;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-new-map.c b/gcc-4.8.1/libgo/runtime/go-new-map.c
deleted file mode 100644
index c289bc0be..000000000
--- a/gcc-4.8.1/libgo/runtime/go-new-map.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* go-new-map.c -- allocate a new map.
-
- 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. */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "map.h"
-
-/* List of prime numbers, copied from libstdc++/src/hashtable.c. */
-
-static const unsigned long prime_list[] = /* 256 + 1 or 256 + 48 + 1 */
-{
- 2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul,
- 37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul,
- 83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul,
- 157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul,
- 277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul,
- 503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul,
- 953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul,
- 1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul,
- 3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul,
- 5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul,
- 11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul,
- 19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul,
- 33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul,
- 57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul,
- 99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul,
- 159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul,
- 256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul,
- 410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul,
- 658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul,
- 1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul,
- 1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul,
- 2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul,
- 4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul,
- 6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul,
- 11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul,
- 16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul,
- 24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul,
- 36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul,
- 54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul,
- 80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul,
- 118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul,
- 176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul,
- 260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul,
- 386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul,
- 573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul,
- 849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul,
- 1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul, 1725587117ul,
- 1866894511ul, 2019773507ul, 2185171673ul, 2364114217ul, 2557710269ul,
- 2767159799ul, 2993761039ul, 3238918481ul, 3504151727ul, 3791104843ul,
- 4101556399ul, 4294967291ul,
-#if __SIZEOF_LONG__ >= 8
- 6442450933ul, 8589934583ul, 12884901857ul, 17179869143ul,
- 25769803693ul, 34359738337ul, 51539607367ul, 68719476731ul,
- 103079215087ul, 137438953447ul, 206158430123ul, 274877906899ul,
- 412316860387ul, 549755813881ul, 824633720731ul, 1099511627689ul,
- 1649267441579ul, 2199023255531ul, 3298534883309ul, 4398046511093ul,
- 6597069766607ul, 8796093022151ul, 13194139533241ul, 17592186044399ul,
- 26388279066581ul, 35184372088777ul, 52776558133177ul, 70368744177643ul,
- 105553116266399ul, 140737488355213ul, 211106232532861ul, 281474976710597ul,
- 562949953421231ul, 1125899906842597ul, 2251799813685119ul,
- 4503599627370449ul, 9007199254740881ul, 18014398509481951ul,
- 36028797018963913ul, 72057594037927931ul, 144115188075855859ul,
- 288230376151711717ul, 576460752303423433ul,
- 1152921504606846883ul, 2305843009213693951ul,
- 4611686018427387847ul, 9223372036854775783ul,
- 18446744073709551557ul
-#endif
-};
-
-/* Return the next number from PRIME_LIST >= N. */
-
-uintptr_t
-__go_map_next_prime (uintptr_t n)
-{
- size_t low;
- size_t high;
-
- low = 0;
- high = sizeof prime_list / sizeof prime_list[0];
- while (low < high)
- {
- size_t mid;
-
- mid = (low + high) / 2;
-
- /* Here LOW <= MID < HIGH. */
-
- if (prime_list[mid] < n)
- low = mid + 1;
- else if (prime_list[mid] > n)
- high = mid;
- else
- return n;
- }
- if (low >= sizeof prime_list / sizeof prime_list[0])
- return n;
- return prime_list[low];
-}
-
-/* Allocate a new map. */
-
-struct __go_map *
-__go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
-{
- int32 ientries;
- struct __go_map *ret;
-
- /* The master library limits map entries to int32, so we do too. */
- ientries = (int32) entries;
- if (ientries < 0 || (uintptr_t) ientries != entries)
- runtime_panicstring ("map size out of range");
-
- if (entries == 0)
- entries = 5;
- else
- entries = __go_map_next_prime (entries);
- ret = (struct __go_map *) __go_alloc (sizeof (struct __go_map));
- ret->__descriptor = descriptor;
- ret->__element_count = 0;
- ret->__bucket_count = entries;
- ret->__buckets = (void **) __go_alloc (entries * sizeof (void *));
- __builtin_memset (ret->__buckets, 0, entries * sizeof (void *));
- return ret;
-}
-
-/* Allocate a new map when the argument to make is a large type. */
-
-struct __go_map *
-__go_new_map_big (const struct __go_map_descriptor *descriptor,
- uint64_t entries)
-{
- uintptr_t sentries;
-
- sentries = (uintptr_t) entries;
- if ((uint64_t) sentries != entries)
- runtime_panicstring ("map size out of range");
- return __go_new_map (descriptor, sentries);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-new.c b/gcc-4.8.1/libgo/runtime/go-new.c
deleted file mode 100644
index b1af5f224..000000000
--- a/gcc-4.8.1/libgo/runtime/go-new.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* go-new.c -- the generic go new() function.
-
- 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. */
-
-#include "go-alloc.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-void *
-__go_new (uintptr_t size)
-{
- return runtime_mallocgc (size, 0, 1, 1);
-}
-
-void *
-__go_new_nopointers (uintptr_t size)
-{
- return runtime_mallocgc (size, FlagNoPointers, 1, 1);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-nosys.c b/gcc-4.8.1/libgo/runtime/go-nosys.c
deleted file mode 100644
index 3ab5ea235..000000000
--- a/gcc-4.8.1/libgo/runtime/go-nosys.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/* go-nosys.c -- functions missing from system.
-
- Copyright 2012 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. */
-
-/* This file exists to provide definitions for functions that are
- missing from libc, according to the configure script. This permits
- the Go syscall package to not worry about whether the functions
- exist or not. */
-
-#include "config.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
-#ifndef HAVE_OFF64_T
-typedef signed int off64_t __attribute__ ((mode (DI)));
-#endif
-
-#ifndef HAVE_LOFF_T
-typedef off64_t loff_t;
-#endif
-
-#ifndef HAVE_ACCEPT4
-struct sockaddr;
-int
-accept4 (int sockfd __attribute__ ((unused)),
- struct sockaddr *addr __attribute__ ((unused)),
- socklen_t *addrlen __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_EPOLL_CREATE1
-int
-epoll_create1 (int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_FACCESSAT
-int
-faccessat (int fd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- int mode __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_FALLOCATE
-int
-fallocate (int fd __attribute__ ((unused)),
- int mode __attribute__ ((unused)),
- off_t offset __attribute__ ((unused)),
- off_t len __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_FCHMODAT
-int
-fchmodat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- mode_t mode __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_FCHOWNAT
-int
-fchownat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- uid_t owner __attribute__ ((unused)),
- gid_t group __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_FUTIMESAT
-int
-futimesat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- const struct timeval times[2] __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_INOTIFY_ADD_WATCH
-int
-inotify_add_watch (int fd __attribute__ ((unused)),
- const char* pathname __attribute__ ((unused)),
- uint32_t mask __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_INOTIFY_INIT
-int
-inotify_init (void)
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_INOTIFY_INIT1
-int
-inotify_init1 (int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_INOTIFY_RM_WATCH
-int
-inotify_rm_watch (int fd __attribute__ ((unused)),
- uint32_t wd __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_MKDIRAT
-int
-mkdirat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- mode_t mode __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_MKNODAT
-int
-mknodat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- mode_t mode __attribute__ ((unused)),
- dev_t dev __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_OPENAT
-int
-openat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- int oflag __attribute__ ((unused)),
- ...)
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_PIPE2
-int
-pipe2 (int pipefd[2] __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_RENAMEAT
-int
-renameat (int olddirfd __attribute__ ((unused)),
- const char *oldpath __attribute__ ((unused)),
- int newdirfd __attribute__ ((unused)),
- const char *newpath __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_SPLICE
-int
-splice (int fd __attribute__ ((unused)),
- loff_t *off_in __attribute__ ((unused)),
- int fd_out __attribute__ ((unused)),
- loff_t *off_out __attribute__ ((unused)),
- size_t len __attribute__ ((unused)),
- unsigned int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_SYNC_FILE_RANGE
-int
-sync_file_range (int fd __attribute__ ((unused)),
- off64_t offset __attribute__ ((unused)),
- off64_t nbytes __attribute__ ((unused)),
- unsigned int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_TEE
-int
-tee (int fd_in __attribute__ ((unused)),
- int fd_out __attribute__ ((unused)),
- size_t len __attribute__ ((unused)),
- unsigned int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_UNLINKAT
-int
-unlinkat (int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_UNSHARE
-int
-unshare (int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-#ifndef HAVE_UTIMENSAT
-struct timespec;
-int
-utimensat(int dirfd __attribute__ ((unused)),
- const char *pathname __attribute__ ((unused)),
- const struct timespec times[2] __attribute__ ((unused)),
- int flags __attribute__ ((unused)))
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-/* Long double math functions. These are needed on old i386 systems
- that don't have them in libm. The compiler translates calls to
- these functions on float64 to call an 80-bit floating point
- function instead, because when optimizing that function can be
- executed as an x87 instructure. However, when not optimizing, this
- translates into a call to the math function. So on systems that
- don't provide these functions, we provide a version that just calls
- the float64 version. */
-
-#ifndef HAVE_COSL
-long double
-cosl (long double a)
-{
- return (long double) cos ((double) a);
-}
-#endif
-
-#ifndef HAVE_EXPL
-long double
-expl (long double a)
-{
- return (long double) exp ((double) a);
-}
-#endif
-
-#ifndef HAVE_LOGL
-long double
-logl (long double a)
-{
- return (long double) log ((double) a);
-}
-#endif
-
-#ifndef HAVE_SINL
-long double
-sinl (long double a)
-{
- return (long double) sin ((double) a);
-}
-#endif
-
-#ifndef HAVE_TANL
-long double
-tanl (long double a)
-{
- return (long double) tan ((double) a);
-}
-#endif
-
-#ifndef HAVE_ACOSL
-long double
-acosl (long double a)
-{
- return (long double) acos ((double) a);
-}
-#endif
-
-#ifndef HAVE_ASINL
-long double
-asinl (long double a)
-{
- return (long double) asin ((double) a);
-}
-#endif
-
-#ifndef HAVE_ATANL
-long double
-atanl (long double a)
-{
- return (long double) atan ((double) a);
-}
-#endif
-
-#ifndef HAVE_ATAN2L
-long double
-atan2l (long double a, long double b)
-{
- return (long double) atan2 ((double) a, (double) b);
-}
-#endif
-
-#ifndef HAVE_EXPM1L
-long double
-expm1l (long double a)
-{
- return (long double) expm1 ((double) a);
-}
-#endif
-
-#ifndef HAVE_LDEXPL
-long double
-ldexpl (long double a, int exp)
-{
- return (long double) ldexp ((double) a, exp);
-}
-#endif
-
-#ifndef HAVE_LOG10L
-long double
-log10l (long double a)
-{
- return (long double) log10 ((double) a);
-}
-#endif
-
-#ifndef HAVE_LOG1PL
-long double
-log1pl (long double a)
-{
- return (long double) log1p ((double) a);
-}
-#endif
diff --git a/gcc-4.8.1/libgo/runtime/go-now.c b/gcc-4.8.1/libgo/runtime/go-now.c
deleted file mode 100644
index 73cc1602d..000000000
--- a/gcc-4.8.1/libgo/runtime/go-now.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2011 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.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/time.h>
-
-#include "runtime.h"
-
-// Return current time. This is the implementation of time.now().
-
-struct time_now_ret
-{
- int64_t sec;
- int32_t nsec;
-};
-
-struct time_now_ret now()
- __asm__ (GOSYM_PREFIX "time.now")
- __attribute__ ((no_split_stack));
-
-struct time_now_ret
-now()
-{
- struct timeval tv;
- struct time_now_ret ret;
-
- gettimeofday (&tv, NULL);
- ret.sec = tv.tv_sec;
- ret.nsec = tv.tv_usec * 1000;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-panic.c b/gcc-4.8.1/libgo/runtime/go-panic.c
deleted file mode 100644
index 530629ca3..000000000
--- a/gcc-4.8.1/libgo/runtime/go-panic.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* go-panic.c -- support for the go panic function.
-
- 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. */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-alloc.h"
-#include "go-defer.h"
-#include "go-panic.h"
-#include "interface.h"
-
-/* Print the panic stack. This is used when there is no recover. */
-
-static void
-__printpanics (struct __go_panic_stack *p)
-{
- if (p->__next != NULL)
- {
- __printpanics (p->__next);
- runtime_printf ("\t");
- }
- runtime_printf ("panic: ");
- runtime_printany (p->__arg);
- if (p->__was_recovered)
- runtime_printf (" [recovered]");
- runtime_printf ("\n");
-}
-
-/* This implements __go_panic which is used for the panic
- function. */
-
-void
-__go_panic (struct __go_empty_interface arg)
-{
- G *g;
- struct __go_panic_stack *n;
-
- g = runtime_g ();
-
- n = (struct __go_panic_stack *) __go_alloc (sizeof (struct __go_panic_stack));
- n->__arg = arg;
- n->__next = g->panic;
- g->panic = n;
-
- /* Run all the defer functions. */
-
- while (1)
- {
- struct __go_defer_stack *d;
- void (*pfn) (void *);
-
- d = g->defer;
- if (d == NULL)
- break;
-
- pfn = d->__pfn;
- d->__pfn = NULL;
-
- if (pfn != NULL)
- {
- (*pfn) (d->__arg);
-
- if (n->__was_recovered)
- {
- /* Some defer function called recover. That means that
- we should stop running this panic. */
-
- g->panic = n->__next;
- __go_free (n);
-
- /* Now unwind the stack by throwing an exception. The
- compiler has arranged to create exception handlers in
- each function which uses a defer statement. These
- exception handlers will check whether the entry on
- the top of the defer stack is from the current
- function. If it is, we have unwound the stack far
- enough. */
- __go_unwind_stack ();
-
- /* __go_unwind_stack should not return. */
- abort ();
- }
-
- /* Because we executed that defer function by a panic, and
- it did not call recover, we know that we are not
- returning from the calling function--we are panicing
- through it. */
- *d->__frame = 0;
- }
-
- g->defer = d->__next;
- __go_free (d);
- }
-
- /* The panic was not recovered. */
-
- runtime_startpanic ();
- __printpanics (g->panic);
- runtime_dopanic (0);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-panic.h b/gcc-4.8.1/libgo/runtime/go-panic.h
deleted file mode 100644
index e7031d404..000000000
--- a/gcc-4.8.1/libgo/runtime/go-panic.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* go-panic.h -- declare the go panic functions.
-
- 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. */
-
-#ifndef LIBGO_GO_PANIC_H
-#define LIBGO_GO_PANIC_H
-
-#include "interface.h"
-
-struct String;
-struct __go_type_descriptor;
-struct __go_defer_stack;
-
-/* The stack of panic calls. */
-
-struct __go_panic_stack
-{
- /* The next entry in the stack. */
- struct __go_panic_stack *__next;
-
- /* The value associated with this panic. */
- struct __go_empty_interface __arg;
-
- /* Whether this panic has been recovered. */
- _Bool __was_recovered;
-
- /* Whether this panic was pushed on the stack because of an
- exception thrown in some other language. */
- _Bool __is_foreign;
-};
-
-extern void __go_panic (struct __go_empty_interface)
- __attribute__ ((noreturn));
-
-extern void __go_print_string (struct String);
-
-extern struct __go_empty_interface __go_recover (void);
-
-extern void __go_unwind_stack (void);
-
-#endif /* !defined(LIBGO_GO_PANIC_H) */
diff --git a/gcc-4.8.1/libgo/runtime/go-print.c b/gcc-4.8.1/libgo/runtime/go-print.c
deleted file mode 100644
index 4c520de3c..000000000
--- a/gcc-4.8.1/libgo/runtime/go-print.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* go-print.c -- support for the go print statement.
-
- 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. */
-
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "runtime.h"
-#include "array.h"
-#include "go-panic.h"
-#include "interface.h"
-
-/* This implements the various little functions which are called by
- the predeclared functions print/println/panic/panicln. */
-
-void
-__go_print_empty_interface (struct __go_empty_interface e)
-{
- runtime_printf ("(%p,%p)", e.__type_descriptor, e.__object);
-}
-
-void
-__go_print_interface (struct __go_interface i)
-{
- runtime_printf ("(%p,%p)", i.__methods, i.__object);
-}
-
-void
-__go_print_slice (struct __go_open_array val)
-{
- runtime_printf ("[%d/%d]", val.__count, val.__capacity);
- runtime_printpointer (val.__values);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-recover.c b/gcc-4.8.1/libgo/runtime/go-recover.c
deleted file mode 100644
index d6403e00d..000000000
--- a/gcc-4.8.1/libgo/runtime/go-recover.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* go-recover.c -- support for the go recover function.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "interface.h"
-#include "go-panic.h"
-#include "go-defer.h"
-
-/* This is called by a thunk to see if the real function should be
- permitted to recover a panic value. Recovering a value is
- permitted if the thunk was called directly by defer. RETADDR is
- the return address of the function which is calling
- __go_can_recover--this is, the thunk. */
-
-_Bool
-__go_can_recover (const void* retaddr)
-{
- G *g;
- struct __go_defer_stack *d;
- const char* ret;
- const char* dret;
-
- g = runtime_g ();
-
- d = g->defer;
- if (d == NULL)
- return 0;
-
- /* The panic which this function would recover is the one on the top
- of the panic stack. We do not want to recover it if that panic
- was on the top of the panic stack when this function was
- deferred. */
- if (d->__panic == g->panic)
- return 0;
-
- /* D->__RETADDR is the address of a label immediately following the
- call to the thunk. We can recover a panic if that is the same as
- the return address of the thunk. We permit a bit of slack in
- case there is any code between the function return and the label,
- such as an instruction to adjust the stack pointer. */
-
- ret = (const char *) retaddr;
-
-#ifdef __sparc__
- /* On SPARC the address we get, from __builtin_return_address, is
- the address of the call instruction. Adjust forward, also
- skipping the delayed instruction following the call. */
- ret += 8;
-#endif
-
- dret = (const char *) d->__retaddr;
- return ret <= dret && ret + 16 >= dret;
-}
-
-/* This is only called when it is valid for the caller to recover the
- value on top of the panic stack, if there is one. */
-
-struct __go_empty_interface
-__go_recover ()
-{
- G *g;
- struct __go_panic_stack *p;
-
- g = runtime_g ();
-
- if (g->panic == NULL || g->panic->__was_recovered)
- {
- struct __go_empty_interface ret;
-
- ret.__type_descriptor = NULL;
- ret.__object = NULL;
- return ret;
- }
- p = g->panic;
- p->__was_recovered = 1;
- return p->__arg;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-reflect-call.c b/gcc-4.8.1/libgo/runtime/go-reflect-call.c
deleted file mode 100644
index a66f92868..000000000
--- a/gcc-4.8.1/libgo/runtime/go-reflect-call.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/* go-reflect-call.c -- call reflection support for Go.
-
- 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. */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "go-type.h"
-
-#ifdef USE_LIBFFI
-
-#include "ffi.h"
-
-/* The functions in this file are only called from reflect_call. As
- reflect_call calls a libffi function, which will be compiled
- without -fsplit-stack, it will always run with a large stack. */
-
-static ffi_type *go_array_to_ffi (const struct __go_array_type *)
- __attribute__ ((no_split_stack));
-static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
- __attribute__ ((no_split_stack));
-static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
- __attribute__ ((no_split_stack));
-static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
-static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
-static ffi_type *go_complex_to_ffi (ffi_type *)
- __attribute__ ((no_split_stack, unused));
-static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
- __attribute__ ((no_split_stack));
-static ffi_type *go_func_return_ffi (const struct __go_func_type *)
- __attribute__ ((no_split_stack));
-static void go_func_to_cif (const struct __go_func_type *, _Bool, _Bool,
- ffi_cif *)
- __attribute__ ((no_split_stack));
-static size_t go_results_size (const struct __go_func_type *)
- __attribute__ ((no_split_stack));
-static void go_set_results (const struct __go_func_type *, unsigned char *,
- void **)
- __attribute__ ((no_split_stack));
-
-/* Return an ffi_type for a Go array type. The libffi library does
- not have any builtin support for passing arrays as values. We work
- around this by pretending that the array is a struct. */
-
-static ffi_type *
-go_array_to_ffi (const struct __go_array_type *descriptor)
-{
- ffi_type *ret;
- uintptr_t len;
- ffi_type *element;
- uintptr_t i;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- len = descriptor->__len;
- ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
- element = go_type_to_ffi (descriptor->__element_type);
- for (i = 0; i < len; ++i)
- ret->elements[i] = element;
- ret->elements[len] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a Go slice type. This describes the
- __go_open_array type defines in array.h. */
-
-static ffi_type *
-go_slice_to_ffi (
- const struct __go_slice_type *descriptor __attribute__ ((unused)))
-{
- ffi_type *ret;
- ffi_type *ffi_intgo;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
- ret->elements[0] = &ffi_type_pointer;
- ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
- ret->elements[1] = ffi_intgo;
- ret->elements[2] = ffi_intgo;
- ret->elements[3] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a Go struct type. */
-
-static ffi_type *
-go_struct_to_ffi (const struct __go_struct_type *descriptor)
-{
- ffi_type *ret;
- int field_count;
- const struct __go_struct_field *fields;
- int i;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- field_count = descriptor->__fields.__count;
- fields = (const struct __go_struct_field *) descriptor->__fields.__values;
- ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
- * sizeof (ffi_type *));
- for (i = 0; i < field_count; ++i)
- ret->elements[i] = go_type_to_ffi (fields[i].__type);
- ret->elements[field_count] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a Go string type. This describes the String
- struct. */
-
-static ffi_type *
-go_string_to_ffi (void)
-{
- ffi_type *ret;
- ffi_type *ffi_intgo;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
- ret->elements[0] = &ffi_type_pointer;
- ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
- ret->elements[1] = ffi_intgo;
- ret->elements[2] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a Go interface type. This describes the
- __go_interface and __go_empty_interface structs. */
-
-static ffi_type *
-go_interface_to_ffi (void)
-{
- ffi_type *ret;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
- ret->elements[0] = &ffi_type_pointer;
- ret->elements[1] = &ffi_type_pointer;
- ret->elements[2] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a Go complex type. */
-
-static ffi_type *
-go_complex_to_ffi (ffi_type *float_type)
-{
- ffi_type *ret;
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
- ret->elements[0] = float_type;
- ret->elements[1] = float_type;
- ret->elements[2] = NULL;
- return ret;
-}
-
-/* Return an ffi_type for a type described by a
- __go_type_descriptor. */
-
-static ffi_type *
-go_type_to_ffi (const struct __go_type_descriptor *descriptor)
-{
- switch (descriptor->__code & GO_CODE_MASK)
- {
- case GO_BOOL:
- if (sizeof (_Bool) == 1)
- return &ffi_type_uint8;
- else if (sizeof (_Bool) == sizeof (int))
- return &ffi_type_uint;
- abort ();
- case GO_FLOAT32:
- if (sizeof (float) == 4)
- return &ffi_type_float;
- abort ();
- case GO_FLOAT64:
- if (sizeof (double) == 8)
- return &ffi_type_double;
- abort ();
- case GO_COMPLEX64:
-#ifdef __alpha__
- runtime_throw("the libffi library does not support Complex64 type with "
- "reflect.Call or runtime.SetFinalizer");
-#else
- if (sizeof (float) == 4)
- return go_complex_to_ffi (&ffi_type_float);
- abort ();
-#endif
- case GO_COMPLEX128:
-#ifdef __alpha__
- runtime_throw("the libffi library does not support Complex128 type with "
- "reflect.Call or runtime.SetFinalizer");
-#else
- if (sizeof (double) == 8)
- return go_complex_to_ffi (&ffi_type_double);
- abort ();
-#endif
- case GO_INT16:
- return &ffi_type_sint16;
- case GO_INT32:
- return &ffi_type_sint32;
- case GO_INT64:
- return &ffi_type_sint64;
- case GO_INT8:
- return &ffi_type_sint8;
- case GO_INT:
- return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
- case GO_UINT16:
- return &ffi_type_uint16;
- case GO_UINT32:
- return &ffi_type_uint32;
- case GO_UINT64:
- return &ffi_type_uint64;
- case GO_UINT8:
- return &ffi_type_uint8;
- case GO_UINT:
- return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64;
- case GO_UINTPTR:
- if (sizeof (void *) == 2)
- return &ffi_type_uint16;
- else if (sizeof (void *) == 4)
- return &ffi_type_uint32;
- else if (sizeof (void *) == 8)
- return &ffi_type_uint64;
- abort ();
- case GO_ARRAY:
- return go_array_to_ffi ((const struct __go_array_type *) descriptor);
- case GO_SLICE:
- return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
- case GO_STRUCT:
- return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
- case GO_STRING:
- return go_string_to_ffi ();
- case GO_INTERFACE:
- return go_interface_to_ffi ();
- case GO_CHAN:
- case GO_FUNC:
- case GO_MAP:
- case GO_PTR:
- case GO_UNSAFE_POINTER:
- /* These types are always pointers, and for FFI purposes nothing
- else matters. */
- return &ffi_type_pointer;
- default:
- abort ();
- }
-}
-
-/* Return the return type for a function, given the number of out
- parameters and their types. */
-
-static ffi_type *
-go_func_return_ffi (const struct __go_func_type *func)
-{
- int count;
- const struct __go_type_descriptor **types;
- ffi_type *ret;
- int i;
-
- count = func->__out.__count;
- if (count == 0)
- return &ffi_type_void;
-
- types = (const struct __go_type_descriptor **) func->__out.__values;
-
- if (count == 1)
- return go_type_to_ffi (types[0]);
-
- ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
- ret->type = FFI_TYPE_STRUCT;
- ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
- for (i = 0; i < count; ++i)
- ret->elements[i] = go_type_to_ffi (types[i]);
- ret->elements[count] = NULL;
- return ret;
-}
-
-/* Build an ffi_cif structure for a function described by a
- __go_func_type structure. */
-
-static void
-go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
- _Bool is_method, ffi_cif *cif)
-{
- int num_params;
- const struct __go_type_descriptor **in_types;
- size_t num_args;
- ffi_type **args;
- int off;
- int i;
- ffi_type *rettype;
- ffi_status status;
-
- num_params = func->__in.__count;
- in_types = ((const struct __go_type_descriptor **)
- func->__in.__values);
-
- num_args = num_params + (is_interface ? 1 : 0);
- args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
- i = 0;
- off = 0;
- if (is_interface)
- {
- args[0] = &ffi_type_pointer;
- off = 1;
- }
- else if (is_method)
- {
- args[0] = &ffi_type_pointer;
- i = 1;
- }
- for (; i < num_params; ++i)
- args[i + off] = go_type_to_ffi (in_types[i]);
-
- rettype = go_func_return_ffi (func);
-
- status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
- __go_assert (status == FFI_OK);
-}
-
-/* Get the total size required for the result parameters of a
- function. */
-
-static size_t
-go_results_size (const struct __go_func_type *func)
-{
- int count;
- const struct __go_type_descriptor **types;
- size_t off;
- size_t maxalign;
- int i;
-
- count = func->__out.__count;
- if (count == 0)
- return 0;
-
- types = (const struct __go_type_descriptor **) func->__out.__values;
-
- /* A single integer return value is always promoted to a full
- word. */
- if (count == 1)
- {
- switch (types[0]->__code & GO_CODE_MASK)
- {
- case GO_BOOL:
- case GO_INT8:
- case GO_INT16:
- case GO_INT32:
- case GO_UINT8:
- case GO_UINT16:
- case GO_UINT32:
- case GO_INT:
- case GO_UINT:
- return sizeof (ffi_arg);
-
- default:
- break;
- }
- }
-
- off = 0;
- maxalign = 0;
- for (i = 0; i < count; ++i)
- {
- size_t align;
-
- align = types[i]->__field_align;
- if (align > maxalign)
- maxalign = align;
- off = (off + align - 1) & ~ (align - 1);
- off += types[i]->__size;
- }
-
- off = (off + maxalign - 1) & ~ (maxalign - 1);
-
- return off;
-}
-
-/* Copy the results of calling a function via FFI from CALL_RESULT
- into the addresses in RESULTS. */
-
-static void
-go_set_results (const struct __go_func_type *func, unsigned char *call_result,
- void **results)
-{
- int count;
- const struct __go_type_descriptor **types;
- size_t off;
- int i;
-
- count = func->__out.__count;
- if (count == 0)
- return;
-
- types = (const struct __go_type_descriptor **) func->__out.__values;
-
- /* A single integer return value is always promoted to a full
- word. */
- if (count == 1)
- {
- switch (types[0]->__code & GO_CODE_MASK)
- {
- case GO_BOOL:
- case GO_INT8:
- case GO_INT16:
- case GO_INT32:
- case GO_UINT8:
- case GO_UINT16:
- case GO_UINT32:
- case GO_INT:
- case GO_UINT:
- {
- union
- {
- unsigned char buf[sizeof (ffi_arg)];
- ffi_arg v;
- } u;
- ffi_arg v;
-
- __builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
- v = u.v;
-
- switch (types[0]->__size)
- {
- case 1:
- {
- uint8_t b;
-
- b = (uint8_t) v;
- __builtin_memcpy (results[0], &b, 1);
- }
- break;
-
- case 2:
- {
- uint16_t s;
-
- s = (uint16_t) v;
- __builtin_memcpy (results[0], &s, 2);
- }
- break;
-
- case 4:
- {
- uint32_t w;
-
- w = (uint32_t) v;
- __builtin_memcpy (results[0], &w, 4);
- }
- break;
-
- case 8:
- {
- uint64_t d;
-
- d = (uint64_t) v;
- __builtin_memcpy (results[0], &d, 8);
- }
- break;
-
- default:
- abort ();
- }
- }
- return;
-
- default:
- break;
- }
- }
-
- off = 0;
- for (i = 0; i < count; ++i)
- {
- size_t align;
- size_t size;
-
- align = types[i]->__field_align;
- size = types[i]->__size;
- off = (off + align - 1) & ~ (align - 1);
- __builtin_memcpy (results[i], call_result + off, size);
- off += size;
- }
-}
-
-/* Call a function. The type of the function is FUNC_TYPE, and the
- address is FUNC_ADDR. PARAMS is an array of parameter addresses.
- RESULTS is an array of result addresses. */
-
-void
-reflect_call (const struct __go_func_type *func_type, const void *func_addr,
- _Bool is_interface, _Bool is_method, void **params,
- void **results)
-{
- ffi_cif cif;
- unsigned char *call_result;
-
- __go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
- go_func_to_cif (func_type, is_interface, is_method, &cif);
-
- call_result = (unsigned char *) malloc (go_results_size (func_type));
-
- ffi_call (&cif, func_addr, call_result, params);
-
- /* Some day we may need to free result values if RESULTS is
- NULL. */
- if (results != NULL)
- go_set_results (func_type, call_result, results);
-
- free (call_result);
-}
-
-#else /* !defined(USE_LIBFFI) */
-
-void
-reflect_call (const struct __go_func_type *func_type __attribute__ ((unused)),
- const void *func_addr __attribute__ ((unused)),
- _Bool is_interface __attribute__ ((unused)),
- _Bool is_method __attribute__ ((unused)),
- void **params __attribute__ ((unused)),
- void **results __attribute__ ((unused)))
-{
- /* Without FFI there is nothing we can do. */
- runtime_throw("libgo built without FFI does not support "
- "reflect.Call or runtime.SetFinalizer");
-}
-
-#endif /* !defined(USE_LIBFFI) */
diff --git a/gcc-4.8.1/libgo/runtime/go-reflect-map.c b/gcc-4.8.1/libgo/runtime/go-reflect-map.c
deleted file mode 100644
index 369753749..000000000
--- a/gcc-4.8.1/libgo/runtime/go-reflect-map.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* go-reflect-map.c -- map reflection support for Go.
-
- Copyright 2009, 2010 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. */
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-assert.h"
-#include "go-type.h"
-#include "map.h"
-
-/* This file implements support for reflection on maps. These
- functions are called from reflect/value.go. */
-
-struct mapaccess_ret
-{
- uintptr_t val;
- _Bool pres;
-};
-
-extern struct mapaccess_ret mapaccess (struct __go_map_type *, uintptr_t,
- uintptr_t)
- __asm__ (GOSYM_PREFIX "reflect.mapaccess");
-
-struct mapaccess_ret
-mapaccess (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i)
-{
- struct __go_map *map = (struct __go_map *) m;
- void *key;
- const struct __go_type_descriptor *key_descriptor;
- void *p;
- const struct __go_type_descriptor *val_descriptor;
- struct mapaccess_ret ret;
- void *val;
- void *pv;
-
- __go_assert (mt->__common.__code == GO_MAP);
-
- key_descriptor = mt->__key_type;
- if (__go_is_pointer_type (key_descriptor))
- key = &key_i;
- else
- key = (void *) key_i;
-
- if (map == NULL)
- p = NULL;
- else
- p = __go_map_index (map, key, 0);
-
- val_descriptor = mt->__val_type;
- if (__go_is_pointer_type (val_descriptor))
- {
- val = NULL;
- pv = &val;
- }
- else
- {
- val = __go_alloc (val_descriptor->__size);
- pv = val;
- }
-
- if (p == NULL)
- ret.pres = 0;
- else
- {
- __builtin_memcpy (pv, p, val_descriptor->__size);
- ret.pres = 1;
- }
-
- ret.val = (uintptr_t) val;
- return ret;
-}
-
-extern void mapassign (struct __go_map_type *, uintptr_t, uintptr_t,
- uintptr_t, _Bool)
- __asm__ (GOSYM_PREFIX "reflect.mapassign");
-
-void
-mapassign (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i,
- uintptr_t val_i, _Bool pres)
-{
- struct __go_map *map = (struct __go_map *) m;
- const struct __go_type_descriptor *key_descriptor;
- void *key;
-
- __go_assert (mt->__common.__code == GO_MAP);
-
- if (map == NULL)
- runtime_panicstring ("assignment to entry in nil map");
-
- key_descriptor = mt->__key_type;
- if (__go_is_pointer_type (key_descriptor))
- key = &key_i;
- else
- key = (void *) key_i;
-
- if (!pres)
- __go_map_delete (map, key);
- else
- {
- void *p;
- const struct __go_type_descriptor *val_descriptor;
- void *pv;
-
- p = __go_map_index (map, key, 1);
-
- val_descriptor = mt->__val_type;
- if (__go_is_pointer_type (val_descriptor))
- pv = &val_i;
- else
- pv = (void *) val_i;
- __builtin_memcpy (p, pv, val_descriptor->__size);
- }
-}
-
-extern int32_t maplen (uintptr_t)
- __asm__ (GOSYM_PREFIX "reflect.maplen");
-
-int32_t
-maplen (uintptr_t m)
-{
- struct __go_map *map = (struct __go_map *) m;
-
- if (map == NULL)
- return 0;
- return (int32_t) map->__element_count;
-}
-
-extern unsigned char *mapiterinit (struct __go_map_type *, uintptr_t)
- __asm__ (GOSYM_PREFIX "reflect.mapiterinit");
-
-unsigned char *
-mapiterinit (struct __go_map_type *mt, uintptr_t m)
-{
- struct __go_hash_iter *it;
-
- __go_assert (mt->__common.__code == GO_MAP);
- it = __go_alloc (sizeof (struct __go_hash_iter));
- __go_mapiterinit ((struct __go_map *) m, it);
- return (unsigned char *) it;
-}
-
-extern void mapiternext (unsigned char *)
- __asm__ (GOSYM_PREFIX "reflect.mapiternext");
-
-void
-mapiternext (unsigned char *it)
-{
- __go_mapiternext ((struct __go_hash_iter *) it);
-}
-
-struct mapiterkey_ret
-{
- uintptr_t key;
- _Bool ok;
-};
-
-extern struct mapiterkey_ret mapiterkey (unsigned char *)
- __asm__ (GOSYM_PREFIX "reflect.mapiterkey");
-
-struct mapiterkey_ret
-mapiterkey (unsigned char *ita)
-{
- struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
- struct mapiterkey_ret ret;
-
- if (it->entry == NULL)
- {
- ret.key = 0;
- ret.ok = 0;
- }
- else
- {
- const struct __go_type_descriptor *key_descriptor;
- void *key;
- void *pk;
-
- key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
- if (__go_is_pointer_type (key_descriptor))
- {
- key = NULL;
- pk = &key;
- }
- else
- {
- key = __go_alloc (key_descriptor->__size);
- pk = key;
- }
-
- __go_mapiter1 (it, pk);
-
- ret.key = (uintptr_t) key;
- ret.ok = 1;
- }
-
- return ret;
-}
-
-/* Make a new map. We have to build our own map descriptor. */
-
-extern uintptr_t makemap (const struct __go_map_type *)
- __asm__ (GOSYM_PREFIX "reflect.makemap");
-
-uintptr_t
-makemap (const struct __go_map_type *t)
-{
- struct __go_map_descriptor *md;
- unsigned int o;
- const struct __go_type_descriptor *kt;
- const struct __go_type_descriptor *vt;
- struct __go_map* map;
- void *ret;
-
- /* FIXME: Reference count. */
- md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
- md->__map_descriptor = t;
- o = sizeof (void *);
- kt = t->__key_type;
- o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
- md->__key_offset = o;
- o += kt->__size;
- vt = t->__val_type;
- o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
- md->__val_offset = o;
- o += vt->__size;
- o = (o + sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
- o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
- o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
- md->__entry_size = o;
-
- map = __go_new_map (md, 0);
-
- ret = __go_alloc (sizeof (void *));
- __builtin_memcpy (ret, &map, sizeof (void *));
- return (uintptr_t) ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-rune.c b/gcc-4.8.1/libgo/runtime/go-rune.c
deleted file mode 100644
index 4c65e2151..000000000
--- a/gcc-4.8.1/libgo/runtime/go-rune.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* go-rune.c -- rune functions for Go.
-
- Copyright 2009, 2010 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-string.h"
-
-/* Get a character from the UTF-8 string STR, of length LEN. Store
- the Unicode character, if any, in *RUNE. Return the number of
- characters used from STR. */
-
-int
-__go_get_rune (const unsigned char *str, size_t len, int32 *rune)
-{
- int c, c1, c2, c3, l;
-
- /* Default to the "replacement character". */
- *rune = 0xfffd;
-
- if (len <= 0)
- return 1;
-
- c = *str;
- if (c <= 0x7f)
- {
- *rune = c;
- return 1;
- }
-
- if (len <= 1)
- return 1;
-
- c1 = str[1];
- if ((c & 0xe0) == 0xc0
- && (c1 & 0xc0) == 0x80)
- {
- l = (((c & 0x1f) << 6) + (c1 & 0x3f));
- if (l <= 0x7f)
- return 1;
- *rune = l;
- return 2;
- }
-
- if (len <= 2)
- return 1;
-
- c2 = str[2];
- if ((c & 0xf0) == 0xe0
- && (c1 & 0xc0) == 0x80
- && (c2 & 0xc0) == 0x80)
- {
- l = (((c & 0xf) << 12)
- + ((c1 & 0x3f) << 6)
- + (c2 & 0x3f));
-
- if (l <= 0x7ff)
- return 1;
-
- if (l >= 0xd800 && l < 0xe000)
- {
- /* Invalid surrogate half; return replace character. */
- return 1;
- }
-
- *rune = l;
-
- return 3;
- }
-
- if (len <= 3)
- return 1;
-
- c3 = str[3];
- if ((c & 0xf8) == 0xf0
- && (c1 & 0xc0) == 0x80
- && (c2 & 0xc0) == 0x80
- && (c3 & 0xc0) == 0x80)
- {
- l = (((c & 0x7) << 18)
- + ((c1 & 0x3f) << 12)
- + ((c2 & 0x3f) << 6)
- + (c3 & 0x3f));
-
- if (l <= 0xffff || l > 0x10ffff)
- return 1;
-
- *rune = l;
- return 4;
- }
-
- /* Invalid encoding. Return 1 so that we advance. */
- return 1;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-runtime-error.c b/gcc-4.8.1/libgo/runtime/go-runtime-error.c
deleted file mode 100644
index f5ab4f919..000000000
--- a/gcc-4.8.1/libgo/runtime/go-runtime-error.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* go-runtime-error.c -- Go runtime error.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-
-/* The compiler generates calls to this function. This enum values
- are known to the compiler and used by compiled code. Any change
- here must be reflected in the compiler. */
-
-enum
-{
- /* Slice index out of bounds: negative or larger than the length of
- the slice. */
- SLICE_INDEX_OUT_OF_BOUNDS = 0,
-
- /* Array index out of bounds. */
- ARRAY_INDEX_OUT_OF_BOUNDS = 1,
-
- /* String index out of bounds. */
- STRING_INDEX_OUT_OF_BOUNDS = 2,
-
- /* Slice slice out of bounds: negative or larger than the length of
- the slice or high bound less than low bound. */
- SLICE_SLICE_OUT_OF_BOUNDS = 3,
-
- /* Array slice out of bounds. */
- ARRAY_SLICE_OUT_OF_BOUNDS = 4,
-
- /* String slice out of bounds. */
- STRING_SLICE_OUT_OF_BOUNDS = 5,
-
- /* Dereference of nil pointer. This is used when there is a
- dereference of a pointer to a very large struct or array, to
- ensure that a gigantic array is not used a proxy to access random
- memory locations. */
- NIL_DEREFERENCE = 6,
-
- /* Slice length or capacity out of bounds in make: negative or
- overflow or length greater than capacity. */
- MAKE_SLICE_OUT_OF_BOUNDS = 7,
-
- /* Map capacity out of bounds in make: negative or overflow. */
- MAKE_MAP_OUT_OF_BOUNDS = 8,
-
- /* Channel capacity out of bounds in make: negative or overflow. */
- MAKE_CHAN_OUT_OF_BOUNDS = 9,
-
- /* Integer division by zero. */
- DIVISION_BY_ZERO = 10
-};
-
-extern void __go_runtime_error () __attribute__ ((noreturn));
-
-void
-__go_runtime_error (int32 i)
-{
- switch (i)
- {
- case SLICE_INDEX_OUT_OF_BOUNDS:
- case ARRAY_INDEX_OUT_OF_BOUNDS:
- case STRING_INDEX_OUT_OF_BOUNDS:
- runtime_panicstring ("index out of range");
-
- case SLICE_SLICE_OUT_OF_BOUNDS:
- case ARRAY_SLICE_OUT_OF_BOUNDS:
- case STRING_SLICE_OUT_OF_BOUNDS:
- runtime_panicstring ("slice bounds out of range");
-
- case NIL_DEREFERENCE:
- runtime_panicstring ("nil pointer dereference");
-
- case MAKE_SLICE_OUT_OF_BOUNDS:
- runtime_panicstring ("make slice len or cap out of range");
-
- case MAKE_MAP_OUT_OF_BOUNDS:
- runtime_panicstring ("make map len out of range");
-
- case MAKE_CHAN_OUT_OF_BOUNDS:
- runtime_panicstring ("make chan len out of range");
-
- case DIVISION_BY_ZERO:
- runtime_panicstring ("integer divide by zero");
-
- default:
- runtime_panicstring ("unknown runtime error");
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-setenv.c b/gcc-4.8.1/libgo/runtime/go-setenv.c
deleted file mode 100644
index 6c7378c9e..000000000
--- a/gcc-4.8.1/libgo/runtime/go-setenv.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* go-setenv.c -- set the C environment from Go.
-
- Copyright 2011 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. */
-
-#include "config.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "go-alloc.h"
-#include "runtime.h"
-
-/* Set the C environment from Go. This is called by syscall.Setenv. */
-
-void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv_c");
-
-void
-setenv_c (String k, String v)
-{
- const byte *ks;
- unsigned char *kn;
- const byte *vs;
- unsigned char *vn;
-
- ks = k.str;
- if (ks == NULL)
- ks = (const byte *) "";
- kn = NULL;
-
- vs = v.str;
- if (vs == NULL)
- vs = (const byte *) "";
- vn = NULL;
-
-#ifdef HAVE_SETENV
-
- if (ks != NULL && ks[k.len] != 0)
- {
- kn = __go_alloc (k.len + 1);
- __builtin_memcpy (kn, ks, k.len);
- ks = kn;
- }
-
- if (vs != NULL && vs[v.len] != 0)
- {
- vn = __go_alloc (v.len + 1);
- __builtin_memcpy (vn, vs, v.len);
- vs = vn;
- }
-
- setenv ((const char *) ks, (const char *) vs, 1);
-
-#else /* !defined(HAVE_SETENV) */
-
- kn = __go_alloc (k.len + v.len + 2);
- __builtin_memcpy (kn, ks, k.len);
- kn[k.len] = '=';
- __builtin_memcpy (kn + k.len + 1, vs, v.len);
- kn[k.len + v.len + 1] = '\0';
- putenv ((char *) kn);
-
-#endif /* !defined(HAVE_SETENV) */
-
- if (kn != NULL)
- __go_free (kn);
- if (vn != NULL)
- __go_free (vn);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-signal.c b/gcc-4.8.1/libgo/runtime/go-signal.c
deleted file mode 100644
index 1965e0588..000000000
--- a/gcc-4.8.1/libgo/runtime/go-signal.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/* go-signal.c -- signal handling for Go.
-
- 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. */
-
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "runtime.h"
-#include "go-assert.h"
-#include "go-panic.h"
-
-#ifndef SA_RESTART
- #define SA_RESTART 0
-#endif
-
-#ifdef USING_SPLIT_STACK
-
-extern void __splitstack_getcontext(void *context[10]);
-
-extern void __splitstack_setcontext(void *context[10]);
-
-#endif
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-/* Signal actions. This collects the sigtab tables for several
- different targets from the master library. SIGKILL, SIGCONT, and
- SIGSTOP are not listed, as we don't want to set signal handlers for
- them. */
-
-SigTab runtime_sigtab[] = {
-#ifdef SIGHUP
- { SIGHUP, N + K },
-#endif
-#ifdef SIGINT
- { SIGINT, N + K },
-#endif
-#ifdef SIGQUIT
- { SIGQUIT, N + T },
-#endif
-#ifdef SIGILL
- { SIGILL, T },
-#endif
-#ifdef SIGTRAP
- { SIGTRAP, T },
-#endif
-#ifdef SIGABRT
- { SIGABRT, N + T },
-#endif
-#ifdef SIGBUS
- { SIGBUS, P },
-#endif
-#ifdef SIGFPE
- { SIGFPE, P },
-#endif
-#ifdef SIGUSR1
- { SIGUSR1, N },
-#endif
-#ifdef SIGSEGV
- { SIGSEGV, P },
-#endif
-#ifdef SIGUSR2
- { SIGUSR2, N },
-#endif
-#ifdef SIGPIPE
- { SIGPIPE, N },
-#endif
-#ifdef SIGALRM
- { SIGALRM, N },
-#endif
-#ifdef SIGTERM
- { SIGTERM, N + K },
-#endif
-#ifdef SIGSTKFLT
- { SIGSTKFLT, T },
-#endif
-#ifdef SIGCHLD
- { SIGCHLD, N },
-#endif
-#ifdef SIGTSTP
- { SIGTSTP, N + D },
-#endif
-#ifdef SIGTTIN
- { SIGTTIN, N + D },
-#endif
-#ifdef SIGTTOU
- { SIGTTOU, N + D },
-#endif
-#ifdef SIGURG
- { SIGURG, N },
-#endif
-#ifdef SIGXCPU
- { SIGXCPU, N },
-#endif
-#ifdef SIGXFSZ
- { SIGXFSZ, N },
-#endif
-#ifdef SIGVTALRM
- { SIGVTALRM, N },
-#endif
-#ifdef SIGPROF
- { SIGPROF, N },
-#endif
-#ifdef SIGWINCH
- { SIGWINCH, N },
-#endif
-#ifdef SIGIO
- { SIGIO, N },
-#endif
-#ifdef SIGPWR
- { SIGPWR, N },
-#endif
-#ifdef SIGSYS
- { SIGSYS, N },
-#endif
-#ifdef SIGEMT
- { SIGEMT, T },
-#endif
-#ifdef SIGINFO
- { SIGINFO, N },
-#endif
-#ifdef SIGTHR
- { SIGTHR, N },
-#endif
- { -1, 0 }
-};
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
-
-
-static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
-
-static void
-runtime_badsignal(int32 sig)
-{
- // Avoid -D_FORTIFY_SOURCE problems.
- int rv __attribute__((unused));
-
- if (sig == SIGPROF) {
- return; // Ignore SIGPROFs intended for a non-Go thread.
- }
- rv = runtime_write(2, badsignal, sizeof badsignal - 1);
- runtime_exit(1);
-}
-
-/* Handle a signal, for cases where we don't panic. We can split the
- stack here. */
-
-static void
-sig_handler (int sig)
-{
- int i;
-
- if (runtime_m () == NULL)
- {
- runtime_badsignal (sig);
- return;
- }
-
-#ifdef SIGPROF
- if (sig == SIGPROF)
- {
- runtime_sigprof ();
- return;
- }
-#endif
-
- for (i = 0; runtime_sigtab[i].sig != -1; ++i)
- {
- SigTab *t;
-
- t = &runtime_sigtab[i];
-
- if (t->sig != sig)
- continue;
-
- if ((t->flags & SigNotify) != 0)
- {
- if (__go_sigsend (sig))
- return;
- }
- if ((t->flags & SigKill) != 0)
- runtime_exit (2);
- if ((t->flags & SigThrow) == 0)
- return;
-
- runtime_startpanic ();
-
- {
- const char *name = NULL;
-
-#ifdef HAVE_STRSIGNAL
- name = strsignal (sig);
-#endif
-
- if (name == NULL)
- runtime_printf ("Signal %d\n", sig);
- else
- runtime_printf ("%s\n", name);
- }
-
- runtime_printf ("\n");
-
- if (runtime_gotraceback ())
- {
- G *g;
-
- g = runtime_g ();
- runtime_traceback (g);
- runtime_tracebackothers (g);
-
- /* The gc library calls runtime_dumpregs here, and provides
- a function that prints the registers saved in context in
- a readable form. */
- }
-
- runtime_exit (2);
- }
-
- __builtin_unreachable ();
-}
-
-/* The start of handling a signal which panics. */
-
-static void
-sig_panic_leadin (int sig)
-{
- int i;
- sigset_t clear;
-
- if (runtime_m ()->mallocing)
- {
- runtime_printf ("caught signal while mallocing: %d\n", sig);
- runtime_throw ("caught signal while mallocing");
- }
-
- /* The signal handler blocked signals; unblock them. */
- i = sigfillset (&clear);
- __go_assert (i == 0);
- i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
- __go_assert (i == 0);
-}
-
-#ifdef SA_SIGINFO
-
-/* Signal dispatch for signals which panic, on systems which support
- SA_SIGINFO. This is called on the thread stack, and as such it is
- permitted to split the stack. */
-
-static void
-sig_panic_info_handler (int sig, siginfo_t *info,
- void *context __attribute__ ((unused)))
-{
- G *g;
-
- g = runtime_g ();
- if (g == NULL || info->si_code == SI_USER)
- {
- sig_handler (sig);
- return;
- }
-
- g->sig = sig;
- g->sigcode0 = info->si_code;
- g->sigcode1 = (uintptr_t) info->si_addr;
-
- /* It would be nice to set g->sigpc here as the gc library does, but
- I don't know how to get it portably. */
-
- sig_panic_leadin (sig);
-
- switch (sig)
- {
-#ifdef SIGBUS
- case SIGBUS:
- if (info->si_code == BUS_ADRERR && (uintptr_t) info->si_addr < 0x1000)
- runtime_panicstring ("invalid memory address or "
- "nil pointer dereference");
- runtime_printf ("unexpected fault address %p\n", info->si_addr);
- runtime_throw ("fault");
-#endif
-
-#ifdef SIGSEGV
- case SIGSEGV:
- if ((info->si_code == 0
- || info->si_code == SEGV_MAPERR
- || info->si_code == SEGV_ACCERR)
- && (uintptr_t) info->si_addr < 0x1000)
- runtime_panicstring ("invalid memory address or "
- "nil pointer dereference");
- runtime_printf ("unexpected fault address %p\n", info->si_addr);
- runtime_throw ("fault");
-#endif
-
-#ifdef SIGFPE
- case SIGFPE:
- switch (info->si_code)
- {
- case FPE_INTDIV:
- runtime_panicstring ("integer divide by zero");
- case FPE_INTOVF:
- runtime_panicstring ("integer overflow");
- }
- runtime_panicstring ("floating point error");
-#endif
- }
-
- /* All signals with SigPanic should be in cases above, and this
- handler should only be invoked for those signals. */
- __builtin_unreachable ();
-}
-
-#else /* !defined (SA_SIGINFO) */
-
-static void
-sig_panic_handler (int sig)
-{
- G *g;
-
- g = runtime_g ();
- if (g == NULL)
- {
- sig_handler (sig);
- return;
- }
-
- g->sig = sig;
- g->sigcode0 = 0;
- g->sigcode1 = 0;
-
- sig_panic_leadin (sig);
-
- switch (sig)
- {
-#ifdef SIGBUS
- case SIGBUS:
- runtime_panicstring ("invalid memory address or "
- "nil pointer dereference");
-#endif
-
-#ifdef SIGSEGV
- case SIGSEGV:
- runtime_panicstring ("invalid memory address or "
- "nil pointer dereference");
-#endif
-
-#ifdef SIGFPE
- case SIGFPE:
- runtime_panicstring ("integer divide by zero or floating point error");
-#endif
- }
-
- /* All signals with SigPanic should be in cases above, and this
- handler should only be invoked for those signals. */
- __builtin_unreachable ();
-}
-
-#endif /* !defined (SA_SIGINFO) */
-
-/* A signal handler used for signals which are not going to panic.
- This is called on the alternate signal stack so it may not split
- the stack. */
-
-static void
-sig_tramp (int) __attribute__ ((no_split_stack));
-
-static void
-sig_tramp (int sig)
-{
- G *gp;
- M *mp;
-
- /* We are now running on the stack registered via sigaltstack.
- (Actually there is a small span of time between runtime_siginit
- and sigaltstack when the program starts.) */
- gp = runtime_g ();
- mp = runtime_m ();
-
- if (gp != NULL)
- {
-#ifdef USING_SPLIT_STACK
- __splitstack_getcontext (&gp->stack_context[0]);
-#endif
- }
-
- if (gp != NULL && mp->gsignal != NULL)
- {
- /* We are running on the signal stack. Set the split stack
- context so that the stack guards are checked correctly. */
-#ifdef USING_SPLIT_STACK
- __splitstack_setcontext (&mp->gsignal->stack_context[0]);
-#endif
- }
-
- sig_handler (sig);
-
- /* We are going to return back to the signal trampoline and then to
- whatever we were doing before we got the signal. Restore the
- split stack context so that stack guards are checked
- correctly. */
-
- if (gp != NULL)
- {
-#ifdef USING_SPLIT_STACK
- __splitstack_setcontext (&gp->stack_context[0]);
-#endif
- }
-}
-
-void
-runtime_setsig (int32 i, bool def __attribute__ ((unused)), bool restart)
-{
- struct sigaction sa;
- int r;
- SigTab *t;
-
- memset (&sa, 0, sizeof sa);
-
- r = sigfillset (&sa.sa_mask);
- __go_assert (r == 0);
-
- t = &runtime_sigtab[i];
-
- if ((t->flags & SigPanic) == 0)
- {
- sa.sa_flags = SA_ONSTACK;
- sa.sa_handler = sig_tramp;
- }
- else
- {
-#ifdef SA_SIGINFO
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = sig_panic_info_handler;
-#else
- sa.sa_flags = 0;
- sa.sa_handler = sig_panic_handler;
-#endif
- }
-
- if (restart)
- sa.sa_flags |= SA_RESTART;
-
- if (sigaction (t->sig, &sa, NULL) != 0)
- __go_assert (0);
-}
-
-/* Used by the os package to raise SIGPIPE. */
-
-void os_sigpipe (void) __asm__ (GOSYM_PREFIX "os.sigpipe");
-
-void
-os_sigpipe (void)
-{
- struct sigaction sa;
- int i;
-
- memset (&sa, 0, sizeof sa);
-
- sa.sa_handler = SIG_DFL;
-
- i = sigemptyset (&sa.sa_mask);
- __go_assert (i == 0);
-
- if (sigaction (SIGPIPE, &sa, NULL) != 0)
- abort ();
-
- raise (SIGPIPE);
-}
-
-void
-runtime_setprof(bool on)
-{
- USED(on);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-strcmp.c b/gcc-4.8.1/libgo/runtime/go-strcmp.c
deleted file mode 100644
index bcc270bf8..000000000
--- a/gcc-4.8.1/libgo/runtime/go-strcmp.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* go-strcmp.c -- the go string comparison function.
-
- 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. */
-
-#include "runtime.h"
-
-intgo
-__go_strcmp(String s1, String s2)
-{
- int i;
-
- i = __builtin_memcmp(s1.str, s2.str,
- (s1.len < s2.len ? s1.len : s2.len));
- if (i != 0)
- return i;
-
- if (s1.len < s2.len)
- return -1;
- else if (s1.len > s2.len)
- return 1;
- else
- return 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-string-to-byte-array.c b/gcc-4.8.1/libgo/runtime/go-string-to-byte-array.c
deleted file mode 100644
index 75fac1dbf..000000000
--- a/gcc-4.8.1/libgo/runtime/go-string-to-byte-array.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* go-string-to-byte-array.c -- convert a string to an array of bytes in Go.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-struct __go_open_array
-__go_string_to_byte_array (String str)
-{
- unsigned char *data;
- struct __go_open_array ret;
-
- data = (unsigned char *) runtime_mallocgc (str.len, FlagNoPointers, 1, 0);
- __builtin_memcpy (data, str.str, str.len);
- ret.__values = (void *) data;
- ret.__count = str.len;
- ret.__capacity = str.len;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-string-to-int-array.c b/gcc-4.8.1/libgo/runtime/go-string-to-int-array.c
deleted file mode 100644
index 16970bdd0..000000000
--- a/gcc-4.8.1/libgo/runtime/go-string-to-int-array.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* go-string-to-int-array.c -- convert a string to an array of ints in Go.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-string.h"
-#include "array.h"
-#include "arch.h"
-#include "malloc.h"
-
-struct __go_open_array
-__go_string_to_int_array (String str)
-{
- size_t c;
- const unsigned char *p;
- const unsigned char *pend;
- uint32_t *data;
- uint32_t *pd;
- struct __go_open_array ret;
-
- c = 0;
- p = str.str;
- pend = p + str.len;
- while (p < pend)
- {
- int rune;
-
- ++c;
- p += __go_get_rune (p, pend - p, &rune);
- }
-
- data = (uint32_t *) runtime_mallocgc (c * sizeof (uint32_t), FlagNoPointers,
- 1, 0);
- p = str.str;
- pd = data;
- while (p < pend)
- {
- int rune;
-
- p += __go_get_rune (p, pend - p, &rune);
- *pd++ = rune;
- }
-
- ret.__values = (void *) data;
- ret.__count = c;
- ret.__capacity = c;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-string.h b/gcc-4.8.1/libgo/runtime/go-string.h
deleted file mode 100644
index 7fee1da03..000000000
--- a/gcc-4.8.1/libgo/runtime/go-string.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* go-string.h -- the string type for Go.
-
- 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. */
-
-#ifndef LIBGO_GO_STRING_H
-#define LIBGO_GO_STRING_H
-
-#include <stddef.h>
-
-static inline _Bool
-__go_strings_equal (String s1, String s2)
-{
- return (s1.len == s2.len
- && __builtin_memcmp (s1.str, s2.str, s1.len) == 0);
-}
-
-static inline _Bool
-__go_ptr_strings_equal (const String *ps1, const String *ps2)
-{
- if (ps1 == NULL)
- return ps2 == NULL;
- if (ps2 == NULL)
- return 0;
- return __go_strings_equal (*ps1, *ps2);
-}
-
-extern int __go_get_rune (const unsigned char *, size_t, int32 *);
-
-#endif /* !defined(LIBGO_GO_STRING_H) */
diff --git a/gcc-4.8.1/libgo/runtime/go-strplus.c b/gcc-4.8.1/libgo/runtime/go-strplus.c
deleted file mode 100644
index d6e6df67f..000000000
--- a/gcc-4.8.1/libgo/runtime/go-strplus.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* go-strplus.c -- the go string append function.
-
- 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. */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_string_plus (String s1, String s2)
-{
- int len;
- byte *retdata;
- String ret;
-
- if (s1.len == 0)
- return s2;
- else if (s2.len == 0)
- return s1;
-
- len = s1.len + s2.len;
- retdata = runtime_mallocgc (len, FlagNoPointers, 1, 0);
- __builtin_memcpy (retdata, s1.str, s1.len);
- __builtin_memcpy (retdata + s1.len, s2.str, s2.len);
- ret.str = retdata;
- ret.len = len;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-strslice.c b/gcc-4.8.1/libgo/runtime/go-strslice.c
deleted file mode 100644
index 21e1bc031..000000000
--- a/gcc-4.8.1/libgo/runtime/go-strslice.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* go-strslice.c -- the go string slice function.
-
- 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. */
-
-#include "go-panic.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-String
-__go_string_slice (String s, intgo start, intgo end)
-{
- intgo len;
- String ret;
-
- len = s.len;
- if (end == -1)
- end = len;
- if (start > len || end < start || end > len)
- runtime_panicstring ("string index out of bounds");
- ret.str = s.str + start;
- ret.len = end - start;
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-traceback.c b/gcc-4.8.1/libgo/runtime/go-traceback.c
deleted file mode 100644
index f397f0752..000000000
--- a/gcc-4.8.1/libgo/runtime/go-traceback.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* go-traceback.c -- stack backtrace for Go.
-
- Copyright 2012 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. */
-
-#include "config.h"
-
-#include "runtime.h"
-
-/* Print a stack trace for the current goroutine. */
-
-void
-runtime_traceback ()
-{
- Location locbuf[100];
- int32 c;
-
- c = runtime_callers (1, locbuf, nelem (locbuf));
- runtime_printtrace (locbuf, c, true);
-}
-
-void
-runtime_printtrace (Location *locbuf, int32 c, bool current)
-{
- int32 i;
-
- for (i = 0; i < c; ++i)
- {
- if (runtime_showframe (locbuf[i].function, current))
- {
- runtime_printf ("%S\n", locbuf[i].function);
- runtime_printf ("\t%S:%D\n", locbuf[i].filename,
- (int64) locbuf[i].lineno);
- }
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-trampoline.c b/gcc-4.8.1/libgo/runtime/go-trampoline.c
deleted file mode 100644
index 17f73d4f5..000000000
--- a/gcc-4.8.1/libgo/runtime/go-trampoline.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* go-trampoline.c -- allocate a trampoline for a nested function.
-
- 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. */
-
-#include "config.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-assert.h"
-
-/* Trampolines need to run in memory that is both writable and
- executable. In order to implement them, we grab a page of memory
- and mprotect it. We fill in the page with trampolines as they are
- required. When we run out of space, we drop the pointer to the
- page and allocate a new one. The page will be freed by the garbage
- collector when there are no more variables of type func pointing to
- it. */
-
-/* A lock to control access to the page of closures. */
-
-static Lock trampoline_lock;
-
-/* The page of closures. */
-
-static unsigned char *trampoline_page;
-
-/* The size of trampoline_page. */
-
-static uintptr_t trampoline_page_size;
-
-/* The number of bytes we have used on trampoline_page. */
-
-static uintptr_t trampoline_page_used;
-
-/* Allocate a trampoline of SIZE bytes that will use the closure in
- CLOSURE. */
-
-void *
-__go_allocate_trampoline (uintptr_t size, void *closure)
-{
- uintptr_t ptr_size;
- uintptr_t full_size;
- unsigned char *ret;
-
- /* Because the garbage collector only looks at aligned addresses, we
- need to store the closure at an aligned address to ensure that it
- sees it. */
- ptr_size = sizeof (void *);
- full_size = (((size + ptr_size - 1) / ptr_size) * ptr_size);
- full_size += ptr_size;
-
- runtime_lock (&trampoline_lock);
-
- if (full_size < trampoline_page_size - trampoline_page_used)
- trampoline_page = NULL;
-
- if (trampoline_page == NULL)
- {
- uintptr_t page_size;
- unsigned char *page;
-
- page_size = getpagesize ();
- __go_assert (page_size >= full_size);
- page = (unsigned char *) runtime_mallocgc (2 * page_size - 1, 0, 0, 0);
- page = (unsigned char *) (((uintptr_t) page + page_size - 1)
- & ~ (page_size - 1));
-
-#ifdef HAVE_SYS_MMAN_H
- {
- int i;
-
- i = mprotect (page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC);
- __go_assert (i == 0);
- }
-#endif
-
- trampoline_page = page;
- trampoline_page_size = page_size;
- trampoline_page_used = 0;
- }
-
- ret = trampoline_page + trampoline_page_used;
- trampoline_page_used += full_size;
-
- runtime_unlock (&trampoline_lock);
-
- __builtin_memcpy (ret + full_size - ptr_size, &closure, ptr_size);
-
- return (void *) ret;
-}
-
-/* Scan the trampoline page when running the garbage collector. This
- just makes sure that the garbage collector sees the pointer in
- trampoline_page, so that the page itself is not freed if there are
- no other references to it. */
-
-void
-runtime_trampoline_scan (void (*addroot) (Obj))
-{
- if (trampoline_page != NULL)
- addroot ((Obj){(byte *) &trampoline_page, sizeof trampoline_page, 0});
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-complex.c b/gcc-4.8.1/libgo/runtime/go-type-complex.c
deleted file mode 100644
index 106024f5c..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-complex.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* go-type-complex.c -- hash and equality complex functions.
-
- Copyright 2012 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-
-/* The 64-bit type. */
-
-typedef unsigned int DItype __attribute__ ((mode (DI)));
-
-/* Hash function for float types. */
-
-uintptr_t
-__go_type_hash_complex (const void *vkey, uintptr_t key_size)
-{
- if (key_size == 8)
- {
- union
- {
- unsigned char a[8];
- __complex float cf;
- DItype di;
- } ucf;
- __complex float cf;
- float cfr;
- float cfi;
-
- __builtin_memcpy (ucf.a, vkey, 8);
- cf = ucf.cf;
- cfr = __builtin_crealf (cf);
- cfi = __builtin_cimagf (cf);
- if (__builtin_isinff (cfr) || __builtin_isinff (cfi))
- return 0;
-
- /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it
- random so that not all NaNs wind up in the same place. */
- if (__builtin_isnanf (cfr) || __builtin_isnanf (cfi))
- return runtime_fastrand1 ();
-
- /* Avoid negative zero. */
- if (cfr == 0 && cfi == 0)
- return 0;
- else if (cfr == 0)
- ucf.cf = cfi * 1.0iF;
- else if (cfi == 0)
- ucf.cf = cfr;
-
- return ucf.di;
- }
- else if (key_size == 16)
- {
- union
- {
- unsigned char a[16];
- __complex double cd;
- DItype adi[2];
- } ucd;
- __complex double cd;
- double cdr;
- double cdi;
-
- __builtin_memcpy (ucd.a, vkey, 16);
- cd = ucd.cd;
- cdr = __builtin_crealf (cd);
- cdi = __builtin_cimagf (cd);
- if (__builtin_isinf (cdr) || __builtin_isinf (cdi))
- return 0;
-
- if (__builtin_isnan (cdr) || __builtin_isnan (cdi))
- return runtime_fastrand1 ();
-
- /* Avoid negative zero. */
- if (cdr == 0 && cdi == 0)
- return 0;
- else if (cdr == 0)
- ucd.cd = cdi * 1.0i;
- else if (cdi == 0)
- ucd.cd = cdr;
-
- return ucd.adi[0] ^ ucd.adi[1];
- }
- else
- runtime_throw ("__go_type_hash_complex: invalid complex size");
-}
-
-/* Equality function for complex types. */
-
-_Bool
-__go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
-{
- if (key_size == 8)
- {
- union
- {
- unsigned char a[8];
- __complex float cf;
- } ucf;
- __complex float cf1;
- __complex float cf2;
-
- __builtin_memcpy (ucf.a, vk1, 8);
- cf1 = ucf.cf;
- __builtin_memcpy (ucf.a, vk2, 8);
- cf2 = ucf.cf;
- return cf1 == cf2;
- }
- else if (key_size == 16)
- {
- union
- {
- unsigned char a[16];
- __complex double cd;
- } ucd;
- __complex double cd1;
- __complex double cd2;
-
- __builtin_memcpy (ucd.a, vk1, 16);
- cd1 = ucd.cd;
- __builtin_memcpy (ucd.a, vk2, 16);
- cd2 = ucd.cd;
- return cd1 == cd2;
- }
- else
- runtime_throw ("__go_type_equal_complex: invalid complex size");
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-eface.c b/gcc-4.8.1/libgo/runtime/go-type-eface.c
deleted file mode 100644
index cb3424b98..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-eface.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* go-type-eface.c -- hash and equality empty interface functions.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "interface.h"
-#include "go-type.h"
-
-/* A hash function for an empty interface. */
-
-uintptr_t
-__go_type_hash_empty_interface (const void *vval,
- uintptr_t key_size __attribute__ ((unused)))
-{
- const struct __go_empty_interface *val;
- const struct __go_type_descriptor *descriptor;
- uintptr_t size;
-
- val = (const struct __go_empty_interface *) vval;
- descriptor = val->__type_descriptor;
- if (descriptor == NULL)
- return 0;
- size = descriptor->__size;
- if (__go_is_pointer_type (descriptor))
- return descriptor->__hashfn (&val->__object, size);
- else
- return descriptor->__hashfn (val->__object, size);
-}
-
-/* An equality function for an empty interface. */
-
-_Bool
-__go_type_equal_empty_interface (const void *vv1, const void *vv2,
- uintptr_t key_size __attribute__ ((unused)))
-{
- const struct __go_empty_interface *v1;
- const struct __go_empty_interface *v2;
- const struct __go_type_descriptor* v1_descriptor;
- const struct __go_type_descriptor* v2_descriptor;
-
- v1 = (const struct __go_empty_interface *) vv1;
- v2 = (const struct __go_empty_interface *) vv2;
- v1_descriptor = v1->__type_descriptor;
- v2_descriptor = v2->__type_descriptor;
- if (((uintptr_t) v1_descriptor & reflectFlags) != 0
- || ((uintptr_t) v2_descriptor & reflectFlags) != 0)
- runtime_panicstring ("invalid interface value");
- if (v1_descriptor == NULL || v2_descriptor == NULL)
- return v1_descriptor == v2_descriptor;
- if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
- return 0;
- if (__go_is_pointer_type (v1_descriptor))
- return v1->__object == v2->__object;
- else
- return v1_descriptor->__equalfn (v1->__object, v2->__object,
- v1_descriptor->__size);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-error.c b/gcc-4.8.1/libgo/runtime/go-type-error.c
deleted file mode 100644
index b4c609b93..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-error.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* go-type-error.c -- invalid hash and equality functions.
-
- 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-
-/* A hash function used for a type which does not support hash
- functions. */
-
-uintptr_t
-__go_type_hash_error (const void *val __attribute__ ((unused)),
- uintptr_t key_size __attribute__ ((unused)))
-{
- runtime_panicstring ("hash of unhashable type");
-}
-
-/* An equality function for an interface. */
-
-_Bool
-__go_type_equal_error (const void *v1 __attribute__ ((unused)),
- const void *v2 __attribute__ ((unused)),
- uintptr_t key_size __attribute__ ((unused)))
-{
- runtime_panicstring ("comparing uncomparable types");
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-float.c b/gcc-4.8.1/libgo/runtime/go-type-float.c
deleted file mode 100644
index e1c03e428..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-float.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* go-type-float.c -- hash and equality float functions.
-
- Copyright 2012 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-
-/* The 32-bit and 64-bit types. */
-
-typedef unsigned int SItype __attribute__ ((mode (SI)));
-typedef unsigned int DItype __attribute__ ((mode (DI)));
-
-/* Hash function for float types. */
-
-uintptr_t
-__go_type_hash_float (const void *vkey, uintptr_t key_size)
-{
- if (key_size == 4)
- {
- union
- {
- unsigned char a[4];
- float f;
- SItype si;
- } uf;
- float f;
-
- __builtin_memcpy (uf.a, vkey, 4);
- f = uf.f;
- if (__builtin_isinff (f) || f == 0)
- return 0;
-
- /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it
- random so that not all NaNs wind up in the same place. */
- if (__builtin_isnanf (f))
- return runtime_fastrand1 ();
-
- return (uintptr_t) uf.si;
- }
- else if (key_size == 8)
- {
- union
- {
- unsigned char a[8];
- double d;
- DItype di;
- } ud;
- double d;
-
- __builtin_memcpy (ud.a, vkey, 8);
- d = ud.d;
- if (__builtin_isinf (d) || d == 0)
- return 0;
-
- if (__builtin_isnan (d))
- return runtime_fastrand1 ();
-
- return (uintptr_t) ud.di;
- }
- else
- runtime_throw ("__go_type_hash_float: invalid float size");
-}
-
-/* Equality function for float types. */
-
-_Bool
-__go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
-{
- if (key_size == 4)
- {
- union
- {
- unsigned char a[4];
- float f;
- } uf;
- float f1;
- float f2;
-
- __builtin_memcpy (uf.a, vk1, 4);
- f1 = uf.f;
- __builtin_memcpy (uf.a, vk2, 4);
- f2 = uf.f;
- return f1 == f2;
- }
- else if (key_size == 8)
- {
- union
- {
- unsigned char a[8];
- double d;
- DItype di;
- } ud;
- double d1;
- double d2;
-
- __builtin_memcpy (ud.a, vk1, 8);
- d1 = ud.d;
- __builtin_memcpy (ud.a, vk2, 8);
- d2 = ud.d;
- return d1 == d2;
- }
- else
- runtime_throw ("__go_type_equal_float: invalid float size");
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-identity.c b/gcc-4.8.1/libgo/runtime/go-type-identity.c
deleted file mode 100644
index ed510f75a..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-identity.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* go-type-identity.c -- hash and equality identity functions.
-
- 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-type.h"
-
-/* An identity hash function for a type. This is used for types where
- we can simply use the type value itself as a hash code. This is
- true of, e.g., integers and pointers. */
-
-uintptr_t
-__go_type_hash_identity (const void *key, uintptr_t key_size)
-{
- uintptr_t ret;
- uintptr_t i;
- const unsigned char *p;
-
- if (key_size <= 8)
- {
- union
- {
- uint64 v;
- unsigned char a[8];
- } u;
- u.v = 0;
-#ifdef WORDS_BIGENDIAN
- __builtin_memcpy (&u.a[8 - key_size], key, key_size);
-#else
- __builtin_memcpy (&u.a[0], key, key_size);
-#endif
- if (sizeof (uintptr_t) >= 8)
- return (uintptr_t) u.v;
- else
- return (uintptr_t) ((u.v >> 32) ^ (u.v & 0xffffffff));
- }
-
- ret = 5381;
- for (i = 0, p = (const unsigned char *) key; i < key_size; i++, p++)
- ret = ret * 33 + *p;
- return ret;
-}
-
-/* An identity equality function for a type. This is used for types
- where we can check for equality by checking that the values have
- the same bits. */
-
-_Bool
-__go_type_equal_identity (const void *k1, const void *k2, uintptr_t key_size)
-{
- return __builtin_memcmp (k1, k2, key_size) == 0;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-interface.c b/gcc-4.8.1/libgo/runtime/go-type-interface.c
deleted file mode 100644
index 9aad72008..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-interface.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* go-type-interface.c -- hash and equality interface functions.
-
- 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. */
-
-#include "runtime.h"
-#include "interface.h"
-#include "go-type.h"
-
-/* A hash function for an interface. */
-
-uintptr_t
-__go_type_hash_interface (const void *vval,
- uintptr_t key_size __attribute__ ((unused)))
-{
- const struct __go_interface *val;
- const struct __go_type_descriptor *descriptor;
- uintptr_t size;
-
- val = (const struct __go_interface *) vval;
- if (val->__methods == NULL)
- return 0;
- descriptor = (const struct __go_type_descriptor *) val->__methods[0];
- size = descriptor->__size;
- if (__go_is_pointer_type (descriptor))
- return descriptor->__hashfn (&val->__object, size);
- else
- return descriptor->__hashfn (val->__object, size);
-}
-
-/* An equality function for an interface. */
-
-_Bool
-__go_type_equal_interface (const void *vv1, const void *vv2,
- uintptr_t key_size __attribute__ ((unused)))
-{
- const struct __go_interface *v1;
- const struct __go_interface *v2;
- const struct __go_type_descriptor* v1_descriptor;
- const struct __go_type_descriptor* v2_descriptor;
-
- v1 = (const struct __go_interface *) vv1;
- v2 = (const struct __go_interface *) vv2;
- if (v1->__methods == NULL || v2->__methods == NULL)
- return v1->__methods == v2->__methods;
- v1_descriptor = (const struct __go_type_descriptor *) v1->__methods[0];
- v2_descriptor = (const struct __go_type_descriptor *) v2->__methods[0];
- if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
- return 0;
- if (__go_is_pointer_type (v1_descriptor))
- return v1->__object == v2->__object;
- else
- return v1_descriptor->__equalfn (v1->__object, v2->__object,
- v1_descriptor->__size);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type-string.c b/gcc-4.8.1/libgo/runtime/go-type-string.c
deleted file mode 100644
index a96af0290..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type-string.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* go-type-string.c -- hash and equality string functions.
-
- 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. */
-
-#include "runtime.h"
-#include "go-type.h"
-#include "go-string.h"
-
-/* A string hash function for a map. */
-
-uintptr_t
-__go_type_hash_string (const void *vkey,
- uintptr_t key_size __attribute__ ((unused)))
-{
- uintptr_t ret;
- const String *key;
- intgo len;
- intgo i;
- const byte *p;
-
- ret = 5381;
- key = (const String *) vkey;
- len = key->len;
- for (i = 0, p = key->str; i < len; i++, p++)
- ret = ret * 33 + *p;
- return ret;
-}
-
-/* A string equality function for a map. */
-
-_Bool
-__go_type_equal_string (const void *vk1, const void *vk2,
- uintptr_t key_size __attribute__ ((unused)))
-{
- const String *k1;
- const String *k2;
-
- k1 = (const String *) vk1;
- k2 = (const String *) vk2;
- return __go_ptr_strings_equal (k1, k2);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-type.h b/gcc-4.8.1/libgo/runtime/go-type.h
deleted file mode 100644
index 2269ae633..000000000
--- a/gcc-4.8.1/libgo/runtime/go-type.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/* go-type.h -- basic information for a Go type.
-
- 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. */
-
-#ifndef LIBGO_GO_TYPE_H
-#define LIBGO_GO_TYPE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "array.h"
-
-struct String;
-
-/* Many of the types in this file must match the data structures
- generated by the compiler, and must also match the Go types which
- appear in go/runtime/type.go and go/reflect/type.go. */
-
-/* Type kinds. These are used to get the type descriptor to use for
- the type itself, when using unsafe.Typeof or unsafe.Reflect. The
- values here must match the values generated by the compiler (the
- RUNTIME_TYPE_KIND_xxx values in gcc/go/types.h). These are macros
- rather than an enum to make it easy to change values in the future
- and hard to get confused about it.
-
- These correspond to the kind values used by the gc compiler. */
-
-#define GO_BOOL 1
-#define GO_INT 2
-#define GO_INT8 3
-#define GO_INT16 4
-#define GO_INT32 5
-#define GO_INT64 6
-#define GO_UINT 7
-#define GO_UINT8 8
-#define GO_UINT16 9
-#define GO_UINT32 10
-#define GO_UINT64 11
-#define GO_UINTPTR 12
-#define GO_FLOAT32 13
-#define GO_FLOAT64 14
-#define GO_COMPLEX64 15
-#define GO_COMPLEX128 16
-#define GO_ARRAY 17
-#define GO_CHAN 18
-#define GO_FUNC 19
-#define GO_INTERFACE 20
-#define GO_MAP 21
-#define GO_PTR 22
-#define GO_SLICE 23
-#define GO_STRING 24
-#define GO_STRUCT 25
-#define GO_UNSAFE_POINTER 26
-
-#define GO_NO_POINTERS (1 << 7)
-
-#define GO_CODE_MASK 0x7f
-
-/* For each Go type the compiler constructs one of these structures.
- This is used for type reflectin, interfaces, maps, and reference
- counting. */
-
-struct __go_type_descriptor
-{
- /* The type code for this type, one of the type kind values above.
- This is used by unsafe.Reflect and unsafe.Typeof to determine the
- type descriptor to return for this type itself. It is also used
- by reflect.toType when mapping to a reflect Type structure. */
- unsigned char __code;
-
- /* The alignment in bytes of a variable with this type. */
- unsigned char __align;
-
- /* The alignment in bytes of a struct field with this type. */
- unsigned char __field_align;
-
- /* The size in bytes of a value of this type. Note that all types
- in Go have a fixed size. */
- uintptr_t __size;
-
- /* The type's hash code. */
- uint32_t __hash;
-
- /* This function takes a pointer to a value of this type, and the
- size of this type, and returns a hash code. We pass the size
- explicitly becaues it means that we can share a single instance
- of this function for various different types. */
- uintptr_t (*__hashfn) (const void *, uintptr_t);
-
- /* This function takes two pointers to values of this type, and the
- size of this type, and returns whether the values are equal. */
- _Bool (*__equalfn) (const void *, const void *, uintptr_t);
-
- /* A string describing this type. This is only used for
- debugging. */
- const struct String *__reflection;
-
- /* A pointer to fields which are only used for some types. */
- const struct __go_uncommon_type *__uncommon;
-
- /* The descriptor for the type which is a pointer to this type.
- This may be NULL. */
- const struct __go_type_descriptor *__pointer_to_this;
-};
-
-/* The information we store for each method of a type. */
-
-struct __go_method
-{
- /* The name of the method. */
- const struct String *__name;
-
- /* This is NULL for an exported method, or the name of the package
- where it lives. */
- const struct String *__pkg_path;
-
- /* The type of the method, without the receiver. This will be a
- function type. */
- const struct __go_type_descriptor *__mtype;
-
- /* The type of the method, with the receiver. This will be a
- function type. */
- const struct __go_type_descriptor *__type;
-
- /* A pointer to the code which implements the method. This is
- really a function pointer. */
- const void *__function;
-};
-
-/* Additional information that we keep for named types and for types
- with methods. */
-
-struct __go_uncommon_type
-{
- /* The name of the type. */
- const struct String *__name;
-
- /* The type's package. This is NULL for builtin types. */
- const struct String *__pkg_path;
-
- /* The type's methods. This is an array of struct __go_method. */
- struct __go_open_array __methods;
-};
-
-/* The type descriptor for a fixed array type. */
-
-struct __go_array_type
-{
- /* Starts like all type descriptors. */
- struct __go_type_descriptor __common;
-
- /* The element type. */
- struct __go_type_descriptor *__element_type;
-
- /* The type of a slice of the same element type. */
- struct __go_type_descriptor *__slice_type;
-
- /* The length of the array. */
- uintptr_t __len;
-};
-
-/* The type descriptor for a slice. */
-
-struct __go_slice_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* The element type. */
- struct __go_type_descriptor *__element_type;
-};
-
-/* The direction of a channel. */
-#define CHANNEL_RECV_DIR 1
-#define CHANNEL_SEND_DIR 2
-#define CHANNEL_BOTH_DIR (CHANNEL_RECV_DIR | CHANNEL_SEND_DIR)
-
-/* The type descriptor for a channel. */
-
-struct __go_channel_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* The element type. */
- const struct __go_type_descriptor *__element_type;
-
- /* The direction. */
- uintptr_t __dir;
-};
-
-/* The type descriptor for a function. */
-
-struct __go_func_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* Whether this is a varargs function. If this is true, there will
- be at least one parameter. For "..." the last parameter type is
- "interface{}". For "... T" the last parameter type is "[]T". */
- _Bool __dotdotdot;
-
- /* The input parameter types. This is an array of pointers to
- struct __go_type_descriptor. */
- struct __go_open_array __in;
-
- /* The output parameter types. This is an array of pointers to
- struct __go_type_descriptor. */
- struct __go_open_array __out;
-};
-
-/* A method on an interface type. */
-
-struct __go_interface_method
-{
- /* The name of the method. */
- const struct String *__name;
-
- /* This is NULL for an exported method, or the name of the package
- where it lives. */
- const struct String *__pkg_path;
-
- /* The real type of the method. */
- struct __go_type_descriptor *__type;
-};
-
-/* An interface type. */
-
-struct __go_interface_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* Array of __go_interface_method . The methods are sorted in the
- same order that they appear in the definition of the
- interface. */
- struct __go_open_array __methods;
-};
-
-/* A map type. */
-
-struct __go_map_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* The map key type. */
- const struct __go_type_descriptor *__key_type;
-
- /* The map value type. */
- const struct __go_type_descriptor *__val_type;
-};
-
-/* A pointer type. */
-
-struct __go_ptr_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* The type to which this points. */
- const struct __go_type_descriptor *__element_type;
-};
-
-/* A field in a structure. */
-
-struct __go_struct_field
-{
- /* The name of the field--NULL for an anonymous field. */
- const struct String *__name;
-
- /* This is NULL for an exported method, or the name of the package
- where it lives. */
- const struct String *__pkg_path;
-
- /* The type of the field. */
- const struct __go_type_descriptor *__type;
-
- /* The field tag, or NULL. */
- const struct String *__tag;
-
- /* The offset of the field in the struct. */
- uintptr_t __offset;
-};
-
-/* A struct type. */
-
-struct __go_struct_type
-{
- /* Starts like all other type descriptors. */
- struct __go_type_descriptor __common;
-
- /* An array of struct __go_struct_field. */
- struct __go_open_array __fields;
-};
-
-/* If an empty interface has these bits set in its type pointer, it
- was copied from a reflect.Value and is not a valid empty
- interface. */
-
-enum
-{
- reflectFlags = 3,
-};
-
-/* Whether a type descriptor is a pointer. */
-
-static inline _Bool
-__go_is_pointer_type (const struct __go_type_descriptor *td)
-{
- return td->__code == GO_PTR || td->__code == GO_UNSAFE_POINTER;
-}
-
-extern _Bool
-__go_type_descriptors_equal(const struct __go_type_descriptor*,
- const struct __go_type_descriptor*);
-
-extern uintptr_t __go_type_hash_identity (const void *, uintptr_t);
-extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t);
-extern uintptr_t __go_type_hash_string (const void *, uintptr_t);
-extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t);
-extern uintptr_t __go_type_hash_float (const void *, uintptr_t);
-extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t);
-extern uintptr_t __go_type_hash_complex (const void *, uintptr_t);
-extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t);
-extern uintptr_t __go_type_hash_interface (const void *, uintptr_t);
-extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t);
-extern uintptr_t __go_type_hash_error (const void *, uintptr_t);
-extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t);
-
-#endif /* !defined(LIBGO_GO_TYPE_H) */
diff --git a/gcc-4.8.1/libgo/runtime/go-typedesc-equal.c b/gcc-4.8.1/libgo/runtime/go-typedesc-equal.c
deleted file mode 100644
index f8474fc9f..000000000
--- a/gcc-4.8.1/libgo/runtime/go-typedesc-equal.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* go-typedesc-equal.c -- return whether two type descriptors are equal.
-
- 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. */
-
-#include "runtime.h"
-#include "go-string.h"
-#include "go-type.h"
-
-/* Compare type descriptors for equality. This is necessary because
- types may have different descriptors in different shared libraries.
- Also, unnamed types may have multiple type descriptors even in a
- single shared library. */
-
-_Bool
-__go_type_descriptors_equal (const struct __go_type_descriptor *td1,
- const struct __go_type_descriptor *td2)
-{
- if (td1 == td2)
- return 1;
- /* In a type switch we can get a NULL descriptor. */
- if (td1 == NULL || td2 == NULL)
- return 0;
- if (td1->__code != td2->__code || td1->__hash != td2->__hash)
- return 0;
- if (td1->__uncommon != NULL && td1->__uncommon->__name != NULL)
- {
- if (td2->__uncommon == NULL || td2->__uncommon->__name == NULL)
- return 0;
- return (__go_ptr_strings_equal (td1->__uncommon->__name,
- td2->__uncommon->__name)
- && __go_ptr_strings_equal (td1->__uncommon->__pkg_path,
- td2->__uncommon->__pkg_path));
- }
- if (td2->__uncommon != NULL && td2->__uncommon->__name != NULL)
- return 0;
- return __go_ptr_strings_equal (td1->__reflection, td2->__reflection);
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-typestring.c b/gcc-4.8.1/libgo/runtime/go-typestring.c
deleted file mode 100644
index 0a90e84bc..000000000
--- a/gcc-4.8.1/libgo/runtime/go-typestring.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* go-typestring.c -- the runtime.typestring function.
-
- Copyright 2010 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. */
-
-#include "runtime.h"
-#include "interface.h"
-#include "go-type.h"
-
-String typestring(struct __go_empty_interface) __asm__ (GOSYM_PREFIX "runtime.typestring");
-
-String
-typestring (struct __go_empty_interface e)
-{
- return *e.__type_descriptor->__reflection;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-unsafe-new.c b/gcc-4.8.1/libgo/runtime/go-unsafe-new.c
deleted file mode 100644
index 54788f196..000000000
--- a/gcc-4.8.1/libgo/runtime/go-unsafe-new.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* go-unsafe-new.c -- unsafe.New function for Go.
-
- 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. */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Implement unsafe_New, called from the reflect package. */
-
-void *unsafe_New (const struct __go_type_descriptor *)
- __asm__ (GOSYM_PREFIX "reflect.unsafe_New");
-
-/* The dynamic type of the argument will be a pointer to a type
- descriptor. */
-
-void *
-unsafe_New (const struct __go_type_descriptor *descriptor)
-{
- uint32 flag;
- void *ret;
-
- flag = (descriptor->__code & GO_NO_POINTERS) != 0 ? FlagNoPointers : 0;
- ret = runtime_mallocgc (descriptor->__size, flag, 1, 1);
-
- if (UseSpanType && flag == 0)
- runtime_settype (ret, (uintptr) descriptor | TypeInfo_SingleObject);
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-unsafe-newarray.c b/gcc-4.8.1/libgo/runtime/go-unsafe-newarray.c
deleted file mode 100644
index e4fb3366b..000000000
--- a/gcc-4.8.1/libgo/runtime/go-unsafe-newarray.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* go-unsafe-newarray.c -- unsafe.NewArray function for Go.
-
- 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. */
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-type.h"
-#include "interface.h"
-
-/* Implement unsafe_NewArray, called from the reflect package. */
-
-void *unsafe_NewArray (const struct __go_type_descriptor *, intgo)
- __asm__ (GOSYM_PREFIX "reflect.unsafe_NewArray");
-
-/* The dynamic type of the argument will be a pointer to a type
- descriptor. */
-
-void *
-unsafe_NewArray (const struct __go_type_descriptor *descriptor, intgo n)
-{
- uint64 size;
- void *ret;
-
- size = n * descriptor->__size;
- if (size == 0)
- ret = &runtime_zerobase;
- else if ((descriptor->__code & GO_NO_POINTERS) != 0)
- ret = runtime_mallocgc (size, FlagNoPointers, 1, 1);
- else
- {
- ret = runtime_mallocgc (size, 0, 1, 1);
-
- if (UseSpanType)
- runtime_settype (ret, (uintptr) descriptor | TypeInfo_Array);
- }
-
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/go-unsafe-pointer.c b/gcc-4.8.1/libgo/runtime/go-unsafe-pointer.c
deleted file mode 100644
index ca1d25364..000000000
--- a/gcc-4.8.1/libgo/runtime/go-unsafe-pointer.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* go-unsafe-pointer.c -- unsafe.Pointer type descriptor for Go.
-
- 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. */
-
-#include <stddef.h>
-
-#include "runtime.h"
-#include "go-type.h"
-
-/* This file provides the type descriptor for the unsafe.Pointer type.
- The unsafe package is defined by the compiler itself, which means
- that there is no package to compile to define the type
- descriptor. */
-
-extern const struct __go_type_descriptor unsafe_Pointer
- __asm__ (GOSYM_PREFIX "__go_tdn_unsafe.Pointer");
-
-/* Used to determine the field alignment. */
-struct field_align
-{
- char c;
- void *p;
-};
-
-/* The reflection string. */
-#define REFLECTION "unsafe.Pointer"
-static const String reflection_string =
-{
- (const byte *) REFLECTION,
- sizeof REFLECTION - 1
-};
-
-const struct __go_type_descriptor unsafe_Pointer =
-{
- /* __code */
- GO_UNSAFE_POINTER,
- /* __align */
- __alignof (void *),
- /* __field_align */
- offsetof (struct field_align, p) - 1,
- /* __size */
- sizeof (void *),
- /* __hash */
- 78501163U,
- /* __hashfn */
- __go_type_hash_identity,
- /* __equalfn */
- __go_type_equal_identity,
- /* __reflection */
- &reflection_string,
- /* __uncommon */
- NULL,
- /* __pointer_to_this */
- NULL
-};
-
-/* We also need the type descriptor for the pointer to unsafe.Pointer,
- since any package which refers to that type descriptor will expect
- it to be defined elsewhere. */
-
-extern const struct __go_ptr_type pointer_unsafe_Pointer
- __asm__ (GOSYM_PREFIX "__go_td_pN14_unsafe.Pointer");
-
-/* The reflection string. */
-#define PREFLECTION "*unsafe.Pointer"
-static const String preflection_string =
-{
- (const byte *) PREFLECTION,
- sizeof PREFLECTION - 1,
-};
-
-const struct __go_ptr_type pointer_unsafe_Pointer =
-{
- /* __common */
- {
- /* __code */
- GO_PTR,
- /* __align */
- __alignof (void *),
- /* __field_align */
- offsetof (struct field_align, p) - 1,
- /* __size */
- sizeof (void *),
- /* __hash */
- 1256018616U,
- /* __hashfn */
- __go_type_hash_identity,
- /* __equalfn */
- __go_type_equal_identity,
- /* __reflection */
- &preflection_string,
- /* __uncommon */
- NULL,
- /* __pointer_to_this */
- NULL
- },
- /* __element_type */
- &unsafe_Pointer
-};
diff --git a/gcc-4.8.1/libgo/runtime/go-unwind.c b/gcc-4.8.1/libgo/runtime/go-unwind.c
deleted file mode 100644
index c669a3ce8..000000000
--- a/gcc-4.8.1/libgo/runtime/go-unwind.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* go-unwind.c -- unwind the stack for panic/recover.
-
- Copyright 2010 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. */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "unwind.h"
-#define NO_SIZE_OF_ENCODED_VALUE
-#include "unwind-pe.h"
-
-#include "runtime.h"
-#include "go-alloc.h"
-#include "go-defer.h"
-#include "go-panic.h"
-
-/* The code for a Go exception. */
-
-#ifdef __ARM_EABI_UNWINDER__
-static const _Unwind_Exception_Class __go_exception_class =
- { 'G', 'N', 'U', 'C', 'G', 'O', '\0', '\0' };
-#else
-static const _Unwind_Exception_Class __go_exception_class =
- ((((((((_Unwind_Exception_Class) 'G'
- << 8 | (_Unwind_Exception_Class) 'N')
- << 8 | (_Unwind_Exception_Class) 'U')
- << 8 | (_Unwind_Exception_Class) 'C')
- << 8 | (_Unwind_Exception_Class) 'G')
- << 8 | (_Unwind_Exception_Class) 'O')
- << 8 | (_Unwind_Exception_Class) '\0')
- << 8 | (_Unwind_Exception_Class) '\0');
-#endif
-
-
-/* This function is called by exception handlers used when unwinding
- the stack after a recovered panic. The exception handler looks
- like this:
- __go_check_defer (frame);
- return;
- If we have not yet reached the frame we are looking for, we
- continue unwinding. */
-
-void
-__go_check_defer (_Bool *frame)
-{
- G *g;
- struct _Unwind_Exception *hdr;
-
- g = runtime_g ();
-
- if (g == NULL)
- {
- /* Some other language has thrown an exception. We know there
- are no defer handlers, so there is nothing to do. */
- }
- else if (g->is_foreign)
- {
- struct __go_panic_stack *n;
- _Bool was_recovered;
-
- /* Some other language has thrown an exception. We need to run
- the local defer handlers. If they call recover, we stop
- unwinding the stack here. */
-
- n = ((struct __go_panic_stack *)
- __go_alloc (sizeof (struct __go_panic_stack)));
-
- n->__arg.__type_descriptor = NULL;
- n->__arg.__object = NULL;
- n->__was_recovered = 0;
- n->__is_foreign = 1;
- n->__next = g->panic;
- g->panic = n;
-
- while (1)
- {
- struct __go_defer_stack *d;
- void (*pfn) (void *);
-
- d = g->defer;
- if (d == NULL || d->__frame != frame || d->__pfn == NULL)
- break;
-
- pfn = d->__pfn;
- g->defer = d->__next;
-
- (*pfn) (d->__arg);
-
- __go_free (d);
-
- if (n->__was_recovered)
- {
- /* The recover function caught the panic thrown by some
- other language. */
- break;
- }
- }
-
- was_recovered = n->__was_recovered;
- g->panic = n->__next;
- __go_free (n);
-
- if (was_recovered)
- {
- /* Just return and continue executing Go code. */
- *frame = 1;
- return;
- }
-
- /* We are panicing through this function. */
- *frame = 0;
- }
- else if (g->defer != NULL
- && g->defer->__pfn == NULL
- && g->defer->__frame == frame)
- {
- struct __go_defer_stack *d;
-
- /* This is the defer function which called recover. Simply
- return to stop the stack unwind, and let the Go code continue
- to execute. */
- d = g->defer;
- g->defer = d->__next;
- __go_free (d);
-
- /* We are returning from this function. */
- *frame = 1;
-
- return;
- }
-
- /* This is some other defer function. It was already run by the
- call to panic, or just above. Rethrow the exception. */
-
- hdr = (struct _Unwind_Exception *) g->exception;
-
-#ifdef LIBGO_SJLJ_EXCEPTIONS
- _Unwind_SjLj_Resume_or_Rethrow (hdr);
-#else
-#if defined(_LIBUNWIND_STD_ABI)
- _Unwind_RaiseException (hdr);
-#else
- _Unwind_Resume_or_Rethrow (hdr);
-#endif
-#endif
-
- /* Rethrowing the exception should not return. */
- abort();
-}
-
-/* Unwind function calls until we reach the one which used a defer
- function which called recover. Each function which uses a defer
- statement will have an exception handler, as shown above. */
-
-void
-__go_unwind_stack ()
-{
- struct _Unwind_Exception *hdr;
-
- hdr = ((struct _Unwind_Exception *)
- __go_alloc (sizeof (struct _Unwind_Exception)));
- __builtin_memcpy (&hdr->exception_class, &__go_exception_class,
- sizeof hdr->exception_class);
- hdr->exception_cleanup = NULL;
-
- runtime_g ()->exception = hdr;
-
-#ifdef __USING_SJLJ_EXCEPTIONS__
- _Unwind_SjLj_RaiseException (hdr);
-#else
- _Unwind_RaiseException (hdr);
-#endif
-
- /* Raising an exception should not return. */
- abort ();
-}
-
-/* The rest of this code is really similar to gcc/unwind-c.c and
- libjava/exception.cc. */
-
-typedef struct
-{
- _Unwind_Ptr Start;
- _Unwind_Ptr LPStart;
- _Unwind_Ptr ttype_base;
- const unsigned char *TType;
- const unsigned char *action_table;
- unsigned char ttype_encoding;
- unsigned char call_site_encoding;
-} lsda_header_info;
-
-static const unsigned char *
-parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
- lsda_header_info *info)
-{
- _uleb128_t tmp;
- unsigned char lpstart_encoding;
-
- info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
-
- /* Find @LPStart, the base to which landing pad offsets are relative. */
- lpstart_encoding = *p++;
- if (lpstart_encoding != DW_EH_PE_omit)
- p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
- else
- info->LPStart = info->Start;
-
- /* Find @TType, the base of the handler and exception spec type data. */
- info->ttype_encoding = *p++;
- if (info->ttype_encoding != DW_EH_PE_omit)
- {
- p = read_uleb128 (p, &tmp);
- info->TType = p + tmp;
- }
- else
- info->TType = 0;
-
- /* The encoding and length of the call-site table; the action table
- immediately follows. */
- info->call_site_encoding = *p++;
- p = read_uleb128 (p, &tmp);
- info->action_table = p + tmp;
-
- return p;
-}
-
-/* The personality function is invoked when unwinding the stack due to
- a panic. Its job is to find the cleanup and exception handlers to
- run. We can't split the stack here, because we won't be able to
- unwind from that split. */
-
-#ifdef __ARM_EABI_UNWINDER__
-/* ARM EABI personality routines must also unwind the stack. */
-#define CONTINUE_UNWINDING \
- do \
- { \
- if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \
- return _URC_FAILURE; \
- return _URC_CONTINUE_UNWIND; \
- } \
- while (0)
-#else
-#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
-#endif
-
-#ifdef __USING_SJLJ_EXCEPTIONS__
-#define PERSONALITY_FUNCTION __gccgo_personality_sj0
-#define __builtin_eh_return_data_regno(x) x
-#else
-#define PERSONALITY_FUNCTION __gccgo_personality_v0
-#endif
-
-#ifdef __ARM_EABI_UNWINDER__
-_Unwind_Reason_Code
-PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *,
- struct _Unwind_Context *)
- __attribute__ ((no_split_stack, flatten));
-
-_Unwind_Reason_Code
-PERSONALITY_FUNCTION (_Unwind_State state,
- struct _Unwind_Exception * ue_header,
- struct _Unwind_Context * context)
-#else
-_Unwind_Reason_Code
-PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
- struct _Unwind_Exception *, struct _Unwind_Context *)
- __attribute__ ((no_split_stack, flatten));
-
-_Unwind_Reason_Code
-PERSONALITY_FUNCTION (int version,
- _Unwind_Action actions,
- _Unwind_Exception_Class exception_class,
- struct _Unwind_Exception *ue_header,
- struct _Unwind_Context *context)
-#endif
-{
- lsda_header_info info;
- const unsigned char *language_specific_data, *p, *action_record;
- _Unwind_Ptr landing_pad, ip;
- int ip_before_insn = 0;
- _Bool is_foreign;
- G *g;
-
-#ifdef __ARM_EABI_UNWINDER__
- _Unwind_Action actions;
-
- switch (state & _US_ACTION_MASK)
- {
- case _US_VIRTUAL_UNWIND_FRAME:
- actions = _UA_SEARCH_PHASE;
- break;
-
- case _US_UNWIND_FRAME_STARTING:
- actions = _UA_CLEANUP_PHASE;
- if (!(state & _US_FORCE_UNWIND)
- && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
- actions |= _UA_HANDLER_FRAME;
- break;
-
- case _US_UNWIND_FRAME_RESUME:
- CONTINUE_UNWINDING;
- break;
-
- default:
- abort();
- }
- actions |= state & _US_FORCE_UNWIND;
-
- is_foreign = 0;
-
- /* The dwarf unwinder assumes the context structure holds things like the
- function and LSDA pointers. The ARM implementation caches these in
- the exception header (UCB). To avoid rewriting everything we make the
- virtual IP register point at the UCB. */
- ip = (_Unwind_Ptr) ue_header;
- _Unwind_SetGR (context, 12, ip);
-#else
- if (version != 1)
- return _URC_FATAL_PHASE1_ERROR;
-
- is_foreign = exception_class != __go_exception_class;
-#endif
-
- language_specific_data = (const unsigned char *)
- _Unwind_GetLanguageSpecificData (context);
-
- /* If no LSDA, then there are no handlers or cleanups. */
- if (! language_specific_data)
- CONTINUE_UNWINDING;
-
- /* Parse the LSDA header. */
- p = parse_lsda_header (context, language_specific_data, &info);
-#ifdef HAVE_GETIPINFO
- ip = _Unwind_GetIPInfo (context, &ip_before_insn);
-#else
- ip = _Unwind_GetIP (context);
-#endif
- if (! ip_before_insn)
- --ip;
- landing_pad = 0;
- action_record = NULL;
-
-#ifdef __USING_SJLJ_EXCEPTIONS__
- /* The given "IP" is an index into the call-site table, with two
- exceptions -- -1 means no-action, and 0 means terminate. But
- since we're using uleb128 values, we've not got random access
- to the array. */
- if ((int) ip <= 0)
- return _URC_CONTINUE_UNWIND;
- else
- {
- _uleb128_t cs_lp, cs_action;
- do
- {
- p = read_uleb128 (p, &cs_lp);
- p = read_uleb128 (p, &cs_action);
- }
- while (--ip);
-
- /* Can never have null landing pad for sjlj -- that would have
- been indicated by a -1 call site index. */
- landing_pad = (_Unwind_Ptr)cs_lp + 1;
- if (cs_action)
- action_record = info.action_table + cs_action - 1;
- goto found_something;
- }
-#else
- /* Search the call-site table for the action associated with this IP. */
- while (p < info.action_table)
- {
- _Unwind_Ptr cs_start, cs_len, cs_lp;
- _uleb128_t cs_action;
-
- /* Note that all call-site encodings are "absolute" displacements. */
- p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
- p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
- p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
- p = read_uleb128 (p, &cs_action);
-
- /* The table is sorted, so if we've passed the ip, stop. */
- if (ip < info.Start + cs_start)
- p = info.action_table;
- else if (ip < info.Start + cs_start + cs_len)
- {
- if (cs_lp)
- landing_pad = info.LPStart + cs_lp;
- if (cs_action)
- action_record = info.action_table + cs_action - 1;
- goto found_something;
- }
- }
-#endif
-
- /* IP is not in table. No associated cleanups. */
- CONTINUE_UNWINDING;
-
- found_something:
- if (landing_pad == 0)
- {
- /* IP is present, but has a null landing pad.
- No handler to be run. */
- CONTINUE_UNWINDING;
- }
-
- if (actions & _UA_SEARCH_PHASE)
- {
- if (action_record == 0)
- {
- /* This indicates a cleanup rather than an exception
- handler. */
- CONTINUE_UNWINDING;
- }
-
- return _URC_HANDLER_FOUND;
- }
-
- /* It's possible for g to be NULL here for an exception thrown by a
- language other than Go. */
- g = runtime_g ();
- if (g == NULL)
- {
- if (!is_foreign)
- abort ();
- }
- else
- {
- g->exception = ue_header;
- g->is_foreign = is_foreign;
- }
-
- _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
- (_Unwind_Ptr) ue_header);
- _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0);
- _Unwind_SetIP (context, landing_pad);
- return _URC_INSTALL_CONTEXT;
-}
diff --git a/gcc-4.8.1/libgo/runtime/goc2c.c b/gcc-4.8.1/libgo/runtime/goc2c.c
deleted file mode 100644
index 87db58f50..000000000
--- a/gcc-4.8.1/libgo/runtime/goc2c.c
+++ /dev/null
@@ -1,676 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
- * Translate a .goc file into a .c file. A .goc file is a combination
- * of a limited form of Go with C.
- */
-
-/*
- package PACKAGENAME
- {# line}
- func NAME([NAME TYPE { , NAME TYPE }]) [(NAME TYPE { , NAME TYPE })] \{
- C code with proper brace nesting
- \}
-*/
-
-/*
- * We generate C code which implements the function such that it can
- * be called from Go and executes the C code.
- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-/* Package path to use. */
-static const char *pkgpath;
-
-/* Package prefix to use. */
-static const char *prefix;
-
-/* File and line number */
-static const char *file;
-static unsigned int lineno = 1;
-
-/* List of names and types. */
-struct params {
- struct params *next;
- char *name;
- char *type;
-};
-
-char *argv0;
-
-static void
-sysfatal(char *fmt, ...)
-{
- char buf[256];
- va_list arg;
-
- va_start(arg, fmt);
- vsnprintf(buf, sizeof buf, fmt, arg);
- va_end(arg);
-
- fprintf(stderr, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
- exit(1);
-}
-
-/* Unexpected EOF. */
-static void
-bad_eof(void)
-{
- sysfatal("%s:%ud: unexpected EOF\n", file, lineno);
-}
-
-/* Out of memory. */
-static void
-bad_mem(void)
-{
- sysfatal("%s:%ud: out of memory\n", file, lineno);
-}
-
-/* Allocate memory without fail. */
-static void *
-xmalloc(unsigned int size)
-{
- void *ret = malloc(size);
- if (ret == NULL)
- bad_mem();
- return ret;
-}
-
-/* Reallocate memory without fail. */
-static void*
-xrealloc(void *buf, unsigned int size)
-{
- void *ret = realloc(buf, size);
- if (ret == NULL)
- bad_mem();
- return ret;
-}
-
-/* Copy a string into memory without fail. */
-static char *
-xstrdup(const char *p)
-{
- char *ret = xmalloc(strlen(p) + 1);
- strcpy(ret, p);
- return ret;
-}
-
-/* Free a list of parameters. */
-static void
-free_params(struct params *p)
-{
- while (p != NULL) {
- struct params *next;
-
- next = p->next;
- free(p->name);
- free(p->type);
- free(p);
- p = next;
- }
-}
-
-/* Read a character, tracking lineno. */
-static int
-getchar_update_lineno(void)
-{
- int c;
-
- c = getchar();
- if (c == '\n')
- ++lineno;
- return c;
-}
-
-/* Read a character, giving an error on EOF, tracking lineno. */
-static int
-getchar_no_eof(void)
-{
- int c;
-
- c = getchar_update_lineno();
- if (c == EOF)
- bad_eof();
- return c;
-}
-
-/* Read a character, skipping comments. */
-static int
-getchar_skipping_comments(void)
-{
- int c;
-
- while (1) {
- c = getchar_update_lineno();
- if (c != '/')
- return c;
-
- c = getchar();
- if (c == '/') {
- do {
- c = getchar_update_lineno();
- } while (c != EOF && c != '\n');
- return c;
- } else if (c == '*') {
- while (1) {
- c = getchar_update_lineno();
- if (c == EOF)
- return EOF;
- if (c == '*') {
- do {
- c = getchar_update_lineno();
- } while (c == '*');
- if (c == '/')
- break;
- }
- }
- } else {
- ungetc(c, stdin);
- return '/';
- }
- }
-}
-
-/*
- * Read and return a token. Tokens are string or character literals
- * or else delimited by whitespace or by [(),{}].
- * The latter are all returned as single characters.
- */
-static char *
-read_token(void)
-{
- int c, q;
- char *buf;
- unsigned int alc, off;
- const char* delims = "(),{}";
-
- while (1) {
- c = getchar_skipping_comments();
- if (c == EOF)
- return NULL;
- if (!isspace(c))
- break;
- }
- alc = 16;
- buf = xmalloc(alc + 1);
- off = 0;
- if(c == '"' || c == '\'') {
- q = c;
- buf[off] = c;
- ++off;
- while (1) {
- if (off+2 >= alc) { // room for c and maybe next char
- alc *= 2;
- buf = xrealloc(buf, alc + 1);
- }
- c = getchar_no_eof();
- buf[off] = c;
- ++off;
- if(c == q)
- break;
- if(c == '\\') {
- buf[off] = getchar_no_eof();
- ++off;
- }
- }
- } else if (strchr(delims, c) != NULL) {
- buf[off] = c;
- ++off;
- } else {
- while (1) {
- if (off >= alc) {
- alc *= 2;
- buf = xrealloc(buf, alc + 1);
- }
- buf[off] = c;
- ++off;
- c = getchar_skipping_comments();
- if (c == EOF)
- break;
- if (isspace(c) || strchr(delims, c) != NULL) {
- if (c == '\n')
- lineno--;
- ungetc(c, stdin);
- break;
- }
- }
- }
- buf[off] = '\0';
- return buf;
-}
-
-/* Read a token, giving an error on EOF. */
-static char *
-read_token_no_eof(void)
-{
- char *token = read_token();
- if (token == NULL)
- bad_eof();
- return token;
-}
-
-/* Read the package clause, and return the package name. */
-static char *
-read_package(void)
-{
- char *token;
-
- token = read_token_no_eof();
- if (token == NULL)
- sysfatal("%s:%ud: no token\n", file, lineno);
- if (strcmp(token, "package") != 0) {
- sysfatal("%s:%ud: expected \"package\", got \"%s\"\n",
- file, lineno, token);
- }
- return read_token_no_eof();
-}
-
-/* Read and copy preprocessor lines. */
-static void
-read_preprocessor_lines(void)
-{
- while (1) {
- int c;
-
- do {
- c = getchar_skipping_comments();
- } while (isspace(c));
- if (c != '#') {
- ungetc(c, stdin);
- break;
- }
- putchar(c);
- do {
- c = getchar_update_lineno();
- putchar(c);
- } while (c != '\n');
- }
-}
-
-/*
- * Read a type in Go syntax and return a type in C syntax. We only
- * permit basic types and pointers.
- */
-static char *
-read_type(void)
-{
- char *p, *op, *q;
- int pointer_count;
- unsigned int len;
-
- p = read_token_no_eof();
- if (*p != '*') {
- /* Convert the Go type "int" to the C type "intgo",
- and similarly for "uint". */
- if (strcmp(p, "int") == 0)
- return xstrdup("intgo");
- else if (strcmp(p, "uint") == 0)
- return xstrdup("uintgo");
- return p;
- }
- op = p;
- pointer_count = 0;
- while (*p == '*') {
- ++pointer_count;
- ++p;
- }
-
- /* Convert the Go type "int" to the C type "intgo", and
- similarly for "uint". */
- if (strcmp(p, "int") == 0)
- p = (char *) "intgo";
- else if (strcmp(p, "uint") == 0)
- p = (char *) "uintgo";
-
- len = strlen(p);
- q = xmalloc(len + pointer_count + 1);
- memcpy(q, p, len);
- while (pointer_count > 0) {
- q[len] = '*';
- ++len;
- --pointer_count;
- }
- q[len] = '\0';
- free(op);
- return q;
-}
-
-/*
- * Read a list of parameters. Each parameter is a name and a type.
- * The list ends with a ')'. We have already read the '('.
- */
-static struct params *
-read_params()
-{
- char *token;
- struct params *ret, **pp, *p;
-
- ret = NULL;
- pp = &ret;
- token = read_token_no_eof();
- if (strcmp(token, ")") != 0) {
- while (1) {
- p = xmalloc(sizeof(struct params));
- p->name = token;
- p->type = read_type();
- p->next = NULL;
- *pp = p;
- pp = &p->next;
-
- token = read_token_no_eof();
- if (strcmp(token, ",") != 0)
- break;
- token = read_token_no_eof();
- }
- }
- if (strcmp(token, ")") != 0) {
- sysfatal("%s:%ud: expected '('\n",
- file, lineno);
- }
- return ret;
-}
-
-/*
- * Read a function header. This reads up to and including the initial
- * '{' character. Returns 1 if it read a header, 0 at EOF.
- */
-static int
-read_func_header(char **name, struct params **params, struct params **rets)
-{
- int lastline;
- char *token;
-
- lastline = -1;
- while (1) {
- token = read_token();
- if (token == NULL)
- return 0;
- if (strcmp(token, "func") == 0) {
- if(lastline != -1)
- printf("\n");
- break;
- }
- if (lastline != lineno) {
- if (lastline == lineno-1)
- printf("\n");
- else
- printf("\n#line %d \"%s\"\n", lineno, file);
- lastline = lineno;
- }
- printf("%s ", token);
- }
-
- *name = read_token_no_eof();
-
- token = read_token();
- if (token == NULL || strcmp(token, "(") != 0) {
- sysfatal("%s:%ud: expected \"(\"\n",
- file, lineno);
- }
- *params = read_params();
-
- token = read_token();
- if (token == NULL || strcmp(token, "(") != 0)
- *rets = NULL;
- else {
- *rets = read_params();
- token = read_token();
- }
- if (token == NULL || strcmp(token, "{") != 0) {
- sysfatal("%s:%ud: expected \"{\"\n",
- file, lineno);
- }
- return 1;
-}
-
-/* Write out parameters. */
-static void
-write_params(struct params *params, int *first)
-{
- struct params *p;
-
- for (p = params; p != NULL; p = p->next) {
- if (*first)
- *first = 0;
- else
- printf(", ");
- printf("%s %s", p->type, p->name);
- }
-}
-
-/* Define the gcc function return type if necessary. */
-static void
-define_gcc_return_type(char *package, char *name, struct params *rets)
-{
- struct params *p;
-
- if (rets == NULL || rets->next == NULL)
- return;
- printf("struct %s_%s_ret {\n", package, name);
- for (p = rets; p != NULL; p = p->next)
- printf(" %s %s;\n", p->type, p->name);
- printf("};\n");
-}
-
-/* Write out the gcc function return type. */
-static void
-write_gcc_return_type(char *package, char *name, struct params *rets)
-{
- if (rets == NULL)
- printf("void");
- else if (rets->next == NULL)
- printf("%s", rets->type);
- else
- printf("struct %s_%s_ret", package, name);
-}
-
-/* Write out a gcc function header. */
-static void
-write_gcc_func_header(char *package, char *name, struct params *params,
- struct params *rets)
-{
- int first;
- struct params *p;
-
- define_gcc_return_type(package, name, rets);
- write_gcc_return_type(package, name, rets);
- printf(" %s_%s(", package, name);
- first = 1;
- write_params(params, &first);
- printf(") __asm__ (GOSYM_PREFIX \"");
- if (pkgpath != NULL)
- printf("%s", pkgpath);
- else if (prefix != NULL)
- printf("%s.%s", prefix, package);
- else
- printf("%s", package);
- printf(".%s\");\n", name);
- write_gcc_return_type(package, name, rets);
- printf(" %s_%s(", package, name);
- first = 1;
- write_params(params, &first);
- printf(")\n{\n");
- for (p = rets; p != NULL; p = p->next)
- printf(" %s %s;\n", p->type, p->name);
-}
-
-/* Write out a gcc function trailer. */
-static void
-write_gcc_func_trailer(char *package, char *name, struct params *rets)
-{
- if (rets == NULL)
- ;
- else if (rets->next == NULL)
- printf("return %s;\n", rets->name);
- else {
- struct params *p;
-
- printf(" {\n struct %s_%s_ret __ret;\n", package, name);
- for (p = rets; p != NULL; p = p->next)
- printf(" __ret.%s = %s;\n", p->name, p->name);
- printf(" return __ret;\n }\n");
- }
- printf("}\n");
-}
-
-/* Write out a function header. */
-static void
-write_func_header(char *package, char *name, struct params *params,
- struct params *rets)
-{
- write_gcc_func_header(package, name, params, rets);
- printf("#line %d \"%s\"\n", lineno, file);
-}
-
-/* Write out a function trailer. */
-static void
-write_func_trailer(char *package, char *name,
- struct params *rets)
-{
- write_gcc_func_trailer(package, name, rets);
-}
-
-/*
- * Read and write the body of the function, ending in an unnested }
- * (which is read but not written).
- */
-static void
-copy_body(void)
-{
- int nesting = 0;
- while (1) {
- int c;
-
- c = getchar_no_eof();
- if (c == '}' && nesting == 0)
- return;
- putchar(c);
- switch (c) {
- default:
- break;
- case '{':
- ++nesting;
- break;
- case '}':
- --nesting;
- break;
- case '/':
- c = getchar_update_lineno();
- putchar(c);
- if (c == '/') {
- do {
- c = getchar_no_eof();
- putchar(c);
- } while (c != '\n');
- } else if (c == '*') {
- while (1) {
- c = getchar_no_eof();
- putchar(c);
- if (c == '*') {
- do {
- c = getchar_no_eof();
- putchar(c);
- } while (c == '*');
- if (c == '/')
- break;
- }
- }
- }
- break;
- case '"':
- case '\'':
- {
- int delim = c;
- do {
- c = getchar_no_eof();
- putchar(c);
- if (c == '\\') {
- c = getchar_no_eof();
- putchar(c);
- c = '\0';
- }
- } while (c != delim);
- }
- break;
- }
- }
-}
-
-/* Process the entire file. */
-static void
-process_file(void)
-{
- char *package, *name;
- struct params *params, *rets;
-
- package = read_package();
- read_preprocessor_lines();
- while (read_func_header(&name, &params, &rets)) {
- write_func_header(package, name, params, rets);
- copy_body();
- write_func_trailer(package, name, rets);
- free(name);
- free_params(params);
- free_params(rets);
- }
- free(package);
-}
-
-static void
-usage(void)
-{
- sysfatal("Usage: goc2c [--go-pkgpath PKGPATH] [--go-prefix PREFIX] [file]\n");
-}
-
-int
-main(int argc, char **argv)
-{
- char *goarch;
-
- argv0 = argv[0];
- while(argc > 1 && argv[1][0] == '-') {
- if(strcmp(argv[1], "-") == 0)
- break;
- if (strcmp(argv[1], "--go-pkgpath") == 0 && argc > 2) {
- pkgpath = argv[2];
- argc--;
- argv++;
- } else if (strcmp(argv[1], "--go-prefix") == 0 && argc > 2) {
- prefix = argv[2];
- argc--;
- argv++;
- } else
- usage();
- argc--;
- argv++;
- }
-
- if(argc <= 1 || strcmp(argv[1], "-") == 0) {
- file = "<stdin>";
- process_file();
- exit(0);
- }
-
- if(argc > 2)
- usage();
-
- file = argv[1];
- if(freopen(file, "r", stdin) == 0) {
- sysfatal("open %s: %r\n", file);
- }
-
- printf("// AUTO-GENERATED by autogen.sh; DO NOT EDIT\n\n");
- process_file();
- exit(0);
-}
diff --git a/gcc-4.8.1/libgo/runtime/iface.goc b/gcc-4.8.1/libgo/runtime/iface.goc
deleted file mode 100644
index 7c74e80ac..000000000
--- a/gcc-4.8.1/libgo/runtime/iface.goc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2010 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.
-
-package runtime
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-
-typedef struct __go_type_descriptor descriptor;
-typedef const struct __go_type_descriptor const_descriptor;
-typedef struct __go_interface interface;
-typedef struct __go_empty_interface empty_interface;
-
-// Compare two type descriptors.
-func ifacetypeeq(a *descriptor, b *descriptor) (eq bool) {
- eq = __go_type_descriptors_equal(a, b);
-}
-
-// Return the descriptor for an empty interface type.n
-func efacetype(e empty_interface) (d *const_descriptor) {
- return e.__type_descriptor;
-}
-
-// Return the descriptor for a non-empty interface type.
-func ifacetype(i interface) (d *const_descriptor) {
- if (i.__methods == nil) {
- return nil;
- }
- d = i.__methods[0];
-}
-
-// Convert an empty interface to an empty interface.
-func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
- if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
- runtime_panicstring("invalid interface value");
- ret = e;
- ok = ret.__type_descriptor != nil;
-}
-
-// Convert a non-empty interface to an empty interface.
-func ifaceI2E2(i interface) (ret empty_interface, ok bool) {
- if (i.__methods == nil) {
- ret.__type_descriptor = nil;
- ret.__object = nil;
- ok = 0;
- } else {
- ret.__type_descriptor = i.__methods[0];
- ret.__object = i.__object;
- ok = 1;
- }
-}
-
-// Convert an empty interface to a non-empty interface.
-func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
- if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
- runtime_panicstring("invalid interface value");
- if (e.__type_descriptor == nil) {
- ret.__methods = nil;
- ret.__object = nil;
- ok = 0;
- } else {
- ret.__methods = __go_convert_interface_2(inter,
- e.__type_descriptor,
- 1);
- ret.__object = e.__object;
- ok = ret.__methods != nil;
- }
-}
-
-// Convert a non-empty interface to a non-empty interface.
-func ifaceI2I2(inter *descriptor, i interface) (ret interface, ok bool) {
- if (i.__methods == nil) {
- ret.__methods = nil;
- ret.__object = nil;
- ok = 0;
- } else {
- ret.__methods = __go_convert_interface_2(inter,
- i.__methods[0], 1);
- ret.__object = i.__object;
- ok = ret.__methods != nil;
- }
-}
-
-// Convert an empty interface to a pointer type.
-func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
- if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
- runtime_panicstring("invalid interface value");
- if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
- ret = nil;
- ok = 0;
- } else {
- ret = e.__object;
- ok = 1;
- }
-}
-
-// Convert a non-empty interface to a pointer type.
-func ifaceI2T2P(inter *descriptor, i interface) (ret *void, ok bool) {
- if (i.__methods == nil
- || !__go_type_descriptors_equal(inter, i.__methods[0])) {
- ret = nil;
- ok = 0;
- } else {
- ret = i.__object;
- ok = 1;
- }
-}
-
-// Convert an empty interface to a non-pointer type.
-func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
- if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
- runtime_panicstring("invalid interface value");
- if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
- __builtin_memset(ret, 0, inter->__size);
- ok = 0;
- } else {
- __builtin_memcpy(ret, e.__object, inter->__size);
- ok = 1;
- }
-}
-
-// Convert a non-empty interface to a non-pointer type.
-func ifaceI2T2(inter *descriptor, i interface, ret *void) (ok bool) {
- if (i.__methods == nil
- || !__go_type_descriptors_equal(inter, i.__methods[0])) {
- __builtin_memset(ret, 0, inter->__size);
- ok = 0;
- } else {
- __builtin_memcpy(ret, i.__object, inter->__size);
- ok = 1;
- }
-}
-
-// Return whether we can convert an interface to a type.
-func ifaceI2Tp(to *descriptor, from *descriptor) (ok bool) {
- ok = __go_can_convert_to_interface(to, from);
-}
diff --git a/gcc-4.8.1/libgo/runtime/interface.h b/gcc-4.8.1/libgo/runtime/interface.h
deleted file mode 100644
index f3068a656..000000000
--- a/gcc-4.8.1/libgo/runtime/interface.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* interface.h -- the interface type for Go.
-
- 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. */
-
-#ifndef LIBGO_INTERFACE_H
-#define LIBGO_INTERFACE_H
-
-struct __go_type_descriptor;
-
-/* A variable of interface type is an instance of this struct, if the
- interface has any methods. */
-
-struct __go_interface
-{
- /* A pointer to the interface method table. The first pointer is
- the type descriptor of the object. Subsequent pointers are
- pointers to functions. This is effectively the vtable for this
- interface. The function pointers are in the same order as the
- list in the internal representation of the interface, which sorts
- them by name. */
- const void **__methods;
-
- /* The object. If the object is a pointer--if the type descriptor
- code is GO_PTR or GO_UNSAFE_POINTER--then this field is the value
- of the object itself. Otherwise this is a pointer to memory
- which holds the value. */
- void *__object;
-};
-
-/* A variable of an empty interface type is an instance of this
- struct. */
-
-struct __go_empty_interface
-{
- /* The type descriptor of the object. */
- const struct __go_type_descriptor *__type_descriptor;
-
- /* The object. This is the same as __go_interface above. */
- void *__object;
-};
-
-extern void *
-__go_convert_interface (const struct __go_type_descriptor *,
- const struct __go_type_descriptor *);
-
-extern void *
-__go_convert_interface_2 (const struct __go_type_descriptor *,
- const struct __go_type_descriptor *,
- _Bool may_fail);
-
-extern _Bool
-__go_can_convert_to_interface(const struct __go_type_descriptor *,
- const struct __go_type_descriptor *);
-
-#endif /* !defined(LIBGO_INTERFACE_H) */
diff --git a/gcc-4.8.1/libgo/runtime/lfstack.c b/gcc-4.8.1/libgo/runtime/lfstack.c
deleted file mode 100644
index 230ed87c4..000000000
--- a/gcc-4.8.1/libgo/runtime/lfstack.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2012 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.
-
-// Lock-free stack.
-
-#include "runtime.h"
-#include "arch.h"
-
-#if __SIZEOF_POINTER__ == 8
-// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
-// So we use 17msb of pointers as ABA counter.
-# define PTR_BITS 47
-#else
-# define PTR_BITS 32
-#endif
-#define PTR_MASK ((1ull<<PTR_BITS)-1)
-#define CNT_MASK (0ull-1)
-
-#if __SIZEOF_POINTER__ == 8 && (defined(__sparc__) || (defined(__sun__) && defined(__amd64__)))
-// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
-// Use low-order three bits as ABA counter.
-// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
-#undef PTR_BITS
-#undef CNT_MASK
-#undef PTR_MASK
-#define PTR_BITS 0
-#define CNT_MASK 7
-#define PTR_MASK ((0ull-1)<<3)
-#endif
-
-void
-runtime_lfstackpush(uint64 *head, LFNode *node)
-{
- uint64 old, new;
-
- if((uintptr)node != ((uintptr)node&PTR_MASK)) {
- runtime_printf("p=%p\n", node);
- runtime_throw("runtime_lfstackpush: invalid pointer");
- }
-
- node->pushcnt++;
- new = (uint64)(uintptr)node|(((uint64)node->pushcnt&CNT_MASK)<<PTR_BITS);
- old = runtime_atomicload64(head);
- for(;;) {
- node->next = (LFNode*)(uintptr)(old&PTR_MASK);
- if(runtime_cas64(head, &old, new))
- break;
- }
-}
-
-LFNode*
-runtime_lfstackpop(uint64 *head)
-{
- LFNode *node, *node2;
- uint64 old, new;
-
- old = runtime_atomicload64(head);
- for(;;) {
- if(old == 0)
- return nil;
- node = (LFNode*)(uintptr)(old&PTR_MASK);
- node2 = runtime_atomicloadp(&node->next);
- new = 0;
- if(node2 != nil)
- new = (uint64)(uintptr)node2|(((uint64)node2->pushcnt&CNT_MASK)<<PTR_BITS);
- if(runtime_cas64(head, &old, new))
- return node;
- }
-}
-
-LFNode* runtime_lfstackpop2(uint64*)
- __asm__ (GOSYM_PREFIX "runtime.lfstackpop2");
-
-LFNode*
-runtime_lfstackpop2(uint64 *head)
-{
- return runtime_lfstackpop(head);
-}
diff --git a/gcc-4.8.1/libgo/runtime/lock_futex.c b/gcc-4.8.1/libgo/runtime/lock_futex.c
deleted file mode 100644
index 5374aff6d..000000000
--- a/gcc-4.8.1/libgo/runtime/lock_futex.c
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2011 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.
-
-// +build freebsd linux
-
-#include "runtime.h"
-
-// This implementation depends on OS-specific implementations of
-//
-// runtime_futexsleep(uint32 *addr, uint32 val, int64 ns)
-// Atomically,
-// if(*addr == val) sleep
-// Might be woken up spuriously; that's allowed.
-// Don't sleep longer than ns; ns < 0 means forever.
-//
-// runtime_futexwakeup(uint32 *addr, uint32 cnt)
-// If any procs are sleeping on addr, wake up at most cnt.
-
-enum
-{
- MUTEX_UNLOCKED = 0,
- MUTEX_LOCKED = 1,
- MUTEX_SLEEPING = 2,
-
- ACTIVE_SPIN = 4,
- ACTIVE_SPIN_CNT = 30,
- PASSIVE_SPIN = 1,
-};
-
-// Possible lock states are MUTEX_UNLOCKED, MUTEX_LOCKED and MUTEX_SLEEPING.
-// MUTEX_SLEEPING means that there is presumably at least one sleeping thread.
-// Note that there can be spinning threads during all states - they do not
-// affect mutex's state.
-void
-runtime_lock(Lock *l)
-{
- uint32 i, v, wait, spin;
-
- if(runtime_m()->locks++ < 0)
- runtime_throw("runtime_lock: lock count");
-
- // Speculative grab for lock.
- v = runtime_xchg(&l->key, MUTEX_LOCKED);
- if(v == MUTEX_UNLOCKED)
- return;
-
- // wait is either MUTEX_LOCKED or MUTEX_SLEEPING
- // depending on whether there is a thread sleeping
- // on this mutex. If we ever change l->key from
- // MUTEX_SLEEPING to some other value, we must be
- // careful to change it back to MUTEX_SLEEPING before
- // returning, to ensure that the sleeping thread gets
- // its wakeup call.
- wait = v;
-
- // On uniprocessor's, no point spinning.
- // On multiprocessors, spin for ACTIVE_SPIN attempts.
- spin = 0;
- if(runtime_ncpu > 1)
- spin = ACTIVE_SPIN;
-
- for(;;) {
- // Try for lock, spinning.
- for(i = 0; i < spin; i++) {
- while(l->key == MUTEX_UNLOCKED)
- if(runtime_cas(&l->key, MUTEX_UNLOCKED, wait))
- return;
- runtime_procyield(ACTIVE_SPIN_CNT);
- }
-
- // Try for lock, rescheduling.
- for(i=0; i < PASSIVE_SPIN; i++) {
- while(l->key == MUTEX_UNLOCKED)
- if(runtime_cas(&l->key, MUTEX_UNLOCKED, wait))
- return;
- runtime_osyield();
- }
-
- // Sleep.
- v = runtime_xchg(&l->key, MUTEX_SLEEPING);
- if(v == MUTEX_UNLOCKED)
- return;
- wait = MUTEX_SLEEPING;
- runtime_futexsleep(&l->key, MUTEX_SLEEPING, -1);
- }
-}
-
-void
-runtime_unlock(Lock *l)
-{
- uint32 v;
-
- if(--runtime_m()->locks < 0)
- runtime_throw("runtime_unlock: lock count");
-
- v = runtime_xchg(&l->key, MUTEX_UNLOCKED);
- if(v == MUTEX_UNLOCKED)
- runtime_throw("unlock of unlocked lock");
- if(v == MUTEX_SLEEPING)
- runtime_futexwakeup(&l->key, 1);
-}
-
-// One-time notifications.
-void
-runtime_noteclear(Note *n)
-{
- n->key = 0;
-}
-
-void
-runtime_notewakeup(Note *n)
-{
- if(runtime_xchg(&n->key, 1))
- runtime_throw("notewakeup - double wakeup");
- runtime_futexwakeup(&n->key, 1);
-}
-
-void
-runtime_notesleep(Note *n)
-{
- if(runtime_m()->profilehz > 0)
- runtime_setprof(false);
- while(runtime_atomicload(&n->key) == 0)
- runtime_futexsleep(&n->key, 0, -1);
- if(runtime_m()->profilehz > 0)
- runtime_setprof(true);
-}
-
-void
-runtime_notetsleep(Note *n, int64 ns)
-{
- int64 deadline, now;
-
- if(ns < 0) {
- runtime_notesleep(n);
- return;
- }
-
- if(runtime_atomicload(&n->key) != 0)
- return;
-
- if(runtime_m()->profilehz > 0)
- runtime_setprof(false);
- deadline = runtime_nanotime() + ns;
- for(;;) {
- runtime_futexsleep(&n->key, 0, ns);
- if(runtime_atomicload(&n->key) != 0)
- break;
- now = runtime_nanotime();
- if(now >= deadline)
- break;
- ns = deadline - now;
- }
- if(runtime_m()->profilehz > 0)
- runtime_setprof(true);
-}
diff --git a/gcc-4.8.1/libgo/runtime/lock_sema.c b/gcc-4.8.1/libgo/runtime/lock_sema.c
deleted file mode 100644
index 8c4b3973b..000000000
--- a/gcc-4.8.1/libgo/runtime/lock_sema.c
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2011 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.
-
-// +build darwin netbsd openbsd plan9 windows
-
-#include "runtime.h"
-
-// This implementation depends on OS-specific implementations of
-//
-// uintptr runtime_semacreate(void)
-// Create a semaphore, which will be assigned to m->waitsema.
-// The zero value is treated as absence of any semaphore,
-// so be sure to return a non-zero value.
-//
-// int32 runtime_semasleep(int64 ns)
-// If ns < 0, acquire m->waitsema and return 0.
-// If ns >= 0, try to acquire m->waitsema for at most ns nanoseconds.
-// Return 0 if the semaphore was acquired, -1 if interrupted or timed out.
-//
-// int32 runtime_semawakeup(M *mp)
-// Wake up mp, which is or will soon be sleeping on mp->waitsema.
-//
-
-enum
-{
- LOCKED = 1,
-
- ACTIVE_SPIN = 4,
- ACTIVE_SPIN_CNT = 30,
- PASSIVE_SPIN = 1,
-};
-
-void
-runtime_lock(Lock *l)
-{
- M *m;
- uintptr v;
- uint32 i, spin;
-
- m = runtime_m();
- if(m->locks++ < 0)
- runtime_throw("runtime_lock: lock count");
-
- // Speculative grab for lock.
- if(runtime_casp(&l->waitm, nil, (void*)LOCKED))
- return;
-
- if(m->waitsema == 0)
- m->waitsema = runtime_semacreate();
-
- // On uniprocessor's, no point spinning.
- // On multiprocessors, spin for ACTIVE_SPIN attempts.
- spin = 0;
- if(runtime_ncpu > 1)
- spin = ACTIVE_SPIN;
-
- for(i=0;; i++) {
- v = (uintptr)runtime_atomicloadp(&l->waitm);
- if((v&LOCKED) == 0) {
-unlocked:
- if(runtime_casp(&l->waitm, (void*)v, (void*)(v|LOCKED)))
- return;
- i = 0;
- }
- if(i<spin)
- runtime_procyield(ACTIVE_SPIN_CNT);
- else if(i<spin+PASSIVE_SPIN)
- runtime_osyield();
- else {
- // Someone else has it.
- // l->waitm points to a linked list of M's waiting
- // for this lock, chained through m->nextwaitm.
- // Queue this M.
- for(;;) {
- m->nextwaitm = (void*)(v&~LOCKED);
- if(runtime_casp(&l->waitm, (void*)v, (void*)((uintptr)m|LOCKED)))
- break;
- v = (uintptr)runtime_atomicloadp(&l->waitm);
- if((v&LOCKED) == 0)
- goto unlocked;
- }
- if(v&LOCKED) {
- // Queued. Wait.
- runtime_semasleep(-1);
- i = 0;
- }
- }
- }
-}
-
-void
-runtime_unlock(Lock *l)
-{
- uintptr v;
- M *mp;
-
- if(--runtime_m()->locks < 0)
- runtime_throw("runtime_unlock: lock count");
-
- for(;;) {
- v = (uintptr)runtime_atomicloadp(&l->waitm);
- if(v == LOCKED) {
- if(runtime_casp(&l->waitm, (void*)LOCKED, nil))
- break;
- } else {
- // Other M's are waiting for the lock.
- // Dequeue an M.
- mp = (void*)(v&~LOCKED);
- if(runtime_casp(&l->waitm, (void*)v, mp->nextwaitm)) {
- // Dequeued an M. Wake it.
- runtime_semawakeup(mp);
- break;
- }
- }
- }
-}
-
-// One-time notifications.
-void
-runtime_noteclear(Note *n)
-{
- n->waitm = nil;
-}
-
-void
-runtime_notewakeup(Note *n)
-{
- M *mp;
-
- do
- mp = runtime_atomicloadp(&n->waitm);
- while(!runtime_casp(&n->waitm, mp, (void*)LOCKED));
-
- // Successfully set waitm to LOCKED.
- // What was it before?
- if(mp == nil) {
- // Nothing was waiting. Done.
- } else if(mp == (M*)LOCKED) {
- // Two notewakeups! Not allowed.
- runtime_throw("notewakeup - double wakeup");
- } else {
- // Must be the waiting m. Wake it up.
- runtime_semawakeup(mp);
- }
-}
-
-void
-runtime_notesleep(Note *n)
-{
- M *m;
-
- m = runtime_m();
- if(m->waitsema == 0)
- m->waitsema = runtime_semacreate();
- if(!runtime_casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup)
- if(n->waitm != (void*)LOCKED)
- runtime_throw("notesleep - waitm out of sync");
- return;
- }
- // Queued. Sleep.
- if(m->profilehz > 0)
- runtime_setprof(false);
- runtime_semasleep(-1);
- if(m->profilehz > 0)
- runtime_setprof(true);
-}
-
-void
-runtime_notetsleep(Note *n, int64 ns)
-{
- M *m;
- M *mp;
- int64 deadline, now;
-
- if(ns < 0) {
- runtime_notesleep(n);
- return;
- }
-
- m = runtime_m();
- if(m->waitsema == 0)
- m->waitsema = runtime_semacreate();
-
- // Register for wakeup on n->waitm.
- if(!runtime_casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup already)
- if(n->waitm != (void*)LOCKED)
- runtime_throw("notetsleep - waitm out of sync");
- return;
- }
-
- if(m->profilehz > 0)
- runtime_setprof(false);
- deadline = runtime_nanotime() + ns;
- for(;;) {
- // Registered. Sleep.
- if(runtime_semasleep(ns) >= 0) {
- // Acquired semaphore, semawakeup unregistered us.
- // Done.
- if(m->profilehz > 0)
- runtime_setprof(true);
- return;
- }
-
- // Interrupted or timed out. Still registered. Semaphore not acquired.
- now = runtime_nanotime();
- if(now >= deadline)
- break;
-
- // Deadline hasn't arrived. Keep sleeping.
- ns = deadline - now;
- }
-
- if(m->profilehz > 0)
- runtime_setprof(true);
-
- // Deadline arrived. Still registered. Semaphore not acquired.
- // Want to give up and return, but have to unregister first,
- // so that any notewakeup racing with the return does not
- // try to grant us the semaphore when we don't expect it.
- for(;;) {
- mp = runtime_atomicloadp(&n->waitm);
- if(mp == m) {
- // No wakeup yet; unregister if possible.
- if(runtime_casp(&n->waitm, mp, nil))
- return;
- } else if(mp == (M*)LOCKED) {
- // Wakeup happened so semaphore is available.
- // Grab it to avoid getting out of sync.
- if(runtime_semasleep(-1) < 0)
- runtime_throw("runtime: unable to acquire - semaphore out of sync");
- return;
- } else {
- runtime_throw("runtime: unexpected waitm - semaphore out of sync");
- }
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/malloc.goc b/gcc-4.8.1/libgo/runtime/malloc.goc
deleted file mode 100644
index a48464207..000000000
--- a/gcc-4.8.1/libgo/runtime/malloc.goc
+++ /dev/null
@@ -1,784 +0,0 @@
-// 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.
-
-// See malloc.h for overview.
-//
-// TODO(rsc): double-check stats.
-
-package runtime
-#include <stddef.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "go-alloc.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "interface.h"
-#include "go-type.h"
-#include "race.h"
-
-MHeap runtime_mheap;
-
-int32 runtime_checking;
-
-extern MStats mstats; // defined in zruntime_def_$GOOS_$GOARCH.go
-
-extern volatile intgo runtime_MemProfileRate
- __asm__ (GOSYM_PREFIX "runtime.MemProfileRate");
-
-// Allocate an object of at least size bytes.
-// Small objects are allocated from the per-thread cache's free lists.
-// Large objects (> 32 kB) are allocated straight from the heap.
-void*
-runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
-{
- M *m;
- G *g;
- int32 sizeclass;
- intgo rate;
- MCache *c;
- uintptr npages;
- MSpan *s;
- void *v;
-
- m = runtime_m();
- g = runtime_g();
- if(g->status == Gsyscall)
- dogc = 0;
- if(runtime_gcwaiting && g != m->g0 && m->locks == 0 && g->status != Gsyscall) {
- runtime_gosched();
- m = runtime_m();
- }
- if(m->mallocing)
- runtime_throw("malloc/free - deadlock");
- m->mallocing = 1;
- if(size == 0)
- size = 1;
-
- if(DebugTypeAtBlockEnd)
- size += sizeof(uintptr);
-
- c = m->mcache;
- c->local_nmalloc++;
- if(size <= MaxSmallSize) {
- // Allocate from mcache free lists.
- sizeclass = runtime_SizeToClass(size);
- size = runtime_class_to_size[sizeclass];
- v = runtime_MCache_Alloc(c, sizeclass, size, zeroed);
- if(v == nil)
- runtime_throw("out of memory");
- c->local_alloc += size;
- c->local_total_alloc += size;
- c->local_by_size[sizeclass].nmalloc++;
- } else {
- // TODO(rsc): Report tracebacks for very large allocations.
-
- // Allocate directly from heap.
- npages = size >> PageShift;
- if((size & PageMask) != 0)
- npages++;
- s = runtime_MHeap_Alloc(&runtime_mheap, npages, 0, 1, zeroed);
- if(s == nil)
- runtime_throw("out of memory");
- size = npages<<PageShift;
- c->local_alloc += size;
- c->local_total_alloc += size;
- v = (void*)(s->start << PageShift);
-
- // setup for mark sweep
- runtime_markspan(v, 0, 0, true);
- }
-
- if (sizeof(void*) == 4 && c->local_total_alloc >= (1<<30)) {
- // purge cache stats to prevent overflow
- runtime_lock(&runtime_mheap);
- runtime_purgecachedstats(c);
- runtime_unlock(&runtime_mheap);
- }
-
- if(!(flag & FlagNoGC))
- runtime_markallocated(v, size, (flag&FlagNoPointers) != 0);
-
- if(DebugTypeAtBlockEnd)
- *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = 0;
-
- m->mallocing = 0;
-
- if(!(flag & FlagNoProfiling) && (rate = runtime_MemProfileRate) > 0) {
- if(size >= (uint32) rate)
- goto profile;
- if((uint32) m->mcache->next_sample > size)
- m->mcache->next_sample -= size;
- else {
- // pick next profile time
- // If you change this, also change allocmcache.
- if(rate > 0x3fffffff) // make 2*rate not overflow
- rate = 0x3fffffff;
- m->mcache->next_sample = runtime_fastrand1() % (2*rate);
- profile:
- runtime_setblockspecial(v, true);
- runtime_MProf_Malloc(v, size);
- }
- }
-
- if(dogc && mstats.heap_alloc >= mstats.next_gc)
- runtime_gc(0);
-
- if(raceenabled) {
- runtime_racemalloc(v, size, m->racepc);
- m->racepc = nil;
- }
- return v;
-}
-
-void*
-__go_alloc(uintptr size)
-{
- return runtime_mallocgc(size, 0, 0, 1);
-}
-
-// Free the object whose base pointer is v.
-void
-__go_free(void *v)
-{
- M *m;
- int32 sizeclass;
- MSpan *s;
- MCache *c;
- uint32 prof;
- uintptr size;
-
- if(v == nil)
- return;
-
- // If you change this also change mgc0.c:/^sweep,
- // which has a copy of the guts of free.
-
- m = runtime_m();
- if(m->mallocing)
- runtime_throw("malloc/free - deadlock");
- m->mallocing = 1;
-
- if(!runtime_mlookup(v, nil, nil, &s)) {
- runtime_printf("free %p: not an allocated block\n", v);
- runtime_throw("free runtime_mlookup");
- }
- prof = runtime_blockspecial(v);
-
- if(raceenabled)
- runtime_racefree(v);
-
- // Find size class for v.
- sizeclass = s->sizeclass;
- c = m->mcache;
- if(sizeclass == 0) {
- // Large object.
- size = s->npages<<PageShift;
- *(uintptr*)(s->start<<PageShift) = 1; // mark as "needs to be zeroed"
- // Must mark v freed before calling unmarkspan and MHeap_Free:
- // they might coalesce v into other spans and change the bitmap further.
- runtime_markfreed(v, size);
- runtime_unmarkspan(v, 1<<PageShift);
- runtime_MHeap_Free(&runtime_mheap, s, 1);
- } else {
- // Small object.
- size = runtime_class_to_size[sizeclass];
- if(size > sizeof(uintptr))
- ((uintptr*)v)[1] = 1; // mark as "needs to be zeroed"
- // Must mark v freed before calling MCache_Free:
- // it might coalesce v and other blocks into a bigger span
- // and change the bitmap further.
- runtime_markfreed(v, size);
- c->local_by_size[sizeclass].nfree++;
- runtime_MCache_Free(c, v, sizeclass, size);
- }
- c->local_nfree++;
- c->local_alloc -= size;
- if(prof)
- runtime_MProf_Free(v, size);
- m->mallocing = 0;
-}
-
-int32
-runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
-{
- M *m;
- uintptr n, i;
- byte *p;
- MSpan *s;
-
- m = runtime_m();
-
- m->mcache->local_nlookup++;
- if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) {
- // purge cache stats to prevent overflow
- runtime_lock(&runtime_mheap);
- runtime_purgecachedstats(m->mcache);
- runtime_unlock(&runtime_mheap);
- }
-
- s = runtime_MHeap_LookupMaybe(&runtime_mheap, v);
- if(sp)
- *sp = s;
- if(s == nil) {
- runtime_checkfreed(v, 1);
- if(base)
- *base = nil;
- if(size)
- *size = 0;
- return 0;
- }
-
- p = (byte*)((uintptr)s->start<<PageShift);
- if(s->sizeclass == 0) {
- // Large object.
- if(base)
- *base = p;
- if(size)
- *size = s->npages<<PageShift;
- return 1;
- }
-
- if((byte*)v >= (byte*)s->limit) {
- // pointers past the last block do not count as pointers.
- return 0;
- }
-
- n = s->elemsize;
- if(base) {
- i = ((byte*)v - p)/n;
- *base = p + i*n;
- }
- if(size)
- *size = n;
-
- return 1;
-}
-
-MCache*
-runtime_allocmcache(void)
-{
- intgo rate;
- MCache *c;
-
- runtime_lock(&runtime_mheap);
- c = runtime_FixAlloc_Alloc(&runtime_mheap.cachealloc);
- mstats.mcache_inuse = runtime_mheap.cachealloc.inuse;
- mstats.mcache_sys = runtime_mheap.cachealloc.sys;
- runtime_unlock(&runtime_mheap);
- runtime_memclr((byte*)c, sizeof(*c));
-
- // Set first allocation sample size.
- rate = runtime_MemProfileRate;
- if(rate > 0x3fffffff) // make 2*rate not overflow
- rate = 0x3fffffff;
- if(rate != 0)
- c->next_sample = runtime_fastrand1() % (2*rate);
-
- return c;
-}
-
-void
-runtime_freemcache(MCache *c)
-{
- runtime_MCache_ReleaseAll(c);
- runtime_lock(&runtime_mheap);
- runtime_purgecachedstats(c);
- runtime_FixAlloc_Free(&runtime_mheap.cachealloc, c);
- runtime_unlock(&runtime_mheap);
-}
-
-void
-runtime_purgecachedstats(MCache *c)
-{
- // Protected by either heap or GC lock.
- mstats.heap_alloc += c->local_cachealloc;
- c->local_cachealloc = 0;
- mstats.heap_objects += c->local_objects;
- c->local_objects = 0;
- mstats.nmalloc += c->local_nmalloc;
- c->local_nmalloc = 0;
- mstats.nfree += c->local_nfree;
- c->local_nfree = 0;
- mstats.nlookup += c->local_nlookup;
- c->local_nlookup = 0;
- mstats.alloc += c->local_alloc;
- c->local_alloc= 0;
- mstats.total_alloc += c->local_total_alloc;
- c->local_total_alloc= 0;
-}
-
-extern uintptr runtime_sizeof_C_MStats
- __asm__ (GOSYM_PREFIX "runtime.Sizeof_C_MStats");
-
-#define MaxArena32 (2U<<30)
-
-void
-runtime_mallocinit(void)
-{
- byte *p;
- uintptr arena_size, bitmap_size;
- extern byte end[];
- byte *want;
- uintptr limit;
-
- runtime_sizeof_C_MStats = sizeof(MStats);
-
- p = nil;
- arena_size = 0;
- bitmap_size = 0;
-
- // for 64-bit build
- USED(p);
- USED(arena_size);
- USED(bitmap_size);
-
- runtime_InitSizes();
-
- limit = runtime_memlimit();
-
- // Set up the allocation arena, a contiguous area of memory where
- // allocated data will be found. The arena begins with a bitmap large
- // enough to hold 4 bits per allocated word.
- if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
- // On a 64-bit machine, allocate from a single contiguous reservation.
- // 128 GB (MaxMem) should be big enough for now.
- //
- // The code will work with the reservation at any address, but ask
- // SysReserve to use 0x000000c000000000 if possible.
- // Allocating a 128 GB region takes away 37 bits, and the amd64
- // doesn't let us choose the top 17 bits, so that leaves the 11 bits
- // in the middle of 0x00c0 for us to choose. Choosing 0x00c0 means
- // that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x0x00df.
- // In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
- // UTF-8 sequences, and they are otherwise as far away from
- // ff (likely a common byte) as possible. An earlier attempt to use 0x11f8
- // caused out of memory errors on OS X during thread allocations.
- // These choices are both for debuggability and to reduce the
- // odds of the conservative garbage collector not collecting memory
- // because some non-pointer block of memory had a bit pattern
- // that matched a memory address.
- //
- // Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
- // but it hardly matters: e0 00 is not valid UTF-8 either.
- //
- // If this fails we fall back to the 32 bit memory mechanism
- arena_size = MaxMem;
- bitmap_size = arena_size / (sizeof(void*)*8/4);
- p = runtime_SysReserve((void*)(0x00c0ULL<<32), bitmap_size + arena_size);
- }
- if (p == nil) {
- // On a 32-bit machine, we can't typically get away
- // with a giant virtual address space reservation.
- // Instead we map the memory information bitmap
- // immediately after the data segment, large enough
- // to handle another 2GB of mappings (256 MB),
- // along with a reservation for another 512 MB of memory.
- // When that gets used up, we'll start asking the kernel
- // for any memory anywhere and hope it's in the 2GB
- // following the bitmap (presumably the executable begins
- // near the bottom of memory, so we'll have to use up
- // most of memory before the kernel resorts to giving out
- // memory before the beginning of the text segment).
- //
- // Alternatively we could reserve 512 MB bitmap, enough
- // for 4GB of mappings, and then accept any memory the
- // kernel threw at us, but normally that's a waste of 512 MB
- // of address space, which is probably too much in a 32-bit world.
- bitmap_size = MaxArena32 / (sizeof(void*)*8/4);
- arena_size = 512<<20;
- if(limit > 0 && arena_size+bitmap_size > limit) {
- bitmap_size = (limit / 9) & ~((1<<PageShift) - 1);
- arena_size = bitmap_size * 8;
- }
-
- // SysReserve treats the address we ask for, end, as a hint,
- // not as an absolute requirement. If we ask for the end
- // of the data segment but the operating system requires
- // a little more space before we can start allocating, it will
- // give out a slightly higher pointer. Except QEMU, which
- // is buggy, as usual: it won't adjust the pointer upward.
- // So adjust it upward a little bit ourselves: 1/4 MB to get
- // away from the running binary image and then round up
- // to a MB boundary.
- want = (byte*)(((uintptr)end + (1<<18) + (1<<20) - 1)&~((1<<20)-1));
- if(0xffffffff - (uintptr)want <= bitmap_size + arena_size)
- want = 0;
- p = runtime_SysReserve(want, bitmap_size + arena_size);
- if(p == nil)
- runtime_throw("runtime: cannot reserve arena virtual address space");
- if((uintptr)p & (((uintptr)1<<PageShift)-1))
- runtime_printf("runtime: SysReserve returned unaligned address %p; asked for %p", p, bitmap_size+arena_size);
- }
- if((uintptr)p & (((uintptr)1<<PageShift)-1))
- runtime_throw("runtime: SysReserve returned unaligned address");
-
- runtime_mheap.bitmap = p;
- runtime_mheap.arena_start = p + bitmap_size;
- runtime_mheap.arena_used = runtime_mheap.arena_start;
- runtime_mheap.arena_end = runtime_mheap.arena_start + arena_size;
-
- // Initialize the rest of the allocator.
- runtime_MHeap_Init(&runtime_mheap, runtime_SysAlloc);
- runtime_m()->mcache = runtime_allocmcache();
-
- // See if it works.
- runtime_free(runtime_malloc(1));
-}
-
-void*
-runtime_MHeap_SysAlloc(MHeap *h, uintptr n)
-{
- byte *p;
-
-
- if(n > (uintptr)(h->arena_end - h->arena_used)) {
- // We are in 32-bit mode, maybe we didn't use all possible address space yet.
- // Reserve some more space.
- byte *new_end;
- uintptr needed;
-
- needed = (uintptr)h->arena_used + n - (uintptr)h->arena_end;
- // Round wanted arena size to a multiple of 256MB.
- needed = (needed + (256<<20) - 1) & ~((256<<20)-1);
- new_end = h->arena_end + needed;
- if(new_end <= h->arena_start + MaxArena32) {
- p = runtime_SysReserve(h->arena_end, new_end - h->arena_end);
- if(p == h->arena_end)
- h->arena_end = new_end;
- }
- }
- if(n <= (uintptr)(h->arena_end - h->arena_used)) {
- // Keep taking from our reservation.
- p = h->arena_used;
- runtime_SysMap(p, n);
- h->arena_used += n;
- runtime_MHeap_MapBits(h);
- if(raceenabled)
- runtime_racemapshadow(p, n);
- return p;
- }
-
- // If using 64-bit, our reservation is all we have.
- if(sizeof(void*) == 8 && (uintptr)h->bitmap >= 0xffffffffU)
- return nil;
-
- // On 32-bit, once the reservation is gone we can
- // try to get memory at a location chosen by the OS
- // and hope that it is in the range we allocated bitmap for.
- p = runtime_SysAlloc(n);
- if(p == nil)
- return nil;
-
- if(p < h->arena_start || (uintptr)(p+n - h->arena_start) >= MaxArena32) {
- runtime_printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n",
- p, h->arena_start, h->arena_start+MaxArena32);
- runtime_SysFree(p, n);
- return nil;
- }
-
- if(p+n > h->arena_used) {
- h->arena_used = p+n;
- if(h->arena_used > h->arena_end)
- h->arena_end = h->arena_used;
- runtime_MHeap_MapBits(h);
- if(raceenabled)
- runtime_racemapshadow(p, n);
- }
-
- return p;
-}
-
-static Lock settype_lock;
-
-void
-runtime_settype_flush(M *mp, bool sysalloc)
-{
- uintptr *buf, *endbuf;
- uintptr size, ofs, j, t;
- uintptr ntypes, nbytes2, nbytes3;
- uintptr *data2;
- byte *data3;
- bool sysalloc3;
- void *v;
- uintptr typ, p;
- MSpan *s;
-
- buf = mp->settype_buf;
- endbuf = buf + mp->settype_bufsize;
-
- runtime_lock(&settype_lock);
- while(buf < endbuf) {
- v = (void*)*buf;
- *buf = 0;
- buf++;
- typ = *buf;
- buf++;
-
- // (Manually inlined copy of runtime_MHeap_Lookup)
- p = (uintptr)v>>PageShift;
- if(sizeof(void*) == 8)
- p -= (uintptr)runtime_mheap.arena_start >> PageShift;
- s = runtime_mheap.map[p];
-
- if(s->sizeclass == 0) {
- s->types.compression = MTypes_Single;
- s->types.data = typ;
- continue;
- }
-
- size = s->elemsize;
- ofs = ((uintptr)v - (s->start<<PageShift)) / size;
-
- switch(s->types.compression) {
- case MTypes_Empty:
- ntypes = (s->npages << PageShift) / size;
- nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
-
- if(!sysalloc) {
- data3 = runtime_mallocgc(nbytes3, FlagNoPointers, 0, 1);
- } else {
- data3 = runtime_SysAlloc(nbytes3);
- if(0) runtime_printf("settype(0->3): SysAlloc(%x) --> %p\n", (uint32)nbytes3, data3);
- }
-
- s->types.compression = MTypes_Bytes;
- s->types.sysalloc = sysalloc;
- s->types.data = (uintptr)data3;
-
- ((uintptr*)data3)[1] = typ;
- data3[8*sizeof(uintptr) + ofs] = 1;
- break;
-
- case MTypes_Words:
- ((uintptr*)s->types.data)[ofs] = typ;
- break;
-
- case MTypes_Bytes:
- data3 = (byte*)s->types.data;
- for(j=1; j<8; j++) {
- if(((uintptr*)data3)[j] == typ) {
- break;
- }
- if(((uintptr*)data3)[j] == 0) {
- ((uintptr*)data3)[j] = typ;
- break;
- }
- }
- if(j < 8) {
- data3[8*sizeof(uintptr) + ofs] = j;
- } else {
- ntypes = (s->npages << PageShift) / size;
- nbytes2 = ntypes * sizeof(uintptr);
-
- if(!sysalloc) {
- data2 = runtime_mallocgc(nbytes2, FlagNoPointers, 0, 1);
- } else {
- data2 = runtime_SysAlloc(nbytes2);
- if(0) runtime_printf("settype.(3->2): SysAlloc(%x) --> %p\n", (uint32)nbytes2, data2);
- }
-
- sysalloc3 = s->types.sysalloc;
-
- s->types.compression = MTypes_Words;
- s->types.sysalloc = sysalloc;
- s->types.data = (uintptr)data2;
-
- // Move the contents of data3 to data2. Then deallocate data3.
- for(j=0; j<ntypes; j++) {
- t = data3[8*sizeof(uintptr) + j];
- t = ((uintptr*)data3)[t];
- data2[j] = t;
- }
- if(sysalloc3) {
- nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
- if(0) runtime_printf("settype.(3->2): SysFree(%p,%x)\n", data3, (uint32)nbytes3);
- runtime_SysFree(data3, nbytes3);
- }
-
- data2[ofs] = typ;
- }
- break;
- }
- }
- runtime_unlock(&settype_lock);
-
- mp->settype_bufsize = 0;
-}
-
-// It is forbidden to use this function if it is possible that
-// explicit deallocation via calling runtime_free(v) may happen.
-void
-runtime_settype(void *v, uintptr t)
-{
- M *mp;
- uintptr *buf;
- uintptr i;
- MSpan *s;
-
- if(t == 0)
- runtime_throw("settype: zero type");
-
- mp = runtime_m();
- buf = mp->settype_buf;
- i = mp->settype_bufsize;
- buf[i+0] = (uintptr)v;
- buf[i+1] = t;
- i += 2;
- mp->settype_bufsize = i;
-
- if(i == nelem(mp->settype_buf)) {
- runtime_settype_flush(mp, false);
- }
-
- if(DebugTypeAtBlockEnd) {
- s = runtime_MHeap_Lookup(&runtime_mheap, v);
- *(uintptr*)((uintptr)v+s->elemsize-sizeof(uintptr)) = t;
- }
-}
-
-void
-runtime_settype_sysfree(MSpan *s)
-{
- uintptr ntypes, nbytes;
-
- if(!s->types.sysalloc)
- return;
-
- nbytes = (uintptr)-1;
-
- switch (s->types.compression) {
- case MTypes_Words:
- ntypes = (s->npages << PageShift) / s->elemsize;
- nbytes = ntypes * sizeof(uintptr);
- break;
- case MTypes_Bytes:
- ntypes = (s->npages << PageShift) / s->elemsize;
- nbytes = 8*sizeof(uintptr) + 1*ntypes;
- break;
- }
-
- if(nbytes != (uintptr)-1) {
- if(0) runtime_printf("settype: SysFree(%p,%x)\n", (void*)s->types.data, (uint32)nbytes);
- runtime_SysFree((void*)s->types.data, nbytes);
- }
-}
-
-uintptr
-runtime_gettype(void *v)
-{
- MSpan *s;
- uintptr t, ofs;
- byte *data;
-
- s = runtime_MHeap_LookupMaybe(&runtime_mheap, v);
- if(s != nil) {
- t = 0;
- switch(s->types.compression) {
- case MTypes_Empty:
- break;
- case MTypes_Single:
- t = s->types.data;
- break;
- case MTypes_Words:
- ofs = (uintptr)v - (s->start<<PageShift);
- t = ((uintptr*)s->types.data)[ofs/s->elemsize];
- break;
- case MTypes_Bytes:
- ofs = (uintptr)v - (s->start<<PageShift);
- data = (byte*)s->types.data;
- t = data[8*sizeof(uintptr) + ofs/s->elemsize];
- t = ((uintptr*)data)[t];
- break;
- default:
- runtime_throw("runtime_gettype: invalid compression kind");
- }
- if(0) {
- runtime_lock(&settype_lock);
- runtime_printf("%p -> %d,%X\n", v, (int32)s->types.compression, (int64)t);
- runtime_unlock(&settype_lock);
- }
- return t;
- }
- return 0;
-}
-
-// Runtime stubs.
-
-void*
-runtime_mal(uintptr n)
-{
- return runtime_mallocgc(n, 0, 1, 1);
-}
-
-void *
-runtime_new(const Type *typ)
-{
- void *ret;
- uint32 flag;
-
- if(raceenabled)
- runtime_m()->racepc = runtime_getcallerpc(&typ);
-
- if(typ->__size == 0) {
- // All 0-length allocations use this pointer.
- // The language does not require the allocations to
- // have distinct values.
- ret = (uint8*)&runtime_zerobase;
- } else {
- flag = typ->__code&GO_NO_POINTERS ? FlagNoPointers : 0;
- ret = runtime_mallocgc(typ->__size, flag, 1, 1);
-
- if(UseSpanType && !flag) {
- if(false) {
- runtime_printf("new %S: %p\n", *typ->__reflection, ret);
- }
- runtime_settype(ret, (uintptr)typ | TypeInfo_SingleObject);
- }
- }
-
- return ret;
-}
-
-func GC() {
- runtime_gc(1);
-}
-
-func SetFinalizer(obj Eface, finalizer Eface) {
- byte *base;
- uintptr size;
- const FuncType *ft;
-
- if(obj.__type_descriptor == nil) {
- runtime_printf("runtime.SetFinalizer: first argument is nil interface\n");
- goto throw;
- }
- if(obj.__type_descriptor->__code != GO_PTR) {
- runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.__type_descriptor->__reflection);
- goto throw;
- }
- if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object != base) {
- runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
- goto throw;
- }
- ft = nil;
- if(finalizer.__type_descriptor != nil) {
- if(finalizer.__type_descriptor->__code != GO_FUNC)
- goto badfunc;
- ft = (const FuncType*)finalizer.__type_descriptor;
- if(ft->__dotdotdot || ft->__in.__count != 1 || !__go_type_descriptors_equal(*(Type**)ft->__in.__values, obj.__type_descriptor))
- goto badfunc;
- }
-
- if(!runtime_addfinalizer(obj.__object, finalizer.__type_descriptor != nil ? *(void**)finalizer.__object : nil, ft)) {
- runtime_printf("runtime.SetFinalizer: finalizer already set\n");
- goto throw;
- }
- return;
-
-badfunc:
- runtime_printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.__type_descriptor->__reflection, *obj.__type_descriptor->__reflection);
-throw:
- runtime_throw("runtime.SetFinalizer");
-}
diff --git a/gcc-4.8.1/libgo/runtime/malloc.h b/gcc-4.8.1/libgo/runtime/malloc.h
deleted file mode 100644
index a82077420..000000000
--- a/gcc-4.8.1/libgo/runtime/malloc.h
+++ /dev/null
@@ -1,508 +0,0 @@
-// 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.
-
-// Memory allocator, based on tcmalloc.
-// http://goog-perftools.sourceforge.net/doc/tcmalloc.html
-
-// The main allocator works in runs of pages.
-// Small allocation sizes (up to and including 32 kB) are
-// rounded to one of about 100 size classes, each of which
-// has its own free list of objects of exactly that size.
-// Any free page of memory can be split into a set of objects
-// of one size class, which are then managed using free list
-// allocators.
-//
-// The allocator's data structures are:
-//
-// FixAlloc: a free-list allocator for fixed-size objects,
-// used to manage storage used by the allocator.
-// MHeap: the malloc heap, managed at page (4096-byte) granularity.
-// MSpan: a run of pages managed by the MHeap.
-// MCentral: a shared free list for a given size class.
-// MCache: a per-thread (in Go, per-M) cache for small objects.
-// MStats: allocation statistics.
-//
-// Allocating a small object proceeds up a hierarchy of caches:
-//
-// 1. Round the size up to one of the small size classes
-// and look in the corresponding MCache free list.
-// If the list is not empty, allocate an object from it.
-// This can all be done without acquiring a lock.
-//
-// 2. If the MCache free list is empty, replenish it by
-// taking a bunch of objects from the MCentral free list.
-// Moving a bunch amortizes the cost of acquiring the MCentral lock.
-//
-// 3. If the MCentral free list is empty, replenish it by
-// allocating a run of pages from the MHeap and then
-// chopping that memory into a objects of the given size.
-// Allocating many objects amortizes the cost of locking
-// the heap.
-//
-// 4. If the MHeap is empty or has no page runs large enough,
-// allocate a new group of pages (at least 1MB) from the
-// operating system. Allocating a large run of pages
-// amortizes the cost of talking to the operating system.
-//
-// Freeing a small object proceeds up the same hierarchy:
-//
-// 1. Look up the size class for the object and add it to
-// the MCache free list.
-//
-// 2. If the MCache free list is too long or the MCache has
-// too much memory, return some to the MCentral free lists.
-//
-// 3. If all the objects in a given span have returned to
-// the MCentral list, return that span to the page heap.
-//
-// 4. If the heap has too much memory, return some to the
-// operating system.
-//
-// TODO(rsc): Step 4 is not implemented.
-//
-// Allocating and freeing a large object uses the page heap
-// directly, bypassing the MCache and MCentral free lists.
-//
-// The small objects on the MCache and MCentral free lists
-// may or may not be zeroed. They are zeroed if and only if
-// the second word of the object is zero. The spans in the
-// page heap are always zeroed. When a span full of objects
-// is returned to the page heap, the objects that need to be
-// are zeroed first. There are two main benefits to delaying the
-// zeroing this way:
-//
-// 1. stack frames allocated from the small object lists
-// can avoid zeroing altogether.
-// 2. the cost of zeroing when reusing a small object is
-// charged to the mutator, not the garbage collector.
-//
-// This C code was written with an eye toward translating to Go
-// in the future. Methods have the form Type_Method(Type *t, ...).
-
-typedef struct MCentral MCentral;
-typedef struct MHeap MHeap;
-typedef struct MSpan MSpan;
-typedef struct MStats MStats;
-typedef struct MLink MLink;
-typedef struct MTypes MTypes;
-
-enum
-{
- PageShift = 12,
- PageSize = 1<<PageShift,
- PageMask = PageSize - 1,
-};
-typedef uintptr PageID; // address >> PageShift
-
-enum
-{
- // Computed constant. The definition of MaxSmallSize and the
- // algorithm in msize.c produce some number of different allocation
- // size classes. NumSizeClasses is that number. It's needed here
- // because there are static arrays of this length; when msize runs its
- // size choosing algorithm it double-checks that NumSizeClasses agrees.
- NumSizeClasses = 61,
-
- // Tunable constants.
- MaxSmallSize = 32<<10,
-
- FixAllocChunk = 128<<10, // Chunk size for FixAlloc
- MaxMCacheListLen = 256, // Maximum objects on MCacheList
- MaxMCacheSize = 2<<20, // Maximum bytes in one MCache
- MaxMHeapList = 1<<(20 - PageShift), // Maximum page length for fixed-size list in MHeap.
- HeapAllocChunk = 1<<20, // Chunk size for heap growth
-
- // Number of bits in page to span calculations (4k pages).
- // On 64-bit, we limit the arena to 128GB, or 37 bits.
- // On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
-#if __SIZEOF_POINTER__ == 8
- MHeapMap_Bits = 37 - PageShift,
-#else
- MHeapMap_Bits = 32 - PageShift,
-#endif
-
- // Max number of threads to run garbage collection.
- // 2, 3, and 4 are all plausible maximums depending
- // on the hardware details of the machine. The garbage
- // collector scales well to 8 cpus.
- MaxGcproc = 8,
-};
-
-// Maximum memory allocation size, a hint for callers.
-// This must be a #define instead of an enum because it
-// is so large.
-#if __SIZEOF_POINTER__ == 8
-#define MaxMem (1ULL<<(MHeapMap_Bits+PageShift)) /* 128 GB */
-#else
-#define MaxMem ((uintptr)-1)
-#endif
-
-// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
-struct MLink
-{
- MLink *next;
-};
-
-// SysAlloc obtains a large chunk of zeroed memory from the
-// operating system, typically on the order of a hundred kilobytes
-// or a megabyte. If the pointer argument is non-nil, the caller
-// wants a mapping there or nowhere.
-//
-// SysUnused notifies the operating system that the contents
-// of the memory region are no longer needed and can be reused
-// for other purposes. The program reserves the right to start
-// accessing those pages in the future.
-//
-// SysFree returns it unconditionally; this is only used if
-// an out-of-memory error has been detected midway through
-// an allocation. It is okay if SysFree is a no-op.
-//
-// SysReserve reserves address space without allocating memory.
-// If the pointer passed to it is non-nil, the caller wants the
-// reservation there, but SysReserve can still choose another
-// location if that one is unavailable.
-//
-// SysMap maps previously reserved address space for use.
-
-void* runtime_SysAlloc(uintptr nbytes);
-void runtime_SysFree(void *v, uintptr nbytes);
-void runtime_SysUnused(void *v, uintptr nbytes);
-void runtime_SysMap(void *v, uintptr nbytes);
-void* runtime_SysReserve(void *v, uintptr nbytes);
-
-// FixAlloc is a simple free-list allocator for fixed size objects.
-// Malloc uses a FixAlloc wrapped around SysAlloc to manages its
-// MCache and MSpan objects.
-//
-// Memory returned by FixAlloc_Alloc is not zeroed.
-// The caller is responsible for locking around FixAlloc calls.
-// Callers can keep state in the object but the first word is
-// smashed by freeing and reallocating.
-struct FixAlloc
-{
- uintptr size;
- void *(*alloc)(uintptr);
- void (*first)(void *arg, byte *p); // called first time p is returned
- void *arg;
- MLink *list;
- byte *chunk;
- uint32 nchunk;
- uintptr inuse; // in-use bytes now
- uintptr sys; // bytes obtained from system
-};
-
-void runtime_FixAlloc_Init(FixAlloc *f, uintptr size, void *(*alloc)(uintptr), void (*first)(void*, byte*), void *arg);
-void* runtime_FixAlloc_Alloc(FixAlloc *f);
-void runtime_FixAlloc_Free(FixAlloc *f, void *p);
-
-
-// Statistics.
-// Shared with Go: if you edit this structure, also edit type MemStats in mem.go.
-struct MStats
-{
- // General statistics.
- uint64 alloc; // bytes allocated and still in use
- uint64 total_alloc; // bytes allocated (even if freed)
- uint64 sys; // bytes obtained from system (should be sum of xxx_sys below, no locking, approximate)
- uint64 nlookup; // number of pointer lookups
- uint64 nmalloc; // number of mallocs
- uint64 nfree; // number of frees
-
- // Statistics about malloc heap.
- // protected by mheap.Lock
- uint64 heap_alloc; // bytes allocated and still in use
- uint64 heap_sys; // bytes obtained from system
- uint64 heap_idle; // bytes in idle spans
- uint64 heap_inuse; // bytes in non-idle spans
- uint64 heap_released; // bytes released to the OS
- uint64 heap_objects; // total number of allocated objects
-
- // Statistics about allocation of low-level fixed-size structures.
- // Protected by FixAlloc locks.
- uint64 stacks_inuse; // bootstrap stacks
- uint64 stacks_sys;
- uint64 mspan_inuse; // MSpan structures
- uint64 mspan_sys;
- uint64 mcache_inuse; // MCache structures
- uint64 mcache_sys;
- uint64 buckhash_sys; // profiling bucket hash table
-
- // Statistics about garbage collector.
- // Protected by stopping the world during GC.
- uint64 next_gc; // next GC (in heap_alloc time)
- uint64 last_gc; // last GC (in absolute time)
- uint64 pause_total_ns;
- uint64 pause_ns[256];
- uint32 numgc;
- bool enablegc;
- bool debuggc;
-
- // Statistics about allocation size classes.
- struct {
- uint32 size;
- uint64 nmalloc;
- uint64 nfree;
- } by_size[NumSizeClasses];
-};
-
-extern MStats mstats
- __asm__ (GOSYM_PREFIX "runtime.VmemStats");
-
-
-// Size classes. Computed and initialized by InitSizes.
-//
-// SizeToClass(0 <= n <= MaxSmallSize) returns the size class,
-// 1 <= sizeclass < NumSizeClasses, for n.
-// Size class 0 is reserved to mean "not small".
-//
-// class_to_size[i] = largest size in class i
-// class_to_allocnpages[i] = number of pages to allocate when
-// making new objects in class i
-// class_to_transfercount[i] = number of objects to move when
-// taking a bunch of objects out of the central lists
-// and putting them in the thread free list.
-
-int32 runtime_SizeToClass(int32);
-extern int32 runtime_class_to_size[NumSizeClasses];
-extern int32 runtime_class_to_allocnpages[NumSizeClasses];
-extern int32 runtime_class_to_transfercount[NumSizeClasses];
-extern void runtime_InitSizes(void);
-
-
-// Per-thread (in Go, per-M) cache for small objects.
-// No locking needed because it is per-thread (per-M).
-typedef struct MCacheList MCacheList;
-struct MCacheList
-{
- MLink *list;
- uint32 nlist;
- uint32 nlistmin;
-};
-
-struct MCache
-{
- MCacheList list[NumSizeClasses];
- uintptr size;
- intptr local_cachealloc; // bytes allocated (or freed) from cache since last lock of heap
- intptr local_objects; // objects allocated (or freed) from cache since last lock of heap
- intptr local_alloc; // bytes allocated (or freed) since last lock of heap
- uintptr local_total_alloc; // bytes allocated (even if freed) since last lock of heap
- uintptr local_nmalloc; // number of mallocs since last lock of heap
- uintptr local_nfree; // number of frees since last lock of heap
- uintptr local_nlookup; // number of pointer lookups since last lock of heap
- int32 next_sample; // trigger heap sample after allocating this many bytes
- // Statistics about allocation size classes since last lock of heap
- struct {
- uintptr nmalloc;
- uintptr nfree;
- } local_by_size[NumSizeClasses];
-
-};
-
-void* runtime_MCache_Alloc(MCache *c, int32 sizeclass, uintptr size, int32 zeroed);
-void runtime_MCache_Free(MCache *c, void *p, int32 sizeclass, uintptr size);
-void runtime_MCache_ReleaseAll(MCache *c);
-
-// MTypes describes the types of blocks allocated within a span.
-// The compression field describes the layout of the data.
-//
-// MTypes_Empty:
-// All blocks are free, or no type information is available for
-// allocated blocks.
-// The data field has no meaning.
-// MTypes_Single:
-// The span contains just one block.
-// The data field holds the type information.
-// The sysalloc field has no meaning.
-// MTypes_Words:
-// The span contains multiple blocks.
-// The data field points to an array of type [NumBlocks]uintptr,
-// and each element of the array holds the type of the corresponding
-// block.
-// MTypes_Bytes:
-// The span contains at most seven different types of blocks.
-// The data field points to the following structure:
-// struct {
-// type [8]uintptr // type[0] is always 0
-// index [NumBlocks]byte
-// }
-// The type of the i-th block is: data.type[data.index[i]]
-enum
-{
- MTypes_Empty = 0,
- MTypes_Single = 1,
- MTypes_Words = 2,
- MTypes_Bytes = 3,
-};
-struct MTypes
-{
- byte compression; // one of MTypes_*
- bool sysalloc; // whether (void*)data is from runtime_SysAlloc
- uintptr data;
-};
-
-// An MSpan is a run of pages.
-enum
-{
- MSpanInUse = 0,
- MSpanFree,
- MSpanListHead,
- MSpanDead,
-};
-struct MSpan
-{
- MSpan *next; // in a span linked list
- MSpan *prev; // in a span linked list
- PageID start; // starting page number
- uintptr npages; // number of pages in span
- MLink *freelist; // list of free objects
- uint32 ref; // number of allocated objects in this span
- int32 sizeclass; // size class
- uintptr elemsize; // computed from sizeclass or from npages
- uint32 state; // MSpanInUse etc
- int64 unusedsince; // First time spotted by GC in MSpanFree state
- uintptr npreleased; // number of pages released to the OS
- byte *limit; // end of data in span
- MTypes types; // types of allocated objects in this span
-};
-
-void runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages);
-
-// Every MSpan is in one doubly-linked list,
-// either one of the MHeap's free lists or one of the
-// MCentral's span lists. We use empty MSpan structures as list heads.
-void runtime_MSpanList_Init(MSpan *list);
-bool runtime_MSpanList_IsEmpty(MSpan *list);
-void runtime_MSpanList_Insert(MSpan *list, MSpan *span);
-void runtime_MSpanList_Remove(MSpan *span); // from whatever list it is in
-
-
-// Central list of free objects of a given size.
-struct MCentral
-{
- Lock;
- int32 sizeclass;
- MSpan nonempty;
- MSpan empty;
- int32 nfree;
-};
-
-void runtime_MCentral_Init(MCentral *c, int32 sizeclass);
-int32 runtime_MCentral_AllocList(MCentral *c, int32 n, MLink **first);
-void runtime_MCentral_FreeList(MCentral *c, int32 n, MLink *first);
-void runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end);
-
-// Main malloc heap.
-// The heap itself is the "free[]" and "large" arrays,
-// but all the other global data is here too.
-struct MHeap
-{
- Lock;
- MSpan free[MaxMHeapList]; // free lists of given length
- MSpan large; // free lists length >= MaxMHeapList
- MSpan **allspans;
- uint32 nspan;
- uint32 nspancap;
-
- // span lookup
- MSpan *map[1<<MHeapMap_Bits];
-
- // range of addresses we might see in the heap
- byte *bitmap;
- uintptr bitmap_mapped;
- byte *arena_start;
- byte *arena_used;
- byte *arena_end;
-
- // central free lists for small size classes.
- // the union makes sure that the MCentrals are
- // spaced CacheLineSize bytes apart, so that each MCentral.Lock
- // gets its own cache line.
- union {
- MCentral;
- byte pad[CacheLineSize];
- } central[NumSizeClasses];
-
- FixAlloc spanalloc; // allocator for Span*
- FixAlloc cachealloc; // allocator for MCache*
-};
-extern MHeap runtime_mheap;
-
-void runtime_MHeap_Init(MHeap *h, void *(*allocator)(uintptr));
-MSpan* runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, int32 acct, int32 zeroed);
-void runtime_MHeap_Free(MHeap *h, MSpan *s, int32 acct);
-MSpan* runtime_MHeap_Lookup(MHeap *h, void *v);
-MSpan* runtime_MHeap_LookupMaybe(MHeap *h, void *v);
-void runtime_MGetSizeClassInfo(int32 sizeclass, uintptr *size, int32 *npages, int32 *nobj);
-void* runtime_MHeap_SysAlloc(MHeap *h, uintptr n);
-void runtime_MHeap_MapBits(MHeap *h);
-void runtime_MHeap_Scavenger(void*);
-
-void* runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed);
-int32 runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **s);
-void runtime_gc(int32 force);
-void runtime_markallocated(void *v, uintptr n, bool noptr);
-void runtime_checkallocated(void *v, uintptr n);
-void runtime_markfreed(void *v, uintptr n);
-void runtime_checkfreed(void *v, uintptr n);
-extern int32 runtime_checking;
-void runtime_markspan(void *v, uintptr size, uintptr n, bool leftover);
-void runtime_unmarkspan(void *v, uintptr size);
-bool runtime_blockspecial(void*);
-void runtime_setblockspecial(void*, bool);
-void runtime_purgecachedstats(MCache*);
-void* runtime_new(const Type *);
-#define runtime_cnew(T) runtime_new(T)
-
-void runtime_settype(void*, uintptr);
-void runtime_settype_flush(M*, bool);
-void runtime_settype_sysfree(MSpan*);
-uintptr runtime_gettype(void*);
-
-enum
-{
- // flags to malloc
- FlagNoPointers = 1<<0, // no pointers here
- FlagNoProfiling = 1<<1, // must not profile
- FlagNoGC = 1<<2, // must not free or scan for pointers
-};
-
-typedef struct Obj Obj;
-struct Obj
-{
- byte *p; // data pointer
- uintptr n; // size of data in bytes
- uintptr ti; // type info
-};
-
-void runtime_MProf_Malloc(void*, uintptr);
-void runtime_MProf_Free(void*, uintptr);
-void runtime_MProf_GC(void);
-void runtime_MProf_Mark(void (*addroot)(Obj));
-int32 runtime_gcprocs(void);
-void runtime_helpgc(int32 nproc);
-void runtime_gchelper(void);
-
-struct __go_func_type;
-bool runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft);
-void runtime_walkfintab(void (*fn)(void*), void (*scan)(Obj));
-
-enum
-{
- TypeInfo_SingleObject = 0,
- TypeInfo_Array = 1,
- TypeInfo_Map = 2,
-
- // Enables type information at the end of blocks allocated from heap
- DebugTypeAtBlockEnd = 0,
-};
-
-// defined in mgc0.go
-void runtime_gc_m_ptr(Eface*);
-void runtime_gc_itab_ptr(Eface*);
-
-void runtime_memorydump(void);
-
-void runtime_time_scan(void (*)(Obj));
-void runtime_trampoline_scan(void (*)(Obj));
diff --git a/gcc-4.8.1/libgo/runtime/map.goc b/gcc-4.8.1/libgo/runtime/map.goc
deleted file mode 100644
index e4b8456dc..000000000
--- a/gcc-4.8.1/libgo/runtime/map.goc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2010 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.
-
-package runtime
-#include "runtime.h"
-#include "map.h"
-
-typedef struct __go_map Hmap;
-typedef struct __go_hash_iter hiter;
-
-/* Access a value in a map, returning a value and a presence indicator. */
-
-func mapaccess2(t *MapType, h *Hmap, key *byte, val *byte) (present bool) {
- byte *mapval;
- size_t valsize;
-
- mapval = __go_map_index(h, key, 0);
- valsize = t->__val_type->__size;
- if (mapval == nil) {
- __builtin_memset(val, 0, valsize);
- present = 0;
- } else {
- __builtin_memcpy(val, mapval, valsize);
- present = 1;
- }
-}
-
-/* Optionally assign a value to a map (m[k] = v, p). */
-
-func mapassign2(h *Hmap, key *byte, val *byte, p bool) {
- if (!p) {
- __go_map_delete(h, key);
- } else {
- byte *mapval;
- size_t valsize;
-
- mapval = __go_map_index(h, key, 1);
- valsize = h->__descriptor->__map_descriptor->__val_type->__size;
- __builtin_memcpy(mapval, val, valsize);
- }
-}
-
-/* Delete a key from a map. */
-
-func mapdelete(h *Hmap, key *byte) {
- __go_map_delete(h, key);
-}
-
-/* Initialize a range over a map. */
-
-func mapiterinit(h *Hmap, it *hiter) {
- __go_mapiterinit(h, it);
-}
-
-/* Move to the next iteration, updating *HITER. */
-
-func mapiternext(it *hiter) {
- __go_mapiternext(it);
-}
-
-/* Get the key of the current iteration. */
-
-func mapiter1(it *hiter, key *byte) {
- __go_mapiter1(it, key);
-}
-
-/* Get the key and value of the current iteration. */
-
-func mapiter2(it *hiter, key *byte, val *byte) {
- __go_mapiter2(it, key, val);
-}
diff --git a/gcc-4.8.1/libgo/runtime/map.h b/gcc-4.8.1/libgo/runtime/map.h
deleted file mode 100644
index 0c587bb2a..000000000
--- a/gcc-4.8.1/libgo/runtime/map.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* map.h -- the map type for Go.
-
- 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. */
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "go-type.h"
-
-/* A map descriptor is what we need to manipulate the map. This is
- constant for a given map type. */
-
-struct __go_map_descriptor
-{
- /* A pointer to the type descriptor for the type of the map itself. */
- const struct __go_map_type *__map_descriptor;
-
- /* A map entry is a struct with three fields:
- map_entry_type *next_entry;
- key_type key;
- value_type value;
- This is the size of that struct. */
- uintptr_t __entry_size;
-
- /* The offset of the key field in a map entry struct. */
- uintptr_t __key_offset;
-
- /* The offset of the value field in a map entry struct (the value
- field immediately follows the key field, but there may be some
- bytes inserted for alignment). */
- uintptr_t __val_offset;
-};
-
-struct __go_map
-{
- /* The constant descriptor for this map. */
- const struct __go_map_descriptor *__descriptor;
-
- /* The number of elements in the hash table. */
- uintptr_t __element_count;
-
- /* The number of entries in the __buckets array. */
- uintptr_t __bucket_count;
-
- /* Each bucket is a pointer to a linked list of map entries. */
- void **__buckets;
-};
-
-/* For a map iteration the compiled code will use a pointer to an
- iteration structure. The iteration structure will be allocated on
- the stack. The Go code must allocate at least enough space. */
-
-struct __go_hash_iter
-{
- /* A pointer to the current entry. This will be set to NULL when
- the range has completed. The Go will test this field, so it must
- be the first one in the structure. */
- const void *entry;
- /* The map we are iterating over. */
- const struct __go_map *map;
- /* A pointer to the next entry in the current bucket. This permits
- deleting the current entry. This will be NULL when we have seen
- all the entries in the current bucket. */
- const void *next_entry;
- /* The bucket index of the current and next entry. */
- uintptr_t bucket;
-};
-
-extern struct __go_map *__go_new_map (const struct __go_map_descriptor *,
- uintptr_t);
-
-extern uintptr_t __go_map_next_prime (uintptr_t);
-
-extern void *__go_map_index (struct __go_map *, const void *, _Bool);
-
-extern void __go_map_delete (struct __go_map *, const void *);
-
-extern void __go_mapiterinit (const struct __go_map *, struct __go_hash_iter *);
-
-extern void __go_mapiternext (struct __go_hash_iter *);
-
-extern void __go_mapiter1 (struct __go_hash_iter *it, unsigned char *key);
-
-extern void __go_mapiter2 (struct __go_hash_iter *it, unsigned char *key,
- unsigned char *val);
diff --git a/gcc-4.8.1/libgo/runtime/mcache.c b/gcc-4.8.1/libgo/runtime/mcache.c
deleted file mode 100644
index 570c06a73..000000000
--- a/gcc-4.8.1/libgo/runtime/mcache.c
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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 "arch.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);
- if(n == 0)
- runtime_throw("out of memory");
- 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);
- }
- c->local_cachealloc += 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_cachealloc -= 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;
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/mcentral.c b/gcc-4.8.1/libgo/runtime/mcentral.c
deleted file mode 100644
index b405438f9..000000000
--- a/gcc-4.8.1/libgo/runtime/mcentral.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// 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.
-
-// Central free lists.
-//
-// See malloc.h for an overview.
-//
-// The MCentral doesn't actually contain the list of free objects; the MSpan does.
-// Each MCentral is two lists of MSpans: those with free objects (c->nonempty)
-// and those that are completely allocated (c->empty).
-//
-// TODO(rsc): tcmalloc uses a "transfer cache" to split the list
-// into sections of class_to_transfercount[sizeclass] objects
-// so that it is faster to move those lists between MCaches and MCentrals.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-static bool MCentral_Grow(MCentral *c);
-static void MCentral_Free(MCentral *c, void *v);
-
-// Initialize a single central free list.
-void
-runtime_MCentral_Init(MCentral *c, int32 sizeclass)
-{
- c->sizeclass = sizeclass;
- runtime_MSpanList_Init(&c->nonempty);
- runtime_MSpanList_Init(&c->empty);
-}
-
-// Allocate up to n objects from the central free list.
-// Return the number of objects allocated.
-// The objects are linked together by their first words.
-// On return, *pstart points at the first object.
-int32
-runtime_MCentral_AllocList(MCentral *c, int32 n, MLink **pfirst)
-{
- MSpan *s;
- MLink *first, *last;
- int32 cap, avail, i;
-
- runtime_lock(c);
- // Replenish central list if empty.
- if(runtime_MSpanList_IsEmpty(&c->nonempty)) {
- if(!MCentral_Grow(c)) {
- runtime_unlock(c);
- *pfirst = nil;
- return 0;
- }
- }
- s = c->nonempty.next;
- cap = (s->npages << PageShift) / s->elemsize;
- avail = cap - s->ref;
- if(avail < n)
- n = avail;
-
- // First one is guaranteed to work, because we just grew the list.
- first = s->freelist;
- last = first;
- for(i=1; i<n; i++) {
- last = last->next;
- }
- s->freelist = last->next;
- last->next = nil;
- s->ref += n;
- c->nfree -= n;
-
- if(n == avail) {
- if(s->freelist != nil || s->ref != (uint32)cap) {
- runtime_throw("invalid freelist");
- }
- runtime_MSpanList_Remove(s);
- runtime_MSpanList_Insert(&c->empty, s);
- }
-
- runtime_unlock(c);
- *pfirst = first;
- return n;
-}
-
-// Free n objects back into the central free list.
-void
-runtime_MCentral_FreeList(MCentral *c, int32 n, MLink *start)
-{
- MLink *v, *next;
-
- // Assume next == nil marks end of list.
- // n and end would be useful if we implemented
- // the transfer cache optimization in the TODO above.
- USED(n);
-
- runtime_lock(c);
- for(v=start; v; v=next) {
- next = v->next;
- MCentral_Free(c, v);
- }
- runtime_unlock(c);
-}
-
-// Helper: free one object back into the central free list.
-static void
-MCentral_Free(MCentral *c, void *v)
-{
- MSpan *s;
- MLink *p;
- int32 size;
-
- // Find span for v.
- s = runtime_MHeap_Lookup(&runtime_mheap, v);
- if(s == nil || s->ref == 0)
- runtime_throw("invalid free");
-
- // Move to nonempty if necessary.
- if(s->freelist == nil) {
- runtime_MSpanList_Remove(s);
- runtime_MSpanList_Insert(&c->nonempty, s);
- }
-
- // Add v back to s's free list.
- p = v;
- p->next = s->freelist;
- s->freelist = p;
- c->nfree++;
-
- // If s is completely freed, return it to the heap.
- if(--s->ref == 0) {
- size = runtime_class_to_size[c->sizeclass];
- runtime_MSpanList_Remove(s);
- runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
- *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing
- s->freelist = nil;
- c->nfree -= (s->npages << PageShift) / size;
- runtime_unlock(c);
- runtime_MHeap_Free(&runtime_mheap, s, 0);
- runtime_lock(c);
- }
-}
-
-// Free n objects from a span s back into the central free list c.
-// Called from GC.
-void
-runtime_MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end)
-{
- int32 size;
-
- runtime_lock(c);
-
- // Move to nonempty if necessary.
- if(s->freelist == nil) {
- runtime_MSpanList_Remove(s);
- runtime_MSpanList_Insert(&c->nonempty, s);
- }
-
- // Add the objects back to s's free list.
- end->next = s->freelist;
- s->freelist = start;
- s->ref -= n;
- c->nfree += n;
-
- // If s is completely freed, return it to the heap.
- if(s->ref == 0) {
- size = runtime_class_to_size[c->sizeclass];
- runtime_MSpanList_Remove(s);
- *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing
- s->freelist = nil;
- c->nfree -= (s->npages << PageShift) / size;
- runtime_unlock(c);
- runtime_unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
- runtime_MHeap_Free(&runtime_mheap, s, 0);
- } else {
- runtime_unlock(c);
- }
-}
-
-void
-runtime_MGetSizeClassInfo(int32 sizeclass, uintptr *sizep, int32 *npagesp, int32 *nobj)
-{
- int32 size;
- int32 npages;
-
- npages = runtime_class_to_allocnpages[sizeclass];
- size = runtime_class_to_size[sizeclass];
- *npagesp = npages;
- *sizep = size;
- *nobj = (npages << PageShift) / size;
-}
-
-// Fetch a new span from the heap and
-// carve into objects for the free list.
-static bool
-MCentral_Grow(MCentral *c)
-{
- int32 i, n, npages;
- uintptr size;
- MLink **tailp, *v;
- byte *p;
- MSpan *s;
-
- runtime_unlock(c);
- runtime_MGetSizeClassInfo(c->sizeclass, &size, &npages, &n);
- s = runtime_MHeap_Alloc(&runtime_mheap, npages, c->sizeclass, 0, 1);
- if(s == nil) {
- // TODO(rsc): Log out of memory
- runtime_lock(c);
- return false;
- }
-
- // Carve span into sequence of blocks.
- tailp = &s->freelist;
- p = (byte*)(s->start << PageShift);
- s->limit = p + size*n;
- for(i=0; i<n; i++) {
- v = (MLink*)p;
- *tailp = v;
- tailp = &v->next;
- p += size;
- }
- *tailp = nil;
- runtime_markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npages<<PageShift));
-
- runtime_lock(c);
- c->nfree += n;
- runtime_MSpanList_Insert(&c->nonempty, s);
- return true;
-}
diff --git a/gcc-4.8.1/libgo/runtime/mem.c b/gcc-4.8.1/libgo/runtime/mem.c
deleted file mode 100644
index e606bdd4d..000000000
--- a/gcc-4.8.1/libgo/runtime/mem.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* Defining _XOPEN_SOURCE hides the declaration of madvise() on Solaris <
- 11 and the MADV_DONTNEED definition on IRIX 6.5. */
-#undef _XOPEN_SOURCE
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-#ifndef MAP_ANON
-#ifdef MAP_ANONYMOUS
-#define MAP_ANON MAP_ANONYMOUS
-#else
-#define USE_DEV_ZERO
-#define MAP_ANON 0
-#endif
-#endif
-
-#ifndef MAP_NORESERVE
-#define MAP_NORESERVE 0
-#endif
-
-#ifdef USE_DEV_ZERO
-static int dev_zero = -1;
-#endif
-
-static _Bool
-addrspace_free(void *v __attribute__ ((unused)), uintptr n __attribute__ ((unused)))
-{
-#ifdef HAVE_MINCORE
- size_t page_size = getpagesize();
- size_t off;
- char one_byte;
-
- errno = 0;
- for(off = 0; off < n; off += page_size)
- if(mincore((char *)v + off, page_size, (void *)&one_byte) != -1
- || errno != ENOMEM)
- return 0;
-#endif
- return 1;
-}
-
-static void *
-mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset)
-{
- void *p;
-
- p = runtime_mmap((void *)v, n, prot, flags, fd, offset);
- if(p != v && addrspace_free(v, n)) {
- // On some systems, mmap ignores v without
- // MAP_FIXED, so retry if the address space is free.
- if(p != MAP_FAILED)
- runtime_munmap(p, n);
- p = runtime_mmap((void *)v, n, prot, flags|MAP_FIXED, fd, offset);
- }
- return p;
-}
-
-void*
-runtime_SysAlloc(uintptr n)
-{
- void *p;
- int fd = -1;
-
- mstats.sys += n;
-
-#ifdef USE_DEV_ZERO
- if (dev_zero == -1) {
- dev_zero = open("/dev/zero", O_RDONLY);
- if (dev_zero < 0) {
- runtime_printf("open /dev/zero: errno=%d\n", errno);
- exit(2);
- }
- }
- fd = dev_zero;
-#endif
-
- p = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0);
- if (p == MAP_FAILED) {
- if(errno == EACCES) {
- runtime_printf("runtime: mmap: access denied\n");
- runtime_printf("if you're running SELinux, enable execmem for this process.\n");
- exit(2);
- }
- if(errno == EAGAIN) {
- runtime_printf("runtime: mmap: too much locked memory (check 'ulimit -l').\n");
- runtime_exit(2);
- }
- return nil;
- }
- return p;
-}
-
-void
-runtime_SysUnused(void *v __attribute__ ((unused)), uintptr n __attribute__ ((unused)))
-{
-#ifdef MADV_DONTNEED
- runtime_madvise(v, n, MADV_DONTNEED);
-#endif
-}
-
-void
-runtime_SysFree(void *v, uintptr n)
-{
- mstats.sys -= n;
- runtime_munmap(v, n);
-}
-
-void*
-runtime_SysReserve(void *v, uintptr n)
-{
- int fd = -1;
- void *p;
-
-#ifdef USE_DEV_ZERO
- if (dev_zero == -1) {
- dev_zero = open("/dev/zero", O_RDONLY);
- if (dev_zero < 0) {
- runtime_printf("open /dev/zero: errno=%d\n", errno);
- exit(2);
- }
- }
- fd = dev_zero;
-#endif
-
- // On 64-bit, people with ulimit -v set complain if we reserve too
- // much address space. Instead, assume that the reservation is okay
- // if we can reserve at least 64K and check the assumption in SysMap.
- // Only user-mode Linux (UML) rejects these requests.
- if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
- p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, fd, 0);
- if (p != v)
- return nil;
- runtime_munmap(p, 64<<10);
- return v;
- }
-
- // Use the MAP_NORESERVE mmap() flag here because typically most of
- // this reservation will never be used. It does not make sense
- // reserve a huge amount of unneeded swap space. This is important on
- // systems which do not overcommit memory by default.
- p = runtime_mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_NORESERVE, fd, 0);
- if(p == MAP_FAILED)
- return nil;
- return p;
-}
-
-void
-runtime_SysMap(void *v, uintptr n)
-{
- void *p;
- int fd = -1;
-
- mstats.sys += n;
-
-#ifdef USE_DEV_ZERO
- if (dev_zero == -1) {
- dev_zero = open("/dev/zero", O_RDONLY);
- if (dev_zero < 0) {
- runtime_printf("open /dev/zero: errno=%d\n", errno);
- exit(2);
- }
- }
- fd = dev_zero;
-#endif
-
- // On 64-bit, we don't actually have v reserved, so tread carefully.
- if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) {
- p = mmap_fixed(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0);
- if(p == MAP_FAILED && errno == ENOMEM)
- runtime_throw("runtime: out of memory");
- if(p != v) {
- runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p);
- runtime_throw("runtime: address space conflict");
- }
- return;
- }
-
- p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0);
- if(p != v)
- runtime_throw("runtime: cannot map pages in arena address space");
-}
diff --git a/gcc-4.8.1/libgo/runtime/mem_posix_memalign.c b/gcc-4.8.1/libgo/runtime/mem_posix_memalign.c
deleted file mode 100644
index 8acdf0705..000000000
--- a/gcc-4.8.1/libgo/runtime/mem_posix_memalign.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <errno.h>
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-void*
-runtime_SysAlloc(uintptr n)
-{
- void *p;
-
- mstats.sys += n;
- errno = posix_memalign(&p, PageSize, n);
- if (errno > 0) {
- perror("posix_memalign");
- exit(2);
- }
- return p;
-}
-
-void
-runtime_SysUnused(void *v, uintptr n)
-{
- USED(v);
- USED(n);
- // TODO(rsc): call madvise MADV_DONTNEED
-}
-
-void
-runtime_SysFree(void *v, uintptr n)
-{
- mstats.sys -= n;
- free(v);
-}
-
-void*
-runtime_SysReserve(void *v, uintptr n)
-{
- USED(v);
- return runtime_SysAlloc(n);
-}
-
-void
-runtime_SysMap(void *v, uintptr n)
-{
- USED(v);
- USED(n);
-}
diff --git a/gcc-4.8.1/libgo/runtime/mfinal.c b/gcc-4.8.1/libgo/runtime/mfinal.c
deleted file mode 100644
index 7c906daf3..000000000
--- a/gcc-4.8.1/libgo/runtime/mfinal.c
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2010 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.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-enum { debug = 0 };
-
-typedef struct Fin Fin;
-struct Fin
-{
- void (*fn)(void*);
- const struct __go_func_type *ft;
-};
-
-// Finalizer hash table. Direct hash, linear scan, at most 3/4 full.
-// Table size is power of 3 so that hash can be key % max.
-// Key[i] == (void*)-1 denotes free but formerly occupied entry
-// (doesn't stop the linear scan).
-// Key and val are separate tables because the garbage collector
-// must be instructed to ignore the pointers in key but follow the
-// pointers in val.
-typedef struct Fintab Fintab;
-struct Fintab
-{
- Lock;
- void **fkey;
- Fin *val;
- int32 nkey; // number of non-nil entries in key
- int32 ndead; // number of dead (-1) entries in key
- int32 max; // size of key, val allocations
-};
-
-#define TABSZ 17
-#define TAB(p) (&fintab[((uintptr)(p)>>3)%TABSZ])
-
-static struct {
- Fintab;
- uint8 pad[0 /* CacheLineSize - sizeof(Fintab) */];
-} fintab[TABSZ];
-
-static void
-addfintab(Fintab *t, void *k, void (*fn)(void*), const struct __go_func_type *ft)
-{
- int32 i, j;
-
- i = (uintptr)k % (uintptr)t->max;
- for(j=0; j<t->max; j++) {
- if(t->fkey[i] == nil) {
- t->nkey++;
- goto ret;
- }
- if(t->fkey[i] == (void*)-1) {
- t->ndead--;
- goto ret;
- }
- if(++i == t->max)
- i = 0;
- }
-
- // cannot happen - table is known to be non-full
- runtime_throw("finalizer table inconsistent");
-
-ret:
- t->fkey[i] = k;
- t->val[i].fn = fn;
- t->val[i].ft = ft;
-}
-
-static bool
-lookfintab(Fintab *t, void *k, bool del, Fin *f)
-{
- int32 i, j;
-
- if(t->max == 0)
- return false;
- i = (uintptr)k % (uintptr)t->max;
- for(j=0; j<t->max; j++) {
- if(t->fkey[i] == nil)
- return false;
- if(t->fkey[i] == k) {
- if(f)
- *f = t->val[i];
- if(del) {
- t->fkey[i] = (void*)-1;
- t->val[i].fn = nil;
- t->val[i].ft = nil;
- t->ndead++;
- }
- return true;
- }
- if(++i == t->max)
- i = 0;
- }
-
- // cannot happen - table is known to be non-full
- runtime_throw("finalizer table inconsistent");
- return false;
-}
-
-static void
-resizefintab(Fintab *tab)
-{
- Fintab newtab;
- void *k;
- int32 i;
-
- runtime_memclr((byte*)&newtab, sizeof newtab);
- newtab.max = tab->max;
- if(newtab.max == 0)
- newtab.max = 3*3*3;
- else if(tab->ndead < tab->nkey/2) {
- // grow table if not many dead values.
- // otherwise just rehash into table of same size.
- newtab.max *= 3;
- }
-
- newtab.fkey = runtime_mallocgc(newtab.max*sizeof newtab.fkey[0], FlagNoPointers, 0, 1);
- newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1);
-
- for(i=0; i<tab->max; i++) {
- k = tab->fkey[i];
- if(k != nil && k != (void*)-1)
- addfintab(&newtab, k, tab->val[i].fn, tab->val[i].ft);
- }
-
- runtime_free(tab->fkey);
- runtime_free(tab->val);
-
- tab->fkey = newtab.fkey;
- tab->val = newtab.val;
- tab->nkey = newtab.nkey;
- tab->ndead = newtab.ndead;
- tab->max = newtab.max;
-}
-
-bool
-runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft)
-{
- Fintab *tab;
- byte *base;
-
- if(debug) {
- if(!runtime_mlookup(p, &base, nil, nil) || p != base)
- runtime_throw("addfinalizer on invalid pointer");
- }
-
- tab = TAB(p);
- runtime_lock(tab);
- if(f == nil) {
- lookfintab(tab, p, true, nil);
- runtime_unlock(tab);
- return true;
- }
-
- if(lookfintab(tab, p, false, nil)) {
- runtime_unlock(tab);
- return false;
- }
-
- if(tab->nkey >= tab->max/2+tab->max/4) {
- // keep table at most 3/4 full:
- // allocate new table and rehash.
- resizefintab(tab);
- }
-
- addfintab(tab, p, f, ft);
- runtime_setblockspecial(p, true);
- runtime_unlock(tab);
- return true;
-}
-
-// get finalizer; if del, delete finalizer.
-// caller is responsible for updating RefHasFinalizer (special) bit.
-bool
-runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft)
-{
- Fintab *tab;
- bool res;
- Fin f;
-
- tab = TAB(p);
- runtime_lock(tab);
- res = lookfintab(tab, p, del, &f);
- runtime_unlock(tab);
- if(res==false)
- return false;
- *fn = f.fn;
- *ft = f.ft;
- return true;
-}
-
-void
-runtime_walkfintab(void (*fn)(void*), void (*addroot)(Obj))
-{
- void **key;
- void **ekey;
- int32 i;
-
- for(i=0; i<TABSZ; i++) {
- runtime_lock(&fintab[i]);
- key = fintab[i].fkey;
- ekey = key + fintab[i].max;
- for(; key < ekey; key++)
- if(*key != nil && *key != ((void*)-1))
- fn(*key);
- addroot((Obj){(byte*)&fintab[i].fkey, sizeof(void*), 0});
- addroot((Obj){(byte*)&fintab[i].val, sizeof(void*), 0});
- runtime_unlock(&fintab[i]);
- }
-}
diff --git a/gcc-4.8.1/libgo/runtime/mfixalloc.c b/gcc-4.8.1/libgo/runtime/mfixalloc.c
deleted file mode 100644
index 109cfe8ee..000000000
--- a/gcc-4.8.1/libgo/runtime/mfixalloc.c
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-// Fixed-size object allocator. Returned memory is not zeroed.
-//
-// See malloc.h for overview.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-// Initialize f to allocate objects of the given size,
-// using the allocator to obtain chunks of memory.
-void
-runtime_FixAlloc_Init(FixAlloc *f, uintptr size, void *(*alloc)(uintptr), void (*first)(void*, byte*), void *arg)
-{
- f->size = size;
- f->alloc = alloc;
- f->first = first;
- f->arg = arg;
- f->list = nil;
- f->chunk = nil;
- f->nchunk = 0;
- f->inuse = 0;
- f->sys = 0;
-}
-
-void*
-runtime_FixAlloc_Alloc(FixAlloc *f)
-{
- void *v;
-
- if(f->list) {
- v = f->list;
- f->list = *(void**)f->list;
- f->inuse += f->size;
- return v;
- }
- if(f->nchunk < f->size) {
- f->sys += FixAllocChunk;
- f->chunk = f->alloc(FixAllocChunk);
- if(f->chunk == nil)
- runtime_throw("out of memory (FixAlloc)");
- f->nchunk = FixAllocChunk;
- }
- v = f->chunk;
- if(f->first)
- f->first(f->arg, v);
- f->chunk += f->size;
- f->nchunk -= f->size;
- f->inuse += f->size;
- return v;
-}
-
-void
-runtime_FixAlloc_Free(FixAlloc *f, void *p)
-{
- f->inuse -= f->size;
- *(void**)p = f->list;
- f->list = p;
-}
-
diff --git a/gcc-4.8.1/libgo/runtime/mgc0.c b/gcc-4.8.1/libgo/runtime/mgc0.c
deleted file mode 100644
index ffbe2cefb..000000000
--- a/gcc-4.8.1/libgo/runtime/mgc0.c
+++ /dev/null
@@ -1,1956 +0,0 @@
-// 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.
-
-// Garbage collector.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "mgc0.h"
-#include "race.h"
-#include "go-type.h"
-
-// Map gccgo field names to gc field names.
-// Slice aka __go_open_array.
-#define array __values
-#define cap __capacity
-// Iface aka __go_interface
-#define tab __methods
-// Eface aka __go_empty_interface.
-#define type __type_descriptor
-// Type aka __go_type_descriptor
-#define kind __code
-#define KindPtr GO_PTR
-#define KindNoPointers GO_NO_POINTERS
-// PtrType aka __go_ptr_type
-#define elem __element_type
-
-#ifdef USING_SPLIT_STACK
-
-extern void * __splitstack_find (void *, void *, size_t *, void **, void **,
- void **);
-
-extern void * __splitstack_find_context (void *context[10], size_t *, void **,
- void **, void **);
-
-#endif
-
-enum {
- Debug = 0,
- DebugMark = 0, // run second pass to check mark
-
- // Four bits per word (see #defines below).
- wordsPerBitmapWord = sizeof(void*)*8/4,
- bitShift = sizeof(void*)*8/4,
-
- handoffThreshold = 4,
- IntermediateBufferCapacity = 64,
-
- // Bits in type information
- PRECISE = 1,
- LOOP = 2,
- PC_BITS = PRECISE | LOOP,
-};
-
-// Bits in per-word bitmap.
-// #defines because enum might not be able to hold the values.
-//
-// Each word in the bitmap describes wordsPerBitmapWord words
-// of heap memory. There are 4 bitmap bits dedicated to each heap word,
-// so on a 64-bit system there is one bitmap word per 16 heap words.
-// The bits in the word are packed together by type first, then by
-// heap location, so each 64-bit bitmap word consists of, from top to bottom,
-// the 16 bitSpecial bits for the corresponding heap words, then the 16 bitMarked bits,
-// then the 16 bitNoPointers/bitBlockBoundary bits, then the 16 bitAllocated bits.
-// This layout makes it easier to iterate over the bits of a given type.
-//
-// The bitmap starts at mheap.arena_start and extends *backward* from
-// there. On a 64-bit system the off'th word in the arena is tracked by
-// the off/16+1'th word before mheap.arena_start. (On a 32-bit system,
-// the only difference is that the divisor is 8.)
-//
-// To pull out the bits corresponding to a given pointer p, we use:
-//
-// off = p - (uintptr*)mheap.arena_start; // word offset
-// b = (uintptr*)mheap.arena_start - off/wordsPerBitmapWord - 1;
-// shift = off % wordsPerBitmapWord
-// bits = *b >> shift;
-// /* then test bits & bitAllocated, bits & bitMarked, etc. */
-//
-#define bitAllocated ((uintptr)1<<(bitShift*0))
-#define bitNoPointers ((uintptr)1<<(bitShift*1)) /* when bitAllocated is set */
-#define bitMarked ((uintptr)1<<(bitShift*2)) /* when bitAllocated is set */
-#define bitSpecial ((uintptr)1<<(bitShift*3)) /* when bitAllocated is set - has finalizer or being profiled */
-#define bitBlockBoundary ((uintptr)1<<(bitShift*1)) /* when bitAllocated is NOT set */
-
-#define bitMask (bitBlockBoundary | bitAllocated | bitMarked | bitSpecial)
-
-// Holding worldsema grants an M the right to try to stop the world.
-// The procedure is:
-//
-// runtime_semacquire(&runtime_worldsema);
-// m->gcing = 1;
-// runtime_stoptheworld();
-//
-// ... do stuff ...
-//
-// m->gcing = 0;
-// runtime_semrelease(&runtime_worldsema);
-// runtime_starttheworld();
-//
-uint32 runtime_worldsema = 1;
-
-static int32 gctrace;
-
-// The size of Workbuf is N*PageSize.
-typedef struct Workbuf Workbuf;
-struct Workbuf
-{
-#define SIZE (2*PageSize-sizeof(LFNode)-sizeof(uintptr))
- LFNode node; // must be first
- uintptr nobj;
- Obj obj[SIZE/sizeof(Obj) - 1];
- uint8 _padding[SIZE%sizeof(Obj) + sizeof(Obj)];
-#undef SIZE
-};
-
-typedef struct Finalizer Finalizer;
-struct Finalizer
-{
- void (*fn)(void*);
- void *arg;
- const struct __go_func_type *ft;
-};
-
-typedef struct FinBlock FinBlock;
-struct FinBlock
-{
- FinBlock *alllink;
- FinBlock *next;
- int32 cnt;
- int32 cap;
- Finalizer fin[1];
-};
-
-static G *fing;
-static FinBlock *finq; // list of finalizers that are to be executed
-static FinBlock *finc; // cache of free blocks
-static FinBlock *allfin; // list of all blocks
-static Lock finlock;
-static int32 fingwait;
-
-static void runfinq(void*);
-static Workbuf* getempty(Workbuf*);
-static Workbuf* getfull(Workbuf*);
-static void putempty(Workbuf*);
-static Workbuf* handoff(Workbuf*);
-
-static struct {
- uint64 full; // lock-free list of full blocks
- uint64 empty; // lock-free list of empty blocks
- byte pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
- uint32 nproc;
- volatile uint32 nwait;
- volatile uint32 ndone;
- volatile uint32 debugmarkdone;
- Note alldone;
- ParFor *markfor;
- ParFor *sweepfor;
-
- Lock;
- byte *chunk;
- uintptr nchunk;
-
- Obj *roots;
- uint32 nroot;
- uint32 rootcap;
-} work;
-
-enum {
- // TODO(atom): to be expanded in a next CL
- GC_DEFAULT_PTR = GC_NUM_INSTR,
-};
-
-// PtrTarget and BitTarget are structures used by intermediate buffers.
-// The intermediate buffers hold GC data before it
-// is moved/flushed to the work buffer (Workbuf).
-// The size of an intermediate buffer is very small,
-// such as 32 or 64 elements.
-typedef struct PtrTarget PtrTarget;
-struct PtrTarget
-{
- void *p;
- uintptr ti;
-};
-
-typedef struct BitTarget BitTarget;
-struct BitTarget
-{
- void *p;
- uintptr ti;
- uintptr *bitp, shift;
-};
-
-typedef struct BufferList BufferList;
-struct BufferList
-{
- PtrTarget ptrtarget[IntermediateBufferCapacity];
- BitTarget bittarget[IntermediateBufferCapacity];
- BufferList *next;
-};
-static BufferList *bufferList;
-
-static Lock lock;
-static Type *itabtype;
-
-static void enqueue(Obj obj, Workbuf **_wbuf, Obj **_wp, uintptr *_nobj);
-
-// flushptrbuf moves data from the PtrTarget buffer to the work buffer.
-// The PtrTarget buffer contains blocks irrespective of whether the blocks have been marked or scanned,
-// while the work buffer contains blocks which have been marked
-// and are prepared to be scanned by the garbage collector.
-//
-// _wp, _wbuf, _nobj are input/output parameters and are specifying the work buffer.
-// bitbuf holds temporary data generated by this function.
-//
-// A simplified drawing explaining how the todo-list moves from a structure to another:
-//
-// scanblock
-// (find pointers)
-// Obj ------> PtrTarget (pointer targets)
-// ↑ |
-// | | flushptrbuf (1st part,
-// | | find block start)
-// | ↓
-// `--------- BitTarget (pointer targets and the corresponding locations in bitmap)
-// flushptrbuf
-// (2nd part, mark and enqueue)
-static void
-flushptrbuf(PtrTarget *ptrbuf, PtrTarget **ptrbufpos, Obj **_wp, Workbuf **_wbuf, uintptr *_nobj, BitTarget *bitbuf)
-{
- byte *p, *arena_start, *obj;
- uintptr size, *bitp, bits, shift, j, x, xbits, off, nobj, ti, n;
- MSpan *s;
- PageID k;
- Obj *wp;
- Workbuf *wbuf;
- PtrTarget *ptrbuf_end;
- BitTarget *bitbufpos, *bt;
-
- arena_start = runtime_mheap.arena_start;
-
- wp = *_wp;
- wbuf = *_wbuf;
- nobj = *_nobj;
-
- ptrbuf_end = *ptrbufpos;
- n = ptrbuf_end - ptrbuf;
- *ptrbufpos = ptrbuf;
-
- // If buffer is nearly full, get a new one.
- if(wbuf == nil || nobj+n >= nelem(wbuf->obj)) {
- if(wbuf != nil)
- wbuf->nobj = nobj;
- wbuf = getempty(wbuf);
- wp = wbuf->obj;
- nobj = 0;
-
- if(n >= nelem(wbuf->obj))
- runtime_throw("ptrbuf has to be smaller than WorkBuf");
- }
-
- // TODO(atom): This block is a branch of an if-then-else statement.
- // The single-threaded branch may be added in a next CL.
- {
- // Multi-threaded version.
-
- bitbufpos = bitbuf;
-
- while(ptrbuf < ptrbuf_end) {
- obj = ptrbuf->p;
- ti = ptrbuf->ti;
- ptrbuf++;
-
- // obj belongs to interval [mheap.arena_start, mheap.arena_used).
- if(Debug > 1) {
- if(obj < runtime_mheap.arena_start || obj >= runtime_mheap.arena_used)
- runtime_throw("object is outside of mheap");
- }
-
- // obj may be a pointer to a live object.
- // Try to find the beginning of the object.
-
- // Round down to word boundary.
- if(((uintptr)obj & ((uintptr)PtrSize-1)) != 0) {
- obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
- ti = 0;
- }
-
- // Find bits for this word.
- off = (uintptr*)obj - (uintptr*)arena_start;
- bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- xbits = *bitp;
- bits = xbits >> shift;
-
- // Pointing at the beginning of a block?
- if((bits & (bitAllocated|bitBlockBoundary)) != 0)
- goto found;
-
- ti = 0;
-
- // Pointing just past the beginning?
- // Scan backward a little to find a block boundary.
- for(j=shift; j-->0; ) {
- if(((xbits>>j) & (bitAllocated|bitBlockBoundary)) != 0) {
- obj = (byte*)obj - (shift-j)*PtrSize;
- shift = j;
- bits = xbits>>shift;
- goto found;
- }
- }
-
- // Otherwise consult span table to find beginning.
- // (Manually inlined copy of MHeap_LookupMaybe.)
- k = (uintptr)obj>>PageShift;
- x = k;
- if(sizeof(void*) == 8)
- x -= (uintptr)arena_start>>PageShift;
- s = runtime_mheap.map[x];
- if(s == nil || k < s->start || k - s->start >= s->npages || s->state != MSpanInUse)
- continue;
- p = (byte*)((uintptr)s->start<<PageShift);
- if(s->sizeclass == 0) {
- obj = p;
- } else {
- if((byte*)obj >= (byte*)s->limit)
- continue;
- size = s->elemsize;
- int32 i = ((byte*)obj - p)/size;
- obj = p+i*size;
- }
-
- // Now that we know the object header, reload bits.
- off = (uintptr*)obj - (uintptr*)arena_start;
- bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- xbits = *bitp;
- bits = xbits >> shift;
-
- found:
- // Now we have bits, bitp, and shift correct for
- // obj pointing at the base of the object.
- // Only care about allocated and not marked.
- if((bits & (bitAllocated|bitMarked)) != bitAllocated)
- continue;
-
- *bitbufpos++ = (BitTarget){obj, ti, bitp, shift};
- }
-
- runtime_lock(&lock);
- for(bt=bitbuf; bt<bitbufpos; bt++){
- xbits = *bt->bitp;
- bits = xbits >> bt->shift;
- if((bits & bitMarked) != 0)
- continue;
-
- // Mark the block
- *bt->bitp = xbits | (bitMarked << bt->shift);
-
- // If object has no pointers, don't need to scan further.
- if((bits & bitNoPointers) != 0)
- continue;
-
- obj = bt->p;
-
- // Ask span about size class.
- // (Manually inlined copy of MHeap_Lookup.)
- x = (uintptr)obj >> PageShift;
- if(sizeof(void*) == 8)
- x -= (uintptr)arena_start>>PageShift;
- s = runtime_mheap.map[x];
-
- PREFETCH(obj);
-
- *wp = (Obj){obj, s->elemsize, bt->ti};
- wp++;
- nobj++;
- }
- runtime_unlock(&lock);
-
- // If another proc wants a pointer, give it some.
- if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
- wbuf->nobj = nobj;
- wbuf = handoff(wbuf);
- nobj = wbuf->nobj;
- wp = wbuf->obj + nobj;
- }
- }
-
- *_wp = wp;
- *_wbuf = wbuf;
- *_nobj = nobj;
-}
-
-// Program that scans the whole block and treats every block element as a potential pointer
-static uintptr defaultProg[2] = {PtrSize, GC_DEFAULT_PTR};
-
-// Local variables of a program fragment or loop
-typedef struct Frame Frame;
-struct Frame {
- uintptr count, elemsize, b;
- uintptr *loop_or_ret;
-};
-
-// scanblock scans a block of n bytes starting at pointer b for references
-// to other objects, scanning any it finds recursively until there are no
-// unscanned objects left. Instead of using an explicit recursion, it keeps
-// a work list in the Workbuf* structures and loops in the main function
-// body. Keeping an explicit work list is easier on the stack allocator and
-// more efficient.
-//
-// wbuf: current work buffer
-// wp: storage for next queued pointer (write pointer)
-// nobj: number of queued objects
-static void
-scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
-{
- byte *b, *arena_start, *arena_used;
- uintptr n, i, end_b, elemsize, ti, objti, count /* , type */;
- uintptr *pc, precise_type, nominal_size;
- void *obj;
- const Type *t;
- Slice *sliceptr;
- Frame *stack_ptr, stack_top, stack[GC_STACK_CAPACITY+4];
- BufferList *scanbuffers;
- PtrTarget *ptrbuf, *ptrbuf_end, *ptrbufpos;
- BitTarget *bitbuf;
- Eface *eface;
- Iface *iface;
-
- if(sizeof(Workbuf) % PageSize != 0)
- runtime_throw("scanblock: size of Workbuf is suboptimal");
-
- // Memory arena parameters.
- arena_start = runtime_mheap.arena_start;
- arena_used = runtime_mheap.arena_used;
-
- stack_ptr = stack+nelem(stack)-1;
-
- precise_type = false;
- nominal_size = 0;
-
- // Allocate ptrbuf, bitbuf
- {
- runtime_lock(&lock);
-
- if(bufferList == nil) {
- bufferList = runtime_SysAlloc(sizeof(*bufferList));
- bufferList->next = nil;
- }
- scanbuffers = bufferList;
- bufferList = bufferList->next;
-
- ptrbuf = &scanbuffers->ptrtarget[0];
- ptrbuf_end = &scanbuffers->ptrtarget[0] + nelem(scanbuffers->ptrtarget);
- bitbuf = &scanbuffers->bittarget[0];
-
- runtime_unlock(&lock);
- }
-
- ptrbufpos = ptrbuf;
-
- goto next_block;
-
- for(;;) {
- // Each iteration scans the block b of length n, queueing pointers in
- // the work buffer.
- if(Debug > 1) {
- runtime_printf("scanblock %p %D\n", b, (int64)n);
- }
-
- if(ti != 0 && 0) {
- pc = (uintptr*)(ti & ~(uintptr)PC_BITS);
- precise_type = (ti & PRECISE);
- stack_top.elemsize = pc[0];
- if(!precise_type)
- nominal_size = pc[0];
- if(ti & LOOP) {
- stack_top.count = 0; // 0 means an infinite number of iterations
- stack_top.loop_or_ret = pc+1;
- } else {
- stack_top.count = 1;
- }
- } else if(UseSpanType && 0) {
-#if 0
- type = runtime_gettype(b);
- if(type != 0) {
- t = (Type*)(type & ~(uintptr)(PtrSize-1));
- switch(type & (PtrSize-1)) {
- case TypeInfo_SingleObject:
- pc = (uintptr*)t->gc;
- precise_type = true; // type information about 'b' is precise
- stack_top.count = 1;
- stack_top.elemsize = pc[0];
- break;
- case TypeInfo_Array:
- pc = (uintptr*)t->gc;
- if(pc[0] == 0)
- goto next_block;
- precise_type = true; // type information about 'b' is precise
- stack_top.count = 0; // 0 means an infinite number of iterations
- stack_top.elemsize = pc[0];
- stack_top.loop_or_ret = pc+1;
- break;
- case TypeInfo_Map:
- // TODO(atom): to be expanded in a next CL
- pc = defaultProg;
- break;
- default:
- runtime_throw("scanblock: invalid type");
- return;
- }
- } else {
- pc = defaultProg;
- }
-#endif
- } else {
- pc = defaultProg;
- }
-
- pc++;
- stack_top.b = (uintptr)b;
-
- end_b = (uintptr)b + n - PtrSize;
-
- for(;;) {
- obj = nil;
- objti = 0;
- switch(pc[0]) {
- case GC_PTR:
- obj = *(void**)(stack_top.b + pc[1]);
- objti = pc[2];
- pc += 3;
- break;
-
- case GC_SLICE:
- sliceptr = (Slice*)(stack_top.b + pc[1]);
- if(sliceptr->cap != 0) {
- obj = sliceptr->array;
- objti = pc[2] | PRECISE | LOOP;
- }
- pc += 3;
- break;
-
- case GC_APTR:
- obj = *(void**)(stack_top.b + pc[1]);
- pc += 2;
- break;
-
- case GC_STRING:
- obj = *(void**)(stack_top.b + pc[1]);
- pc += 2;
- break;
-
- case GC_EFACE:
- eface = (Eface*)(stack_top.b + pc[1]);
- pc += 2;
- if(eface->type != nil && ((byte*)eface->__object >= arena_start && (byte*)eface->__object < arena_used)) {
- t = eface->type;
- if(t->__size <= sizeof(void*)) {
- if((t->kind & KindNoPointers))
- break;
-
- obj = eface->__object;
- if((t->kind & ~KindNoPointers) == KindPtr)
- // objti = (uintptr)((PtrType*)t)->elem->gc;
- objti = 0;
- } else {
- obj = eface->__object;
- // objti = (uintptr)t->gc;
- objti = 0;
- }
- }
- break;
-
- case GC_IFACE:
- iface = (Iface*)(stack_top.b + pc[1]);
- pc += 2;
- if(iface->tab == nil)
- break;
-
- // iface->tab
- if((byte*)iface->tab >= arena_start && (byte*)iface->tab < arena_used) {
- // *ptrbufpos++ = (struct PtrTarget){iface->tab, (uintptr)itabtype->gc};
- *ptrbufpos++ = (struct PtrTarget){iface->tab, 0};
- if(ptrbufpos == ptrbuf_end)
- flushptrbuf(ptrbuf, &ptrbufpos, &wp, &wbuf, &nobj, bitbuf);
- }
-
- // iface->data
- if((byte*)iface->__object >= arena_start && (byte*)iface->__object < arena_used) {
- // t = iface->tab->type;
- t = nil;
- if(t->__size <= sizeof(void*)) {
- if((t->kind & KindNoPointers))
- break;
-
- obj = iface->__object;
- if((t->kind & ~KindNoPointers) == KindPtr)
- // objti = (uintptr)((const PtrType*)t)->elem->gc;
- objti = 0;
- } else {
- obj = iface->__object;
- // objti = (uintptr)t->gc;
- objti = 0;
- }
- }
- break;
-
- case GC_DEFAULT_PTR:
- while((i = stack_top.b) <= end_b) {
- stack_top.b += PtrSize;
- obj = *(byte**)i;
- if((byte*)obj >= arena_start && (byte*)obj < arena_used) {
- *ptrbufpos++ = (struct PtrTarget){obj, 0};
- if(ptrbufpos == ptrbuf_end)
- flushptrbuf(ptrbuf, &ptrbufpos, &wp, &wbuf, &nobj, bitbuf);
- }
- }
- goto next_block;
-
- case GC_END:
- if(--stack_top.count != 0) {
- // Next iteration of a loop if possible.
- elemsize = stack_top.elemsize;
- stack_top.b += elemsize;
- if(stack_top.b + elemsize <= end_b+PtrSize) {
- pc = stack_top.loop_or_ret;
- continue;
- }
- i = stack_top.b;
- } else {
- // Stack pop if possible.
- if(stack_ptr+1 < stack+nelem(stack)) {
- pc = stack_top.loop_or_ret;
- stack_top = *(++stack_ptr);
- continue;
- }
- i = (uintptr)b + nominal_size;
- }
- if(!precise_type) {
- // Quickly scan [b+i,b+n) for possible pointers.
- for(; i<=end_b; i+=PtrSize) {
- if(*(byte**)i != nil) {
- // Found a value that may be a pointer.
- // Do a rescan of the entire block.
- enqueue((Obj){b, n, 0}, &wbuf, &wp, &nobj);
- break;
- }
- }
- }
- goto next_block;
-
- case GC_ARRAY_START:
- i = stack_top.b + pc[1];
- count = pc[2];
- elemsize = pc[3];
- pc += 4;
-
- // Stack push.
- *stack_ptr-- = stack_top;
- stack_top = (Frame){count, elemsize, i, pc};
- continue;
-
- case GC_ARRAY_NEXT:
- if(--stack_top.count != 0) {
- stack_top.b += stack_top.elemsize;
- pc = stack_top.loop_or_ret;
- } else {
- // Stack pop.
- stack_top = *(++stack_ptr);
- pc += 1;
- }
- continue;
-
- case GC_CALL:
- // Stack push.
- *stack_ptr-- = stack_top;
- stack_top = (Frame){1, 0, stack_top.b + pc[1], pc+3 /*return address*/};
- pc = (uintptr*)pc[2]; // target of the CALL instruction
- continue;
-
- case GC_MAP_PTR:
- // TODO(atom): to be expanded in a next CL. Same as GC_APTR for now.
- obj = *(void**)(stack_top.b + pc[1]);
- pc += 3;
- break;
-
- case GC_REGION:
- // TODO(atom): to be expanded in a next CL. Same as GC_APTR for now.
- obj = (void*)(stack_top.b + pc[1]);
- pc += 4;
- break;
-
- default:
- runtime_throw("scanblock: invalid GC instruction");
- return;
- }
-
- if((byte*)obj >= arena_start && (byte*)obj < arena_used) {
- *ptrbufpos++ = (PtrTarget){obj, objti};
- if(ptrbufpos == ptrbuf_end)
- flushptrbuf(ptrbuf, &ptrbufpos, &wp, &wbuf, &nobj, bitbuf);
- }
- }
-
- next_block:
- // Done scanning [b, b+n). Prepare for the next iteration of
- // the loop by setting b, n, ti to the parameters for the next block.
-
- if(nobj == 0) {
- flushptrbuf(ptrbuf, &ptrbufpos, &wp, &wbuf, &nobj, bitbuf);
-
- if(nobj == 0) {
- if(!keepworking) {
- if(wbuf)
- putempty(wbuf);
- goto endscan;
- }
- // Emptied our buffer: refill.
- wbuf = getfull(wbuf);
- if(wbuf == nil)
- goto endscan;
- nobj = wbuf->nobj;
- wp = wbuf->obj + wbuf->nobj;
- }
- }
-
- // Fetch b from the work buffer.
- --wp;
- b = wp->p;
- n = wp->n;
- ti = wp->ti;
- nobj--;
- }
-
-endscan:
- runtime_lock(&lock);
- scanbuffers->next = bufferList;
- bufferList = scanbuffers;
- runtime_unlock(&lock);
-}
-
-// debug_scanblock is the debug copy of scanblock.
-// it is simpler, slower, single-threaded, recursive,
-// and uses bitSpecial as the mark bit.
-static void
-debug_scanblock(byte *b, uintptr n)
-{
- byte *obj, *p;
- void **vp;
- uintptr size, *bitp, bits, shift, i, xbits, off;
- MSpan *s;
-
- if(!DebugMark)
- runtime_throw("debug_scanblock without DebugMark");
-
- if((intptr)n < 0) {
- runtime_printf("debug_scanblock %p %D\n", b, (int64)n);
- runtime_throw("debug_scanblock");
- }
-
- // Align b to a word boundary.
- off = (uintptr)b & (PtrSize-1);
- if(off != 0) {
- b += PtrSize - off;
- n -= PtrSize - off;
- }
-
- vp = (void**)b;
- n /= PtrSize;
- for(i=0; i<(uintptr)n; i++) {
- obj = (byte*)vp[i];
-
- // Words outside the arena cannot be pointers.
- if((byte*)obj < runtime_mheap.arena_start || (byte*)obj >= runtime_mheap.arena_used)
- continue;
-
- // Round down to word boundary.
- obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
-
- // Consult span table to find beginning.
- s = runtime_MHeap_LookupMaybe(&runtime_mheap, obj);
- if(s == nil)
- continue;
-
- p = (byte*)((uintptr)s->start<<PageShift);
- size = s->elemsize;
- if(s->sizeclass == 0) {
- obj = p;
- } else {
- if((byte*)obj >= (byte*)s->limit)
- continue;
- int32 i = ((byte*)obj - p)/size;
- obj = p+i*size;
- }
-
- // Now that we know the object header, reload bits.
- off = (uintptr*)obj - (uintptr*)runtime_mheap.arena_start;
- bitp = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- xbits = *bitp;
- bits = xbits >> shift;
-
- // Now we have bits, bitp, and shift correct for
- // obj pointing at the base of the object.
- // If not allocated or already marked, done.
- if((bits & bitAllocated) == 0 || (bits & bitSpecial) != 0) // NOTE: bitSpecial not bitMarked
- continue;
- *bitp |= bitSpecial<<shift;
- if(!(bits & bitMarked))
- runtime_printf("found unmarked block %p in %p\n", obj, vp+i);
-
- // If object has no pointers, don't need to scan further.
- if((bits & bitNoPointers) != 0)
- continue;
-
- debug_scanblock(obj, size);
- }
-}
-
-// Append obj to the work buffer.
-// _wbuf, _wp, _nobj are input/output parameters and are specifying the work buffer.
-static void
-enqueue(Obj obj, Workbuf **_wbuf, Obj **_wp, uintptr *_nobj)
-{
- uintptr nobj, off;
- Obj *wp;
- Workbuf *wbuf;
-
- if(Debug > 1)
- runtime_printf("append obj(%p %D %p)\n", obj.p, (int64)obj.n, obj.ti);
-
- // Align obj.b to a word boundary.
- off = (uintptr)obj.p & (PtrSize-1);
- if(off != 0) {
- obj.p += PtrSize - off;
- obj.n -= PtrSize - off;
- obj.ti = 0;
- }
-
- if(obj.p == nil || obj.n == 0)
- return;
-
- // Load work buffer state
- wp = *_wp;
- wbuf = *_wbuf;
- nobj = *_nobj;
-
- // If another proc wants a pointer, give it some.
- if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
- wbuf->nobj = nobj;
- wbuf = handoff(wbuf);
- nobj = wbuf->nobj;
- wp = wbuf->obj + nobj;
- }
-
- // If buffer is full, get a new one.
- if(wbuf == nil || nobj >= nelem(wbuf->obj)) {
- if(wbuf != nil)
- wbuf->nobj = nobj;
- wbuf = getempty(wbuf);
- wp = wbuf->obj;
- nobj = 0;
- }
-
- *wp = obj;
- wp++;
- nobj++;
-
- // Save work buffer state
- *_wp = wp;
- *_wbuf = wbuf;
- *_nobj = nobj;
-}
-
-static void
-markroot(ParFor *desc, uint32 i)
-{
- Obj *wp;
- Workbuf *wbuf;
- uintptr nobj;
-
- USED(&desc);
- wp = nil;
- wbuf = nil;
- nobj = 0;
- enqueue(work.roots[i], &wbuf, &wp, &nobj);
- scanblock(wbuf, wp, nobj, false);
-}
-
-// Get an empty work buffer off the work.empty list,
-// allocating new buffers as needed.
-static Workbuf*
-getempty(Workbuf *b)
-{
- if(b != nil)
- runtime_lfstackpush(&work.full, &b->node);
- b = (Workbuf*)runtime_lfstackpop(&work.empty);
- if(b == nil) {
- // Need to allocate.
- runtime_lock(&work);
- if(work.nchunk < sizeof *b) {
- work.nchunk = 1<<20;
- work.chunk = runtime_SysAlloc(work.nchunk);
- }
- b = (Workbuf*)work.chunk;
- work.chunk += sizeof *b;
- work.nchunk -= sizeof *b;
- runtime_unlock(&work);
- }
- b->nobj = 0;
- return b;
-}
-
-static void
-putempty(Workbuf *b)
-{
- runtime_lfstackpush(&work.empty, &b->node);
-}
-
-// Get a full work buffer off the work.full list, or return nil.
-static Workbuf*
-getfull(Workbuf *b)
-{
- M *m;
- int32 i;
-
- if(b != nil)
- runtime_lfstackpush(&work.empty, &b->node);
- b = (Workbuf*)runtime_lfstackpop(&work.full);
- if(b != nil || work.nproc == 1)
- return b;
-
- m = runtime_m();
- runtime_xadd(&work.nwait, +1);
- for(i=0;; i++) {
- if(work.full != 0) {
- runtime_xadd(&work.nwait, -1);
- b = (Workbuf*)runtime_lfstackpop(&work.full);
- if(b != nil)
- return b;
- runtime_xadd(&work.nwait, +1);
- }
- if(work.nwait == work.nproc)
- return nil;
- if(i < 10) {
- m->gcstats.nprocyield++;
- runtime_procyield(20);
- } else if(i < 20) {
- m->gcstats.nosyield++;
- runtime_osyield();
- } else {
- m->gcstats.nsleep++;
- runtime_usleep(100);
- }
- }
-}
-
-static Workbuf*
-handoff(Workbuf *b)
-{
- M *m;
- int32 n;
- Workbuf *b1;
-
- m = runtime_m();
-
- // Make new buffer with half of b's pointers.
- b1 = getempty(nil);
- n = b->nobj/2;
- b->nobj -= n;
- b1->nobj = n;
- runtime_memmove(b1->obj, b->obj+b->nobj, n*sizeof b1->obj[0]);
- m->gcstats.nhandoff++;
- m->gcstats.nhandoffcnt += n;
-
- // Put b on full list - let first half of b get stolen.
- runtime_lfstackpush(&work.full, &b->node);
- return b1;
-}
-
-static void
-addroot(Obj obj)
-{
- uint32 cap;
- Obj *new;
-
- if(work.nroot >= work.rootcap) {
- cap = PageSize/sizeof(Obj);
- if(cap < 2*work.rootcap)
- cap = 2*work.rootcap;
- new = (Obj*)runtime_SysAlloc(cap*sizeof(Obj));
- if(work.roots != nil) {
- runtime_memmove(new, work.roots, work.rootcap*sizeof(Obj));
- runtime_SysFree(work.roots, work.rootcap*sizeof(Obj));
- }
- work.roots = new;
- work.rootcap = cap;
- }
- work.roots[work.nroot] = obj;
- work.nroot++;
-}
-
-static void
-addstackroots(G *gp)
-{
-#ifdef USING_SPLIT_STACK
- M *mp;
- void* sp;
- size_t spsize;
- void* next_segment;
- void* next_sp;
- void* initial_sp;
-
- if(gp == runtime_g()) {
- // Scanning our own stack.
- sp = __splitstack_find(nil, nil, &spsize, &next_segment,
- &next_sp, &initial_sp);
- } else if((mp = gp->m) != nil && mp->helpgc) {
- // gchelper's stack is in active use and has no interesting pointers.
- return;
- } else {
- // Scanning another goroutine's stack.
- // The goroutine is usually asleep (the world is stopped).
-
- // The exception is that if the goroutine is about to enter or might
- // have just exited a system call, it may be executing code such
- // as schedlock and may have needed to start a new stack segment.
- // Use the stack segment and stack pointer at the time of
- // the system call instead, since that won't change underfoot.
- if(gp->gcstack != nil) {
- sp = gp->gcstack;
- spsize = gp->gcstack_size;
- next_segment = gp->gcnext_segment;
- next_sp = gp->gcnext_sp;
- initial_sp = gp->gcinitial_sp;
- } else {
- sp = __splitstack_find_context(&gp->stack_context[0],
- &spsize, &next_segment,
- &next_sp, &initial_sp);
- }
- }
- if(sp != nil) {
- addroot((Obj){sp, spsize, 0});
- while((sp = __splitstack_find(next_segment, next_sp,
- &spsize, &next_segment,
- &next_sp, &initial_sp)) != nil)
- addroot((Obj){sp, spsize, 0});
- }
-#else
- M *mp;
- byte* bottom;
- byte* top;
-
- if(gp == runtime_g()) {
- // Scanning our own stack.
- bottom = (byte*)&gp;
- } else if((mp = gp->m) != nil && mp->helpgc) {
- // gchelper's stack is in active use and has no interesting pointers.
- return;
- } else {
- // Scanning another goroutine's stack.
- // The goroutine is usually asleep (the world is stopped).
- bottom = (byte*)gp->gcnext_sp;
- if(bottom == nil)
- return;
- }
- top = (byte*)gp->gcinitial_sp + gp->gcstack_size;
- if(top > bottom)
- addroot((Obj){bottom, top - bottom, 0});
- else
- addroot((Obj){top, bottom - top, 0});
-#endif
-}
-
-static void
-addfinroots(void *v)
-{
- uintptr size;
-
- size = 0;
- if(!runtime_mlookup(v, (byte**)&v, &size, nil) || !runtime_blockspecial(v))
- runtime_throw("mark - finalizer inconsistency");
-
- // do not mark the finalizer block itself. just mark the things it points at.
- addroot((Obj){v, size, 0});
-}
-
-static struct root_list* roots;
-
-void
-__go_register_gc_roots (struct root_list* r)
-{
- // FIXME: This needs locking if multiple goroutines can call
- // dlopen simultaneously.
- r->next = roots;
- roots = r;
-}
-
-static void
-addroots(void)
-{
- struct root_list *pl;
- G *gp;
- FinBlock *fb;
- MSpan *s, **allspans;
- uint32 spanidx;
-
- work.nroot = 0;
-
- // mark data+bss.
- for(pl = roots; pl != nil; pl = pl->next) {
- struct root* pr = &pl->roots[0];
- while(1) {
- void *decl = pr->decl;
- if(decl == nil)
- break;
- addroot((Obj){decl, pr->size, 0});
- pr++;
- }
- }
-
- addroot((Obj){(byte*)&runtime_m0, sizeof runtime_m0, 0});
- addroot((Obj){(byte*)&runtime_g0, sizeof runtime_g0, 0});
- addroot((Obj){(byte*)&runtime_allg, sizeof runtime_allg, 0});
- addroot((Obj){(byte*)&runtime_allm, sizeof runtime_allm, 0});
- runtime_MProf_Mark(addroot);
- runtime_time_scan(addroot);
- runtime_trampoline_scan(addroot);
-
- // MSpan.types
- allspans = runtime_mheap.allspans;
- for(spanidx=0; spanidx<runtime_mheap.nspan; spanidx++) {
- s = allspans[spanidx];
- if(s->state == MSpanInUse) {
- switch(s->types.compression) {
- case MTypes_Empty:
- case MTypes_Single:
- break;
- case MTypes_Words:
- case MTypes_Bytes:
- // TODO(atom): consider using defaultProg instead of 0
- addroot((Obj){(byte*)&s->types.data, sizeof(void*), 0});
- break;
- }
- }
- }
-
- // stacks
- for(gp=runtime_allg; gp!=nil; gp=gp->alllink) {
- switch(gp->status){
- default:
- runtime_printf("unexpected G.status %d\n", gp->status);
- runtime_throw("mark - bad status");
- case Gdead:
- break;
- case Grunning:
- if(gp != runtime_g())
- runtime_throw("mark - world not stopped");
- addstackroots(gp);
- break;
- case Grunnable:
- case Gsyscall:
- case Gwaiting:
- addstackroots(gp);
- break;
- }
- }
-
- runtime_walkfintab(addfinroots, addroot);
-
- for(fb=allfin; fb; fb=fb->alllink)
- addroot((Obj){(byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]), 0});
-
- addroot((Obj){(byte*)&work, sizeof work, 0});
-}
-
-static bool
-handlespecial(byte *p, uintptr size)
-{
- void (*fn)(void*);
- const struct __go_func_type *ft;
- FinBlock *block;
- Finalizer *f;
-
- if(!runtime_getfinalizer(p, true, &fn, &ft)) {
- runtime_setblockspecial(p, false);
- runtime_MProf_Free(p, size);
- return false;
- }
-
- runtime_lock(&finlock);
- if(finq == nil || finq->cnt == finq->cap) {
- if(finc == nil) {
- finc = runtime_SysAlloc(PageSize);
- finc->cap = (PageSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
- finc->alllink = allfin;
- allfin = finc;
- }
- block = finc;
- finc = block->next;
- block->next = finq;
- finq = block;
- }
- f = &finq->fin[finq->cnt];
- finq->cnt++;
- f->fn = fn;
- f->ft = ft;
- f->arg = p;
- runtime_unlock(&finlock);
- return true;
-}
-
-// Sweep frees or collects finalizers for blocks not marked in the mark phase.
-// It clears the mark bits in preparation for the next GC round.
-static void
-sweepspan(ParFor *desc, uint32 idx)
-{
- M *m;
- int32 cl, n, npages;
- uintptr size;
- byte *p;
- MCache *c;
- byte *arena_start;
- MLink head, *end;
- int32 nfree;
- byte *type_data;
- byte compression;
- uintptr type_data_inc;
- MSpan *s;
-
- m = runtime_m();
-
- USED(&desc);
- s = runtime_mheap.allspans[idx];
- if(s->state != MSpanInUse)
- return;
- arena_start = runtime_mheap.arena_start;
- p = (byte*)(s->start << PageShift);
- cl = s->sizeclass;
- size = s->elemsize;
- if(cl == 0) {
- n = 1;
- } else {
- // Chunk full of small blocks.
- npages = runtime_class_to_allocnpages[cl];
- n = (npages << PageShift) / size;
- }
- nfree = 0;
- end = &head;
- c = m->mcache;
-
- type_data = (byte*)s->types.data;
- type_data_inc = sizeof(uintptr);
- compression = s->types.compression;
- switch(compression) {
- case MTypes_Bytes:
- type_data += 8*sizeof(uintptr);
- type_data_inc = 1;
- break;
- }
-
- // Sweep through n objects of given size starting at p.
- // This thread owns the span now, so it can manipulate
- // the block bitmap without atomic operations.
- for(; n > 0; n--, p += size, type_data+=type_data_inc) {
- uintptr off, *bitp, shift, bits;
-
- off = (uintptr*)p - (uintptr*)arena_start;
- bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- bits = *bitp>>shift;
-
- if((bits & bitAllocated) == 0)
- continue;
-
- if((bits & bitMarked) != 0) {
- if(DebugMark) {
- if(!(bits & bitSpecial))
- runtime_printf("found spurious mark on %p\n", p);
- *bitp &= ~(bitSpecial<<shift);
- }
- *bitp &= ~(bitMarked<<shift);
- continue;
- }
-
- // Special means it has a finalizer or is being profiled.
- // In DebugMark mode, the bit has been coopted so
- // we have to assume all blocks are special.
- if(DebugMark || (bits & bitSpecial) != 0) {
- if(handlespecial(p, size))
- continue;
- }
-
- // Mark freed; restore block boundary bit.
- *bitp = (*bitp & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
-
- if(cl == 0) {
- // Free large span.
- runtime_unmarkspan(p, 1<<PageShift);
- *(uintptr*)p = 1; // needs zeroing
- runtime_MHeap_Free(&runtime_mheap, s, 1);
- c->local_alloc -= size;
- c->local_nfree++;
- } else {
- // Free small object.
- switch(compression) {
- case MTypes_Words:
- *(uintptr*)type_data = 0;
- break;
- case MTypes_Bytes:
- *(byte*)type_data = 0;
- break;
- }
- if(size > sizeof(uintptr))
- ((uintptr*)p)[1] = 1; // mark as "needs to be zeroed"
-
- end->next = (MLink*)p;
- end = (MLink*)p;
- nfree++;
- }
- }
-
- if(nfree) {
- c->local_by_size[cl].nfree += nfree;
- c->local_alloc -= size * nfree;
- c->local_nfree += nfree;
- c->local_cachealloc -= nfree * size;
- c->local_objects -= nfree;
- runtime_MCentral_FreeSpan(&runtime_mheap.central[cl], s, nfree, head.next, end);
- }
-}
-
-static void
-dumpspan(uint32 idx)
-{
- int32 sizeclass, n, npages, i, column;
- uintptr size;
- byte *p;
- byte *arena_start;
- MSpan *s;
- bool allocated, special;
-
- s = runtime_mheap.allspans[idx];
- if(s->state != MSpanInUse)
- return;
- arena_start = runtime_mheap.arena_start;
- p = (byte*)(s->start << PageShift);
- sizeclass = s->sizeclass;
- size = s->elemsize;
- if(sizeclass == 0) {
- n = 1;
- } else {
- npages = runtime_class_to_allocnpages[sizeclass];
- n = (npages << PageShift) / size;
- }
-
- runtime_printf("%p .. %p:\n", p, p+n*size);
- column = 0;
- for(; n>0; n--, p+=size) {
- uintptr off, *bitp, shift, bits;
-
- off = (uintptr*)p - (uintptr*)arena_start;
- bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- bits = *bitp>>shift;
-
- allocated = ((bits & bitAllocated) != 0);
- special = ((bits & bitSpecial) != 0);
-
- for(i=0; (uint32)i<size; i+=sizeof(void*)) {
- if(column == 0) {
- runtime_printf("\t");
- }
- if(i == 0) {
- runtime_printf(allocated ? "(" : "[");
- runtime_printf(special ? "@" : "");
- runtime_printf("%p: ", p+i);
- } else {
- runtime_printf(" ");
- }
-
- runtime_printf("%p", *(void**)(p+i));
-
- if(i+sizeof(void*) >= size) {
- runtime_printf(allocated ? ") " : "] ");
- }
-
- column++;
- if(column == 8) {
- runtime_printf("\n");
- column = 0;
- }
- }
- }
- runtime_printf("\n");
-}
-
-// A debugging function to dump the contents of memory
-void
-runtime_memorydump(void)
-{
- uint32 spanidx;
-
- for(spanidx=0; spanidx<runtime_mheap.nspan; spanidx++) {
- dumpspan(spanidx);
- }
-}
-
-void
-runtime_gchelper(void)
-{
- // parallel mark for over gc roots
- runtime_parfordo(work.markfor);
-
- // help other threads scan secondary blocks
- scanblock(nil, nil, 0, true);
-
- if(DebugMark) {
- // wait while the main thread executes mark(debug_scanblock)
- while(runtime_atomicload(&work.debugmarkdone) == 0)
- runtime_usleep(10);
- }
-
- runtime_parfordo(work.sweepfor);
- if(runtime_xadd(&work.ndone, +1) == work.nproc-1)
- runtime_notewakeup(&work.alldone);
-}
-
-// Initialized from $GOGC. GOGC=off means no gc.
-//
-// Next gc is after we've allocated an extra amount of
-// memory proportional to the amount already in use.
-// If gcpercent=100 and we're using 4M, we'll gc again
-// when we get to 8M. This keeps the gc cost in linear
-// proportion to the allocation cost. Adjusting gcpercent
-// just changes the linear constant (and also the amount of
-// extra memory used).
-static int32 gcpercent = -2;
-
-static void
-stealcache(void)
-{
- M *mp;
-
- for(mp=runtime_allm; mp; mp=mp->alllink)
- runtime_MCache_ReleaseAll(mp->mcache);
-}
-
-static void
-cachestats(GCStats *stats)
-{
- M *mp;
- MCache *c;
- uint32 i;
- uint64 stacks_inuse;
- uint64 *src, *dst;
-
- if(stats)
- runtime_memclr((byte*)stats, sizeof(*stats));
- stacks_inuse = 0;
- for(mp=runtime_allm; mp; mp=mp->alllink) {
- c = mp->mcache;
- runtime_purgecachedstats(c);
- // stacks_inuse += mp->stackinuse*FixedStack;
- if(stats) {
- src = (uint64*)&mp->gcstats;
- dst = (uint64*)stats;
- for(i=0; i<sizeof(*stats)/sizeof(uint64); i++)
- dst[i] += src[i];
- runtime_memclr((byte*)&mp->gcstats, sizeof(mp->gcstats));
- }
- for(i=0; i<nelem(c->local_by_size); i++) {
- mstats.by_size[i].nmalloc += c->local_by_size[i].nmalloc;
- c->local_by_size[i].nmalloc = 0;
- mstats.by_size[i].nfree += c->local_by_size[i].nfree;
- c->local_by_size[i].nfree = 0;
- }
- }
- mstats.stacks_inuse = stacks_inuse;
-}
-
-// Structure of arguments passed to function gc().
-// This allows the arguments to be passed via reflect_call.
-struct gc_args
-{
- int32 force;
-};
-
-static void gc(struct gc_args *args);
-
-void
-runtime_gc(int32 force)
-{
- M *m;
- const byte *p;
- struct gc_args a, *ap;
-
- // The atomic operations are not atomic if the uint64s
- // are not aligned on uint64 boundaries. This has been
- // a problem in the past.
- if((((uintptr)&work.empty) & 7) != 0)
- runtime_throw("runtime: gc work buffer is misaligned");
-
- // Make sure all registers are saved on stack so that
- // scanstack sees them.
- __builtin_unwind_init();
-
- // The gc is turned off (via enablegc) until
- // the bootstrap has completed.
- // Also, malloc gets called in the guts
- // of a number of libraries that might be
- // holding locks. To avoid priority inversion
- // problems, don't bother trying to run gc
- // while holding a lock. The next mallocgc
- // without a lock will do the gc instead.
- m = runtime_m();
- if(!mstats.enablegc || m->locks > 0 || runtime_panicking)
- return;
-
- if(gcpercent == -2) { // first time through
- p = runtime_getenv("GOGC");
- if(p == nil || p[0] == '\0')
- gcpercent = 100;
- else if(runtime_strcmp((const char*)p, "off") == 0)
- gcpercent = -1;
- else
- gcpercent = runtime_atoi(p);
-
- p = runtime_getenv("GOGCTRACE");
- if(p != nil)
- gctrace = runtime_atoi(p);
- }
- if(gcpercent < 0)
- return;
-
- // Run gc on a bigger stack to eliminate
- // a potentially large number of calls to runtime_morestack.
- // But not when using gccgo.
- a.force = force;
- ap = &a;
- gc(ap);
-
- if(gctrace > 1 && !force) {
- a.force = 1;
- gc(&a);
- }
-}
-
-static void
-gc(struct gc_args *args)
-{
- M *m;
- int64 t0, t1, t2, t3, t4;
- uint64 heap0, heap1, obj0, obj1;
- GCStats stats;
- M *mp;
- uint32 i;
- // Eface eface;
-
- runtime_semacquire(&runtime_worldsema);
- if(!args->force && mstats.heap_alloc < mstats.next_gc) {
- runtime_semrelease(&runtime_worldsema);
- return;
- }
-
- m = runtime_m();
-
- t0 = runtime_nanotime();
-
- m->gcing = 1;
- runtime_stoptheworld();
-
- for(mp=runtime_allm; mp; mp=mp->alllink)
- runtime_settype_flush(mp, false);
-
- heap0 = 0;
- obj0 = 0;
- if(gctrace) {
- cachestats(nil);
- heap0 = mstats.heap_alloc;
- obj0 = mstats.nmalloc - mstats.nfree;
- }
-
- m->locks++; // disable gc during mallocs in parforalloc
- if(work.markfor == nil)
- work.markfor = runtime_parforalloc(MaxGcproc);
- if(work.sweepfor == nil)
- work.sweepfor = runtime_parforalloc(MaxGcproc);
- m->locks--;
-
- if(itabtype == nil) {
- // get C pointer to the Go type "itab"
- // runtime_gc_itab_ptr(&eface);
- // itabtype = ((PtrType*)eface.type)->elem;
- }
-
- work.nwait = 0;
- work.ndone = 0;
- work.debugmarkdone = 0;
- work.nproc = runtime_gcprocs();
- addroots();
- runtime_parforsetup(work.markfor, work.nproc, work.nroot, nil, false, markroot);
- runtime_parforsetup(work.sweepfor, work.nproc, runtime_mheap.nspan, nil, true, sweepspan);
- if(work.nproc > 1) {
- runtime_noteclear(&work.alldone);
- runtime_helpgc(work.nproc);
- }
-
- t1 = runtime_nanotime();
-
- runtime_parfordo(work.markfor);
- scanblock(nil, nil, 0, true);
-
- if(DebugMark) {
- for(i=0; i<work.nroot; i++)
- debug_scanblock(work.roots[i].p, work.roots[i].n);
- runtime_atomicstore(&work.debugmarkdone, 1);
- }
- t2 = runtime_nanotime();
-
- runtime_parfordo(work.sweepfor);
- t3 = runtime_nanotime();
-
- stealcache();
- cachestats(&stats);
-
- if(work.nproc > 1)
- runtime_notesleep(&work.alldone);
-
- stats.nprocyield += work.sweepfor->nprocyield;
- stats.nosyield += work.sweepfor->nosyield;
- stats.nsleep += work.sweepfor->nsleep;
-
- mstats.next_gc = mstats.heap_alloc+(mstats.heap_alloc-runtime_stacks_sys)*gcpercent/100;
- m->gcing = 0;
-
- if(finq != nil) {
- m->locks++; // disable gc during the mallocs in newproc
- // kick off or wake up goroutine to run queued finalizers
- if(fing == nil)
- fing = __go_go(runfinq, nil);
- else if(fingwait) {
- fingwait = 0;
- runtime_ready(fing);
- }
- m->locks--;
- }
-
- heap1 = mstats.heap_alloc;
- obj1 = mstats.nmalloc - mstats.nfree;
-
- t4 = runtime_nanotime();
- mstats.last_gc = t4;
- mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
- mstats.pause_total_ns += t4 - t0;
- mstats.numgc++;
- if(mstats.debuggc)
- runtime_printf("pause %D\n", t4-t0);
-
- if(gctrace) {
- runtime_printf("gc%d(%d): %D+%D+%D ms, %D -> %D MB %D -> %D (%D-%D) objects,"
- " %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\n",
- mstats.numgc, work.nproc, (t2-t1)/1000000, (t3-t2)/1000000, (t1-t0+t4-t3)/1000000,
- heap0>>20, heap1>>20, obj0, obj1,
- mstats.nmalloc, mstats.nfree,
- stats.nhandoff, stats.nhandoffcnt,
- work.sweepfor->nsteal, work.sweepfor->nstealcnt,
- stats.nprocyield, stats.nosyield, stats.nsleep);
- }
-
- runtime_MProf_GC();
- runtime_semrelease(&runtime_worldsema);
- runtime_starttheworld();
-
- // give the queued finalizers, if any, a chance to run
- if(finq != nil)
- runtime_gosched();
-}
-
-void runtime_ReadMemStats(MStats *)
- __asm__ (GOSYM_PREFIX "runtime.ReadMemStats");
-
-void
-runtime_ReadMemStats(MStats *stats)
-{
- M *m;
-
- // Have to acquire worldsema to stop the world,
- // because stoptheworld can only be used by
- // one goroutine at a time, and there might be
- // a pending garbage collection already calling it.
- runtime_semacquire(&runtime_worldsema);
- m = runtime_m();
- m->gcing = 1;
- runtime_stoptheworld();
- cachestats(nil);
- *stats = mstats;
- m->gcing = 0;
- runtime_semrelease(&runtime_worldsema);
- runtime_starttheworld();
-}
-
-static void
-runfinq(void* dummy __attribute__ ((unused)))
-{
- Finalizer *f;
- FinBlock *fb, *next;
- uint32 i;
-
- for(;;) {
- // There's no need for a lock in this section
- // because it only conflicts with the garbage
- // collector, and the garbage collector only
- // runs when everyone else is stopped, and
- // runfinq only stops at the gosched() or
- // during the calls in the for loop.
- fb = finq;
- finq = nil;
- if(fb == nil) {
- fingwait = 1;
- runtime_park(nil, nil, "finalizer wait");
- continue;
- }
- if(raceenabled)
- runtime_racefingo();
- for(; fb; fb=next) {
- next = fb->next;
- for(i=0; i<(uint32)fb->cnt; i++) {
- void *params[1];
-
- f = &fb->fin[i];
- params[0] = &f->arg;
- reflect_call(f->ft, (void*)f->fn, 0, 0, params, nil);
- f->fn = nil;
- f->arg = nil;
- }
- fb->cnt = 0;
- fb->next = finc;
- finc = fb;
- }
- runtime_gc(1); // trigger another gc to clean up the finalized objects, if possible
- }
-}
-
-// mark the block at v of size n as allocated.
-// If noptr is true, mark it as having no pointers.
-void
-runtime_markallocated(void *v, uintptr n, bool noptr)
-{
- uintptr *b, obits, bits, off, shift;
-
- if(0)
- runtime_printf("markallocated %p+%p\n", v, n);
-
- if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
- runtime_throw("markallocated: bad pointer");
-
- off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start; // word offset
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
-
- for(;;) {
- obits = *b;
- bits = (obits & ~(bitMask<<shift)) | (bitAllocated<<shift);
- if(noptr)
- bits |= bitNoPointers<<shift;
- if(runtime_singleproc) {
- *b = bits;
- break;
- } else {
- // more than one goroutine is potentially running: use atomic op
- if(runtime_casp((void**)b, (void*)obits, (void*)bits))
- break;
- }
- }
-}
-
-// mark the block at v of size n as freed.
-void
-runtime_markfreed(void *v, uintptr n)
-{
- uintptr *b, obits, bits, off, shift;
-
- if(0)
- runtime_printf("markallocated %p+%p\n", v, n);
-
- if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
- runtime_throw("markallocated: bad pointer");
-
- off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start; // word offset
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
-
- for(;;) {
- obits = *b;
- bits = (obits & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
- if(runtime_singleproc) {
- *b = bits;
- break;
- } else {
- // more than one goroutine is potentially running: use atomic op
- if(runtime_casp((void**)b, (void*)obits, (void*)bits))
- break;
- }
- }
-}
-
-// check that the block at v of size n is marked freed.
-void
-runtime_checkfreed(void *v, uintptr n)
-{
- uintptr *b, bits, off, shift;
-
- if(!runtime_checking)
- return;
-
- if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
- return; // not allocated, so okay
-
- off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start; // word offset
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
-
- bits = *b>>shift;
- if((bits & bitAllocated) != 0) {
- runtime_printf("checkfreed %p+%p: off=%p have=%p\n",
- v, n, off, bits & bitMask);
- runtime_throw("checkfreed: not freed");
- }
-}
-
-// mark the span of memory at v as having n blocks of the given size.
-// if leftover is true, there is left over space at the end of the span.
-void
-runtime_markspan(void *v, uintptr size, uintptr n, bool leftover)
-{
- uintptr *b, off, shift;
- byte *p;
-
- if((byte*)v+size*n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
- runtime_throw("markspan: bad pointer");
-
- p = v;
- if(leftover) // mark a boundary just past end of last block too
- n++;
- for(; n-- > 0; p += size) {
- // Okay to use non-atomic ops here, because we control
- // the entire span, and each bitmap word has bits for only
- // one span, so no other goroutines are changing these
- // bitmap words.
- off = (uintptr*)p - (uintptr*)runtime_mheap.arena_start; // word offset
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
- *b = (*b & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
- }
-}
-
-// unmark the span of memory at v of length n bytes.
-void
-runtime_unmarkspan(void *v, uintptr n)
-{
- uintptr *p, *b, off;
-
- if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
- runtime_throw("markspan: bad pointer");
-
- p = v;
- off = p - (uintptr*)runtime_mheap.arena_start; // word offset
- if(off % wordsPerBitmapWord != 0)
- runtime_throw("markspan: unaligned pointer");
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- n /= PtrSize;
- if(n%wordsPerBitmapWord != 0)
- runtime_throw("unmarkspan: unaligned length");
- // Okay to use non-atomic ops here, because we control
- // the entire span, and each bitmap word has bits for only
- // one span, so no other goroutines are changing these
- // bitmap words.
- n /= wordsPerBitmapWord;
- while(n-- > 0)
- *b-- = 0;
-}
-
-bool
-runtime_blockspecial(void *v)
-{
- uintptr *b, off, shift;
-
- if(DebugMark)
- return true;
-
- off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
-
- return (*b & (bitSpecial<<shift)) != 0;
-}
-
-void
-runtime_setblockspecial(void *v, bool s)
-{
- uintptr *b, off, shift, bits, obits;
-
- if(DebugMark)
- return;
-
- off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
- b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = off % wordsPerBitmapWord;
-
- for(;;) {
- obits = *b;
- if(s)
- bits = obits | (bitSpecial<<shift);
- else
- bits = obits & ~(bitSpecial<<shift);
- if(runtime_singleproc) {
- *b = bits;
- break;
- } else {
- // more than one goroutine is potentially running: use atomic op
- if(runtime_casp((void**)b, (void*)obits, (void*)bits))
- break;
- }
- }
-}
-
-void
-runtime_MHeap_MapBits(MHeap *h)
-{
- size_t page_size;
-
- // Caller has added extra mappings to the arena.
- // Add extra mappings of bitmap words as needed.
- // We allocate extra bitmap pieces in chunks of bitmapChunk.
- enum {
- bitmapChunk = 8192
- };
- uintptr n;
-
- n = (h->arena_used - h->arena_start) / wordsPerBitmapWord;
- n = (n+bitmapChunk-1) & ~(bitmapChunk-1);
- if(h->bitmap_mapped >= n)
- return;
-
- page_size = getpagesize();
- n = (n+page_size-1) & ~(page_size-1);
-
- runtime_SysMap(h->arena_start - n, n - h->bitmap_mapped);
- h->bitmap_mapped = n;
-}
diff --git a/gcc-4.8.1/libgo/runtime/mgc0.h b/gcc-4.8.1/libgo/runtime/mgc0.h
deleted file mode 100644
index a2798ef34..000000000
--- a/gcc-4.8.1/libgo/runtime/mgc0.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 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.
-
-// Garbage collector (GC)
-
-// GC instruction opcodes.
-//
-// The opcode of an instruction is followed by zero or more
-// arguments to the instruction.
-//
-// Meaning of arguments:
-// off Offset (in bytes) from the start of the current object
-// objgc Pointer to GC info of an object
-// len Length of an array
-// elemsize Size (in bytes) of an element
-// size Size (in bytes)
-enum {
- GC_END, // End of object, loop or subroutine. Args: none
- GC_PTR, // A typed pointer. Args: (off, objgc)
- GC_APTR, // Pointer to an arbitrary object. Args: (off)
- GC_ARRAY_START, // Start an array with a fixed length. Args: (off, len, elemsize)
- GC_ARRAY_NEXT, // The next element of an array. Args: none
- GC_CALL, // Call a subroutine. Args: (off, objgc)
- GC_MAP_PTR, // Go map. Args: (off, MapType*)
- GC_STRING, // Go string. Args: (off)
- GC_EFACE, // interface{}. Args: (off)
- GC_IFACE, // interface{...}. Args: (off)
- GC_SLICE, // Go slice. Args: (off, objgc)
- GC_REGION, // A region/part of the current object. Args: (off, size, objgc)
-
- GC_NUM_INSTR, // Number of instruction opcodes
-};
-
-enum {
- // Size of GC's fixed stack.
- //
- // The current GC implementation permits:
- // - at most 1 stack allocation because of GC_CALL
- // - at most GC_STACK_CAPACITY allocations because of GC_ARRAY_START
- GC_STACK_CAPACITY = 8,
-};
diff --git a/gcc-4.8.1/libgo/runtime/mheap.c b/gcc-4.8.1/libgo/runtime/mheap.c
deleted file mode 100644
index 6636b015d..000000000
--- a/gcc-4.8.1/libgo/runtime/mheap.c
+++ /dev/null
@@ -1,504 +0,0 @@
-// 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.
-
-// Page heap.
-//
-// See malloc.h for overview.
-//
-// When a MSpan is in the heap free list, state == MSpanFree
-// and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span.
-//
-// When a MSpan is allocated, state == MSpanInUse
-// and heapmap(i) == span for all s->start <= i < s->start+s->npages.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-static MSpan *MHeap_AllocLocked(MHeap*, uintptr, int32);
-static bool MHeap_Grow(MHeap*, uintptr);
-static void MHeap_FreeLocked(MHeap*, MSpan*);
-static MSpan *MHeap_AllocLarge(MHeap*, uintptr);
-static MSpan *BestFit(MSpan*, uintptr, MSpan*);
-
-static void
-RecordSpan(void *vh, byte *p)
-{
- MHeap *h;
- MSpan *s;
- MSpan **all;
- uint32 cap;
-
- h = vh;
- s = (MSpan*)p;
- if(h->nspan >= h->nspancap) {
- cap = 64*1024/sizeof(all[0]);
- if(cap < h->nspancap*3/2)
- cap = h->nspancap*3/2;
- all = (MSpan**)runtime_SysAlloc(cap*sizeof(all[0]));
- if(h->allspans) {
- runtime_memmove(all, h->allspans, h->nspancap*sizeof(all[0]));
- runtime_SysFree(h->allspans, h->nspancap*sizeof(all[0]));
- }
- h->allspans = all;
- h->nspancap = cap;
- }
- h->allspans[h->nspan++] = s;
-}
-
-// Initialize the heap; fetch memory using alloc.
-void
-runtime_MHeap_Init(MHeap *h, void *(*alloc)(uintptr))
-{
- uint32 i;
-
- runtime_FixAlloc_Init(&h->spanalloc, sizeof(MSpan), alloc, RecordSpan, h);
- runtime_FixAlloc_Init(&h->cachealloc, sizeof(MCache), alloc, nil, nil);
- // h->mapcache needs no init
- for(i=0; i<nelem(h->free); i++)
- runtime_MSpanList_Init(&h->free[i]);
- runtime_MSpanList_Init(&h->large);
- for(i=0; i<nelem(h->central); i++)
- runtime_MCentral_Init(&h->central[i], i);
-}
-
-// Allocate a new span of npage pages from the heap
-// and record its size class in the HeapMap and HeapMapCache.
-MSpan*
-runtime_MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, int32 acct, int32 zeroed)
-{
- MSpan *s;
-
- runtime_lock(h);
- runtime_purgecachedstats(runtime_m()->mcache);
- s = MHeap_AllocLocked(h, npage, sizeclass);
- if(s != nil) {
- mstats.heap_inuse += npage<<PageShift;
- if(acct) {
- mstats.heap_objects++;
- mstats.heap_alloc += npage<<PageShift;
- }
- }
- runtime_unlock(h);
- if(s != nil && *(uintptr*)(s->start<<PageShift) != 0 && zeroed)
- runtime_memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
- return s;
-}
-
-static MSpan*
-MHeap_AllocLocked(MHeap *h, uintptr npage, int32 sizeclass)
-{
- uintptr n;
- MSpan *s, *t;
- PageID p;
-
- // Try in fixed-size lists up to max.
- for(n=npage; n < nelem(h->free); n++) {
- if(!runtime_MSpanList_IsEmpty(&h->free[n])) {
- s = h->free[n].next;
- goto HaveSpan;
- }
- }
-
- // Best fit in list of large spans.
- if((s = MHeap_AllocLarge(h, npage)) == nil) {
- if(!MHeap_Grow(h, npage))
- return nil;
- if((s = MHeap_AllocLarge(h, npage)) == nil)
- return nil;
- }
-
-HaveSpan:
- // Mark span in use.
- if(s->state != MSpanFree)
- runtime_throw("MHeap_AllocLocked - MSpan not free");
- if(s->npages < npage)
- runtime_throw("MHeap_AllocLocked - bad npages");
- runtime_MSpanList_Remove(s);
- s->state = MSpanInUse;
- mstats.heap_idle -= s->npages<<PageShift;
- mstats.heap_released -= s->npreleased<<PageShift;
- s->npreleased = 0;
-
- if(s->npages > npage) {
- // Trim extra and put it back in the heap.
- t = runtime_FixAlloc_Alloc(&h->spanalloc);
- mstats.mspan_inuse = h->spanalloc.inuse;
- mstats.mspan_sys = h->spanalloc.sys;
- runtime_MSpan_Init(t, s->start + npage, s->npages - npage);
- s->npages = npage;
- p = t->start;
- if(sizeof(void*) == 8)
- p -= ((uintptr)h->arena_start>>PageShift);
- if(p > 0)
- h->map[p-1] = s;
- h->map[p] = t;
- h->map[p+t->npages-1] = t;
- *(uintptr*)(t->start<<PageShift) = *(uintptr*)(s->start<<PageShift); // copy "needs zeroing" mark
- t->state = MSpanInUse;
- MHeap_FreeLocked(h, t);
- t->unusedsince = s->unusedsince; // preserve age
- }
- s->unusedsince = 0;
-
- // Record span info, because gc needs to be
- // able to map interior pointer to containing span.
- s->sizeclass = sizeclass;
- s->elemsize = (sizeclass==0 ? s->npages<<PageShift : (uintptr)runtime_class_to_size[sizeclass]);
- s->types.compression = MTypes_Empty;
- p = s->start;
- if(sizeof(void*) == 8)
- p -= ((uintptr)h->arena_start>>PageShift);
- for(n=0; n<npage; n++)
- h->map[p+n] = s;
- return s;
-}
-
-// Allocate a span of exactly npage pages from the list of large spans.
-static MSpan*
-MHeap_AllocLarge(MHeap *h, uintptr npage)
-{
- return BestFit(&h->large, npage, nil);
-}
-
-// Search list for smallest span with >= npage pages.
-// If there are multiple smallest spans, take the one
-// with the earliest starting address.
-static MSpan*
-BestFit(MSpan *list, uintptr npage, MSpan *best)
-{
- MSpan *s;
-
- for(s=list->next; s != list; s=s->next) {
- if(s->npages < npage)
- continue;
- if(best == nil
- || s->npages < best->npages
- || (s->npages == best->npages && s->start < best->start))
- best = s;
- }
- return best;
-}
-
-// Try to add at least npage pages of memory to the heap,
-// returning whether it worked.
-static bool
-MHeap_Grow(MHeap *h, uintptr npage)
-{
- uintptr ask;
- void *v;
- MSpan *s;
- PageID p;
-
- // Ask for a big chunk, to reduce the number of mappings
- // the operating system needs to track; also amortizes
- // the overhead of an operating system mapping.
- // Allocate a multiple of 64kB (16 pages).
- npage = (npage+15)&~15;
- ask = npage<<PageShift;
- if(ask < HeapAllocChunk)
- ask = HeapAllocChunk;
-
- v = runtime_MHeap_SysAlloc(h, ask);
- if(v == nil) {
- if(ask > (npage<<PageShift)) {
- ask = npage<<PageShift;
- v = runtime_MHeap_SysAlloc(h, ask);
- }
- if(v == nil) {
- runtime_printf("runtime: out of memory: cannot allocate %D-byte block (%D in use)\n", (uint64)ask, mstats.heap_sys);
- return false;
- }
- }
- mstats.heap_sys += ask;
-
- // Create a fake "in use" span and free it, so that the
- // right coalescing happens.
- s = runtime_FixAlloc_Alloc(&h->spanalloc);
- mstats.mspan_inuse = h->spanalloc.inuse;
- mstats.mspan_sys = h->spanalloc.sys;
- runtime_MSpan_Init(s, (uintptr)v>>PageShift, ask>>PageShift);
- p = s->start;
- if(sizeof(void*) == 8)
- p -= ((uintptr)h->arena_start>>PageShift);
- h->map[p] = s;
- h->map[p + s->npages - 1] = s;
- s->state = MSpanInUse;
- MHeap_FreeLocked(h, s);
- return true;
-}
-
-// Look up the span at the given address.
-// Address is guaranteed to be in map
-// and is guaranteed to be start or end of span.
-MSpan*
-runtime_MHeap_Lookup(MHeap *h, void *v)
-{
- uintptr p;
-
- p = (uintptr)v;
- if(sizeof(void*) == 8)
- p -= (uintptr)h->arena_start;
- return h->map[p >> PageShift];
-}
-
-// Look up the span at the given address.
-// Address is *not* guaranteed to be in map
-// and may be anywhere in the span.
-// Map entries for the middle of a span are only
-// valid for allocated spans. Free spans may have
-// other garbage in their middles, so we have to
-// check for that.
-MSpan*
-runtime_MHeap_LookupMaybe(MHeap *h, void *v)
-{
- MSpan *s;
- PageID p, q;
-
- if((byte*)v < h->arena_start || (byte*)v >= h->arena_used)
- return nil;
- p = (uintptr)v>>PageShift;
- q = p;
- if(sizeof(void*) == 8)
- q -= (uintptr)h->arena_start >> PageShift;
- s = h->map[q];
- if(s == nil || p < s->start || p - s->start >= s->npages)
- return nil;
- if(s->state != MSpanInUse)
- return nil;
- return s;
-}
-
-// Free the span back into the heap.
-void
-runtime_MHeap_Free(MHeap *h, MSpan *s, int32 acct)
-{
- runtime_lock(h);
- runtime_purgecachedstats(runtime_m()->mcache);
- mstats.heap_inuse -= s->npages<<PageShift;
- if(acct) {
- mstats.heap_alloc -= s->npages<<PageShift;
- mstats.heap_objects--;
- }
- MHeap_FreeLocked(h, s);
- runtime_unlock(h);
-}
-
-static void
-MHeap_FreeLocked(MHeap *h, MSpan *s)
-{
- uintptr *sp, *tp;
- MSpan *t;
- PageID p;
-
- if(s->types.sysalloc)
- runtime_settype_sysfree(s);
- s->types.compression = MTypes_Empty;
-
- if(s->state != MSpanInUse || s->ref != 0) {
- runtime_printf("MHeap_FreeLocked - span %p ptr %p state %d ref %d\n", s, s->start<<PageShift, s->state, s->ref);
- runtime_throw("MHeap_FreeLocked - invalid free");
- }
- mstats.heap_idle += s->npages<<PageShift;
- s->state = MSpanFree;
- runtime_MSpanList_Remove(s);
- sp = (uintptr*)(s->start<<PageShift);
- // Stamp newly unused spans. The scavenger will use that
- // info to potentially give back some pages to the OS.
- s->unusedsince = runtime_nanotime();
- s->npreleased = 0;
-
- // Coalesce with earlier, later spans.
- p = s->start;
- if(sizeof(void*) == 8)
- p -= (uintptr)h->arena_start >> PageShift;
- if(p > 0 && (t = h->map[p-1]) != nil && t->state != MSpanInUse) {
- tp = (uintptr*)(t->start<<PageShift);
- *tp |= *sp; // propagate "needs zeroing" mark
- s->start = t->start;
- s->npages += t->npages;
- s->npreleased = t->npreleased; // absorb released pages
- p -= t->npages;
- h->map[p] = s;
- runtime_MSpanList_Remove(t);
- t->state = MSpanDead;
- runtime_FixAlloc_Free(&h->spanalloc, t);
- mstats.mspan_inuse = h->spanalloc.inuse;
- mstats.mspan_sys = h->spanalloc.sys;
- }
- if(p+s->npages < nelem(h->map) && (t = h->map[p+s->npages]) != nil && t->state != MSpanInUse) {
- tp = (uintptr*)(t->start<<PageShift);
- *sp |= *tp; // propagate "needs zeroing" mark
- s->npages += t->npages;
- s->npreleased += t->npreleased;
- h->map[p + s->npages - 1] = s;
- runtime_MSpanList_Remove(t);
- t->state = MSpanDead;
- runtime_FixAlloc_Free(&h->spanalloc, t);
- mstats.mspan_inuse = h->spanalloc.inuse;
- mstats.mspan_sys = h->spanalloc.sys;
- }
-
- // Insert s into appropriate list.
- if(s->npages < nelem(h->free))
- runtime_MSpanList_Insert(&h->free[s->npages], s);
- else
- runtime_MSpanList_Insert(&h->large, s);
-}
-
-static void
-forcegchelper(void *vnote)
-{
- Note *note = (Note*)vnote;
-
- runtime_gc(1);
- runtime_notewakeup(note);
-}
-
-// Release (part of) unused memory to OS.
-// Goroutine created at startup.
-// Loop forever.
-void
-runtime_MHeap_Scavenger(void* dummy)
-{
- MHeap *h;
- MSpan *s, *list;
- uint64 tick, now, forcegc, limit;
- uint32 k, i;
- uintptr released, sumreleased;
- const byte *env;
- bool trace;
- Note note, *notep;
-
- USED(dummy);
-
- // If we go two minutes without a garbage collection, force one to run.
- forcegc = 2*60*1e9;
- // If a span goes unused for 5 minutes after a garbage collection,
- // we hand it back to the operating system.
- limit = 5*60*1e9;
- // Make wake-up period small enough for the sampling to be correct.
- if(forcegc < limit)
- tick = forcegc/2;
- else
- tick = limit/2;
-
- trace = false;
- env = runtime_getenv("GOGCTRACE");
- if(env != nil)
- trace = runtime_atoi(env) > 0;
-
- h = &runtime_mheap;
- for(k=0;; k++) {
- runtime_noteclear(&note);
- runtime_entersyscall();
- runtime_notetsleep(&note, tick);
- runtime_exitsyscall();
-
- runtime_lock(h);
- now = runtime_nanotime();
- if(now - mstats.last_gc > forcegc) {
- runtime_unlock(h);
- // The scavenger can not block other goroutines,
- // otherwise deadlock detector can fire spuriously.
- // GC blocks other goroutines via the runtime_worldsema.
- runtime_noteclear(&note);
- notep = &note;
- __go_go(forcegchelper, (void*)notep);
- runtime_entersyscall();
- runtime_notesleep(&note);
- runtime_exitsyscall();
- if(trace)
- runtime_printf("scvg%d: GC forced\n", k);
- runtime_lock(h);
- now = runtime_nanotime();
- }
- sumreleased = 0;
- for(i=0; i < nelem(h->free)+1; i++) {
- if(i < nelem(h->free))
- list = &h->free[i];
- else
- list = &h->large;
- if(runtime_MSpanList_IsEmpty(list))
- continue;
- for(s=list->next; s != list; s=s->next) {
- if((now - s->unusedsince) > limit) {
- released = (s->npages - s->npreleased) << PageShift;
- mstats.heap_released += released;
- sumreleased += released;
- s->npreleased = s->npages;
- runtime_SysUnused((void*)(s->start << PageShift), s->npages << PageShift);
- }
- }
- }
- runtime_unlock(h);
-
- if(trace) {
- if(sumreleased > 0)
- runtime_printf("scvg%d: %p MB released\n", k, sumreleased>>20);
- runtime_printf("scvg%d: inuse: %D, idle: %D, sys: %D, released: %D, consumed: %D (MB)\n",
- k, mstats.heap_inuse>>20, mstats.heap_idle>>20, mstats.heap_sys>>20,
- mstats.heap_released>>20, (mstats.heap_sys - mstats.heap_released)>>20);
- }
- }
-}
-
-// Initialize a new span with the given start and npages.
-void
-runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages)
-{
- span->next = nil;
- span->prev = nil;
- span->start = start;
- span->npages = npages;
- span->freelist = nil;
- span->ref = 0;
- span->sizeclass = 0;
- span->elemsize = 0;
- span->state = 0;
- span->unusedsince = 0;
- span->npreleased = 0;
- span->types.compression = MTypes_Empty;
-}
-
-// Initialize an empty doubly-linked list.
-void
-runtime_MSpanList_Init(MSpan *list)
-{
- list->state = MSpanListHead;
- list->next = list;
- list->prev = list;
-}
-
-void
-runtime_MSpanList_Remove(MSpan *span)
-{
- if(span->prev == nil && span->next == nil)
- return;
- span->prev->next = span->next;
- span->next->prev = span->prev;
- span->prev = nil;
- span->next = nil;
-}
-
-bool
-runtime_MSpanList_IsEmpty(MSpan *list)
-{
- return list->next == list;
-}
-
-void
-runtime_MSpanList_Insert(MSpan *list, MSpan *span)
-{
- if(span->next != nil || span->prev != nil) {
- runtime_printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
- runtime_throw("MSpanList_Insert");
- }
- span->next = list->next;
- span->prev = list;
- span->next->prev = span;
- span->prev->next = span;
-}
-
-
diff --git a/gcc-4.8.1/libgo/runtime/mprof.goc b/gcc-4.8.1/libgo/runtime/mprof.goc
deleted file mode 100644
index c1b09bea7..000000000
--- a/gcc-4.8.1/libgo/runtime/mprof.goc
+++ /dev/null
@@ -1,533 +0,0 @@
-// 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.
-
-// Malloc profiling.
-// Patterned after tcmalloc's algorithms; shorter code.
-
-package runtime
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "defs.h"
-#include "go-type.h"
-#include "go-string.h"
-
-// NOTE(rsc): Everything here could use cas if contention became an issue.
-static Lock proflock;
-
-enum { MProf, BProf }; // profile types
-
-// Per-call-stack profiling information.
-// Lookup by hashing call stack into a linked-list hash table.
-typedef struct Bucket Bucket;
-struct Bucket
-{
- Bucket *next; // next in hash list
- Bucket *allnext; // next in list of all mbuckets/bbuckets
- int32 typ;
- union
- {
- struct // typ == MProf
- {
- uintptr allocs;
- uintptr frees;
- uintptr alloc_bytes;
- uintptr free_bytes;
- uintptr recent_allocs; // since last gc
- uintptr recent_frees;
- uintptr recent_alloc_bytes;
- uintptr recent_free_bytes;
- };
- struct // typ == BProf
- {
- int64 count;
- int64 cycles;
- };
- };
- uintptr hash;
- uintptr nstk;
- Location stk[1];
-};
-enum {
- BuckHashSize = 179999,
-};
-static Bucket **buckhash;
-static Bucket *mbuckets; // memory profile buckets
-static Bucket *bbuckets; // blocking profile buckets
-static uintptr bucketmem;
-
-// Return the bucket for stk[0:nstk], allocating new bucket if needed.
-static Bucket*
-stkbucket(int32 typ, Location *stk, int32 nstk, bool alloc)
-{
- int32 i, j;
- uintptr h;
- Bucket *b;
-
- if(buckhash == nil) {
- buckhash = runtime_SysAlloc(BuckHashSize*sizeof buckhash[0]);
- mstats.buckhash_sys += BuckHashSize*sizeof buckhash[0];
- }
-
- // Hash stack.
- h = 0;
- for(i=0; i<nstk; i++) {
- h += stk[i].pc;
- h += h<<10;
- h ^= h>>6;
- }
- h += h<<3;
- h ^= h>>11;
-
- i = h%BuckHashSize;
- for(b = buckhash[i]; b; b=b->next) {
- if(b->typ == typ && b->hash == h && b->nstk == (uintptr)nstk) {
- for(j = 0; j < nstk; j++) {
- if(b->stk[j].pc != stk[j].pc ||
- b->stk[j].lineno != stk[j].lineno ||
- !__go_strings_equal(b->stk[j].filename, stk[j].filename))
- break;
- }
- if (j == nstk)
- return b;
- }
- }
-
- if(!alloc)
- return nil;
-
- b = runtime_mallocgc(sizeof *b + nstk*sizeof stk[0], FlagNoProfiling, 0, 1);
- bucketmem += sizeof *b + nstk*sizeof stk[0];
- runtime_memmove(b->stk, stk, nstk*sizeof stk[0]);
- b->typ = typ;
- b->hash = h;
- b->nstk = nstk;
- b->next = buckhash[i];
- buckhash[i] = b;
- if(typ == MProf) {
- b->allnext = mbuckets;
- mbuckets = b;
- } else {
- b->allnext = bbuckets;
- bbuckets = b;
- }
- return b;
-}
-
-// Record that a gc just happened: all the 'recent' statistics are now real.
-void
-runtime_MProf_GC(void)
-{
- Bucket *b;
-
- runtime_lock(&proflock);
- for(b=mbuckets; b; b=b->allnext) {
- b->allocs += b->recent_allocs;
- b->frees += b->recent_frees;
- b->alloc_bytes += b->recent_alloc_bytes;
- b->free_bytes += b->recent_free_bytes;
- b->recent_allocs = 0;
- b->recent_frees = 0;
- b->recent_alloc_bytes = 0;
- b->recent_free_bytes = 0;
- }
- runtime_unlock(&proflock);
-}
-
-// Map from pointer to Bucket* that allocated it.
-// Three levels:
-// Linked-list hash table for top N-AddrHashShift bits.
-// Array index for next AddrDenseBits bits.
-// Linked list for next AddrHashShift-AddrDenseBits bits.
-// This is more efficient than using a general map,
-// because of the typical clustering of the pointer keys.
-
-typedef struct AddrHash AddrHash;
-typedef struct AddrEntry AddrEntry;
-
-enum {
- AddrHashBits = 12, // good for 4GB of used address space
- AddrHashShift = 20, // each AddrHash knows about 1MB of address space
- AddrDenseBits = 8, // good for a profiling rate of 4096 bytes
-};
-
-struct AddrHash
-{
- AddrHash *next; // next in top-level hash table linked list
- uintptr addr; // addr>>20
- AddrEntry *dense[1<<AddrDenseBits];
-};
-
-struct AddrEntry
-{
- AddrEntry *next; // next in bottom-level linked list
- uint32 addr;
- Bucket *b;
-};
-
-static AddrHash *addrhash[1<<AddrHashBits];
-static AddrEntry *addrfree;
-static uintptr addrmem;
-
-// Multiplicative hash function:
-// hashMultiplier is the bottom 32 bits of int((sqrt(5)-1)/2 * (1<<32)).
-// This is a good multiplier as suggested in CLR, Knuth. The hash
-// value is taken to be the top AddrHashBits bits of the bottom 32 bits
-// of the multiplied value.
-enum {
- HashMultiplier = 2654435769U
-};
-
-// Set the bucket associated with addr to b.
-static void
-setaddrbucket(uintptr addr, Bucket *b)
-{
- int32 i;
- uint32 h;
- AddrHash *ah;
- AddrEntry *e;
-
- h = (uint32)((addr>>AddrHashShift)*HashMultiplier) >> (32-AddrHashBits);
- for(ah=addrhash[h]; ah; ah=ah->next)
- if(ah->addr == (addr>>AddrHashShift))
- goto found;
-
- ah = runtime_mallocgc(sizeof *ah, FlagNoProfiling, 0, 1);
- addrmem += sizeof *ah;
- ah->next = addrhash[h];
- ah->addr = addr>>AddrHashShift;
- addrhash[h] = ah;
-
-found:
- if((e = addrfree) == nil) {
- e = runtime_mallocgc(64*sizeof *e, FlagNoProfiling, 0, 0);
- addrmem += 64*sizeof *e;
- for(i=0; i+1<64; i++)
- e[i].next = &e[i+1];
- e[63].next = nil;
- }
- addrfree = e->next;
- e->addr = (uint32)~(addr & ((1<<AddrHashShift)-1));
- e->b = b;
- h = (addr>>(AddrHashShift-AddrDenseBits))&(nelem(ah->dense)-1); // entry in dense is top 8 bits of low 20.
- e->next = ah->dense[h];
- ah->dense[h] = e;
-}
-
-// Get the bucket associated with addr and clear the association.
-static Bucket*
-getaddrbucket(uintptr addr)
-{
- uint32 h;
- AddrHash *ah;
- AddrEntry *e, **l;
- Bucket *b;
-
- h = (uint32)((addr>>AddrHashShift)*HashMultiplier) >> (32-AddrHashBits);
- for(ah=addrhash[h]; ah; ah=ah->next)
- if(ah->addr == (addr>>AddrHashShift))
- goto found;
- return nil;
-
-found:
- h = (addr>>(AddrHashShift-AddrDenseBits))&(nelem(ah->dense)-1); // entry in dense is top 8 bits of low 20.
- for(l=&ah->dense[h]; (e=*l) != nil; l=&e->next) {
- if(e->addr == (uint32)~(addr & ((1<<AddrHashShift)-1))) {
- *l = e->next;
- b = e->b;
- e->next = addrfree;
- addrfree = e;
- return b;
- }
- }
- return nil;
-}
-
-// Called by malloc to record a profiled block.
-void
-runtime_MProf_Malloc(void *p, uintptr size)
-{
- M *m;
- int32 nstk;
- Location stk[32];
- Bucket *b;
-
- m = runtime_m();
- if(m->nomemprof > 0)
- return;
-
- m->nomemprof++;
- nstk = runtime_callers(1, stk, 32);
- runtime_lock(&proflock);
- b = stkbucket(MProf, stk, nstk, true);
- b->recent_allocs++;
- b->recent_alloc_bytes += size;
- setaddrbucket((uintptr)p, b);
- runtime_unlock(&proflock);
- m = runtime_m();
- m->nomemprof--;
-}
-
-// Called when freeing a profiled block.
-void
-runtime_MProf_Free(void *p, uintptr size)
-{
- M *m;
- Bucket *b;
-
- m = runtime_m();
- if(m->nomemprof > 0)
- return;
-
- m->nomemprof++;
- runtime_lock(&proflock);
- b = getaddrbucket((uintptr)p);
- if(b != nil) {
- b->recent_frees++;
- b->recent_free_bytes += size;
- }
- runtime_unlock(&proflock);
- m = runtime_m();
- m->nomemprof--;
-}
-
-int64 runtime_blockprofilerate; // in CPU ticks
-
-void runtime_SetBlockProfileRate(intgo) __asm__ (GOSYM_PREFIX "runtime.SetBlockProfileRate");
-
-void
-runtime_SetBlockProfileRate(intgo rate)
-{
- runtime_atomicstore64((uint64*)&runtime_blockprofilerate, rate * runtime_tickspersecond() / (1000*1000*1000));
-}
-
-void
-runtime_blockevent(int64 cycles, int32 skip)
-{
- int32 nstk;
- int64 rate;
- Location stk[32];
- Bucket *b;
-
- if(cycles <= 0)
- return;
- rate = runtime_atomicload64((uint64*)&runtime_blockprofilerate);
- if(rate <= 0 || (rate > cycles && runtime_fastrand1()%rate > cycles))
- return;
-
- nstk = runtime_callers(skip, stk, 32);
- runtime_lock(&proflock);
- b = stkbucket(BProf, stk, nstk, true);
- b->count++;
- b->cycles += cycles;
- runtime_unlock(&proflock);
-}
-
-// Go interface to profile data. (Declared in debug.go)
-
-// Must match MemProfileRecord in debug.go.
-typedef struct Record Record;
-struct Record {
- int64 alloc_bytes, free_bytes;
- int64 alloc_objects, free_objects;
- uintptr stk[32];
-};
-
-// Write b's data to r.
-static void
-record(Record *r, Bucket *b)
-{
- uint32 i;
-
- r->alloc_bytes = b->alloc_bytes;
- r->free_bytes = b->free_bytes;
- r->alloc_objects = b->allocs;
- r->free_objects = b->frees;
- for(i=0; i<b->nstk && i<nelem(r->stk); i++)
- r->stk[i] = b->stk[i].pc;
- for(; i<nelem(r->stk); i++)
- r->stk[i] = 0;
-}
-
-func MemProfile(p Slice, include_inuse_zero bool) (n int, ok bool) {
- Bucket *b;
- Record *r;
-
- runtime_lock(&proflock);
- n = 0;
- for(b=mbuckets; b; b=b->allnext)
- if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
- n++;
- ok = false;
- if(n <= p.__count) {
- ok = true;
- r = (Record*)p.__values;
- for(b=mbuckets; b; b=b->allnext)
- if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
- record(r++, b);
- }
- runtime_unlock(&proflock);
-}
-
-void
-runtime_MProf_Mark(void (*addroot)(Obj))
-{
- // buckhash is not allocated via mallocgc.
- addroot((Obj){(byte*)&mbuckets, sizeof mbuckets, 0});
- addroot((Obj){(byte*)&bbuckets, sizeof bbuckets, 0});
- addroot((Obj){(byte*)&addrhash, sizeof addrhash, 0});
- addroot((Obj){(byte*)&addrfree, sizeof addrfree, 0});
-}
-
-// Must match BlockProfileRecord in debug.go.
-typedef struct BRecord BRecord;
-struct BRecord {
- int64 count;
- int64 cycles;
- uintptr stk[32];
-};
-
-func BlockProfile(p Slice) (n int, ok bool) {
- Bucket *b;
- BRecord *r;
- int32 i;
-
- runtime_lock(&proflock);
- n = 0;
- for(b=bbuckets; b; b=b->allnext)
- n++;
- ok = false;
- if(n <= p.__count) {
- ok = true;
- r = (BRecord*)p.__values;
- for(b=bbuckets; b; b=b->allnext, r++) {
- r->count = b->count;
- r->cycles = b->cycles;
- for(i=0; (uintptr)i<b->nstk && (uintptr)i<nelem(r->stk); i++)
- r->stk[i] = b->stk[i].pc;
- for(; (uintptr)i<nelem(r->stk); i++)
- r->stk[i] = 0;
- }
- }
- runtime_unlock(&proflock);
-}
-
-// Must match StackRecord in debug.go.
-typedef struct TRecord TRecord;
-struct TRecord {
- uintptr stk[32];
-};
-
-func ThreadCreateProfile(p Slice) (n int, ok bool) {
- TRecord *r;
- M *first, *mp;
- int32 i;
-
- first = runtime_atomicloadp(&runtime_allm);
- n = 0;
- for(mp=first; mp; mp=mp->alllink)
- n++;
- ok = false;
- if(n <= p.__count) {
- ok = true;
- r = (TRecord*)p.__values;
- for(mp=first; mp; mp=mp->alllink) {
- for(i = 0; (uintptr)i < nelem(r->stk); i++) {
- r->stk[i] = mp->createstack[i].pc;
- }
- r++;
- }
- }
-}
-
-func Stack(b Slice, all bool) (n int) {
- byte *pc, *sp;
- bool enablegc;
-
- sp = runtime_getcallersp(&b);
- pc = runtime_getcallerpc(&b);
-
- if(all) {
- runtime_semacquire(&runtime_worldsema);
- runtime_m()->gcing = 1;
- runtime_stoptheworld();
- enablegc = mstats.enablegc;
- mstats.enablegc = false;
- }
-
- if(b.__count == 0)
- n = 0;
- else{
- G* g = runtime_g();
- g->writebuf = (byte*)b.__values;
- g->writenbuf = b.__count;
- USED(pc);
- USED(sp);
- runtime_goroutineheader(g);
- runtime_traceback();
- runtime_goroutinetrailer(g);
- if(all)
- runtime_tracebackothers(g);
- n = b.__count - g->writenbuf;
- g->writebuf = nil;
- g->writenbuf = 0;
- }
-
- if(all) {
- runtime_m()->gcing = 0;
- mstats.enablegc = enablegc;
- runtime_semrelease(&runtime_worldsema);
- runtime_starttheworld();
- }
-}
-
-static void
-saveg(G *gp, TRecord *r)
-{
- int32 n, i;
- Location locstk[nelem(r->stk)];
-
- if(gp == runtime_g()) {
- n = runtime_callers(0, locstk, nelem(r->stk));
- for(i = 0; i < n; i++)
- r->stk[i] = locstk[i].pc;
- }
- else {
- // FIXME: Not implemented.
- n = 0;
- }
- if((size_t)n < nelem(r->stk))
- r->stk[n] = 0;
-}
-
-func GoroutineProfile(b Slice) (n int, ok bool) {
- TRecord *r;
- G *gp;
-
- ok = false;
- n = runtime_gcount();
- if(n <= b.__count) {
- runtime_semacquire(&runtime_worldsema);
- runtime_m()->gcing = 1;
- runtime_stoptheworld();
-
- n = runtime_gcount();
- if(n <= b.__count) {
- G* g = runtime_g();
- ok = true;
- r = (TRecord*)b.__values;
- saveg(g, r++);
- for(gp = runtime_allg; gp != nil; gp = gp->alllink) {
- if(gp == g || gp->status == Gdead)
- continue;
- saveg(gp, r++);
- }
- }
-
- runtime_m()->gcing = 0;
- runtime_semrelease(&runtime_worldsema);
- runtime_starttheworld();
- }
-}
-
diff --git a/gcc-4.8.1/libgo/runtime/msize.c b/gcc-4.8.1/libgo/runtime/msize.c
deleted file mode 100644
index 3b5591c1b..000000000
--- a/gcc-4.8.1/libgo/runtime/msize.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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.
-
-// Malloc small size classes.
-//
-// See malloc.h for overview.
-//
-// The size classes are chosen so that rounding an allocation
-// request up to the next size class wastes at most 12.5% (1.125x).
-//
-// Each size class has its own page count that gets allocated
-// and chopped up when new objects of the size class are needed.
-// That page count is chosen so that chopping up the run of
-// pages into objects of the given size wastes at most 12.5% (1.125x)
-// of the memory. It is not necessary that the cutoff here be
-// the same as above.
-//
-// The two sources of waste multiply, so the worst possible case
-// for the above constraints would be that allocations of some
-// size might have a 26.6% (1.266x) overhead.
-// In practice, only one of the wastes comes into play for a
-// given size (sizes < 512 waste mainly on the round-up,
-// sizes > 512 waste mainly on the page chopping).
-//
-// TODO(rsc): Compute max waste for any given size.
-
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-
-int32 runtime_class_to_size[NumSizeClasses];
-int32 runtime_class_to_allocnpages[NumSizeClasses];
-int32 runtime_class_to_transfercount[NumSizeClasses];
-
-// The SizeToClass lookup is implemented using two arrays,
-// one mapping sizes <= 1024 to their class and one mapping
-// sizes >= 1024 and <= MaxSmallSize to their class.
-// All objects are 8-aligned, so the first array is indexed by
-// the size divided by 8 (rounded up). Objects >= 1024 bytes
-// are 128-aligned, so the second array is indexed by the
-// size divided by 128 (rounded up). The arrays are filled in
-// by InitSizes.
-
-static int32 size_to_class8[1024/8 + 1];
-static int32 size_to_class128[(MaxSmallSize-1024)/128 + 1];
-
-int32
-runtime_SizeToClass(int32 size)
-{
- if(size > MaxSmallSize)
- runtime_throw("SizeToClass - invalid size");
- if(size > 1024-8)
- return size_to_class128[(size-1024+127) >> 7];
- return size_to_class8[(size+7)>>3];
-}
-
-void
-runtime_InitSizes(void)
-{
- int32 align, sizeclass, size, nextsize, n;
- uint32 i;
- uintptr allocsize, npages;
-
- // Initialize the runtime_class_to_size table (and choose class sizes in the process).
- runtime_class_to_size[0] = 0;
- sizeclass = 1; // 0 means no class
- align = 8;
- for(size = align; size <= MaxSmallSize; size += align) {
- if((size&(size-1)) == 0) { // bump alignment once in a while
- if(size >= 2048)
- align = 256;
- else if(size >= 128)
- align = size / 8;
- else if(size >= 16)
- align = 16; // required for x86 SSE instructions, if we want to use them
- }
- if((align&(align-1)) != 0)
- runtime_throw("InitSizes - bug");
-
- // Make the allocnpages big enough that
- // the leftover is less than 1/8 of the total,
- // so wasted space is at most 12.5%.
- allocsize = PageSize;
- while(allocsize%size > allocsize/8)
- allocsize += PageSize;
- npages = allocsize >> PageShift;
-
- // If the previous sizeclass chose the same
- // allocation size and fit the same number of
- // objects into the page, we might as well
- // use just this size instead of having two
- // different sizes.
- if(sizeclass > 1
- && (int32)npages == runtime_class_to_allocnpages[sizeclass-1]
- && allocsize/size == allocsize/runtime_class_to_size[sizeclass-1]) {
- runtime_class_to_size[sizeclass-1] = size;
- continue;
- }
-
- runtime_class_to_allocnpages[sizeclass] = npages;
- runtime_class_to_size[sizeclass] = size;
- sizeclass++;
- }
- if(sizeclass != NumSizeClasses) {
- runtime_printf("sizeclass=%d NumSizeClasses=%d\n", sizeclass, NumSizeClasses);
- runtime_throw("InitSizes - bad NumSizeClasses");
- }
-
- // Initialize the size_to_class tables.
- nextsize = 0;
- for (sizeclass = 1; sizeclass < NumSizeClasses; sizeclass++) {
- for(; nextsize < 1024 && nextsize <= runtime_class_to_size[sizeclass]; nextsize+=8)
- size_to_class8[nextsize/8] = sizeclass;
- if(nextsize >= 1024)
- for(; nextsize <= runtime_class_to_size[sizeclass]; nextsize += 128)
- size_to_class128[(nextsize-1024)/128] = sizeclass;
- }
-
- // Double-check SizeToClass.
- if(0) {
- for(n=0; n < MaxSmallSize; n++) {
- sizeclass = runtime_SizeToClass(n);
- if(sizeclass < 1 || sizeclass >= NumSizeClasses || runtime_class_to_size[sizeclass] < n) {
- runtime_printf("size=%d sizeclass=%d runtime_class_to_size=%d\n", n, sizeclass, runtime_class_to_size[sizeclass]);
- runtime_printf("incorrect SizeToClass");
- goto dump;
- }
- if(sizeclass > 1 && runtime_class_to_size[sizeclass-1] >= n) {
- runtime_printf("size=%d sizeclass=%d runtime_class_to_size=%d\n", n, sizeclass, runtime_class_to_size[sizeclass]);
- runtime_printf("SizeToClass too big");
- goto dump;
- }
- }
- }
-
- // Copy out for statistics table.
- for(i=0; i<nelem(runtime_class_to_size); i++)
- mstats.by_size[i].size = runtime_class_to_size[i];
-
- // Initialize the runtime_class_to_transfercount table.
- for(sizeclass = 1; sizeclass < NumSizeClasses; sizeclass++) {
- n = 64*1024 / runtime_class_to_size[sizeclass];
- if(n < 2)
- n = 2;
- if(n > 32)
- n = 32;
- runtime_class_to_transfercount[sizeclass] = n;
- }
- return;
-
-dump:
- if(1){
- runtime_printf("NumSizeClasses=%d\n", NumSizeClasses);
- runtime_printf("runtime_class_to_size:");
- for(sizeclass=0; sizeclass<NumSizeClasses; sizeclass++)
- runtime_printf(" %d", runtime_class_to_size[sizeclass]);
- runtime_printf("\n\n");
- runtime_printf("size_to_class8:");
- for(i=0; i<nelem(size_to_class8); i++)
- runtime_printf(" %d=>%d(%d)\n", i*8, size_to_class8[i], runtime_class_to_size[size_to_class8[i]]);
- runtime_printf("\n");
- runtime_printf("size_to_class128:");
- for(i=0; i<nelem(size_to_class128); i++)
- runtime_printf(" %d=>%d(%d)\n", i*128, size_to_class128[i], runtime_class_to_size[size_to_class128[i]]);
- runtime_printf("\n");
- }
- runtime_throw("InitSizes failed");
-}
diff --git a/gcc-4.8.1/libgo/runtime/panic.c b/gcc-4.8.1/libgo/runtime/panic.c
deleted file mode 100644
index 7b9b578e4..000000000
--- a/gcc-4.8.1/libgo/runtime/panic.c
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2012 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.
-
-#include "runtime.h"
-#include "go-defer.h"
-#include "go-panic.h"
-
-// Code related to defer, panic and recover.
-
-uint32 runtime_panicking;
-static Lock paniclk;
-
-// Run all deferred functions for the current goroutine.
-static void
-rundefer(void)
-{
- G *g;
- Defer *d;
-
- g = runtime_g();
- while((d = g->defer) != nil) {
- void (*pfn)(void*);
-
- g->defer = d->__next;
- pfn = d->__pfn;
- d->__pfn = nil;
- if (pfn != nil)
- (*pfn)(d->__arg);
- runtime_free(d);
- }
-}
-
-void
-runtime_startpanic(void)
-{
- M *m;
-
- m = runtime_m();
- if(m->dying) {
- runtime_printf("panic during panic\n");
- runtime_exit(3);
- }
- m->dying = 1;
- runtime_xadd(&runtime_panicking, 1);
- runtime_lock(&paniclk);
-}
-
-void
-runtime_dopanic(int32 unused __attribute__ ((unused)))
-{
- G *g;
- static bool didothers;
-
- g = runtime_g();
- if(g->sig != 0)
- runtime_printf("[signal %x code=%p addr=%p]\n",
- g->sig, (void*)g->sigcode0, (void*)g->sigcode1);
-
- if(runtime_gotraceback()){
- if(g != runtime_m()->g0) {
- runtime_printf("\n");
- runtime_goroutineheader(g);
- runtime_traceback();
- runtime_goroutinetrailer(g);
- }
- if(!didothers) {
- didothers = true;
- runtime_tracebackothers(g);
- }
- }
- runtime_unlock(&paniclk);
- if(runtime_xadd(&runtime_panicking, -1) != 0) {
- // Some other m is panicking too.
- // Let it print what it needs to print.
- // Wait forever without chewing up cpu.
- // It will exit when it's done.
- static Lock deadlock;
- runtime_lock(&deadlock);
- runtime_lock(&deadlock);
- }
-
- runtime_exit(2);
-}
-
-void
-runtime_throw(const char *s)
-{
- M *mp;
-
- mp = runtime_m();
- if(mp->throwing == 0)
- mp->throwing = 1;
- runtime_startpanic();
- runtime_printf("fatal error: %s\n", s);
- runtime_dopanic(0);
- *(int32*)0 = 0; // not reached
- runtime_exit(1); // even more not reached
-}
-
-void
-runtime_panicstring(const char *s)
-{
- Eface err;
-
- if(runtime_m()->gcing) {
- runtime_printf("panic: %s\n", s);
- runtime_throw("panic during gc");
- }
- runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
- runtime_panic(err);
-}
-
-void runtime_Goexit (void) __asm__ (GOSYM_PREFIX "runtime.Goexit");
-
-void
-runtime_Goexit(void)
-{
- rundefer();
- runtime_goexit();
-}
diff --git a/gcc-4.8.1/libgo/runtime/parfor.c b/gcc-4.8.1/libgo/runtime/parfor.c
deleted file mode 100644
index 591b968c0..000000000
--- a/gcc-4.8.1/libgo/runtime/parfor.c
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2012 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.
-
-// Parallel for algorithm.
-
-#include "runtime.h"
-#include "arch.h"
-
-struct ParForThread
-{
- // the thread's iteration space [32lsb, 32msb)
- uint64 pos;
- // stats
- uint64 nsteal;
- uint64 nstealcnt;
- uint64 nprocyield;
- uint64 nosyield;
- uint64 nsleep;
- byte pad[CacheLineSize];
-};
-
-ParFor*
-runtime_parforalloc(uint32 nthrmax)
-{
- ParFor *desc;
-
- // The ParFor object is followed by CacheLineSize padding
- // and then nthrmax ParForThread.
- desc = (ParFor*)runtime_malloc(sizeof(ParFor) + CacheLineSize + nthrmax * sizeof(ParForThread));
- desc->thr = (ParForThread*)((byte*)(desc+1) + CacheLineSize);
- desc->nthrmax = nthrmax;
- return desc;
-}
-
-// For testing from Go
-// func parforalloc2(nthrmax uint32) *ParFor
-
-ParFor *runtime_parforalloc2(uint32)
- __asm__ (GOSYM_PREFIX "runtime.parforalloc2");
-
-ParFor *
-runtime_parforalloc2(uint32 nthrmax)
-{
- return runtime_parforalloc(nthrmax);
-}
-
-void
-runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32))
-{
- uint32 i, begin, end;
-
- if(desc == nil || nthr == 0 || nthr > desc->nthrmax || body == nil) {
- runtime_printf("desc=%p nthr=%d count=%d body=%p\n", desc, nthr, n, body);
- runtime_throw("parfor: invalid args");
- }
-
- desc->body = body;
- desc->done = 0;
- desc->nthr = nthr;
- desc->thrseq = 0;
- desc->cnt = n;
- desc->ctx = ctx;
- desc->wait = wait;
- desc->nsteal = 0;
- desc->nstealcnt = 0;
- desc->nprocyield = 0;
- desc->nosyield = 0;
- desc->nsleep = 0;
- for(i=0; i<nthr; i++) {
- begin = (uint64)n*i / nthr;
- end = (uint64)n*(i+1) / nthr;
- desc->thr[i].pos = (uint64)begin | (((uint64)end)<<32);
- }
-}
-
-// For testing from Go
-// func parforsetup2(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*ParFor, uint32))
-
-void runtime_parforsetup2(ParFor *, uint32, uint32, void *, bool, void *)
- __asm__ (GOSYM_PREFIX "runtime.parforsetup2");
-
-void
-runtime_parforsetup2(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void *body)
-{
- runtime_parforsetup(desc, nthr, n, ctx, wait, (void(*)(ParFor*, uint32))body);
-}
-
-void
-runtime_parfordo(ParFor *desc)
-{
- ParForThread *me;
- uint32 tid, begin, end, begin2, try, victim, i;
- uint64 *mypos, *victimpos, pos, newpos;
- void (*body)(ParFor*, uint32);
- bool idle;
-
- // Obtain 0-based thread index.
- tid = runtime_xadd(&desc->thrseq, 1) - 1;
- if(tid >= desc->nthr) {
- runtime_printf("tid=%d nthr=%d\n", tid, desc->nthr);
- runtime_throw("parfor: invalid tid");
- }
-
- // If single-threaded, just execute the for serially.
- if(desc->nthr==1) {
- for(i=0; i<desc->cnt; i++)
- desc->body(desc, i);
- return;
- }
-
- body = desc->body;
- me = &desc->thr[tid];
- mypos = &me->pos;
- for(;;) {
- for(;;) {
- // While there is local work,
- // bump low index and execute the iteration.
- pos = runtime_xadd64(mypos, 1);
- begin = (uint32)pos-1;
- end = (uint32)(pos>>32);
- if(begin < end) {
- body(desc, begin);
- continue;
- }
- break;
- }
-
- // Out of work, need to steal something.
- idle = false;
- for(try=0;; try++) {
- // If we don't see any work for long enough,
- // increment the done counter...
- if(try > desc->nthr*4 && !idle) {
- idle = true;
- runtime_xadd(&desc->done, 1);
- }
- // ...if all threads have incremented the counter,
- // we are done.
- if(desc->done + !idle == desc->nthr) {
- if(!idle)
- runtime_xadd(&desc->done, 1);
- goto exit;
- }
- // Choose a random victim for stealing.
- victim = runtime_fastrand1() % (desc->nthr-1);
- if(victim >= tid)
- victim++;
- victimpos = &desc->thr[victim].pos;
- pos = runtime_atomicload64(victimpos);
- for(;;) {
- // See if it has any work.
- begin = (uint32)pos;
- end = (uint32)(pos>>32);
- if(begin >= end-1) {
- begin = end = 0;
- break;
- }
- if(idle) {
- runtime_xadd(&desc->done, -1);
- idle = false;
- }
- begin2 = begin + (end-begin)/2;
- newpos = (uint64)begin | (uint64)begin2<<32;
- if(runtime_cas64(victimpos, &pos, newpos)) {
- begin = begin2;
- break;
- }
- }
- if(begin < end) {
- // Has successfully stolen some work.
- if(idle)
- runtime_throw("parfor: should not be idle");
- runtime_atomicstore64(mypos, (uint64)begin | (uint64)end<<32);
- me->nsteal++;
- me->nstealcnt += end-begin;
- break;
- }
- // Backoff.
- if(try < desc->nthr) {
- // nothing
- } else if (try < 4*desc->nthr) {
- me->nprocyield++;
- runtime_procyield(20);
- // If a caller asked not to wait for the others, exit now
- // (assume that most work is already done at this point).
- } else if (!desc->wait) {
- if(!idle)
- runtime_xadd(&desc->done, 1);
- goto exit;
- } else if (try < 6*desc->nthr) {
- me->nosyield++;
- runtime_osyield();
- } else {
- me->nsleep++;
- runtime_usleep(1);
- }
- }
- }
-exit:
- runtime_xadd64(&desc->nsteal, me->nsteal);
- runtime_xadd64(&desc->nstealcnt, me->nstealcnt);
- runtime_xadd64(&desc->nprocyield, me->nprocyield);
- runtime_xadd64(&desc->nosyield, me->nosyield);
- runtime_xadd64(&desc->nsleep, me->nsleep);
- me->nsteal = 0;
- me->nstealcnt = 0;
- me->nprocyield = 0;
- me->nosyield = 0;
- me->nsleep = 0;
-}
-
-// For testing from Go
-// func parforiters(desc *ParFor, tid uintptr) (uintptr, uintptr)
-
-struct parforiters_ret {
- uintptr start;
- uintptr end;
-};
-
-struct parforiters_ret runtime_parforiters(ParFor *, uintptr)
- __asm__ (GOSYM_PREFIX "runtime.parforiters");
-
-struct parforiters_ret
-runtime_parforiters(ParFor *desc, uintptr tid)
-{
- struct parforiters_ret ret;
-
- ret.start = (uint32)desc->thr[tid].pos;
- ret.end = (uint32)(desc->thr[tid].pos>>32);
- return ret;
-}
diff --git a/gcc-4.8.1/libgo/runtime/print.c b/gcc-4.8.1/libgo/runtime/print.c
deleted file mode 100644
index 9e0c45b0d..000000000
--- a/gcc-4.8.1/libgo/runtime/print.c
+++ /dev/null
@@ -1,315 +0,0 @@
-// 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.
-
-#include <stdarg.h>
-#include "runtime.h"
-#include "array.h"
-
-//static Lock debuglock;
-
-static void go_vprintf(const char*, va_list);
-
-// write to goroutine-local buffer if diverting output,
-// or else standard error.
-static void
-gwrite(const void *v, int32 n)
-{
- G* g = runtime_g();
-
- if(g == nil || g->writebuf == nil) {
- // Avoid -D_FORTIFY_SOURCE problems.
- int rv __attribute__((unused));
-
- rv = runtime_write(2, v, n);
- return;
- }
-
- if(g->writenbuf == 0)
- return;
-
- if(n > g->writenbuf)
- n = g->writenbuf;
- runtime_memmove(g->writebuf, v, n);
- g->writebuf += n;
- g->writenbuf -= n;
-}
-
-void
-runtime_dump(byte *p, int32 n)
-{
- int32 i;
-
- for(i=0; i<n; i++) {
- runtime_printpointer((byte*)(uintptr)(p[i]>>4));
- runtime_printpointer((byte*)(uintptr)(p[i]&0xf));
- if((i&15) == 15)
- runtime_prints("\n");
- else
- runtime_prints(" ");
- }
- if(n & 15)
- runtime_prints("\n");
-}
-
-void
-runtime_prints(const char *s)
-{
- gwrite(s, runtime_findnull((const byte*)s));
-}
-
-void
-runtime_printf(const char *s, ...)
-{
- va_list va;
-
- va_start(va, s);
- go_vprintf(s, va);
- va_end(va);
-}
-
-// Very simple printf. Only for debugging prints.
-// Do not add to this without checking with Rob.
-static void
-go_vprintf(const char *s, va_list va)
-{
- const char *p, *lp;
-
- //runtime_lock(&debuglock);
-
- lp = p = s;
- for(; *p; p++) {
- if(*p != '%')
- continue;
- if(p > lp)
- gwrite(lp, p-lp);
- p++;
- switch(*p) {
- case 'a':
- runtime_printslice(va_arg(va, Slice));
- break;
- case 'd':
- runtime_printint(va_arg(va, int32));
- break;
- case 'D':
- runtime_printint(va_arg(va, int64));
- break;
- case 'e':
- runtime_printeface(va_arg(va, Eface));
- break;
- case 'f':
- runtime_printfloat(va_arg(va, float64));
- break;
- case 'C':
- runtime_printcomplex(va_arg(va, __complex double));
- break;
- case 'i':
- runtime_printiface(va_arg(va, Iface));
- break;
- case 'p':
- runtime_printpointer(va_arg(va, void*));
- break;
- case 's':
- runtime_prints(va_arg(va, char*));
- break;
- case 'S':
- runtime_printstring(va_arg(va, String));
- break;
- case 't':
- runtime_printbool(va_arg(va, int));
- break;
- case 'U':
- runtime_printuint(va_arg(va, uint64));
- break;
- case 'x':
- runtime_printhex(va_arg(va, uint32));
- break;
- case 'X':
- runtime_printhex(va_arg(va, uint64));
- break;
- }
- lp = p+1;
- }
- if(p > lp)
- gwrite(lp, p-lp);
-
- //runtime_unlock(&debuglock);
-}
-
-void
-runtime_printpc(void *p __attribute__ ((unused)))
-{
- runtime_prints("PC=");
- runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p));
-}
-
-void
-runtime_printbool(_Bool v)
-{
- if(v) {
- gwrite("true", 4);
- return;
- }
- gwrite("false", 5);
-}
-
-void
-runtime_printfloat(double v)
-{
- byte buf[20];
- int32 e, s, i, n;
- float64 h;
-
- if(ISNAN(v)) {
- gwrite("NaN", 3);
- return;
- }
- i = __builtin_isinf_sign(v);
- if(i > 0) {
- gwrite("+Inf", 4);
- return;
- }
- if(i < 0) {
- gwrite("-Inf", 4);
- return;
- }
-
- n = 7; // digits printed
- e = 0; // exp
- s = 0; // sign
- if(v != 0) {
- // sign
- if(v < 0) {
- v = -v;
- s = 1;
- }
-
- // normalize
- while(v >= 10) {
- e++;
- v /= 10;
- }
- while(v < 1) {
- e--;
- v *= 10;
- }
-
- // round
- h = 5;
- for(i=0; i<n; i++)
- h /= 10;
-
- v += h;
- if(v >= 10) {
- e++;
- v /= 10;
- }
- }
-
- // format +d.dddd+edd
- buf[0] = '+';
- if(s)
- buf[0] = '-';
- for(i=0; i<n; i++) {
- s = v;
- buf[i+2] = s+'0';
- v -= s;
- v *= 10.;
- }
- buf[1] = buf[2];
- buf[2] = '.';
-
- buf[n+2] = 'e';
- buf[n+3] = '+';
- if(e < 0) {
- e = -e;
- buf[n+3] = '-';
- }
-
- buf[n+4] = (e/100) + '0';
- buf[n+5] = (e/10)%10 + '0';
- buf[n+6] = (e%10) + '0';
- gwrite(buf, n+7);
-}
-
-void
-runtime_printcomplex(__complex double v)
-{
- gwrite("(", 1);
- runtime_printfloat(__builtin_creal(v));
- runtime_printfloat(__builtin_cimag(v));
- gwrite("i)", 2);
-}
-
-void
-runtime_printuint(uint64 v)
-{
- byte buf[100];
- int32 i;
-
- for(i=nelem(buf)-1; i>0; i--) {
- buf[i] = v%10 + '0';
- if(v < 10)
- break;
- v = v/10;
- }
- gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime_printint(int64 v)
-{
- if(v < 0) {
- gwrite("-", 1);
- v = -v;
- }
- runtime_printuint(v);
-}
-
-void
-runtime_printhex(uint64 v)
-{
- static const char *dig = "0123456789abcdef";
- byte buf[100];
- int32 i;
-
- i=nelem(buf);
- for(; v>0; v/=16)
- buf[--i] = dig[v%16];
- if(i == nelem(buf))
- buf[--i] = '0';
- buf[--i] = 'x';
- buf[--i] = '0';
- gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime_printpointer(void *p)
-{
- runtime_printhex((uint64)(uintptr)p);
-}
-
-void
-runtime_printstring(String v)
-{
- // extern uint32 runtime_maxstring;
-
- // if(v.len > runtime_maxstring) {
- // gwrite("[string too long]", 17);
- // return;
- // }
- if(v.len > 0)
- gwrite(v.str, v.len);
-}
-
-void
-__go_print_space(void)
-{
- gwrite(" ", 1);
-}
-
-void
-__go_print_nl(void)
-{
- gwrite("\n", 1);
-}
diff --git a/gcc-4.8.1/libgo/runtime/proc.c b/gcc-4.8.1/libgo/runtime/proc.c
deleted file mode 100644
index 9b563a509..000000000
--- a/gcc-4.8.1/libgo/runtime/proc.c
+++ /dev/null
@@ -1,1815 +0,0 @@
-// 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.
-
-#include <limits.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include "config.h"
-
-#ifdef HAVE_DL_ITERATE_PHDR
-#include <link.h>
-#endif
-
-#include "runtime.h"
-#include "arch.h"
-#include "defs.h"
-#include "malloc.h"
-#include "race.h"
-#include "go-type.h"
-#include "go-defer.h"
-
-#ifdef USING_SPLIT_STACK
-
-/* FIXME: These are not declared anywhere. */
-
-extern void __splitstack_getcontext(void *context[10]);
-
-extern void __splitstack_setcontext(void *context[10]);
-
-extern void *__splitstack_makecontext(size_t, void *context[10], size_t *);
-
-extern void * __splitstack_resetcontext(void *context[10], size_t *);
-
-extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
- void **);
-
-extern void __splitstack_block_signals (int *, int *);
-
-extern void __splitstack_block_signals_context (void *context[10], int *,
- int *);
-
-#endif
-
-#ifndef PTHREAD_STACK_MIN
-# define PTHREAD_STACK_MIN 8192
-#endif
-
-#if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
-# define StackMin PTHREAD_STACK_MIN
-#else
-# define StackMin 2 * 1024 * 1024
-#endif
-
-uintptr runtime_stacks_sys;
-
-static void schedule(G*);
-
-static void gtraceback(G*);
-
-typedef struct Sched Sched;
-
-M runtime_m0;
-G runtime_g0; // idle goroutine for m0
-
-#ifdef __rtems__
-#define __thread
-#endif
-
-static __thread G *g;
-static __thread M *m;
-
-#ifndef SETCONTEXT_CLOBBERS_TLS
-
-static inline void
-initcontext(void)
-{
-}
-
-static inline void
-fixcontext(ucontext_t *c __attribute__ ((unused)))
-{
-}
-
-#else
-
-# if defined(__x86_64__) && defined(__sun__)
-
-// x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs
-// register to that of the thread which called getcontext. The effect
-// is that the address of all __thread variables changes. This bug
-// also affects pthread_self() and pthread_getspecific. We work
-// around it by clobbering the context field directly to keep %fs the
-// same.
-
-static __thread greg_t fs;
-
-static inline void
-initcontext(void)
-{
- ucontext_t c;
-
- getcontext(&c);
- fs = c.uc_mcontext.gregs[REG_FSBASE];
-}
-
-static inline void
-fixcontext(ucontext_t* c)
-{
- c->uc_mcontext.gregs[REG_FSBASE] = fs;
-}
-
-# elif defined(__NetBSD__)
-
-// NetBSD has a bug: setcontext clobbers tlsbase, we need to save
-// and restore it ourselves.
-
-static __thread __greg_t tlsbase;
-
-static inline void
-initcontext(void)
-{
- ucontext_t c;
-
- getcontext(&c);
- tlsbase = c.uc_mcontext._mc_tlsbase;
-}
-
-static inline void
-fixcontext(ucontext_t* c)
-{
- c->uc_mcontext._mc_tlsbase = tlsbase;
-}
-
-# else
-
-# error unknown case for SETCONTEXT_CLOBBERS_TLS
-
-# endif
-
-#endif
-
-// We can not always refer to the TLS variables directly. The
-// compiler will call tls_get_addr to get the address of the variable,
-// and it may hold it in a register across a call to schedule. When
-// we get back from the call we may be running in a different thread,
-// in which case the register now points to the TLS variable for a
-// different thread. We use non-inlinable functions to avoid this
-// when necessary.
-
-G* runtime_g(void) __attribute__ ((noinline, no_split_stack));
-
-G*
-runtime_g(void)
-{
- return g;
-}
-
-M* runtime_m(void) __attribute__ ((noinline, no_split_stack));
-
-M*
-runtime_m(void)
-{
- return m;
-}
-
-int32 runtime_gcwaiting;
-
-G* runtime_allg;
-G* runtime_lastg;
-M* runtime_allm;
-
-int8* runtime_goos;
-int32 runtime_ncpu;
-
-// The static TLS size. See runtime_newm.
-static int tlssize;
-
-#ifdef HAVE_DL_ITERATE_PHDR
-
-// Called via dl_iterate_phdr.
-
-static int
-addtls(struct dl_phdr_info* info, size_t size __attribute__ ((unused)), void *data)
-{
- size_t *total = (size_t *)data;
- unsigned int i;
-
- for(i = 0; i < info->dlpi_phnum; ++i) {
- if(info->dlpi_phdr[i].p_type == PT_TLS)
- *total += info->dlpi_phdr[i].p_memsz;
- }
- return 0;
-}
-
-// Set the total TLS size.
-
-static void
-inittlssize()
-{
- size_t total = 0;
-
- dl_iterate_phdr(addtls, (void *)&total);
- tlssize = total;
-}
-
-#else
-
-static void
-inittlssize()
-{
-}
-
-#endif
-
-// Go scheduler
-//
-// The go scheduler's job is to match ready-to-run goroutines (`g's)
-// with waiting-for-work schedulers (`m's). If there are ready g's
-// and no waiting m's, ready() will start a new m running in a new
-// OS thread, so that all ready g's can run simultaneously, up to a limit.
-// For now, m's never go away.
-//
-// By default, Go keeps only one kernel thread (m) running user code
-// at a single time; other threads may be blocked in the operating system.
-// Setting the environment variable $GOMAXPROCS or calling
-// runtime.GOMAXPROCS() will change the number of user threads
-// allowed to execute simultaneously. $GOMAXPROCS is thus an
-// approximation of the maximum number of cores to use.
-//
-// Even a program that can run without deadlock in a single process
-// might use more m's if given the chance. For example, the prime
-// sieve will use as many m's as there are primes (up to runtime_sched.mmax),
-// allowing different stages of the pipeline to execute in parallel.
-// We could revisit this choice, only kicking off new m's for blocking
-// system calls, but that would limit the amount of parallel computation
-// that go would try to do.
-//
-// In general, one could imagine all sorts of refinements to the
-// scheduler, but the goal now is just to get something working on
-// Linux and OS X.
-
-struct Sched {
- Lock;
-
- G *gfree; // available g's (status == Gdead)
- int64 goidgen;
-
- G *ghead; // g's waiting to run
- G *gtail;
- int32 gwait; // number of g's waiting to run
- int32 gcount; // number of g's that are alive
- int32 grunning; // number of g's running on cpu or in syscall
-
- M *mhead; // m's waiting for work
- int32 mwait; // number of m's waiting for work
- int32 mcount; // number of m's that have been created
-
- volatile uint32 atomic; // atomic scheduling word (see below)
-
- int32 profilehz; // cpu profiling rate
-
- bool init; // running initialization
- bool lockmain; // init called runtime.LockOSThread
-
- Note stopped; // one g can set waitstop and wait here for m's to stop
-};
-
-// The atomic word in sched is an atomic uint32 that
-// holds these fields.
-//
-// [15 bits] mcpu number of m's executing on cpu
-// [15 bits] mcpumax max number of m's allowed on cpu
-// [1 bit] waitstop some g is waiting on stopped
-// [1 bit] gwaiting gwait != 0
-//
-// These fields are the information needed by entersyscall
-// and exitsyscall to decide whether to coordinate with the
-// scheduler. Packing them into a single machine word lets
-// them use a fast path with a single atomic read/write and
-// no lock/unlock. This greatly reduces contention in
-// syscall- or cgo-heavy multithreaded programs.
-//
-// Except for entersyscall and exitsyscall, the manipulations
-// to these fields only happen while holding the schedlock,
-// so the routines holding schedlock only need to worry about
-// what entersyscall and exitsyscall do, not the other routines
-// (which also use the schedlock).
-//
-// In particular, entersyscall and exitsyscall only read mcpumax,
-// waitstop, and gwaiting. They never write them. Thus, writes to those
-// fields can be done (holding schedlock) without fear of write conflicts.
-// There may still be logic conflicts: for example, the set of waitstop must
-// be conditioned on mcpu >= mcpumax or else the wait may be a
-// spurious sleep. The Promela model in proc.p verifies these accesses.
-enum {
- mcpuWidth = 15,
- mcpuMask = (1<<mcpuWidth) - 1,
- mcpuShift = 0,
- mcpumaxShift = mcpuShift + mcpuWidth,
- waitstopShift = mcpumaxShift + mcpuWidth,
- gwaitingShift = waitstopShift+1,
-
- // The max value of GOMAXPROCS is constrained
- // by the max value we can store in the bit fields
- // of the atomic word. Reserve a few high values
- // so that we can detect accidental decrement
- // beyond zero.
- maxgomaxprocs = mcpuMask - 10,
-};
-
-#define atomic_mcpu(v) (((v)>>mcpuShift)&mcpuMask)
-#define atomic_mcpumax(v) (((v)>>mcpumaxShift)&mcpuMask)
-#define atomic_waitstop(v) (((v)>>waitstopShift)&1)
-#define atomic_gwaiting(v) (((v)>>gwaitingShift)&1)
-
-Sched runtime_sched;
-int32 runtime_gomaxprocs;
-bool runtime_singleproc;
-
-static bool canaddmcpu(void);
-
-// An m that is waiting for notewakeup(&m->havenextg). This may
-// only be accessed while the scheduler lock is held. This is used to
-// minimize the number of times we call notewakeup while the scheduler
-// lock is held, since the m will normally move quickly to lock the
-// scheduler itself, producing lock contention.
-static M* mwakeup;
-
-// Scheduling helpers. Sched must be locked.
-static void gput(G*); // put/get on ghead/gtail
-static G* gget(void);
-static void mput(M*); // put/get on mhead
-static M* mget(G*);
-static void gfput(G*); // put/get on gfree
-static G* gfget(void);
-static void matchmg(void); // match m's to g's
-static void readylocked(G*); // ready, but sched is locked
-static void mnextg(M*, G*);
-static void mcommoninit(M*);
-
-void
-setmcpumax(uint32 n)
-{
- uint32 v, w;
-
- for(;;) {
- v = runtime_sched.atomic;
- w = v;
- w &= ~(mcpuMask<<mcpumaxShift);
- w |= n<<mcpumaxShift;
- if(runtime_cas(&runtime_sched.atomic, v, w))
- break;
- }
-}
-
-// First function run by a new goroutine. This replaces gogocall.
-static void
-kickoff(void)
-{
- void (*fn)(void*);
-
- if(g->traceback != nil)
- gtraceback(g);
-
- fn = (void (*)(void*))(g->entry);
- fn(g->param);
- runtime_goexit();
-}
-
-// Switch context to a different goroutine. This is like longjmp.
-static void runtime_gogo(G*) __attribute__ ((noinline));
-static void
-runtime_gogo(G* newg)
-{
-#ifdef USING_SPLIT_STACK
- __splitstack_setcontext(&newg->stack_context[0]);
-#endif
- g = newg;
- newg->fromgogo = true;
- fixcontext(&newg->context);
- setcontext(&newg->context);
- runtime_throw("gogo setcontext returned");
-}
-
-// Save context and call fn passing g as a parameter. This is like
-// setjmp. Because getcontext always returns 0, unlike setjmp, we use
-// g->fromgogo as a code. It will be true if we got here via
-// setcontext. g == nil the first time this is called in a new m.
-static void runtime_mcall(void (*)(G*)) __attribute__ ((noinline));
-static void
-runtime_mcall(void (*pfn)(G*))
-{
- M *mp;
- G *gp;
-#ifndef USING_SPLIT_STACK
- int i;
-#endif
-
- // Ensure that all registers are on the stack for the garbage
- // collector.
- __builtin_unwind_init();
-
- mp = m;
- gp = g;
- if(gp == mp->g0)
- runtime_throw("runtime: mcall called on m->g0 stack");
-
- if(gp != nil) {
-
-#ifdef USING_SPLIT_STACK
- __splitstack_getcontext(&g->stack_context[0]);
-#else
- gp->gcnext_sp = &i;
-#endif
- gp->fromgogo = false;
- getcontext(&gp->context);
-
- // When we return from getcontext, we may be running
- // in a new thread. That means that m and g may have
- // changed. They are global variables so we will
- // reload them, but the addresses of m and g may be
- // cached in our local stack frame, and those
- // addresses may be wrong. Call functions to reload
- // the values for this thread.
- mp = runtime_m();
- gp = runtime_g();
-
- if(gp->traceback != nil)
- gtraceback(gp);
- }
- if (gp == nil || !gp->fromgogo) {
-#ifdef USING_SPLIT_STACK
- __splitstack_setcontext(&mp->g0->stack_context[0]);
-#endif
- mp->g0->entry = (byte*)pfn;
- mp->g0->param = gp;
-
- // It's OK to set g directly here because this case
- // can not occur if we got here via a setcontext to
- // the getcontext call just above.
- g = mp->g0;
-
- fixcontext(&mp->g0->context);
- setcontext(&mp->g0->context);
- runtime_throw("runtime: mcall function returned");
- }
-}
-
-// Keep trace of scavenger's goroutine for deadlock detection.
-static G *scvg;
-
-// The bootstrap sequence is:
-//
-// call osinit
-// call schedinit
-// make & queue new G
-// call runtime_mstart
-//
-// The new G calls runtime_main.
-void
-runtime_schedinit(void)
-{
- int32 n;
- const byte *p;
-
- m = &runtime_m0;
- g = &runtime_g0;
- m->g0 = g;
- m->curg = g;
- g->m = m;
-
- initcontext();
- inittlssize();
-
- m->nomemprof++;
- runtime_mallocinit();
- mcommoninit(m);
-
- runtime_goargs();
- runtime_goenvs();
-
- // For debugging:
- // Allocate internal symbol table representation now,
- // so that we don't need to call malloc when we crash.
- // runtime_findfunc(0);
-
- runtime_gomaxprocs = 1;
- p = runtime_getenv("GOMAXPROCS");
- if(p != nil && (n = runtime_atoi(p)) != 0) {
- if(n > maxgomaxprocs)
- n = maxgomaxprocs;
- runtime_gomaxprocs = n;
- }
- // wait for the main goroutine to start before taking
- // GOMAXPROCS into account.
- setmcpumax(1);
- runtime_singleproc = runtime_gomaxprocs == 1;
-
- canaddmcpu(); // mcpu++ to account for bootstrap m
- m->helpgc = 1; // flag to tell schedule() to mcpu--
- runtime_sched.grunning++;
-
- // Can not enable GC until all roots are registered.
- // mstats.enablegc = 1;
- m->nomemprof--;
-
- if(raceenabled)
- runtime_raceinit();
-}
-
-extern void main_init(void) __asm__ (GOSYM_PREFIX "__go_init_main");
-extern void main_main(void) __asm__ (GOSYM_PREFIX "main.main");
-
-// The main goroutine.
-void
-runtime_main(void)
-{
- // Lock the main goroutine onto this, the main OS thread,
- // during initialization. Most programs won't care, but a few
- // do require certain calls to be made by the main thread.
- // Those can arrange for main.main to run in the main thread
- // by calling runtime.LockOSThread during initialization
- // to preserve the lock.
- runtime_LockOSThread();
- // From now on, newgoroutines may use non-main threads.
- setmcpumax(runtime_gomaxprocs);
- runtime_sched.init = true;
- scvg = __go_go(runtime_MHeap_Scavenger, nil);
- scvg->issystem = true;
- main_init();
- runtime_sched.init = false;
- if(!runtime_sched.lockmain)
- runtime_UnlockOSThread();
-
- // For gccgo we have to wait until after main is initialized
- // to enable GC, because initializing main registers the GC
- // roots.
- mstats.enablegc = 1;
-
- // The deadlock detection has false negatives.
- // Let scvg start up, to eliminate the false negative
- // for the trivial program func main() { select{} }.
- runtime_gosched();
-
- main_main();
- if(raceenabled)
- runtime_racefini();
- runtime_exit(0);
- for(;;)
- *(int32*)0 = 0;
-}
-
-// Lock the scheduler.
-static void
-schedlock(void)
-{
- runtime_lock(&runtime_sched);
-}
-
-// Unlock the scheduler.
-static void
-schedunlock(void)
-{
- M *mp;
-
- mp = mwakeup;
- mwakeup = nil;
- runtime_unlock(&runtime_sched);
- if(mp != nil)
- runtime_notewakeup(&mp->havenextg);
-}
-
-void
-runtime_goexit(void)
-{
- g->status = Gmoribund;
- runtime_gosched();
-}
-
-void
-runtime_goroutineheader(G *gp)
-{
- const char *status;
-
- switch(gp->status) {
- case Gidle:
- status = "idle";
- break;
- case Grunnable:
- status = "runnable";
- break;
- case Grunning:
- status = "running";
- break;
- case Gsyscall:
- status = "syscall";
- break;
- case Gwaiting:
- if(gp->waitreason)
- status = gp->waitreason;
- else
- status = "waiting";
- break;
- case Gmoribund:
- status = "moribund";
- break;
- default:
- status = "???";
- break;
- }
- runtime_printf("goroutine %D [%s]:\n", gp->goid, status);
-}
-
-void
-runtime_goroutinetrailer(G *g)
-{
- if(g != nil && g->gopc != 0 && g->goid != 1) {
- String fn;
- String file;
- intgo line;
-
- if(__go_file_line(g->gopc - 1, &fn, &file, &line)) {
- runtime_printf("created by %S\n", fn);
- runtime_printf("\t%S:%D\n", file, (int64) line);
- }
- }
-}
-
-struct Traceback
-{
- G* gp;
- Location locbuf[100];
- int32 c;
-};
-
-void
-runtime_tracebackothers(G * volatile me)
-{
- G * volatile gp;
- Traceback tb;
- int32 traceback;
-
- tb.gp = me;
- traceback = runtime_gotraceback();
- for(gp = runtime_allg; gp != nil; gp = gp->alllink) {
- if(gp == me || gp->status == Gdead)
- continue;
- if(gp->issystem && traceback < 2)
- continue;
- runtime_printf("\n");
- runtime_goroutineheader(gp);
-
- // Our only mechanism for doing a stack trace is
- // _Unwind_Backtrace. And that only works for the
- // current thread, not for other random goroutines.
- // So we need to switch context to the goroutine, get
- // the backtrace, and then switch back.
-
- // This means that if g is running or in a syscall, we
- // can't reliably print a stack trace. FIXME.
- if(gp->status == Gsyscall || gp->status == Grunning) {
- runtime_printf("no stack trace available\n");
- runtime_goroutinetrailer(gp);
- continue;
- }
-
- gp->traceback = &tb;
-
-#ifdef USING_SPLIT_STACK
- __splitstack_getcontext(&me->stack_context[0]);
-#endif
- getcontext(&me->context);
-
- if(gp->traceback != nil) {
- runtime_gogo(gp);
- }
-
- runtime_printtrace(tb.locbuf, tb.c, false);
- runtime_goroutinetrailer(gp);
- }
-}
-
-// Do a stack trace of gp, and then restore the context to
-// gp->dotraceback.
-
-static void
-gtraceback(G* gp)
-{
- Traceback* traceback;
-
- traceback = gp->traceback;
- gp->traceback = nil;
- traceback->c = runtime_callers(1, traceback->locbuf,
- sizeof traceback->locbuf / sizeof traceback->locbuf[0]);
- runtime_gogo(traceback->gp);
-}
-
-// Mark this g as m's idle goroutine.
-// This functionality might be used in environments where programs
-// are limited to a single thread, to simulate a select-driven
-// network server. It is not exposed via the standard runtime API.
-void
-runtime_idlegoroutine(void)
-{
- if(g->idlem != nil)
- runtime_throw("g is already an idle goroutine");
- g->idlem = m;
-}
-
-static void
-mcommoninit(M *mp)
-{
- mp->id = runtime_sched.mcount++;
- mp->fastrand = 0x49f6428aUL + mp->id + runtime_cputicks();
-
- if(mp->mcache == nil)
- mp->mcache = runtime_allocmcache();
-
- runtime_callers(1, mp->createstack, nelem(mp->createstack));
-
- // Add to runtime_allm so garbage collector doesn't free m
- // when it is just in a register or thread-local storage.
- mp->alllink = runtime_allm;
- // runtime_NumCgoCall() iterates over allm w/o schedlock,
- // so we need to publish it safely.
- runtime_atomicstorep(&runtime_allm, mp);
-}
-
-// Try to increment mcpu. Report whether succeeded.
-static bool
-canaddmcpu(void)
-{
- uint32 v;
-
- for(;;) {
- v = runtime_sched.atomic;
- if(atomic_mcpu(v) >= atomic_mcpumax(v))
- return 0;
- if(runtime_cas(&runtime_sched.atomic, v, v+(1<<mcpuShift)))
- return 1;
- }
-}
-
-// Put on `g' queue. Sched must be locked.
-static void
-gput(G *gp)
-{
- M *mp;
-
- // If g is wired, hand it off directly.
- if((mp = gp->lockedm) != nil && canaddmcpu()) {
- mnextg(mp, gp);
- return;
- }
-
- // If g is the idle goroutine for an m, hand it off.
- if(gp->idlem != nil) {
- if(gp->idlem->idleg != nil) {
- runtime_printf("m%d idle out of sync: g%D g%D\n",
- gp->idlem->id,
- gp->idlem->idleg->goid, gp->goid);
- runtime_throw("runtime: double idle");
- }
- gp->idlem->idleg = gp;
- return;
- }
-
- gp->schedlink = nil;
- if(runtime_sched.ghead == nil)
- runtime_sched.ghead = gp;
- else
- runtime_sched.gtail->schedlink = gp;
- runtime_sched.gtail = gp;
-
- // increment gwait.
- // if it transitions to nonzero, set atomic gwaiting bit.
- if(runtime_sched.gwait++ == 0)
- runtime_xadd(&runtime_sched.atomic, 1<<gwaitingShift);
-}
-
-// Report whether gget would return something.
-static bool
-haveg(void)
-{
- return runtime_sched.ghead != nil || m->idleg != nil;
-}
-
-// Get from `g' queue. Sched must be locked.
-static G*
-gget(void)
-{
- G *gp;
-
- gp = runtime_sched.ghead;
- if(gp) {
- runtime_sched.ghead = gp->schedlink;
- if(runtime_sched.ghead == nil)
- runtime_sched.gtail = nil;
- // decrement gwait.
- // if it transitions to zero, clear atomic gwaiting bit.
- if(--runtime_sched.gwait == 0)
- runtime_xadd(&runtime_sched.atomic, -1<<gwaitingShift);
- } else if(m->idleg != nil) {
- gp = m->idleg;
- m->idleg = nil;
- }
- return gp;
-}
-
-// Put on `m' list. Sched must be locked.
-static void
-mput(M *mp)
-{
- mp->schedlink = runtime_sched.mhead;
- runtime_sched.mhead = mp;
- runtime_sched.mwait++;
-}
-
-// Get an `m' to run `g'. Sched must be locked.
-static M*
-mget(G *gp)
-{
- M *mp;
-
- // if g has its own m, use it.
- if(gp && (mp = gp->lockedm) != nil)
- return mp;
-
- // otherwise use general m pool.
- if((mp = runtime_sched.mhead) != nil) {
- runtime_sched.mhead = mp->schedlink;
- runtime_sched.mwait--;
- }
- return mp;
-}
-
-// Mark g ready to run.
-void
-runtime_ready(G *gp)
-{
- schedlock();
- readylocked(gp);
- schedunlock();
-}
-
-// Mark g ready to run. Sched is already locked.
-// G might be running already and about to stop.
-// The sched lock protects g->status from changing underfoot.
-static void
-readylocked(G *gp)
-{
- if(gp->m) {
- // Running on another machine.
- // Ready it when it stops.
- gp->readyonstop = 1;
- return;
- }
-
- // Mark runnable.
- if(gp->status == Grunnable || gp->status == Grunning) {
- runtime_printf("goroutine %D has status %d\n", gp->goid, gp->status);
- runtime_throw("bad g->status in ready");
- }
- gp->status = Grunnable;
-
- gput(gp);
- matchmg();
-}
-
-// Same as readylocked but a different symbol so that
-// debuggers can set a breakpoint here and catch all
-// new goroutines.
-static void
-newprocreadylocked(G *gp)
-{
- readylocked(gp);
-}
-
-// Pass g to m for running.
-// Caller has already incremented mcpu.
-static void
-mnextg(M *mp, G *gp)
-{
- runtime_sched.grunning++;
- mp->nextg = gp;
- if(mp->waitnextg) {
- mp->waitnextg = 0;
- if(mwakeup != nil)
- runtime_notewakeup(&mwakeup->havenextg);
- mwakeup = mp;
- }
-}
-
-// Get the next goroutine that m should run.
-// Sched must be locked on entry, is unlocked on exit.
-// Makes sure that at most $GOMAXPROCS g's are
-// running on cpus (not in system calls) at any given time.
-static G*
-nextgandunlock(void)
-{
- G *gp;
- uint32 v;
-
-top:
- if(atomic_mcpu(runtime_sched.atomic) >= maxgomaxprocs)
- runtime_throw("negative mcpu");
-
- // If there is a g waiting as m->nextg, the mcpu++
- // happened before it was passed to mnextg.
- if(m->nextg != nil) {
- gp = m->nextg;
- m->nextg = nil;
- schedunlock();
- return gp;
- }
-
- if(m->lockedg != nil) {
- // We can only run one g, and it's not available.
- // Make sure some other cpu is running to handle
- // the ordinary run queue.
- if(runtime_sched.gwait != 0) {
- matchmg();
- // m->lockedg might have been on the queue.
- if(m->nextg != nil) {
- gp = m->nextg;
- m->nextg = nil;
- schedunlock();
- return gp;
- }
- }
- } else {
- // Look for work on global queue.
- while(haveg() && canaddmcpu()) {
- gp = gget();
- if(gp == nil)
- runtime_throw("gget inconsistency");
-
- if(gp->lockedm) {
- mnextg(gp->lockedm, gp);
- continue;
- }
- runtime_sched.grunning++;
- schedunlock();
- return gp;
- }
-
- // The while loop ended either because the g queue is empty
- // or because we have maxed out our m procs running go
- // code (mcpu >= mcpumax). We need to check that
- // concurrent actions by entersyscall/exitsyscall cannot
- // invalidate the decision to end the loop.
- //
- // We hold the sched lock, so no one else is manipulating the
- // g queue or changing mcpumax. Entersyscall can decrement
- // mcpu, but if does so when there is something on the g queue,
- // the gwait bit will be set, so entersyscall will take the slow path
- // and use the sched lock. So it cannot invalidate our decision.
- //
- // Wait on global m queue.
- mput(m);
- }
-
- // Look for deadlock situation.
- // There is a race with the scavenger that causes false negatives:
- // if the scavenger is just starting, then we have
- // scvg != nil && grunning == 0 && gwait == 0
- // and we do not detect a deadlock. It is possible that we should
- // add that case to the if statement here, but it is too close to Go 1
- // to make such a subtle change. Instead, we work around the
- // false negative in trivial programs by calling runtime.gosched
- // from the main goroutine just before main.main.
- // See runtime_main above.
- //
- // On a related note, it is also possible that the scvg == nil case is
- // wrong and should include gwait, but that does not happen in
- // standard Go programs, which all start the scavenger.
- //
- if((scvg == nil && runtime_sched.grunning == 0) ||
- (scvg != nil && runtime_sched.grunning == 1 && runtime_sched.gwait == 0 &&
- (scvg->status == Grunning || scvg->status == Gsyscall))) {
- m->throwing = -1; // do not dump full stacks
- runtime_throw("all goroutines are asleep - deadlock!");
- }
-
- m->nextg = nil;
- m->waitnextg = 1;
- runtime_noteclear(&m->havenextg);
-
- // Stoptheworld is waiting for all but its cpu to go to stop.
- // Entersyscall might have decremented mcpu too, but if so
- // it will see the waitstop and take the slow path.
- // Exitsyscall never increments mcpu beyond mcpumax.
- v = runtime_atomicload(&runtime_sched.atomic);
- if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) {
- // set waitstop = 0 (known to be 1)
- runtime_xadd(&runtime_sched.atomic, -1<<waitstopShift);
- runtime_notewakeup(&runtime_sched.stopped);
- }
- schedunlock();
-
- runtime_notesleep(&m->havenextg);
- if(m->helpgc) {
- runtime_gchelper();
- m->helpgc = 0;
- runtime_lock(&runtime_sched);
- goto top;
- }
- if((gp = m->nextg) == nil)
- runtime_throw("bad m->nextg in nextgoroutine");
- m->nextg = nil;
- return gp;
-}
-
-int32
-runtime_gcprocs(void)
-{
- int32 n;
-
- // Figure out how many CPUs to use during GC.
- // Limited by gomaxprocs, number of actual CPUs, and MaxGcproc.
- n = runtime_gomaxprocs;
- if(n > runtime_ncpu)
- n = runtime_ncpu > 0 ? runtime_ncpu : 1;
- if(n > MaxGcproc)
- n = MaxGcproc;
- if(n > runtime_sched.mwait+1) // one M is currently running
- n = runtime_sched.mwait+1;
- return n;
-}
-
-void
-runtime_helpgc(int32 nproc)
-{
- M *mp;
- int32 n;
-
- runtime_lock(&runtime_sched);
- for(n = 1; n < nproc; n++) { // one M is currently running
- mp = mget(nil);
- if(mp == nil)
- runtime_throw("runtime_gcprocs inconsistency");
- mp->helpgc = 1;
- mp->waitnextg = 0;
- runtime_notewakeup(&mp->havenextg);
- }
- runtime_unlock(&runtime_sched);
-}
-
-void
-runtime_stoptheworld(void)
-{
- uint32 v;
-
- schedlock();
- runtime_gcwaiting = 1;
-
- setmcpumax(1);
-
- // while mcpu > 1
- for(;;) {
- v = runtime_sched.atomic;
- if(atomic_mcpu(v) <= 1)
- break;
-
- // It would be unsafe for multiple threads to be using
- // the stopped note at once, but there is only
- // ever one thread doing garbage collection.
- runtime_noteclear(&runtime_sched.stopped);
- if(atomic_waitstop(v))
- runtime_throw("invalid waitstop");
-
- // atomic { waitstop = 1 }, predicated on mcpu <= 1 check above
- // still being true.
- if(!runtime_cas(&runtime_sched.atomic, v, v+(1<<waitstopShift)))
- continue;
-
- schedunlock();
- runtime_notesleep(&runtime_sched.stopped);
- schedlock();
- }
- runtime_singleproc = runtime_gomaxprocs == 1;
- schedunlock();
-}
-
-void
-runtime_starttheworld(void)
-{
- M *mp;
- int32 max;
-
- // Figure out how many CPUs GC could possibly use.
- max = runtime_gomaxprocs;
- if(max > runtime_ncpu)
- max = runtime_ncpu > 0 ? runtime_ncpu : 1;
- if(max > MaxGcproc)
- max = MaxGcproc;
-
- schedlock();
- runtime_gcwaiting = 0;
- setmcpumax(runtime_gomaxprocs);
- matchmg();
- if(runtime_gcprocs() < max && canaddmcpu()) {
- // If GC could have used another helper proc, start one now,
- // in the hope that it will be available next time.
- // It would have been even better to start it before the collection,
- // but doing so requires allocating memory, so it's tricky to
- // coordinate. This lazy approach works out in practice:
- // we don't mind if the first couple gc rounds don't have quite
- // the maximum number of procs.
- // canaddmcpu above did mcpu++
- // (necessary, because m will be doing various
- // initialization work so is definitely running),
- // but m is not running a specific goroutine,
- // so set the helpgc flag as a signal to m's
- // first schedule(nil) to mcpu-- and grunning--.
- mp = runtime_newm();
- mp->helpgc = 1;
- runtime_sched.grunning++;
- }
- schedunlock();
-}
-
-// Called to start an M.
-void*
-runtime_mstart(void* mp)
-{
- m = (M*)mp;
- g = m->g0;
-
- initcontext();
-
- g->entry = nil;
- g->param = nil;
-
- // Record top of stack for use by mcall.
- // Once we call schedule we're never coming back,
- // so other calls can reuse this stack space.
-#ifdef USING_SPLIT_STACK
- __splitstack_getcontext(&g->stack_context[0]);
-#else
- g->gcinitial_sp = &mp;
- // Setting gcstack_size to 0 is a marker meaning that gcinitial_sp
- // is the top of the stack, not the bottom.
- g->gcstack_size = 0;
- g->gcnext_sp = &mp;
-#endif
- getcontext(&g->context);
-
- if(g->entry != nil) {
- // Got here from mcall.
- void (*pfn)(G*) = (void (*)(G*))g->entry;
- G* gp = (G*)g->param;
- pfn(gp);
- *(int*)0x21 = 0x21;
- }
- runtime_minit();
-
-#ifdef USING_SPLIT_STACK
- {
- int dont_block_signals = 0;
- __splitstack_block_signals(&dont_block_signals, nil);
- }
-#endif
-
- // Install signal handlers; after minit so that minit can
- // prepare the thread to be able to handle the signals.
- if(m == &runtime_m0)
- runtime_initsig();
-
- schedule(nil);
-
- // TODO(brainman): This point is never reached, because scheduler
- // does not release os threads at the moment. But once this path
- // is enabled, we must remove our seh here.
-
- return nil;
-}
-
-typedef struct CgoThreadStart CgoThreadStart;
-struct CgoThreadStart
-{
- M *m;
- G *g;
- void (*fn)(void);
-};
-
-// Kick off new m's as needed (up to mcpumax).
-// Sched is locked.
-static void
-matchmg(void)
-{
- G *gp;
- M *mp;
-
- if(m->mallocing || m->gcing)
- return;
-
- while(haveg() && canaddmcpu()) {
- gp = gget();
- if(gp == nil)
- runtime_throw("gget inconsistency");
-
- // Find the m that will run gp.
- if((mp = mget(gp)) == nil)
- mp = runtime_newm();
- mnextg(mp, gp);
- }
-}
-
-// Create a new m. It will start off with a call to runtime_mstart.
-M*
-runtime_newm(void)
-{
- M *mp;
- pthread_attr_t attr;
- pthread_t tid;
- size_t stacksize;
- sigset_t clear;
- sigset_t old;
- int ret;
-
-#if 0
- static const Type *mtype; // The Go type M
- if(mtype == nil) {
- Eface e;
- runtime_gc_m_ptr(&e);
- mtype = ((const PtrType*)e.__type_descriptor)->__element_type;
- }
-#endif
-
- mp = runtime_mal(sizeof *mp);
- mcommoninit(mp);
- mp->g0 = runtime_malg(-1, nil, nil);
-
- if(pthread_attr_init(&attr) != 0)
- runtime_throw("pthread_attr_init");
- if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
- runtime_throw("pthread_attr_setdetachstate");
-
- stacksize = PTHREAD_STACK_MIN;
-
- // With glibc before version 2.16 the static TLS size is taken
- // out of the stack size, and we get an error or a crash if
- // there is not enough stack space left. Add it back in if we
- // can, in case the program uses a lot of TLS space. FIXME:
- // This can be disabled in glibc 2.16 and later, if the bug is
- // indeed fixed then.
- stacksize += tlssize;
-
- if(pthread_attr_setstacksize(&attr, stacksize) != 0)
- runtime_throw("pthread_attr_setstacksize");
-
- // Block signals during pthread_create so that the new thread
- // starts with signals disabled. It will enable them in minit.
- sigfillset(&clear);
-
-#ifdef SIGTRAP
- // Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
- sigdelset(&clear, SIGTRAP);
-#endif
-
- sigemptyset(&old);
- sigprocmask(SIG_BLOCK, &clear, &old);
- ret = pthread_create(&tid, &attr, runtime_mstart, mp);
- sigprocmask(SIG_SETMASK, &old, nil);
-
- if (ret != 0)
- runtime_throw("pthread_create");
-
- return mp;
-}
-
-// One round of scheduler: find a goroutine and run it.
-// The argument is the goroutine that was running before
-// schedule was called, or nil if this is the first call.
-// Never returns.
-static void
-schedule(G *gp)
-{
- int32 hz;
- uint32 v;
-
- schedlock();
- if(gp != nil) {
- // Just finished running gp.
- gp->m = nil;
- runtime_sched.grunning--;
-
- // atomic { mcpu-- }
- v = runtime_xadd(&runtime_sched.atomic, -1<<mcpuShift);
- if(atomic_mcpu(v) > maxgomaxprocs)
- runtime_throw("negative mcpu in scheduler");
-
- switch(gp->status) {
- case Grunnable:
- case Gdead:
- // Shouldn't have been running!
- runtime_throw("bad gp->status in sched");
- case Grunning:
- gp->status = Grunnable;
- gput(gp);
- break;
- case Gmoribund:
- if(raceenabled)
- runtime_racegoend(gp->goid);
- gp->status = Gdead;
- if(gp->lockedm) {
- gp->lockedm = nil;
- m->lockedg = nil;
- }
- gp->idlem = nil;
- runtime_memclr(&gp->context, sizeof gp->context);
- gfput(gp);
- if(--runtime_sched.gcount == 0)
- runtime_exit(0);
- break;
- }
- if(gp->readyonstop) {
- gp->readyonstop = 0;
- readylocked(gp);
- }
- } else if(m->helpgc) {
- // Bootstrap m or new m started by starttheworld.
- // atomic { mcpu-- }
- v = runtime_xadd(&runtime_sched.atomic, -1<<mcpuShift);
- if(atomic_mcpu(v) > maxgomaxprocs)
- runtime_throw("negative mcpu in scheduler");
- // Compensate for increment in starttheworld().
- runtime_sched.grunning--;
- m->helpgc = 0;
- } else if(m->nextg != nil) {
- // New m started by matchmg.
- } else {
- runtime_throw("invalid m state in scheduler");
- }
-
- // Find (or wait for) g to run. Unlocks runtime_sched.
- gp = nextgandunlock();
- gp->readyonstop = 0;
- gp->status = Grunning;
- m->curg = gp;
- gp->m = m;
-
- // Check whether the profiler needs to be turned on or off.
- hz = runtime_sched.profilehz;
- if(m->profilehz != hz)
- runtime_resetcpuprofiler(hz);
-
- runtime_gogo(gp);
-}
-
-// Enter scheduler. If g->status is Grunning,
-// re-queues g and runs everyone else who is waiting
-// before running g again. If g->status is Gmoribund,
-// kills off g.
-void
-runtime_gosched(void)
-{
- if(m->locks != 0)
- runtime_throw("gosched holding locks");
- if(g == m->g0)
- runtime_throw("gosched of g0");
- runtime_mcall(schedule);
-}
-
-// Puts the current goroutine into a waiting state and unlocks the lock.
-// The goroutine can be made runnable again by calling runtime_ready(gp).
-void
-runtime_park(void (*unlockf)(Lock*), Lock *lock, const char *reason)
-{
- g->status = Gwaiting;
- g->waitreason = reason;
- if(unlockf)
- unlockf(lock);
- runtime_gosched();
-}
-
-// The goroutine g is about to enter a system call.
-// Record that it's not using the cpu anymore.
-// This is called only from the go syscall library and cgocall,
-// not from the low-level system calls used by the runtime.
-//
-// Entersyscall cannot split the stack: the runtime_gosave must
-// make g->sched refer to the caller's stack segment, because
-// entersyscall is going to return immediately after.
-// It's okay to call matchmg and notewakeup even after
-// decrementing mcpu, because we haven't released the
-// sched lock yet, so the garbage collector cannot be running.
-
-void runtime_entersyscall(void) __attribute__ ((no_split_stack));
-
-void
-runtime_entersyscall(void)
-{
- uint32 v;
-
- if(m->profilehz > 0)
- runtime_setprof(false);
-
- // Leave SP around for gc and traceback.
-#ifdef USING_SPLIT_STACK
- g->gcstack = __splitstack_find(nil, nil, &g->gcstack_size,
- &g->gcnext_segment, &g->gcnext_sp,
- &g->gcinitial_sp);
-#else
- g->gcnext_sp = (byte *) &v;
-#endif
-
- // Save the registers in the g structure so that any pointers
- // held in registers will be seen by the garbage collector.
- getcontext(&g->gcregs);
-
- g->status = Gsyscall;
-
- // Fast path.
- // The slow path inside the schedlock/schedunlock will get
- // through without stopping if it does:
- // mcpu--
- // gwait not true
- // waitstop && mcpu <= mcpumax not true
- // If we can do the same with a single atomic add,
- // then we can skip the locks.
- v = runtime_xadd(&runtime_sched.atomic, -1<<mcpuShift);
- if(!atomic_gwaiting(v) && (!atomic_waitstop(v) || atomic_mcpu(v) > atomic_mcpumax(v)))
- return;
-
- schedlock();
- v = runtime_atomicload(&runtime_sched.atomic);
- if(atomic_gwaiting(v)) {
- matchmg();
- v = runtime_atomicload(&runtime_sched.atomic);
- }
- if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) {
- runtime_xadd(&runtime_sched.atomic, -1<<waitstopShift);
- runtime_notewakeup(&runtime_sched.stopped);
- }
-
- schedunlock();
-}
-
-// The goroutine g exited its system call.
-// Arrange for it to run on a cpu again.
-// This is called only from the go syscall library, not
-// from the low-level system calls used by the runtime.
-void
-runtime_exitsyscall(void)
-{
- G *gp;
- uint32 v;
-
- // Fast path.
- // If we can do the mcpu++ bookkeeping and
- // find that we still have mcpu <= mcpumax, then we can
- // start executing Go code immediately, without having to
- // schedlock/schedunlock.
- // Also do fast return if any locks are held, so that
- // panic code can use syscalls to open a file.
- gp = g;
- v = runtime_xadd(&runtime_sched.atomic, (1<<mcpuShift));
- if((m->profilehz == runtime_sched.profilehz && atomic_mcpu(v) <= atomic_mcpumax(v)) || m->locks > 0) {
- // There's a cpu for us, so we can run.
- gp->status = Grunning;
- // Garbage collector isn't running (since we are),
- // so okay to clear gcstack.
-#ifdef USING_SPLIT_STACK
- gp->gcstack = nil;
-#endif
- gp->gcnext_sp = nil;
- runtime_memclr(&gp->gcregs, sizeof gp->gcregs);
-
- if(m->profilehz > 0)
- runtime_setprof(true);
- return;
- }
-
- // Tell scheduler to put g back on the run queue:
- // mostly equivalent to g->status = Grunning,
- // but keeps the garbage collector from thinking
- // that g is running right now, which it's not.
- gp->readyonstop = 1;
-
- // All the cpus are taken.
- // The scheduler will ready g and put this m to sleep.
- // When the scheduler takes g away from m,
- // it will undo the runtime_sched.mcpu++ above.
- runtime_gosched();
-
- // Gosched returned, so we're allowed to run now.
- // Delete the gcstack information that we left for
- // the garbage collector during the system call.
- // Must wait until now because until gosched returns
- // we don't know for sure that the garbage collector
- // is not running.
-#ifdef USING_SPLIT_STACK
- gp->gcstack = nil;
-#endif
- gp->gcnext_sp = nil;
- runtime_memclr(&gp->gcregs, sizeof gp->gcregs);
-}
-
-// Allocate a new g, with a stack big enough for stacksize bytes.
-G*
-runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize)
-{
- G *newg;
-
- newg = runtime_malloc(sizeof(G));
- if(stacksize >= 0) {
-#if USING_SPLIT_STACK
- int dont_block_signals = 0;
-
- *ret_stack = __splitstack_makecontext(stacksize,
- &newg->stack_context[0],
- ret_stacksize);
- __splitstack_block_signals_context(&newg->stack_context[0],
- &dont_block_signals, nil);
-#else
- *ret_stack = runtime_mallocgc(stacksize, FlagNoProfiling|FlagNoGC, 0, 0);
- *ret_stacksize = stacksize;
- newg->gcinitial_sp = *ret_stack;
- newg->gcstack_size = stacksize;
- runtime_xadd(&runtime_stacks_sys, stacksize);
-#endif
- }
- return newg;
-}
-
-/* For runtime package testing. */
-
-void runtime_testing_entersyscall(void)
- __asm__ (GOSYM_PREFIX "runtime.entersyscall");
-
-void
-runtime_testing_entersyscall()
-{
- runtime_entersyscall();
-}
-
-void runtime_testing_exitsyscall(void)
- __asm__ (GOSYM_PREFIX "runtime.exitsyscall");
-
-void
-runtime_testing_exitsyscall()
-{
- runtime_exitsyscall();
-}
-
-G*
-__go_go(void (*fn)(void*), void* arg)
-{
- byte *sp;
- size_t spsize;
- G *newg;
- int64 goid;
-
- goid = runtime_xadd64((uint64*)&runtime_sched.goidgen, 1);
- if(raceenabled)
- runtime_racegostart(goid, runtime_getcallerpc(&fn));
-
- schedlock();
-
- if((newg = gfget()) != nil) {
-#ifdef USING_SPLIT_STACK
- int dont_block_signals = 0;
-
- sp = __splitstack_resetcontext(&newg->stack_context[0],
- &spsize);
- __splitstack_block_signals_context(&newg->stack_context[0],
- &dont_block_signals, nil);
-#else
- sp = newg->gcinitial_sp;
- spsize = newg->gcstack_size;
- if(spsize == 0)
- runtime_throw("bad spsize in __go_go");
- newg->gcnext_sp = sp;
-#endif
- } else {
- newg = runtime_malg(StackMin, &sp, &spsize);
- if(runtime_lastg == nil)
- runtime_allg = newg;
- else
- runtime_lastg->alllink = newg;
- runtime_lastg = newg;
- }
- newg->status = Gwaiting;
- newg->waitreason = "new goroutine";
-
- newg->entry = (byte*)fn;
- newg->param = arg;
- newg->gopc = (uintptr)__builtin_return_address(0);
-
- runtime_sched.gcount++;
- newg->goid = goid;
-
- if(sp == nil)
- runtime_throw("nil g->stack0");
-
- {
- // Avoid warnings about variables clobbered by
- // longjmp.
- byte * volatile vsp = sp;
- size_t volatile vspsize = spsize;
- G * volatile vnewg = newg;
-
- getcontext(&vnewg->context);
- vnewg->context.uc_stack.ss_sp = vsp;
-#ifdef MAKECONTEXT_STACK_TOP
- vnewg->context.uc_stack.ss_sp += vspsize;
-#endif
- vnewg->context.uc_stack.ss_size = vspsize;
- makecontext(&vnewg->context, kickoff, 0);
-
- newprocreadylocked(vnewg);
- schedunlock();
-
- return vnewg;
- }
-}
-
-// Put on gfree list. Sched must be locked.
-static void
-gfput(G *gp)
-{
- gp->schedlink = runtime_sched.gfree;
- runtime_sched.gfree = gp;
-}
-
-// Get from gfree list. Sched must be locked.
-static G*
-gfget(void)
-{
- G *gp;
-
- gp = runtime_sched.gfree;
- if(gp)
- runtime_sched.gfree = gp->schedlink;
- return gp;
-}
-
-void runtime_Gosched (void) __asm__ (GOSYM_PREFIX "runtime.Gosched");
-
-void
-runtime_Gosched(void)
-{
- runtime_gosched();
-}
-
-// Implementation of runtime.GOMAXPROCS.
-// delete when scheduler is stronger
-int32
-runtime_gomaxprocsfunc(int32 n)
-{
- int32 ret;
- uint32 v;
-
- schedlock();
- ret = runtime_gomaxprocs;
- if(n <= 0)
- n = ret;
- if(n > maxgomaxprocs)
- n = maxgomaxprocs;
- runtime_gomaxprocs = n;
- if(runtime_gomaxprocs > 1)
- runtime_singleproc = false;
- if(runtime_gcwaiting != 0) {
- if(atomic_mcpumax(runtime_sched.atomic) != 1)
- runtime_throw("invalid mcpumax during gc");
- schedunlock();
- return ret;
- }
-
- setmcpumax(n);
-
- // If there are now fewer allowed procs
- // than procs running, stop.
- v = runtime_atomicload(&runtime_sched.atomic);
- if((int32)atomic_mcpu(v) > n) {
- schedunlock();
- runtime_gosched();
- return ret;
- }
- // handle more procs
- matchmg();
- schedunlock();
- return ret;
-}
-
-void
-runtime_LockOSThread(void)
-{
- if(m == &runtime_m0 && runtime_sched.init) {
- runtime_sched.lockmain = true;
- return;
- }
- m->lockedg = g;
- g->lockedm = m;
-}
-
-void
-runtime_UnlockOSThread(void)
-{
- if(m == &runtime_m0 && runtime_sched.init) {
- runtime_sched.lockmain = false;
- return;
- }
- m->lockedg = nil;
- g->lockedm = nil;
-}
-
-bool
-runtime_lockedOSThread(void)
-{
- return g->lockedm != nil && m->lockedg != nil;
-}
-
-// for testing of callbacks
-
-_Bool runtime_golockedOSThread(void)
- __asm__ (GOSYM_PREFIX "runtime.golockedOSThread");
-
-_Bool
-runtime_golockedOSThread(void)
-{
- return runtime_lockedOSThread();
-}
-
-// for testing of wire, unwire
-uint32
-runtime_mid()
-{
- return m->id;
-}
-
-intgo runtime_NumGoroutine (void)
- __asm__ (GOSYM_PREFIX "runtime.NumGoroutine");
-
-intgo
-runtime_NumGoroutine()
-{
- return runtime_sched.gcount;
-}
-
-int32
-runtime_gcount(void)
-{
- return runtime_sched.gcount;
-}
-
-int32
-runtime_mcount(void)
-{
- return runtime_sched.mcount;
-}
-
-static struct {
- Lock;
- void (*fn)(uintptr*, int32);
- int32 hz;
- uintptr pcbuf[100];
- Location locbuf[100];
-} prof;
-
-// Called if we receive a SIGPROF signal.
-void
-runtime_sigprof()
-{
- int32 n, i;
-
- if(prof.fn == nil || prof.hz == 0)
- return;
-
- runtime_lock(&prof);
- if(prof.fn == nil) {
- runtime_unlock(&prof);
- return;
- }
- n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf));
- for(i = 0; i < n; i++)
- prof.pcbuf[i] = prof.locbuf[i].pc;
- if(n > 0)
- prof.fn(prof.pcbuf, n);
- runtime_unlock(&prof);
-}
-
-// Arrange to call fn with a traceback hz times a second.
-void
-runtime_setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz)
-{
- // Force sane arguments.
- if(hz < 0)
- hz = 0;
- if(hz == 0)
- fn = nil;
- if(fn == nil)
- hz = 0;
-
- // Stop profiler on this cpu so that it is safe to lock prof.
- // if a profiling signal came in while we had prof locked,
- // it would deadlock.
- runtime_resetcpuprofiler(0);
-
- runtime_lock(&prof);
- prof.fn = fn;
- prof.hz = hz;
- runtime_unlock(&prof);
- runtime_lock(&runtime_sched);
- runtime_sched.profilehz = hz;
- runtime_unlock(&runtime_sched);
-
- if(hz != 0)
- runtime_resetcpuprofiler(hz);
-}
diff --git a/gcc-4.8.1/libgo/runtime/race.h b/gcc-4.8.1/libgo/runtime/race.h
deleted file mode 100644
index 9f3b3ec66..000000000
--- a/gcc-4.8.1/libgo/runtime/race.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 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.
-
-// Definitions related to data race detection.
-
-#ifdef RACE
-enum { raceenabled = 1 };
-#else
-enum { raceenabled = 0 };
-#endif
-
-// Initialize race detection subsystem.
-void runtime_raceinit(void);
-// Finalize race detection subsystem, does not return.
-void runtime_racefini(void);
-
-void runtime_racemapshadow(void *addr, uintptr size);
-void runtime_racemalloc(void *p, uintptr sz, void *pc);
-void runtime_racefree(void *p);
-void runtime_racegostart(int32 goid, void *pc);
-void runtime_racegoend(int32 goid);
-void runtime_racewritepc(void *addr, void *callpc, void *pc);
-void runtime_racereadpc(void *addr, void *callpc, void *pc);
-void runtime_racefingo(void);
-void runtime_raceacquire(void *addr);
-void runtime_raceacquireg(G *gp, void *addr);
-void runtime_racerelease(void *addr);
-void runtime_racereleaseg(G *gp, void *addr);
-void runtime_racereleasemerge(void *addr);
-void runtime_racereleasemergeg(G *gp, void *addr);
diff --git a/gcc-4.8.1/libgo/runtime/reflect.goc b/gcc-4.8.1/libgo/runtime/reflect.goc
deleted file mode 100644
index c798b269e..000000000
--- a/gcc-4.8.1/libgo/runtime/reflect.goc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2010 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.
-
-package reflect
-#include "runtime.h"
-#include "go-type.h"
-#include "interface.h"
-#include "go-panic.h"
-
-func ifaceE2I(inter *Type, e Eface, ret *Iface) {
- const Type *t;
- Eface err;
-
- if(((uintptr)e.__type_descriptor&reflectFlags) != 0)
- runtime_throw("invalid interface value");
- t = e.__type_descriptor;
- if(t == nil) {
- // explicit conversions require non-nil interface value.
- runtime_newTypeAssertionError(
- nil, nil, inter->__reflection,
- nil, &err);
- runtime_panic(err);
- }
- ret->__object = e.__object;
- ret->__methods = __go_convert_interface(inter, t);
-}
diff --git a/gcc-4.8.1/libgo/runtime/rtems-task-variable-add.c b/gcc-4.8.1/libgo/runtime/rtems-task-variable-add.c
deleted file mode 100644
index 89dbb007a..000000000
--- a/gcc-4.8.1/libgo/runtime/rtems-task-variable-add.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* rtems-task-variable-add.c -- adding a task specific variable in RTEMS OS.
-
- Copyright 2010 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. */
-
-#include <rtems/error.h>
-#include <rtems/system.h>
-#include <rtems/rtems/tasks.h>
-
-#include "go-assert.h"
-
-/* RTEMS does not support GNU TLS extension __thread. */
-void
-__wrap_rtems_task_variable_add (void **var)
-{
- rtems_status_code sc = rtems_task_variable_add (RTEMS_SELF, var, NULL);
- if (sc != RTEMS_SUCCESSFUL)
- {
- rtems_error (sc, "rtems_task_variable_add failed");
- __go_assert (0);
- }
-}
-
diff --git a/gcc-4.8.1/libgo/runtime/runtime.c b/gcc-4.8.1/libgo/runtime/runtime.c
deleted file mode 100644
index 48ece55d1..000000000
--- a/gcc-4.8.1/libgo/runtime/runtime.c
+++ /dev/null
@@ -1,183 +0,0 @@
-// 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.
-
-#include <unistd.h>
-
-#include "config.h"
-
-#include "runtime.h"
-#include "array.h"
-#include "go-panic.h"
-
-int32
-runtime_gotraceback(void)
-{
- const byte *p;
-
- p = runtime_getenv("GOTRACEBACK");
- if(p == nil || p[0] == '\0')
- return 1; // default is on
- return runtime_atoi(p);
-}
-
-static int32 argc;
-static byte** argv;
-
-extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args");
-extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
-
-void (*runtime_sysargs)(int32, uint8**);
-
-void
-runtime_args(int32 c, byte **v)
-{
- argc = c;
- argv = v;
- if(runtime_sysargs != nil)
- runtime_sysargs(c, v);
-}
-
-byte*
-runtime_progname()
-{
- return argc == 0 ? nil : argv[0];
-}
-
-void
-runtime_goargs(void)
-{
- String *s;
- int32 i;
-
- // for windows implementation see "os" package
- if(Windows)
- return;
-
- s = runtime_malloc(argc*sizeof s[0]);
- for(i=0; i<argc; i++)
- s[i] = runtime_gostringnocopy((const byte*)argv[i]);
- os_Args.__values = (void*)s;
- os_Args.__count = argc;
- os_Args.__capacity = argc;
-}
-
-void
-runtime_goenvs_unix(void)
-{
- String *s;
- int32 i, n;
-
- for(n=0; argv[argc+1+n] != 0; n++)
- ;
-
- s = runtime_malloc(n*sizeof s[0]);
- for(i=0; i<n; i++)
- s[i] = runtime_gostringnocopy(argv[argc+1+i]);
- syscall_Envs.__values = (void*)s;
- syscall_Envs.__count = n;
- syscall_Envs.__capacity = n;
-}
-
-int32
-runtime_atoi(const byte *p)
-{
- int32 n;
-
- n = 0;
- while('0' <= *p && *p <= '9')
- n = n*10 + *p++ - '0';
- return n;
-}
-
-uint32
-runtime_fastrand1(void)
-{
- M *m;
- uint32 x;
-
- m = runtime_m();
- x = m->fastrand;
- x += x;
- if(x & 0x80000000L)
- x ^= 0x88888eefUL;
- m->fastrand = x;
- return x;
-}
-
-static struct root_list runtime_roots =
-{ nil,
- { { &syscall_Envs, sizeof syscall_Envs },
- { &os_Args, sizeof os_Args },
- { nil, 0 } },
-};
-
-void
-runtime_check(void)
-{
- __go_register_gc_roots(&runtime_roots);
-}
-
-int64
-runtime_cputicks(void)
-{
-#if defined(__386__) || defined(__x86_64__)
- uint32 low, high;
- asm("rdtsc" : "=a" (low), "=d" (high));
- return (int64)(((uint64)high << 32) | (uint64)low);
-#else
- // FIXME: implement for other processors.
- return 0;
-#endif
-}
-
-bool
-runtime_showframe(String s, bool current)
-{
- static int32 traceback = -1;
-
- if(current && runtime_m()->throwing > 0)
- return 1;
- if(traceback < 0)
- traceback = runtime_gotraceback();
- return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0);
-}
-
-static Lock ticksLock;
-static int64 ticks;
-
-int64
-runtime_tickspersecond(void)
-{
- int64 res, t0, t1, c0, c1;
-
- res = (int64)runtime_atomicload64((uint64*)&ticks);
- if(res != 0)
- return ticks;
- runtime_lock(&ticksLock);
- res = ticks;
- if(res == 0) {
- t0 = runtime_nanotime();
- c0 = runtime_cputicks();
- runtime_usleep(100*1000);
- t1 = runtime_nanotime();
- c1 = runtime_cputicks();
- if(t1 == t0)
- t1++;
- res = (c1-c0)*1000*1000*1000/(t1-t0);
- if(res == 0)
- res++;
- runtime_atomicstore64((uint64*)&ticks, res);
- }
- runtime_unlock(&ticksLock);
- return res;
-}
-
-int64 runtime_pprof_runtime_cyclesPerSecond(void)
- __asm__ (GOSYM_PREFIX "runtime_pprof.runtime_cyclesPerSecond");
-
-int64
-runtime_pprof_runtime_cyclesPerSecond(void)
-{
- return runtime_tickspersecond();
-}
diff --git a/gcc-4.8.1/libgo/runtime/runtime.h b/gcc-4.8.1/libgo/runtime/runtime.h
deleted file mode 100644
index 9392df162..000000000
--- a/gcc-4.8.1/libgo/runtime/runtime.h
+++ /dev/null
@@ -1,656 +0,0 @@
-// 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.
-
-#include "config.h"
-
-#include "go-assert.h"
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <ucontext.h>
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#include "interface.h"
-#include "go-alloc.h"
-
-#define _STRINGIFY2_(x) #x
-#define _STRINGIFY_(x) _STRINGIFY2_(x)
-#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
-
-/* This file supports C files copied from the 6g runtime library.
- This is a version of the 6g runtime.h rewritten for gccgo's version
- of the code. */
-
-typedef signed int int8 __attribute__ ((mode (QI)));
-typedef unsigned int uint8 __attribute__ ((mode (QI)));
-typedef signed int int16 __attribute__ ((mode (HI)));
-typedef unsigned int uint16 __attribute__ ((mode (HI)));
-typedef signed int int32 __attribute__ ((mode (SI)));
-typedef unsigned int uint32 __attribute__ ((mode (SI)));
-typedef signed int int64 __attribute__ ((mode (DI)));
-typedef unsigned int uint64 __attribute__ ((mode (DI)));
-typedef float float32 __attribute__ ((mode (SF)));
-typedef double float64 __attribute__ ((mode (DF)));
-typedef signed int intptr __attribute__ ((mode (pointer)));
-typedef unsigned int uintptr __attribute__ ((mode (pointer)));
-
-typedef intptr intgo; // Go's int
-typedef uintptr uintgo; // Go's uint
-
-/* Defined types. */
-
-typedef uint8 bool;
-typedef uint8 byte;
-typedef struct Func Func;
-typedef struct G G;
-typedef union Lock Lock;
-typedef struct M M;
-typedef union Note Note;
-typedef struct SigTab SigTab;
-typedef struct MCache MCache;
-typedef struct FixAlloc FixAlloc;
-typedef struct Hchan Hchan;
-typedef struct Timers Timers;
-typedef struct Timer Timer;
-typedef struct GCStats GCStats;
-typedef struct LFNode LFNode;
-typedef struct ParFor ParFor;
-typedef struct ParForThread ParForThread;
-typedef struct CgoMal CgoMal;
-
-typedef struct __go_open_array Slice;
-typedef struct String String;
-typedef struct __go_interface Iface;
-typedef struct __go_empty_interface Eface;
-typedef struct __go_type_descriptor Type;
-typedef struct __go_defer_stack Defer;
-typedef struct __go_panic_stack Panic;
-
-typedef struct __go_ptr_type PtrType;
-typedef struct __go_func_type FuncType;
-typedef struct __go_map_type MapType;
-
-typedef struct Traceback Traceback;
-
-typedef struct Location Location;
-
-/*
- * Per-CPU declaration.
- */
-extern M* runtime_m(void);
-extern G* runtime_g(void);
-
-extern M runtime_m0;
-extern G runtime_g0;
-
-/*
- * defined constants
- */
-enum
-{
- // G status
- //
- // If you add to this list, add to the list
- // of "okay during garbage collection" status
- // in mgc0.c too.
- Gidle,
- Grunnable,
- Grunning,
- Gsyscall,
- Gwaiting,
- Gmoribund,
- Gdead,
-};
-enum
-{
- true = 1,
- false = 0,
-};
-enum
-{
- PtrSize = sizeof(void*),
-};
-enum
-{
- // Per-M stack segment cache size.
- StackCacheSize = 32,
- // Global <-> per-M stack segment cache transfer batch size.
- StackCacheBatch = 16,
-};
-
-/*
- * structures
- */
-union Lock
-{
- uint32 key; // futex-based impl
- M* waitm; // linked list of waiting M's (sema-based impl)
-};
-union Note
-{
- uint32 key; // futex-based impl
- M* waitm; // waiting M (sema-based impl)
-};
-struct String
-{
- const byte* str;
- intgo len;
-};
-struct GCStats
-{
- // the struct must consist of only uint64's,
- // because it is casted to uint64[].
- uint64 nhandoff;
- uint64 nhandoffcnt;
- uint64 nprocyield;
- uint64 nosyield;
- uint64 nsleep;
-};
-
-// A location in the program, used for backtraces.
-struct Location
-{
- uintptr pc;
- String filename;
- String function;
- intgo lineno;
-};
-
-struct G
-{
- Defer* defer;
- Panic* panic;
- void* exception; // current exception being thrown
- bool is_foreign; // whether current exception from other language
- void *gcstack; // if status==Gsyscall, gcstack = stackbase to use during gc
- uintptr gcstack_size;
- void* gcnext_segment;
- void* gcnext_sp;
- void* gcinitial_sp;
- ucontext_t gcregs;
- byte* entry; // initial function
- G* alllink; // on allg
- void* param; // passed parameter on wakeup
- bool fromgogo; // reached from gogo
- int16 status;
- int64 goid;
- uint32 selgen; // valid sudog pointer
- const char* waitreason; // if status==Gwaiting
- G* schedlink;
- bool readyonstop;
- bool ispanic;
- bool issystem;
- int8 raceignore; // ignore race detection events
- M* m; // for debuggers, but offset not hard-coded
- M* lockedm;
- M* idlem;
- int32 sig;
- int32 writenbuf;
- byte* writebuf;
- // DeferChunk *dchunk;
- // DeferChunk *dchunknext;
- uintptr sigcode0;
- uintptr sigcode1;
- // uintptr sigpc;
- uintptr gopc; // pc of go statement that created this goroutine
-
- int32 ncgo;
- CgoMal* cgomal;
-
- Traceback* traceback;
-
- ucontext_t context;
- void* stack_context[10];
-};
-
-struct M
-{
- G* g0; // goroutine with scheduling stack
- G* gsignal; // signal-handling G
- G* curg; // current running goroutine
- int32 id;
- int32 mallocing;
- int32 throwing;
- int32 gcing;
- int32 locks;
- int32 nomemprof;
- int32 waitnextg;
- int32 dying;
- int32 profilehz;
- int32 helpgc;
- uint32 fastrand;
- uint64 ncgocall; // number of cgo calls in total
- Note havenextg;
- G* nextg;
- M* alllink; // on allm
- M* schedlink;
- MCache *mcache;
- G* lockedg;
- G* idleg;
- Location createstack[32]; // Stack that created this thread.
- M* nextwaitm; // next M waiting for lock
- uintptr waitsema; // semaphore for parking on locks
- uint32 waitsemacount;
- uint32 waitsemalock;
- GCStats gcstats;
- bool racecall;
- void* racepc;
-
- uintptr settype_buf[1024];
- uintptr settype_bufsize;
-
- uintptr end[];
-};
-
-struct SigTab
-{
- int32 sig;
- int32 flags;
-};
-enum
-{
- SigNotify = 1<<0, // let signal.Notify have signal, even if from kernel
- SigKill = 1<<1, // if signal.Notify doesn't take it, exit quietly
- SigThrow = 1<<2, // if signal.Notify doesn't take it, exit loudly
- SigPanic = 1<<3, // if the signal is from the kernel, panic
- SigDefault = 1<<4, // if the signal isn't explicitly requested, don't monitor it
-};
-
-#ifndef NSIG
-#define NSIG 32
-#endif
-
-// NOTE(rsc): keep in sync with extern.go:/type.Func.
-// Eventually, the loaded symbol table should be closer to this form.
-struct Func
-{
- String name;
- uintptr entry; // entry pc
-};
-
-
-#ifdef GOOS_windows
-enum {
- Windows = 1
-};
-#else
-enum {
- Windows = 0
-};
-#endif
-
-struct Timers
-{
- Lock;
- G *timerproc;
- bool sleeping;
- bool rescheduling;
- Note waitnote;
- Timer **t;
- int32 len;
- int32 cap;
-};
-
-// Package time knows the layout of this structure.
-// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
-struct Timer
-{
- int32 i; // heap index
-
- // Timer wakes up at when, and then at when+period, ... (period > 0 only)
- // each time calling f(now, arg) in the timer goroutine, so f must be
- // a well-behaved function and not block.
- int64 when;
- int64 period;
- void (*f)(int64, Eface);
- Eface arg;
-};
-
-// Lock-free stack node.
-struct LFNode
-{
- LFNode *next;
- uintptr pushcnt;
-};
-
-// Parallel for descriptor.
-struct ParFor
-{
- void (*body)(ParFor*, uint32); // executed for each element
- uint32 done; // number of idle threads
- uint32 nthr; // total number of threads
- uint32 nthrmax; // maximum number of threads
- uint32 thrseq; // thread id sequencer
- uint32 cnt; // iteration space [0, cnt)
- void *ctx; // arbitrary user context
- bool wait; // if true, wait while all threads finish processing,
- // otherwise parfor may return while other threads are still working
- ParForThread *thr; // array of thread descriptors
- // stats
- uint64 nsteal;
- uint64 nstealcnt;
- uint64 nprocyield;
- uint64 nosyield;
- uint64 nsleep;
-};
-
-// Track memory allocated by code not written in Go during a cgo call,
-// so that the garbage collector can see them.
-struct CgoMal
-{
- CgoMal *next;
- byte *alloc;
-};
-
-/*
- * defined macros
- * you need super-gopher-guru privilege
- * to add this list.
- */
-#define nelem(x) (sizeof(x)/sizeof((x)[0]))
-#define nil ((void*)0)
-#define USED(v) ((void) v)
-#define ROUND(x, n) (((x)+(n)-1)&~((n)-1)) /* all-caps to mark as macro: it evaluates n twice */
-
-/*
- * external data
- */
-extern uintptr runtime_zerobase;
-extern G* runtime_allg;
-extern G* runtime_lastg;
-extern M* runtime_allm;
-extern int32 runtime_gomaxprocs;
-extern bool runtime_singleproc;
-extern uint32 runtime_panicking;
-extern int32 runtime_gcwaiting; // gc is waiting to run
-extern int32 runtime_ncpu;
-
-/*
- * common functions and data
- */
-intgo runtime_findnull(const byte*);
-void runtime_dump(byte*, int32);
-
-/*
- * very low level c-called
- */
-void runtime_args(int32, byte**);
-void runtime_osinit();
-void runtime_goargs(void);
-void runtime_goenvs(void);
-void runtime_goenvs_unix(void);
-void runtime_throw(const char*) __attribute__ ((noreturn));
-void runtime_panicstring(const char*) __attribute__ ((noreturn));
-void runtime_prints(const char*);
-void runtime_printf(const char*, ...);
-void* runtime_mal(uintptr);
-void runtime_schedinit(void);
-void runtime_initsig(void);
-void runtime_sigenable(uint32 sig);
-int32 runtime_gotraceback(void);
-void runtime_goroutineheader(G*);
-void runtime_goroutinetrailer(G*);
-void runtime_traceback();
-void runtime_tracebackothers(G*);
-void runtime_printtrace(Location*, int32, bool);
-String runtime_gostring(const byte*);
-String runtime_gostringnocopy(const byte*);
-void* runtime_mstart(void*);
-G* runtime_malg(int32, byte**, size_t*);
-void runtime_minit(void);
-void runtime_mallocinit(void);
-void runtime_gosched(void);
-void runtime_park(void(*)(Lock*), Lock*, const char*);
-void runtime_tsleep(int64, const char*);
-M* runtime_newm(void);
-void runtime_goexit(void);
-void runtime_entersyscall(void) __asm__ (GOSYM_PREFIX "syscall.Entersyscall");
-void runtime_exitsyscall(void) __asm__ (GOSYM_PREFIX "syscall.Exitsyscall");
-void siginit(void);
-bool __go_sigsend(int32 sig);
-int32 runtime_callers(int32, Location*, int32);
-int64 runtime_nanotime(void);
-int64 runtime_cputicks(void);
-int64 runtime_tickspersecond(void);
-void runtime_blockevent(int64, int32);
-extern int64 runtime_blockprofilerate;
-
-void runtime_stoptheworld(void);
-void runtime_starttheworld(void);
-extern uint32 runtime_worldsema;
-G* __go_go(void (*pfn)(void*), void*);
-
-/*
- * mutual exclusion locks. in the uncontended case,
- * as fast as spin locks (just a few user-level instructions),
- * but on the contention path they sleep in the kernel.
- * a zeroed Lock is unlocked (no need to initialize each lock).
- */
-void runtime_lock(Lock*);
-void runtime_unlock(Lock*);
-
-/*
- * sleep and wakeup on one-time events.
- * before any calls to notesleep or notewakeup,
- * must call noteclear to initialize the Note.
- * then, exactly one thread can call notesleep
- * and exactly one thread can call notewakeup (once).
- * once notewakeup has been called, the notesleep
- * will return. future notesleep will return immediately.
- * subsequent noteclear must be called only after
- * previous notesleep has returned, e.g. it's disallowed
- * to call noteclear straight after notewakeup.
- *
- * notetsleep is like notesleep but wakes up after
- * a given number of nanoseconds even if the event
- * has not yet happened. if a goroutine uses notetsleep to
- * wake up early, it must wait to call noteclear until it
- * can be sure that no other goroutine is calling
- * notewakeup.
- */
-void runtime_noteclear(Note*);
-void runtime_notesleep(Note*);
-void runtime_notewakeup(Note*);
-void runtime_notetsleep(Note*, int64);
-
-/*
- * low-level synchronization for implementing the above
- */
-uintptr runtime_semacreate(void);
-int32 runtime_semasleep(int64);
-void runtime_semawakeup(M*);
-// or
-void runtime_futexsleep(uint32*, uint32, int64);
-void runtime_futexwakeup(uint32*, uint32);
-
-/*
- * Lock-free stack.
- * Initialize uint64 head to 0, compare with 0 to test for emptiness.
- * The stack does not keep pointers to nodes,
- * so they can be garbage collected if there are no other pointers to nodes.
- */
-void runtime_lfstackpush(uint64 *head, LFNode *node)
- __asm__ (GOSYM_PREFIX "runtime.lfstackpush");
-LFNode* runtime_lfstackpop(uint64 *head);
-
-/*
- * Parallel for over [0, n).
- * body() is executed for each iteration.
- * nthr - total number of worker threads.
- * ctx - arbitrary user context.
- * if wait=true, threads return from parfor() when all work is done;
- * otherwise, threads can return while other threads are still finishing processing.
- */
-ParFor* runtime_parforalloc(uint32 nthrmax);
-void runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32));
-void runtime_parfordo(ParFor *desc) __asm__ (GOSYM_PREFIX "runtime.parfordo");
-
-/*
- * low level C-called
- */
-#define runtime_mmap mmap
-#define runtime_munmap munmap
-#define runtime_madvise madvise
-#define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size))
-#define runtime_getcallerpc(p) __builtin_return_address(0)
-
-#ifdef __rtems__
-void __wrap_rtems_task_variable_add(void **);
-#endif
-
-/*
- * Names generated by gccgo.
- */
-#define runtime_printbool __go_print_bool
-#define runtime_printfloat __go_print_double
-#define runtime_printint __go_print_int64
-#define runtime_printiface __go_print_interface
-#define runtime_printeface __go_print_empty_interface
-#define runtime_printstring __go_print_string
-#define runtime_printpointer __go_print_pointer
-#define runtime_printuint __go_print_uint64
-#define runtime_printslice __go_print_slice
-#define runtime_printcomplex __go_print_complex
-
-/*
- * runtime go-called
- */
-void runtime_printbool(_Bool);
-void runtime_printfloat(double);
-void runtime_printint(int64);
-void runtime_printiface(Iface);
-void runtime_printeface(Eface);
-void runtime_printstring(String);
-void runtime_printpc(void*);
-void runtime_printpointer(void*);
-void runtime_printuint(uint64);
-void runtime_printhex(uint64);
-void runtime_printslice(Slice);
-void runtime_printcomplex(__complex double);
-
-struct __go_func_type;
-void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool,
- void **, void **)
- __asm__ (GOSYM_PREFIX "reflect.call");
-
-/* Functions. */
-#define runtime_panic __go_panic
-#define runtime_write(d, v, n) write((d), (v), (n))
-#define runtime_malloc(s) __go_alloc(s)
-#define runtime_free(p) __go_free(p)
-#define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2))
-#define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s))
-#define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s))
-#define runtime_exit(s) exit(s)
-MCache* runtime_allocmcache(void);
-void free(void *v);
-#define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
-#define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new)
-#define runtime_cas64(pval, pold, new) __atomic_compare_exchange_n (pval, pold, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
-#define runtime_xadd(p, v) __sync_add_and_fetch (p, v)
-#define runtime_xadd64(p, v) __sync_add_and_fetch (p, v)
-#define runtime_xchg(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicload(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicstore(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
-#define runtime_atomicload64(p) __atomic_load_n (p, __ATOMIC_SEQ_CST)
-#define runtime_atomicstore64(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST)
-#define PREFETCH(p) __builtin_prefetch(p)
-
-struct __go_func_type;
-bool runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type *);
-#define runtime_getcallersp(p) __builtin_frame_address(1)
-int32 runtime_mcount(void);
-int32 runtime_gcount(void);
-void runtime_dopanic(int32) __attribute__ ((noreturn));
-void runtime_startpanic(void);
-void runtime_ready(G*);
-const byte* runtime_getenv(const char*);
-int32 runtime_atoi(const byte*);
-uint32 runtime_fastrand1(void);
-
-void runtime_sigprof();
-void runtime_resetcpuprofiler(int32);
-void runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
-void runtime_usleep(uint32);
-
-/*
- * runtime c-called (but written in Go)
- */
-void runtime_printany(Eface)
- __asm__ (GOSYM_PREFIX "runtime.Printany");
-void runtime_newTypeAssertionError(const String*, const String*, const String*, const String*, Eface*)
- __asm__ (GOSYM_PREFIX "runtime.NewTypeAssertionError");
-void runtime_newErrorString(String, Eface*)
- __asm__ (GOSYM_PREFIX "runtime.NewErrorString");
-
-/*
- * wrapped for go users
- */
-#define ISNAN(f) __builtin_isnan(f)
-void runtime_semacquire(uint32 volatile *);
-void runtime_semrelease(uint32 volatile *);
-int32 runtime_gomaxprocsfunc(int32 n);
-void runtime_procyield(uint32);
-void runtime_osyield(void);
-void runtime_LockOSThread(void) __asm__ (GOSYM_PREFIX "runtime.LockOSThread");
-void runtime_UnlockOSThread(void) __asm__ (GOSYM_PREFIX "runtime.UnlockOSThread");
-
-bool runtime_showframe(String, bool);
-
-uintptr runtime_memlimit(void);
-
-// If appropriate, ask the operating system to control whether this
-// thread should receive profiling signals. This is only necessary on OS X.
-// An operating system should not deliver a profiling signal to a
-// thread that is not actually executing (what good is that?), but that's
-// what OS X prefers to do. When profiling is turned on, we mask
-// away the profiling signal when threads go to sleep, so that OS X
-// is forced to deliver the signal to a thread that's actually running.
-// This is a no-op on other systems.
-void runtime_setprof(bool);
-
-enum
-{
- UseSpanType = 1,
-};
-
-void runtime_setsig(int32, bool, bool);
-#define runtime_setitimer setitimer
-
-void runtime_check(void);
-
-// A list of global variables that the garbage collector must scan.
-struct root_list {
- struct root_list *next;
- struct root {
- void *decl;
- size_t size;
- } roots[];
-};
-
-void __go_register_gc_roots(struct root_list*);
-
-// Size of stack space allocated using Go's allocator.
-// This will be 0 when using split stacks, as in that case
-// the stacks are allocated by the splitstack library.
-extern uintptr runtime_stacks_sys;
-
-struct backtrace_state;
-extern struct backtrace_state *__go_get_backtrace_state(void);
-extern _Bool __go_file_line(uintptr, String*, String*, intgo *);
-extern byte* runtime_progname();
-
-int32 getproccount(void);
diff --git a/gcc-4.8.1/libgo/runtime/runtime1.goc b/gcc-4.8.1/libgo/runtime/runtime1.goc
deleted file mode 100644
index 9ce83000b..000000000
--- a/gcc-4.8.1/libgo/runtime/runtime1.goc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 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.
-
-package runtime
-#include "runtime.h"
-
-func GOMAXPROCS(n int) (ret int) {
- ret = runtime_gomaxprocsfunc(n);
-}
-
-func NumCPU() (ret int) {
- ret = runtime_ncpu;
-}
diff --git a/gcc-4.8.1/libgo/runtime/sema.goc b/gcc-4.8.1/libgo/runtime/sema.goc
deleted file mode 100644
index 4622f6c8a..000000000
--- a/gcc-4.8.1/libgo/runtime/sema.goc
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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.
-
-// Semaphore implementation exposed to Go.
-// Intended use is provide a sleep and wakeup
-// primitive that can be used in the contended case
-// of other synchronization primitives.
-// Thus it targets the same goal as Linux's futex,
-// but it has much simpler semantics.
-//
-// That is, don't think of these as semaphores.
-// Think of them as a way to implement sleep and wakeup
-// such that every sleep is paired with a single wakeup,
-// even if, due to races, the wakeup happens before the sleep.
-//
-// See Mullender and Cox, ``Semaphores in Plan 9,''
-// http://swtch.com/semaphore.pdf
-
-package sync
-#include "runtime.h"
-#include "arch.h"
-
-typedef struct Sema Sema;
-struct Sema
-{
- uint32 volatile* addr;
- G* g;
- int64 releasetime;
- Sema* prev;
- Sema* next;
-};
-
-typedef struct SemaRoot SemaRoot;
-struct SemaRoot
-{
- Lock;
- Sema* head;
- Sema* tail;
- // Number of waiters. Read w/o the lock.
- uint32 volatile nwait;
-};
-
-// Prime to not correlate with any user patterns.
-#define SEMTABLESZ 251
-
-union semtable
-{
- SemaRoot;
- uint8 pad[CacheLineSize];
-};
-static union semtable semtable[SEMTABLESZ];
-
-static SemaRoot*
-semroot(uint32 volatile *addr)
-{
- return &semtable[((uintptr)addr >> 3) % SEMTABLESZ];
-}
-
-static void
-semqueue(SemaRoot *root, uint32 volatile *addr, Sema *s)
-{
- s->g = runtime_g();
- s->addr = addr;
- s->next = nil;
- s->prev = root->tail;
- if(root->tail)
- root->tail->next = s;
- else
- root->head = s;
- root->tail = s;
-}
-
-static void
-semdequeue(SemaRoot *root, Sema *s)
-{
- if(s->next)
- s->next->prev = s->prev;
- else
- root->tail = s->prev;
- if(s->prev)
- s->prev->next = s->next;
- else
- root->head = s->next;
- s->prev = nil;
- s->next = nil;
-}
-
-static int32
-cansemacquire(uint32 volatile *addr)
-{
- uint32 v;
-
- while((v = runtime_atomicload(addr)) > 0)
- if(runtime_cas(addr, v, v-1))
- return 1;
- return 0;
-}
-
-static void
-semacquireimpl(uint32 volatile *addr, int32 profile)
-{
- Sema s; // Needs to be allocated on stack, otherwise garbage collector could deallocate it
- SemaRoot *root;
- int64 t0;
-
- // Easy case.
- if(cansemacquire(addr))
- return;
-
- // Harder case:
- // increment waiter count
- // try cansemacquire one more time, return if succeeded
- // enqueue itself as a waiter
- // sleep
- // (waiter descriptor is dequeued by signaler)
- root = semroot(addr);
- t0 = 0;
- s.releasetime = 0;
- if(profile && runtime_blockprofilerate > 0) {
- t0 = runtime_cputicks();
- s.releasetime = -1;
- }
- for(;;) {
-
- runtime_lock(root);
- // Add ourselves to nwait to disable "easy case" in semrelease.
- runtime_xadd(&root->nwait, 1);
- // Check cansemacquire to avoid missed wakeup.
- if(cansemacquire(addr)) {
- runtime_xadd(&root->nwait, -1);
- runtime_unlock(root);
- return;
- }
- // Any semrelease after the cansemacquire knows we're waiting
- // (we set nwait above), so go to sleep.
- semqueue(root, addr, &s);
- runtime_park(runtime_unlock, root, "semacquire");
- if(cansemacquire(addr)) {
- if(t0)
- runtime_blockevent(s.releasetime - t0, 3);
- return;
- }
- }
-}
-
-void
-runtime_semacquire(uint32 volatile *addr)
-{
- semacquireimpl(addr, 0);
-}
-
-void
-runtime_semrelease(uint32 volatile *addr)
-{
- Sema *s;
- SemaRoot *root;
-
- root = semroot(addr);
- runtime_xadd(addr, 1);
-
- // Easy case: no waiters?
- // This check must happen after the xadd, to avoid a missed wakeup
- // (see loop in semacquire).
- if(runtime_atomicload(&root->nwait) == 0)
- return;
-
- // Harder case: search for a waiter and wake it.
- runtime_lock(root);
- if(runtime_atomicload(&root->nwait) == 0) {
- // The count is already consumed by another goroutine,
- // so no need to wake up another goroutine.
- runtime_unlock(root);
- return;
- }
- for(s = root->head; s; s = s->next) {
- if(s->addr == addr) {
- runtime_xadd(&root->nwait, -1);
- semdequeue(root, s);
- break;
- }
- }
- runtime_unlock(root);
- if(s) {
- if(s->releasetime)
- s->releasetime = runtime_cputicks();
- runtime_ready(s->g);
- }
-}
-
-func runtime_Semacquire(addr *uint32) {
- semacquireimpl(addr, 1);
-}
-
-func runtime_Semrelease(addr *uint32) {
- runtime_semrelease(addr);
-}
diff --git a/gcc-4.8.1/libgo/runtime/signal_unix.c b/gcc-4.8.1/libgo/runtime/signal_unix.c
deleted file mode 100644
index 3b8f43937..000000000
--- a/gcc-4.8.1/libgo/runtime/signal_unix.c
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2012 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.
-
-// +build darwin freebsd linux openbsd netbsd
-
-#include <sys/time.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-extern SigTab runtime_sigtab[];
-
-void
-runtime_initsig(void)
-{
- int32 i;
- SigTab *t;
-
- // First call: basic setup.
- for(i = 0; runtime_sigtab[i].sig != -1; i++) {
- t = &runtime_sigtab[i];
- if((t->flags == 0) || (t->flags & SigDefault))
- continue;
- runtime_setsig(i, false, true);
- }
-}
-
-void
-runtime_sigenable(uint32 sig)
-{
- int32 i;
- SigTab *t;
-
- for(i = 0; runtime_sigtab[i].sig != -1; i++) {
- // ~0 means all signals.
- if(~sig == 0 || runtime_sigtab[i].sig == (int32)sig) {
- t = &runtime_sigtab[i];
- if(t->flags & SigDefault) {
- runtime_setsig(i, false, true);
- t->flags &= ~SigDefault; // make this idempotent
- }
- }
- }
-}
-
-void
-runtime_resetcpuprofiler(int32 hz)
-{
- struct itimerval it;
-
- runtime_memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime_setitimer(ITIMER_PROF, &it, nil);
- runtime_setprof(false);
- } else {
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime_setitimer(ITIMER_PROF, &it, nil);
- runtime_setprof(true);
- }
- runtime_m()->profilehz = hz;
-}
diff --git a/gcc-4.8.1/libgo/runtime/sigqueue.goc b/gcc-4.8.1/libgo/runtime/sigqueue.goc
deleted file mode 100644
index 82b0400d6..000000000
--- a/gcc-4.8.1/libgo/runtime/sigqueue.goc
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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.
-
-// This file implements runtime support for signal handling.
-//
-// Most synchronization primitives are not available from
-// the signal handler (it cannot block, allocate memory, or use locks)
-// so the handler communicates with a processing goroutine
-// via struct sig, below.
-//
-// sigsend() is called by the signal handler to queue a new signal.
-// signal_recv() is called by the Go program to receive a newly queued signal.
-// Synchronization between sigsend() and signal_recv() is based on the sig.state
-// variable. It can be in 3 states: 0, HASWAITER and HASSIGNAL.
-// HASWAITER means that signal_recv() is blocked on sig.Note and there are no
-// new pending signals.
-// HASSIGNAL means that sig.mask *may* contain new pending signals,
-// signal_recv() can't be blocked in this state.
-// 0 means that there are no new pending signals and signal_recv() is not blocked.
-// Transitions between states are done atomically with CAS.
-// When signal_recv() is unblocked, it resets sig.Note and rechecks sig.mask.
-// If several sigsend()'s and signal_recv() execute concurrently, it can lead to
-// unnecessary rechecks of sig.mask, but must not lead to missed signals
-// nor deadlocks.
-
-package signal
-#include "config.h"
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "defs.h"
-
-static struct {
- Note;
- uint32 mask[(NSIG+31)/32];
- uint32 wanted[(NSIG+31)/32];
- uint32 state;
- bool inuse;
-} sig;
-
-enum {
- HASWAITER = 1,
- HASSIGNAL = 2,
-};
-
-// Called from sighandler to send a signal back out of the signal handling thread.
-bool
-__go_sigsend(int32 s)
-{
- uint32 bit, mask, old, new;
-
- if(!sig.inuse || s < 0 || (size_t)s >= 32*nelem(sig.wanted) || !(sig.wanted[s/32]&(1U<<(s&31))))
- return false;
- bit = 1 << (s&31);
- for(;;) {
- mask = sig.mask[s/32];
- if(mask & bit)
- break; // signal already in queue
- if(runtime_cas(&sig.mask[s/32], mask, mask|bit)) {
- // Added to queue.
- // Only send a wakeup if the receiver needs a kick.
- for(;;) {
- old = runtime_atomicload(&sig.state);
- if(old == HASSIGNAL)
- break;
- if(old == HASWAITER)
- new = 0;
- else // if(old == 0)
- new = HASSIGNAL;
- if(runtime_cas(&sig.state, old, new)) {
- if (old == HASWAITER)
- runtime_notewakeup(&sig);
- break;
- }
- }
- break;
- }
- }
- return true;
-}
-
-// Called to receive the next queued signal.
-// Must only be called from a single goroutine at a time.
-func signal_recv() (m uint32) {
- static uint32 recv[nelem(sig.mask)];
- uint32 i, old, new;
-
- for(;;) {
- // Serve from local copy if there are bits left.
- for(i=0; i<NSIG; i++) {
- if(recv[i/32]&(1U<<(i&31))) {
- recv[i/32] ^= 1U<<(i&31);
- m = i;
- goto done;
- }
- }
-
- // Check and update sig.state.
- for(;;) {
- old = runtime_atomicload(&sig.state);
- if(old == HASWAITER)
- runtime_throw("inconsistent state in signal_recv");
- if(old == HASSIGNAL)
- new = 0;
- else // if(old == 0)
- new = HASWAITER;
- if(runtime_cas(&sig.state, old, new)) {
- if (new == HASWAITER) {
- runtime_entersyscall();
- runtime_notesleep(&sig);
- runtime_exitsyscall();
- runtime_noteclear(&sig);
- }
- break;
- }
- }
-
- // Get a new local copy.
- for(i=0; (size_t)i<nelem(sig.mask); i++) {
- for(;;) {
- m = sig.mask[i];
- if(runtime_cas(&sig.mask[i], m, 0))
- break;
- }
- recv[i] = m;
- }
- }
-
-done:;
- // goc requires that we fall off the end of functions
- // that return values instead of using our own return
- // statements.
-}
-
-// Must only be called from a single goroutine at a time.
-func signal_enable(s uint32) {
- int32 i;
-
- if(!sig.inuse) {
- // The first call to signal_enable is for us
- // to use for initialization. It does not pass
- // signal information in m.
- sig.inuse = true; // enable reception of signals; cannot disable
- runtime_noteclear(&sig);
- return;
- }
-
- if(~s == 0) {
- // Special case: want everything.
- for(i=0; (size_t)i<nelem(sig.wanted); i++)
- sig.wanted[i] = ~(uint32)0;
- runtime_sigenable(s);
- return;
- }
-
- if(s >= nelem(sig.wanted)*32)
- return;
- sig.wanted[s/32] |= 1U<<(s&31);
- runtime_sigenable(s);
-}
diff --git a/gcc-4.8.1/libgo/runtime/string.goc b/gcc-4.8.1/libgo/runtime/string.goc
deleted file mode 100644
index 04ecbe6f7..000000000
--- a/gcc-4.8.1/libgo/runtime/string.goc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2009, 2010 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.
-
-package runtime
-#include "runtime.h"
-#include "arch.h"
-#include "malloc.h"
-#include "go-string.h"
-
-#define charntorune(pv, str, len) __go_get_rune(str, len, pv)
-
-const String runtime_emptystring;
-
-intgo
-runtime_findnull(const byte *s)
-{
- if(s == nil)
- return 0;
- return __builtin_strlen((const char*) s);
-}
-
-static String
-gostringsize(intgo l, byte** pmem)
-{
- String s;
- byte *mem;
-
- if(l == 0) {
- *pmem = nil;
- return runtime_emptystring;
- }
- // leave room for NUL for C runtime (e.g., callers of getenv)
- mem = runtime_mallocgc(l+1, FlagNoPointers, 1, 0);
- s.str = mem;
- s.len = l;
- mem[l] = 0;
- *pmem = mem;
- return s;
-}
-
-String
-runtime_gostring(const byte *str)
-{
- intgo l;
- String s;
- byte *mem;
-
- l = runtime_findnull(str);
- s = gostringsize(l, &mem);
- runtime_memmove(mem, str, l);
- return s;
-}
-
-String
-runtime_gostringnocopy(const byte *str)
-{
- String s;
-
- s.str = str;
- s.len = runtime_findnull(str);
- return s;
-}
-
-enum
-{
- Runeself = 0x80,
-};
-
-func stringiter(s String, k int) (retk int) {
- int32 l;
-
- if(k >= s.len) {
- // retk=0 is end of iteration
- retk = 0;
- goto out;
- }
-
- l = s.str[k];
- if(l < Runeself) {
- retk = k+1;
- goto out;
- }
-
- // multi-char rune
- retk = k + charntorune(&l, s.str+k, s.len-k);
-
-out:
-}
-
-func stringiter2(s String, k int) (retk int, retv int32) {
- if(k >= s.len) {
- // retk=0 is end of iteration
- retk = 0;
- retv = 0;
- goto out;
- }
-
- retv = s.str[k];
- if(retv < Runeself) {
- retk = k+1;
- goto out;
- }
-
- // multi-char rune
- retk = k + charntorune(&retv, s.str+k, s.len-k);
-
-out:
-}
diff --git a/gcc-4.8.1/libgo/runtime/thread-linux.c b/gcc-4.8.1/libgo/runtime/thread-linux.c
deleted file mode 100644
index 13d23c47b..000000000
--- a/gcc-4.8.1/libgo/runtime/thread-linux.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs.h"
-
-// Linux futex.
-//
-// futexsleep(uint32 *addr, uint32 val)
-// futexwakeup(uint32 *addr)
-//
-// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
-// Futexwakeup wakes up threads sleeping on addr.
-// Futexsleep is allowed to wake up spuriously.
-
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <syscall.h>
-#include <linux/futex.h>
-
-typedef struct timespec Timespec;
-
-// Atomically,
-// if(*addr == val) sleep
-// Might be woken up spuriously; that's allowed.
-// Don't sleep longer than ns; ns < 0 means forever.
-void
-runtime_futexsleep(uint32 *addr, uint32 val, int64 ns)
-{
- Timespec ts, *tsp;
-
- if(ns < 0)
- tsp = nil;
- else {
- ts.tv_sec = ns/1000000000LL;
- ts.tv_nsec = ns%1000000000LL;
- // Avoid overflow
- if(ts.tv_sec > 1<<30)
- ts.tv_sec = 1<<30;
- tsp = &ts;
- }
-
- // Some Linux kernels have a bug where futex of
- // FUTEX_WAIT returns an internal error code
- // as an errno. Libpthread ignores the return value
- // here, and so can we: as it says a few lines up,
- // spurious wakeups are allowed.
- syscall(__NR_futex, addr, FUTEX_WAIT, val, tsp, nil, 0);
-}
-
-// If any procs are sleeping on addr, wake up at most cnt.
-void
-runtime_futexwakeup(uint32 *addr, uint32 cnt)
-{
- int64 ret;
-
- ret = syscall(__NR_futex, addr, FUTEX_WAKE, cnt, nil, nil, 0);
-
- if(ret >= 0)
- return;
-
- // I don't know that futex wakeup can return
- // EAGAIN or EINTR, but if it does, it would be
- // safe to loop and call futex again.
- runtime_printf("futexwakeup addr=%p returned %D\n", addr, ret);
- *(int32*)0x1006 = 0x1006;
-}
-
-void
-runtime_osinit(void)
-{
- runtime_ncpu = getproccount();
-}
-
-void
-runtime_goenvs(void)
-{
- runtime_goenvs_unix();
-}
diff --git a/gcc-4.8.1/libgo/runtime/thread-sema.c b/gcc-4.8.1/libgo/runtime/thread-sema.c
deleted file mode 100644
index 18827b025..000000000
--- a/gcc-4.8.1/libgo/runtime/thread-sema.c
+++ /dev/null
@@ -1,148 +0,0 @@
-// 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.
-
-#include "config.h"
-#include "runtime.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-#include <semaphore.h>
-
-/* If we don't have sem_timedwait, use pthread_cond_timedwait instead.
- We don't always use condition variables because on some systems
- pthread_mutex_lock and pthread_mutex_unlock must be called by the
- same thread. That is never true of semaphores. */
-
-struct go_sem
-{
- sem_t sem;
-
-#ifndef HAVE_SEM_TIMEDWAIT
- int timedwait;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-#endif
-};
-
-/* Create a semaphore. */
-
-uintptr
-runtime_semacreate(void)
-{
- struct go_sem *p;
-
- /* Call malloc rather than runtime_malloc. This will allocate space
- on the C heap. We can't call runtime_malloc here because it
- could cause a deadlock. */
- p = malloc (sizeof (struct go_sem));
- if (sem_init (&p->sem, 0, 0) != 0)
- runtime_throw ("sem_init");
-
-#ifndef HAVE_SEM_TIMEDWAIT
- if (pthread_mutex_init (&p->mutex, NULL) != 0)
- runtime_throw ("pthread_mutex_init");
- if (pthread_cond_init (&p->cond, NULL) != 0)
- runtime_throw ("pthread_cond_init");
-#endif
-
- return (uintptr) p;
-}
-
-/* Acquire m->waitsema. */
-
-int32
-runtime_semasleep (int64 ns)
-{
- M *m;
- struct go_sem *sem;
- int r;
-
- m = runtime_m ();
- sem = (struct go_sem *) m->waitsema;
- if (ns >= 0)
- {
- int64 abs;
- struct timespec ts;
- int err;
-
- abs = ns + runtime_nanotime ();
- ts.tv_sec = abs / 1000000000LL;
- ts.tv_nsec = abs % 1000000000LL;
-
- err = 0;
-
-#ifdef HAVE_SEM_TIMEDWAIT
- r = sem_timedwait (&sem->sem, &ts);
- if (r != 0)
- err = errno;
-#else
- if (pthread_mutex_lock (&sem->mutex) != 0)
- runtime_throw ("pthread_mutex_lock");
-
- while ((r = sem_trywait (&sem->sem)) != 0)
- {
- r = pthread_cond_timedwait (&sem->cond, &sem->mutex, &ts);
- if (r != 0)
- {
- err = r;
- break;
- }
- }
-
- if (pthread_mutex_unlock (&sem->mutex) != 0)
- runtime_throw ("pthread_mutex_unlock");
-#endif
-
- if (err != 0)
- {
- if (err == ETIMEDOUT || err == EAGAIN || err == EINTR)
- return -1;
- runtime_throw ("sema_timedwait");
- }
- return 0;
- }
-
- while (sem_wait (&sem->sem) != 0)
- {
- if (errno == EINTR)
- continue;
- runtime_throw ("sem_wait");
- }
-
- return 0;
-}
-
-/* Wake up mp->waitsema. */
-
-void
-runtime_semawakeup (M *mp)
-{
- struct go_sem *sem;
-
- sem = (struct go_sem *) mp->waitsema;
- if (sem_post (&sem->sem) != 0)
- runtime_throw ("sem_post");
-
-#ifndef HAVE_SEM_TIMEDWAIT
- if (pthread_mutex_lock (&sem->mutex) != 0)
- runtime_throw ("pthread_mutex_lock");
- if (pthread_cond_broadcast (&sem->cond) != 0)
- runtime_throw ("pthread_cond_broadcast");
- if (pthread_mutex_unlock (&sem->mutex) != 0)
- runtime_throw ("pthread_mutex_unlock");
-#endif
-}
-
-void
-runtime_osinit (void)
-{
- runtime_ncpu = getproccount();
-}
-
-void
-runtime_goenvs (void)
-{
- runtime_goenvs_unix ();
-}
diff --git a/gcc-4.8.1/libgo/runtime/thread.c b/gcc-4.8.1/libgo/runtime/thread.c
deleted file mode 100644
index 12d009926..000000000
--- a/gcc-4.8.1/libgo/runtime/thread.c
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2010 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.
-
-#include <errno.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include "runtime.h"
-#include "go-assert.h"
-
-/* For targets which don't have the required sync support. Really
- these should be provided by gcc itself. FIXME. */
-
-#if !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4) || !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8) || !defined (HAVE_SYNC_FETCH_AND_ADD_4) || !defined (HAVE_SYNC_ADD_AND_FETCH_8)
-
-static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#endif
-
-#ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
-
-_Bool
-__sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
- __attribute__ ((visibility ("hidden")));
-
-_Bool
-__sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new)
-{
- int i;
- _Bool ret;
-
- i = pthread_mutex_lock (&sync_lock);
- __go_assert (i == 0);
-
- if (*ptr != old)
- ret = 0;
- else
- {
- *ptr = new;
- ret = 1;
- }
-
- i = pthread_mutex_unlock (&sync_lock);
- __go_assert (i == 0);
-
- return ret;
-}
-
-#endif
-
-#ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
-
-_Bool
-__sync_bool_compare_and_swap_8 (uint64*, uint64, uint64)
- __attribute__ ((visibility ("hidden")));
-
-_Bool
-__sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new)
-{
- int i;
- _Bool ret;
-
- i = pthread_mutex_lock (&sync_lock);
- __go_assert (i == 0);
-
- if (*ptr != old)
- ret = 0;
- else
- {
- *ptr = new;
- ret = 1;
- }
-
- i = pthread_mutex_unlock (&sync_lock);
- __go_assert (i == 0);
-
- return ret;
-}
-
-#endif
-
-#ifndef HAVE_SYNC_FETCH_AND_ADD_4
-
-uint32
-__sync_fetch_and_add_4 (uint32*, uint32)
- __attribute__ ((visibility ("hidden")));
-
-uint32
-__sync_fetch_and_add_4 (uint32* ptr, uint32 add)
-{
- int i;
- uint32 ret;
-
- i = pthread_mutex_lock (&sync_lock);
- __go_assert (i == 0);
-
- ret = *ptr;
- *ptr += add;
-
- i = pthread_mutex_unlock (&sync_lock);
- __go_assert (i == 0);
-
- return ret;
-}
-
-#endif
-
-#ifndef HAVE_SYNC_ADD_AND_FETCH_8
-
-uint64
-__sync_add_and_fetch_8 (uint64*, uint64)
- __attribute__ ((visibility ("hidden")));
-
-uint64
-__sync_add_and_fetch_8 (uint64* ptr, uint64 add)
-{
- int i;
- uint64 ret;
-
- i = pthread_mutex_lock (&sync_lock);
- __go_assert (i == 0);
-
- *ptr += add;
- ret = *ptr;
-
- i = pthread_mutex_unlock (&sync_lock);
- __go_assert (i == 0);
-
- return ret;
-}
-
-#endif
-
-// Called to initialize a new m (including the bootstrap m).
-void
-runtime_minit(void)
-{
- byte* stack;
- size_t stacksize;
- stack_t ss;
- sigset_t sigs;
-
- // Initialize signal handling.
- runtime_m()->gsignal = runtime_malg(32*1024, &stack, &stacksize); // OS X wants >=8K, Linux >=2K
- ss.ss_sp = stack;
- ss.ss_flags = 0;
- ss.ss_size = stacksize;
- if(sigaltstack(&ss, nil) < 0)
- *(int *)0xf1 = 0xf1;
- if (sigemptyset(&sigs) != 0)
- runtime_throw("sigemptyset");
- sigprocmask(SIG_SETMASK, &sigs, nil);
-}
-
-uintptr
-runtime_memlimit(void)
-{
- struct rlimit rl;
- uintptr used;
-
- if(getrlimit(RLIMIT_AS, &rl) != 0)
- return 0;
- if(rl.rlim_cur >= 0x7fffffff)
- return 0;
-
- // Estimate our VM footprint excluding the heap.
- // Not an exact science: use size of binary plus
- // some room for thread stacks.
- used = (64<<20);
- if(used >= rl.rlim_cur)
- return 0;
-
- // If there's not at least 16 MB left, we're probably
- // not going to be able to do much. Treat as no limit.
- rl.rlim_cur -= used;
- if(rl.rlim_cur < (16<<20))
- return 0;
-
- return rl.rlim_cur - used;
-}
diff --git a/gcc-4.8.1/libgo/runtime/time.goc b/gcc-4.8.1/libgo/runtime/time.goc
deleted file mode 100644
index 9a5cbdfed..000000000
--- a/gcc-4.8.1/libgo/runtime/time.goc
+++ /dev/null
@@ -1,263 +0,0 @@
-// 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.
-
-// Time-related runtime and pieces of package time.
-
-package time
-
-#include "runtime.h"
-#include "defs.h"
-#include "arch.h"
-#include "malloc.h"
-#include "race.h"
-
-static Timers timers;
-static void addtimer(Timer*);
-static bool deltimer(Timer*);
-
-// Package time APIs.
-// Godoc uses the comments in package time, not these.
-
-// time.now is implemented in assembly.
-
-// Sleep puts the current goroutine to sleep for at least ns nanoseconds.
-func Sleep(ns int64) {
- runtime_tsleep(ns, "sleep");
-}
-
-// startTimer adds t to the timer heap.
-func startTimer(t *Timer) {
- if(raceenabled)
- runtime_racerelease(t);
- runtime_lock(&timers);
- addtimer(t);
- runtime_unlock(&timers);
-}
-
-// stopTimer removes t from the timer heap if it is there.
-// It returns true if t was removed, false if t wasn't even there.
-func stopTimer(t *Timer) (stopped bool) {
- stopped = deltimer(t);
-}
-
-// C runtime.
-
-static void timerproc(void*);
-static void siftup(int32);
-static void siftdown(int32);
-
-// Ready the goroutine e.data.
-static void
-ready(int64 now, Eface e)
-{
- USED(now);
-
- runtime_ready(e.__object);
-}
-
-// Put the current goroutine to sleep for ns nanoseconds.
-void
-runtime_tsleep(int64 ns, const char *reason)
-{
- G* g;
- Timer t;
-
- g = runtime_g();
-
- if(ns <= 0)
- return;
-
- t.when = runtime_nanotime() + ns;
- t.period = 0;
- t.f = ready;
- t.arg.__object = g;
- runtime_lock(&timers);
- addtimer(&t);
- runtime_park(runtime_unlock, &timers, reason);
-}
-
-// Add a timer to the heap and start or kick the timer proc
-// if the new timer is earlier than any of the others.
-static void
-addtimer(Timer *t)
-{
- int32 n;
- Timer **nt;
-
- if(timers.len >= timers.cap) {
- // Grow slice.
- n = 16;
- if(n <= timers.cap)
- n = timers.cap*3 / 2;
- nt = runtime_malloc(n*sizeof nt[0]);
- runtime_memmove(nt, timers.t, timers.len*sizeof nt[0]);
- runtime_free(timers.t);
- timers.t = nt;
- timers.cap = n;
- }
- t->i = timers.len++;
- timers.t[t->i] = t;
- siftup(t->i);
- if(t->i == 0) {
- // siftup moved to top: new earliest deadline.
- if(timers.sleeping) {
- timers.sleeping = false;
- runtime_notewakeup(&timers.waitnote);
- }
- if(timers.rescheduling) {
- timers.rescheduling = false;
- runtime_ready(timers.timerproc);
- }
- }
- if(timers.timerproc == nil) {
- timers.timerproc = __go_go(timerproc, nil);
- timers.timerproc->issystem = true;
- }
-}
-
-// Delete timer t from the heap.
-// Do not need to update the timerproc:
-// if it wakes up early, no big deal.
-static bool
-deltimer(Timer *t)
-{
- int32 i;
-
- runtime_lock(&timers);
-
- // t may not be registered anymore and may have
- // a bogus i (typically 0, if generated by Go).
- // Verify it before proceeding.
- i = t->i;
- if(i < 0 || i >= timers.len || timers.t[i] != t) {
- runtime_unlock(&timers);
- return false;
- }
-
- timers.len--;
- if(i == timers.len) {
- timers.t[i] = nil;
- } else {
- timers.t[i] = timers.t[timers.len];
- timers.t[timers.len] = nil;
- timers.t[i]->i = i;
- siftup(i);
- siftdown(i);
- }
- runtime_unlock(&timers);
- return true;
-}
-
-// Timerproc runs the time-driven events.
-// It sleeps until the next event in the timers heap.
-// If addtimer inserts a new earlier event, addtimer
-// wakes timerproc early.
-static void
-timerproc(void* dummy __attribute__ ((unused)))
-{
- int64 delta, now;
- Timer *t;
- void (*f)(int64, Eface);
- Eface arg;
-
- for(;;) {
- runtime_lock(&timers);
- now = runtime_nanotime();
- for(;;) {
- if(timers.len == 0) {
- delta = -1;
- break;
- }
- t = timers.t[0];
- delta = t->when - now;
- if(delta > 0)
- break;
- if(t->period > 0) {
- // leave in heap but adjust next time to fire
- t->when += t->period * (1 + -delta/t->period);
- siftdown(0);
- } else {
- // remove from heap
- timers.t[0] = timers.t[--timers.len];
- timers.t[0]->i = 0;
- siftdown(0);
- t->i = -1; // mark as removed
- }
- f = t->f;
- arg = t->arg;
- runtime_unlock(&timers);
- if(raceenabled)
- runtime_raceacquire(t);
- f(now, arg);
- runtime_lock(&timers);
- }
- if(delta < 0) {
- // No timers left - put goroutine to sleep.
- timers.rescheduling = true;
- runtime_park(runtime_unlock, &timers, "timer goroutine (idle)");
- continue;
- }
- // At least one timer pending. Sleep until then.
- timers.sleeping = true;
- runtime_noteclear(&timers.waitnote);
- runtime_unlock(&timers);
- runtime_entersyscall();
- runtime_notetsleep(&timers.waitnote, delta);
- runtime_exitsyscall();
- }
-}
-
-// heap maintenance algorithms.
-
-static void
-siftup(int32 i)
-{
- int32 p;
- Timer **t, *tmp;
-
- t = timers.t;
- while(i > 0) {
- p = (i-1)/2; // parent
- if(t[i]->when >= t[p]->when)
- break;
- tmp = t[i];
- t[i] = t[p];
- t[p] = tmp;
- t[i]->i = i;
- t[p]->i = p;
- i = p;
- }
-}
-
-static void
-siftdown(int32 i)
-{
- int32 c, len;
- Timer **t, *tmp;
-
- t = timers.t;
- len = timers.len;
- for(;;) {
- c = i*2 + 1; // left child
- if(c >= len) {
- break;
- }
- if(c+1 < len && t[c+1]->when < t[c]->when)
- c++;
- if(t[c]->when >= t[i]->when)
- break;
- tmp = t[i];
- t[i] = t[c];
- t[c] = tmp;
- t[i]->i = i;
- t[c]->i = c;
- i = c;
- }
-}
-
-void
-runtime_time_scan(void (*addroot)(Obj))
-{
- addroot((Obj){(byte*)&timers, sizeof timers, 0});
-}
diff --git a/gcc-4.8.1/libgo/runtime/yield.c b/gcc-4.8.1/libgo/runtime/yield.c
deleted file mode 100644
index 5c47719d4..000000000
--- a/gcc-4.8.1/libgo/runtime/yield.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2011 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.
-
-#include "config.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sched.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include "runtime.h"
-
-/* Spin wait. */
-
-void
-runtime_procyield (uint32 cnt)
-{
- volatile uint32 i;
-
- for (i = 0; i < cnt; ++i)
- {
-#if defined (__i386__) || defined (__x86_64__)
- __builtin_ia32_pause ();
-#endif
- }
-}
-
-/* Ask the OS to reschedule this thread. */
-
-void
-runtime_osyield (void)
-{
- sched_yield ();
-}
-
-/* Sleep for some number of microseconds. */
-
-void
-runtime_usleep (uint32 us)
-{
- struct timeval tv;
-
- tv.tv_sec = us / 1000000;
- tv.tv_usec = us % 1000000;
- select (0, NULL, NULL, NULL, &tv);
-}