aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-10-28 22:34:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-10-28 22:34:47 +0000
commit94f56408db96e2e12f6e1322ed2c1c465df934f6 (patch)
treef5eaac76bc47cc2637e5e30b9ff6c27499fac2d9 /libgo
parent21f1031d6cc228e2b468338b3dfa4303d54ac207 (diff)
downloadgcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.zip
gcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.tar.gz
gcc-94f56408db96e2e12f6e1322ed2c1c465df934f6.tar.bz2
compiler, runtime: copy slice code from Go 1.7 runtime
Change the compiler handle append as the gc compiler does: call a function to grow the slice, but otherwise assign the new elements directly to the final slice. For the current gccgo memory allocator the slice code has to call runtime_newarray, not mallocgc directly, so that the allocator sets the TypeInfo_Array bit in the type pointer. Rename the static function cnew to runtime_docnew, so that the stack trace ignores it when ignoring runtime functions. This was needed to fix the runtime/pprof tests on 386. Reviewed-on: https://go-review.googlesource.com/32218 From-SVN: r241667
Diffstat (limited to 'libgo')
-rw-r--r--libgo/Makefile.am3
-rw-r--r--libgo/Makefile.in60
-rw-r--r--libgo/go/runtime/slice.go212
-rw-r--r--libgo/go/runtime/stubs.go25
-rw-r--r--libgo/runtime/go-append.c74
-rw-r--r--libgo/runtime/go-copy.c22
-rw-r--r--libgo/runtime/go-make-slice.c99
-rw-r--r--libgo/runtime/malloc.goc8
-rw-r--r--libgo/runtime/runtime.h3
9 files changed, 254 insertions, 252 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 2e46ecd..8237bb6 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -428,7 +428,6 @@ endif
endif
runtime_files = \
- runtime/go-append.c \
runtime/go-assert.c \
runtime/go-breakpoint.c \
runtime/go-caller.c \
@@ -436,12 +435,10 @@ runtime_files = \
runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-construct-map.c \
- runtime/go-copy.c \
runtime/go-defer.c \
runtime/go-deferred-recover.c \
runtime/go-ffi.c \
runtime/go-fieldtrack.c \
- runtime/go-make-slice.c \
runtime/go-matherr.c \
runtime/go-memclr.c \
runtime/go-memcmp.c \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 25b5a7b..50fc3f6 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -237,23 +237,22 @@ libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_4 = \
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ getncpu-bsd.lo
@LIBGO_IS_LINUX_TRUE@am__objects_4 = getncpu-linux.lo
-am__objects_5 = go-append.lo go-assert.lo go-breakpoint.lo \
- go-caller.lo go-callers.lo go-cdiv.lo go-cgo.lo \
- go-construct-map.lo go-copy.lo go-defer.lo \
- go-deferred-recover.lo go-ffi.lo go-fieldtrack.lo \
- go-make-slice.lo go-matherr.lo go-memclr.lo go-memcmp.lo \
- go-memequal.lo go-memmove.lo go-nanotime.lo go-now.lo \
- go-new.lo go-nosys.lo go-panic.lo go-recover.lo \
- go-reflect-call.lo go-runtime-error.lo go-setenv.lo \
- go-signal.lo go-strslice.lo go-type-complex.lo \
- go-type-float.lo go-type-identity.lo go-type-string.lo \
- go-typedesc-equal.lo go-unsafe-new.lo go-unsafe-newarray.lo \
- go-unsafe-pointer.lo go-unsetenv.lo go-unwind.lo go-varargs.lo \
- env_posix.lo heapdump.lo mcache.lo mcentral.lo \
- $(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo msize.lo \
- panic.lo parfor.lo print.lo proc.lo runtime.lo signal_unix.lo \
- thread.lo $(am__objects_2) yield.lo $(am__objects_3) malloc.lo \
- runtime1.lo sigqueue.lo $(am__objects_4)
+am__objects_5 = go-assert.lo go-breakpoint.lo go-caller.lo \
+ go-callers.lo go-cdiv.lo go-cgo.lo go-construct-map.lo \
+ go-defer.lo go-deferred-recover.lo go-ffi.lo go-fieldtrack.lo \
+ go-matherr.lo go-memclr.lo go-memcmp.lo go-memequal.lo \
+ go-memmove.lo go-nanotime.lo go-now.lo go-new.lo go-nosys.lo \
+ go-panic.lo go-recover.lo go-reflect-call.lo \
+ go-runtime-error.lo go-setenv.lo go-signal.lo go-strslice.lo \
+ go-type-complex.lo go-type-float.lo go-type-identity.lo \
+ go-type-string.lo go-typedesc-equal.lo go-unsafe-new.lo \
+ go-unsafe-newarray.lo go-unsafe-pointer.lo go-unsetenv.lo \
+ go-unwind.lo go-varargs.lo env_posix.lo heapdump.lo mcache.lo \
+ mcentral.lo $(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo \
+ msize.lo panic.lo parfor.lo print.lo proc.lo runtime.lo \
+ signal_unix.lo thread.lo $(am__objects_2) yield.lo \
+ $(am__objects_3) malloc.lo runtime1.lo sigqueue.lo \
+ $(am__objects_4)
am_libgo_llgo_la_OBJECTS = $(am__objects_5)
libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -824,7 +823,6 @@ toolexeclibgounicode_DATA = \
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c
@LIBGO_IS_LINUX_TRUE@runtime_getncpu_file = runtime/getncpu-linux.c
runtime_files = \
- runtime/go-append.c \
runtime/go-assert.c \
runtime/go-breakpoint.c \
runtime/go-caller.c \
@@ -832,12 +830,10 @@ runtime_files = \
runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-construct-map.c \
- runtime/go-copy.c \
runtime/go-defer.c \
runtime/go-deferred-recover.c \
runtime/go-ffi.c \
runtime/go-fieldtrack.c \
- runtime/go-make-slice.c \
runtime/go-matherr.c \
runtime/go-memclr.c \
runtime/go-memcmp.c \
@@ -1519,7 +1515,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getncpu-linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getncpu-none.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getncpu-solaris.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-append.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-assert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-breakpoint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@
@@ -1527,12 +1522,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cdiv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cgo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-construct-map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-copy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-defer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-deferred-recover.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-fieldtrack.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-make-slice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-matherr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-memclr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-memcmp.Plo@am__quote@
@@ -1650,13 +1643,6 @@ libgolibbegin_a-go-libmain.obj: runtime/go-libmain.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -c -o libgolibbegin_a-go-libmain.obj `if test -f 'runtime/go-libmain.c'; then $(CYGPATH_W) 'runtime/go-libmain.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-libmain.c'; fi`
-go-append.lo: runtime/go-append.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-append.lo -MD -MP -MF $(DEPDIR)/go-append.Tpo -c -o go-append.lo `test -f 'runtime/go-append.c' || echo '$(srcdir)/'`runtime/go-append.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-append.Tpo $(DEPDIR)/go-append.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-append.c' object='go-append.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-append.lo `test -f 'runtime/go-append.c' || echo '$(srcdir)/'`runtime/go-append.c
-
go-assert.lo: runtime/go-assert.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-assert.lo -MD -MP -MF $(DEPDIR)/go-assert.Tpo -c -o go-assert.lo `test -f 'runtime/go-assert.c' || echo '$(srcdir)/'`runtime/go-assert.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-assert.Tpo $(DEPDIR)/go-assert.Plo
@@ -1706,13 +1692,6 @@ go-construct-map.lo: runtime/go-construct-map.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-construct-map.lo `test -f 'runtime/go-construct-map.c' || echo '$(srcdir)/'`runtime/go-construct-map.c
-go-copy.lo: runtime/go-copy.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-copy.lo -MD -MP -MF $(DEPDIR)/go-copy.Tpo -c -o go-copy.lo `test -f 'runtime/go-copy.c' || echo '$(srcdir)/'`runtime/go-copy.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-copy.Tpo $(DEPDIR)/go-copy.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-copy.c' object='go-copy.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-copy.lo `test -f 'runtime/go-copy.c' || echo '$(srcdir)/'`runtime/go-copy.c
-
go-defer.lo: runtime/go-defer.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-defer.lo -MD -MP -MF $(DEPDIR)/go-defer.Tpo -c -o go-defer.lo `test -f 'runtime/go-defer.c' || echo '$(srcdir)/'`runtime/go-defer.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-defer.Tpo $(DEPDIR)/go-defer.Plo
@@ -1741,13 +1720,6 @@ go-fieldtrack.lo: runtime/go-fieldtrack.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-fieldtrack.lo `test -f 'runtime/go-fieldtrack.c' || echo '$(srcdir)/'`runtime/go-fieldtrack.c
-go-make-slice.lo: runtime/go-make-slice.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-make-slice.lo -MD -MP -MF $(DEPDIR)/go-make-slice.Tpo -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-make-slice.Tpo $(DEPDIR)/go-make-slice.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-make-slice.c' object='go-make-slice.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c
-
go-matherr.lo: runtime/go-matherr.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-matherr.lo -MD -MP -MF $(DEPDIR)/go-matherr.Tpo -c -o go-matherr.lo `test -f 'runtime/go-matherr.c' || echo '$(srcdir)/'`runtime/go-matherr.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-matherr.Tpo $(DEPDIR)/go-matherr.Plo
diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go
new file mode 100644
index 0000000..4548a5b
--- /dev/null
+++ b/libgo/go/runtime/slice.go
@@ -0,0 +1,212 @@
+// 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.
+
+package runtime
+
+import (
+ "unsafe"
+)
+
+// For gccgo, use go:linkname to rename compiler-called functions to
+// themselves, so that the compiler will export them.
+//
+//go:linkname makeslice runtime.makeslice
+//go:linkname growslice runtime.growslice
+//go:linkname slicecopy runtime.slicecopy
+//go:linkname slicestringcopy runtime.slicestringcopy
+
+type slice struct {
+ array unsafe.Pointer
+ len int
+ cap int
+}
+
+// maxElems is a lookup table containing the maximum capacity for a slice.
+// The index is the size of the slice element.
+var maxElems = [...]uintptr{
+ ^uintptr(0),
+ _MaxMem / 1, _MaxMem / 2, _MaxMem / 3, _MaxMem / 4,
+ _MaxMem / 5, _MaxMem / 6, _MaxMem / 7, _MaxMem / 8,
+ _MaxMem / 9, _MaxMem / 10, _MaxMem / 11, _MaxMem / 12,
+ _MaxMem / 13, _MaxMem / 14, _MaxMem / 15, _MaxMem / 16,
+ _MaxMem / 17, _MaxMem / 18, _MaxMem / 19, _MaxMem / 20,
+ _MaxMem / 21, _MaxMem / 22, _MaxMem / 23, _MaxMem / 24,
+ _MaxMem / 25, _MaxMem / 26, _MaxMem / 27, _MaxMem / 28,
+ _MaxMem / 29, _MaxMem / 30, _MaxMem / 31, _MaxMem / 32,
+}
+
+// maxSliceCap returns the maximum capacity for a slice.
+func maxSliceCap(elemsize uintptr) uintptr {
+ if elemsize < uintptr(len(maxElems)) {
+ return maxElems[elemsize]
+ }
+ return _MaxMem / elemsize
+}
+
+// TODO: take uintptrs instead of int64s?
+func makeslice(et *_type, len64, cap64 int64) slice {
+ // NOTE: The len > maxElements check here is not strictly necessary,
+ // but it produces a 'len out of range' error instead of a 'cap out of range' error
+ // when someone does make([]T, bignumber). 'cap out of range' is true too,
+ // but since the cap is only being supplied implicitly, saying len is clearer.
+ // See issue 4085.
+ maxElements := maxSliceCap(et.size)
+ len := int(len64)
+ if len64 < 0 || int64(len) != len64 || uintptr(len) > maxElements {
+ panic(errorString("makeslice: len out of range"))
+ }
+
+ cap := int(cap64)
+ if cap < len || int64(cap) != cap64 || uintptr(cap) > maxElements {
+ panic(errorString("makeslice: cap out of range"))
+ }
+
+ // gccgo's current garbage collector requires using newarray,
+ // not mallocgc here. This can change back to mallocgc when
+ // we port the garbage collector.
+ p := newarray(et, cap)
+ return slice{p, len, cap}
+}
+
+// growslice handles slice growth during append.
+// It is passed the slice element type, the old slice, and the desired new minimum capacity,
+// and it returns a new slice with at least that capacity, with the old data
+// copied into it.
+// The new slice's length is set to the requested capacity.
+func growslice(et *_type, old slice, cap int) slice {
+ if raceenabled {
+ callerpc := getcallerpc(unsafe.Pointer(&et))
+ racereadrangepc(old.array, uintptr(old.len*int(et.size)), callerpc, funcPC(growslice))
+ }
+ if msanenabled {
+ msanread(old.array, uintptr(old.len*int(et.size)))
+ }
+
+ if et.size == 0 {
+ if cap < old.cap {
+ panic(errorString("growslice: cap out of range"))
+ }
+ // append should not create a slice with nil pointer but non-zero len.
+ // We assume that append doesn't need to preserve old.array in this case.
+ return slice{unsafe.Pointer(&zerobase), cap, cap}
+ }
+
+ newcap := old.cap
+ doublecap := newcap + newcap
+ if cap > doublecap {
+ newcap = cap
+ } else {
+ if old.len < 1024 {
+ newcap = doublecap
+ } else {
+ for newcap < cap {
+ newcap += newcap / 4
+ }
+ }
+ }
+
+ var lenmem, capmem uintptr
+ const ptrSize = unsafe.Sizeof((*byte)(nil))
+ switch et.size {
+ case 1:
+ lenmem = uintptr(old.len)
+ capmem = roundupsize(uintptr(newcap))
+ newcap = int(capmem)
+ case ptrSize:
+ lenmem = uintptr(old.len) * ptrSize
+ capmem = roundupsize(uintptr(newcap) * ptrSize)
+ newcap = int(capmem / ptrSize)
+ default:
+ lenmem = uintptr(old.len) * et.size
+ capmem = roundupsize(uintptr(newcap) * et.size)
+ newcap = int(capmem / et.size)
+ }
+
+ if cap < old.cap || uintptr(newcap) > maxSliceCap(et.size) {
+ panic(errorString("growslice: cap out of range"))
+ }
+
+ var p unsafe.Pointer
+ if et.kind&kindNoPointers != 0 {
+ // gccgo's current GC requires newarray, not mallocgc.
+ p = newarray(et, newcap)
+ memmove(p, old.array, lenmem)
+ // The call to memclr is not needed for gccgo since
+ // the newarray function will zero the memory.
+ // Calling memclr is also wrong since we allocated
+ // newcap*et.size bytes, which is not the same as capmem.
+ // memclr(add(p, lenmem), capmem-lenmem)
+ } else {
+ // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
+ // gccgo's current GC requires newarray, not mallocgc.
+ p = newarray(et, newcap)
+ if !writeBarrier.enabled {
+ memmove(p, old.array, lenmem)
+ } else {
+ for i := uintptr(0); i < lenmem; i += et.size {
+ typedmemmove(et, add(p, i), add(old.array, i))
+ }
+ }
+ }
+
+ return slice{p, cap, newcap}
+}
+
+func slicecopy(to, fm slice, width uintptr) int {
+ if fm.len == 0 || to.len == 0 {
+ return 0
+ }
+
+ n := fm.len
+ if to.len < n {
+ n = to.len
+ }
+
+ if width == 0 {
+ return n
+ }
+
+ if raceenabled {
+ callerpc := getcallerpc(unsafe.Pointer(&to))
+ pc := funcPC(slicecopy)
+ racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
+ racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
+ }
+ if msanenabled {
+ msanwrite(to.array, uintptr(n*int(width)))
+ msanread(fm.array, uintptr(n*int(width)))
+ }
+
+ size := uintptr(n) * width
+ if size == 1 { // common case worth about 2x to do here
+ // TODO: is this still worth it with new memmove impl?
+ *(*byte)(to.array) = *(*byte)(fm.array) // known to be a byte pointer
+ } else {
+ memmove(to.array, fm.array, size)
+ }
+ return n
+}
+
+func slicestringcopy(to []byte, fm string) int {
+ if len(fm) == 0 || len(to) == 0 {
+ return 0
+ }
+
+ n := len(fm)
+ if len(to) < n {
+ n = len(to)
+ }
+
+ if raceenabled {
+ callerpc := getcallerpc(unsafe.Pointer(&to))
+ pc := funcPC(slicestringcopy)
+ racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
+ }
+ if msanenabled {
+ msanwrite(unsafe.Pointer(&to[0]), uintptr(n))
+ }
+
+ memmove(unsafe.Pointer(&to[0]), stringStructOf(&fm).str, uintptr(n))
+ return n
+}
diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go
index 5924ee6..755933d 100644
--- a/libgo/go/runtime/stubs.go
+++ b/libgo/go/runtime/stubs.go
@@ -253,11 +253,18 @@ func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
memmove(dst, src, typ.size)
}
-// Here for gccgo unless and until we port slice.go.
-type slice struct {
- array unsafe.Pointer
- len int
- cap int
+// Temporary for gccgo until we port mbarrier.go.
+//go:linkname typedslicecopy runtime.typedslicecopy
+func typedslicecopy(typ *_type, dst, src slice) int {
+ n := dst.len
+ if n > src.len {
+ n = src.len
+ }
+ if n == 0 {
+ return 0
+ }
+ memmove(dst.array, src.array, uintptr(n)*typ.size)
+ return n
}
// Here for gccgo until we port malloc.go.
@@ -474,3 +481,11 @@ func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
func writebarrierptr(dst *uintptr, src uintptr) {
*dst = src
}
+
+// Temporary for gccgo until we port malloc.go
+var zerobase uintptr
+
+//go:linkname getZerobase runtime.getZerobase
+func getZerobase() *uintptr {
+ return &zerobase
+}
diff --git a/libgo/runtime/go-append.c b/libgo/runtime/go-append.c
deleted file mode 100644
index 1b2d49e..0000000
--- a/libgo/runtime/go-append.c
+++ /dev/null
@@ -1,74 +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;
- intgo count;
-
- if (bvalues == NULL || bcount == 0)
- return a;
-
- ucount = (uintptr_t) a.__count + bcount;
- count = (intgo) ucount;
- if ((uintptr_t) count != ucount || count <= a.__count)
- runtime_panicstring ("append: slice overflow");
-
- if (count > a.__capacity)
- {
- intgo m;
- uintptr capmem;
- void *n;
-
- m = a.__capacity;
- if (m + m < count)
- m = count;
- else
- {
- do
- {
- if (a.__count < 1024)
- m += m;
- else
- m += m / 4;
- }
- while (m < count);
- }
-
- if (element_size > 0 && (uintptr) m > MaxMem / element_size)
- runtime_panicstring ("growslice: cap out of range");
-
- capmem = runtime_roundupsize (m * element_size);
-
- n = __go_alloc (capmem);
- __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/libgo/runtime/go-copy.c b/libgo/runtime/go-copy.c
deleted file mode 100644
index 05e16acb..0000000
--- a/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/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c
deleted file mode 100644
index ccd07e5..0000000
--- a/libgo/runtime/go-make-slice.c
+++ /dev/null
@@ -1,99 +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_CODE_MASK) == GO_SLICE);
- std = (const struct __go_slice_type *) td;
-
- ilen = (intgo) len;
- if (ilen < 0
- || (uintptr_t) ilen != len
- || (std->__element_type->__size > 0
- && len > MaxMem / std->__element_type->__size))
- 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,
- (uintptr) std->__element_type | TypeInfo_Array,
- FlagNoScan);
- else
- ret.__values =
- runtime_mallocgc (size,
- (uintptr) std->__element_type | TypeInfo_Array,
- 0);
-
- 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/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc
index 1fd4461..5cbdc46 100644
--- a/libgo/runtime/malloc.goc
+++ b/libgo/runtime/malloc.goc
@@ -81,7 +81,7 @@ runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
// All 0-length allocations use this pointer.
// The language does not require the allocations to
// have distinct values.
- return &runtime_zerobase;
+ return runtime_getZerobase();
}
g = runtime_g();
@@ -881,7 +881,7 @@ func new(typ *Type) (ret *uint8) {
}
static void*
-cnew(const Type *typ, intgo n, int32 objtyp)
+runtime_docnew(const Type *typ, intgo n, int32 objtyp)
{
if((objtyp&(PtrSize-1)) != objtyp)
runtime_throw("runtime: invalid objtyp");
@@ -894,13 +894,13 @@ cnew(const Type *typ, intgo n, int32 objtyp)
void*
runtime_cnew(const Type *typ)
{
- return cnew(typ, 1, TypeInfo_SingleObject);
+ return runtime_docnew(typ, 1, TypeInfo_SingleObject);
}
void*
runtime_cnewarray(const Type *typ, intgo n)
{
- return cnew(typ, n, TypeInfo_Array);
+ return runtime_docnew(typ, n, TypeInfo_Array);
}
func GC() {
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 8be0df4..501f1b4 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -234,7 +234,8 @@ enum
/*
* external data
*/
-extern uintptr runtime_zerobase;
+extern uintptr* runtime_getZerobase(void)
+ __asm__(GOSYM_PREFIX "runtime.getZerobase");
extern G** runtime_allg;
extern uintptr runtime_allglen;
extern G* runtime_lastg;