I've committed a patch to libgo to update it to the Go 1.4 release,
except for the runtime package. Much of the runtime package was
rewritten in Go, and it does not really affect users of the library,
so I've postponed that complex merge. All the other packages are
updated. A few minor compiler changes were required, as well as a few
changes to the runtime packages required for other changes. The
testsuite script was changed to add support for the new TestMain
function, which is used by one or two of the standard packages.
As usual with libgo updates the entire patch is too large to attach
here. I've attached the changes to configuration/build files and the
runtime package.
Note that the type descriptor format has changed very very slightly to
include an additional flag. This means that all existing Go files
must be recompiled in order to work with this updated libgo. I will
bump the libgo version number shortly.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.
Ian
gotools/ChangeLog:
2015-01-14 Ian Lance Taylor <[email protected]>
* Makefile.am (go_cmd_go_files): Sort entries. Add generate.go.
* Makefile.in: Rebuild.
diff -r 0fde0b6a7eb2 go/expressions.cc
--- a/go/expressions.cc Fri Jan 09 17:00:26 2015 -0800
+++ b/go/expressions.cc Wed Jan 14 15:56:44 2015 -0800
@@ -15559,7 +15559,7 @@
Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
{
bool ret;
- if (type == NULL)
+ if (type == NULL || type->is_error())
ret = true;
else if (type->integer_type() != NULL)
ret = this->check_int_type(type->integer_type(), issue_error, loc);
diff -r 0fde0b6a7eb2 go/types.cc
--- a/go/types.cc Fri Jan 09 17:00:26 2015 -0800
+++ b/go/types.cc Wed Jan 14 15:56:44 2015 -0800
@@ -1966,6 +1966,8 @@
if (!this->has_pointer())
runtime_type_kind |= RUNTIME_TYPE_KIND_NO_POINTERS;
+ if (this->points_to() != NULL)
+ runtime_type_kind |= RUNTIME_TYPE_KIND_DIRECT_IFACE;
Struct_field_list::const_iterator p = fields->begin();
go_assert(p->is_field_name("kind"));
vals->push_back(Expression::make_integer_ul(runtime_type_kind, p->type(),
diff -r 0fde0b6a7eb2 go/types.h
--- a/go/types.h Fri Jan 09 17:00:26 2015 -0800
+++ b/go/types.h Wed Jan 14 15:56:44 2015 -0800
@@ -81,6 +81,8 @@
static const int RUNTIME_TYPE_KIND_STRUCT = 25;
static const int RUNTIME_TYPE_KIND_UNSAFE_POINTER = 26;
+static const int RUNTIME_TYPE_KIND_DIRECT_IFACE = (1 << 5);
+static const int RUNTIME_TYPE_KIND_GC_PROG = (1 << 6);
static const int RUNTIME_TYPE_KIND_NO_POINTERS = (1 << 7);
// GC instruction opcodes. These must match the values in
libgo/runtime/mgc0.h.
diff -r 0fde0b6a7eb2 libgo/MERGE
--- a/libgo/MERGE Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/MERGE Wed Jan 14 15:56:44 2015 -0800
@@ -1,4 +1,4 @@
-f44017549ff9
+14854533dcc7
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
diff -r 0fde0b6a7eb2 libgo/Makefile.am
--- a/libgo/Makefile.am Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/Makefile.am Wed Jan 14 15:56:44 2015 -0800
@@ -495,6 +495,7 @@
runtime/go-unsafe-new.c \
runtime/go-unsafe-newarray.c \
runtime/go-unsafe-pointer.c \
+ runtime/go-unsetenv.c \
runtime/go-unwind.c \
runtime/go-varargs.c \
runtime/env_posix.c \
@@ -695,7 +696,7 @@
else
if LIBGO_IS_SOLARIS
go_net_cgo_file = go/net/cgo_linux.go
-go_net_sock_file = go/net/sock_solaris.go
+go_net_sock_file = go/net/sock_stub.go
go_net_sockopt_file = go/net/sockopt_solaris.go
go_net_sockoptip_file = go/net/sockoptip_stub.go
else
@@ -761,9 +762,6 @@
if LIBGO_IS_DARWIN
go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
else
-if LIBGO_IS_SOLARIS
-go_net_tcpsockopt_file = go/net/tcpsockopt_solaris.go
-else
if LIBGO_IS_DRAGONFLY
go_net_tcpsockopt_file = go/net/tcpsockopt_dragonfly.go
else
@@ -771,7 +769,6 @@
endif
endif
endif
-endif
go_net_files = \
go/net/cgo_unix.go \
@@ -997,7 +994,6 @@
go/runtime/extern.go \
go/runtime/mem.go \
go/runtime/softfloat64.go \
- go/runtime/type.go \
version.go
version.go: s-version; @true
@@ -1187,10 +1183,19 @@
go/crypto/md5/md5.go \
go/crypto/md5/md5block.go \
go/crypto/md5/md5block_generic.go
+
+if LIBGO_IS_LINUX
+crypto_rand_file = go/crypto/rand/rand_linux.go
+else
+crypto_rand_file =
+endif
+
go_crypto_rand_files = \
go/crypto/rand/rand.go \
go/crypto/rand/rand_unix.go \
+ $(crypto_rand_file) \
go/crypto/rand/util.go
+
go_crypto_rc4_files = \
go/crypto/rc4/rc4.go \
go/crypto/rc4/rc4_ref.go
@@ -1289,9 +1294,11 @@
go_encoding_gob_files = \
go/encoding/gob/decode.go \
go/encoding/gob/decoder.go \
+ go/encoding/gob/dec_helpers.go \
go/encoding/gob/doc.go \
go/encoding/gob/encode.go \
go/encoding/gob/encoder.go \
+ go/encoding/gob/enc_helpers.go \
go/encoding/gob/error.go \
go/encoding/gob/type.go
go_encoding_hex_files = \
@@ -1452,7 +1459,6 @@
go/mime/multipart/writer.go
go_net_http_files = \
- go/net/http/chunked.go \
go/net/http/client.go \
go/net/http/cookie.go \
go/net/http/filetransport.go \
@@ -1496,12 +1502,12 @@
go_net_http_pprof_files = \
go/net/http/pprof/pprof.go
go_net_http_httputil_files = \
- go/net/http/httputil/chunked.go \
go/net/http/httputil/dump.go \
go/net/http/httputil/httputil.go \
go/net/http/httputil/persist.go \
go/net/http/httputil/reverseproxy.go
-
+go_net_http_internal_files = \
+ go/net/http/internal/chunked.go
go_old_regexp_files = \
go/old/regexp/regexp.go
@@ -1535,7 +1541,8 @@
go/path/filepath/match.go \
go/path/filepath/path.go \
go/path/filepath/path_unix.go \
- go/path/filepath/symlink.go
+ go/path/filepath/symlink.go \
+ go/path/filepath/symlink_unix.go
go_regexp_syntax_files = \
go/regexp/syntax/compile.go \
@@ -1570,7 +1577,8 @@
go/text/template/parse/parse.go
go_sync_atomic_files = \
- go/sync/atomic/doc.go
+ go/sync/atomic/doc.go \
+ go/sync/atomic/value.go
go_sync_atomic_c_files = \
go/sync/atomic/atomic.c
@@ -1784,10 +1792,21 @@
go_syscall_test_files = \
$(syscall_creds_test_file) \
+ go/syscall/export_test.go \
go/syscall/mmap_unix_test.go \
go/syscall/syscall_test.go \
go/syscall/syscall_unix_test.go
+if LIBGO_IS_LINUX
+internal_syscall_getrandom_file = go/internal/syscall/getrandom_linux.go
+else
+internal_syscall_getrandom_file =
+endif
+
+go_internal_syscall_files = \
+ go/internal/syscall/dummy.go \
+ $(internal_syscall_getrandom_file)
+
libcalls.go: s-libcalls; @true
s-libcalls: libcalls-list go/syscall/mksyscall.awk $(go_base_syscall_files)
rm -f libcalls.go.tmp
@@ -1957,6 +1976,7 @@
net/http/fcgi.lo \
net/http/httptest.lo \
net/http/httputil.lo \
+ net/http/internal.lo \
net/http/pprof.lo \
image/color.lo \
image/color/palette.lo \
@@ -1965,6 +1985,7 @@
image/jpeg.lo \
image/png.lo \
index/suffixarray.lo \
+ internal/syscall.lo \
io/ioutil.lo \
log/syslog.lo \
log/syslog/syslog_c.lo \
@@ -3160,6 +3181,15 @@
@$(CHECK)
.PHONY: net/http/httputil/check
+@go_include@ net/http/internal.lo.dep
+net/http/internal.lo.dep: $(go_net_http_internal_files)
+ $(BUILDDEPS)
+net/http/internal.lo: $(go_net_http_internal_files)
+ $(BUILDPACKAGE)
+net/http/internal/check: $(CHECK_DEPS)
+ @$(CHECK)
+.PHONY: net/http/internal/check
+
@go_include@ net/http/pprof.lo.dep
net/http/pprof.lo.dep: $(go_net_http_pprof_files)
$(BUILDDEPS)
@@ -3260,7 +3290,8 @@
.PHONY: runtime/pprof/check
# At least for now, we need -static-libgo for this test, because
# otherwise we can't get the line numbers.
-runtime_pprof_check_GOCFLAGS = -static-libgo
+# Also use -fno-inline to get better results from the memory profiler.
+runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline
@go_include@ sync/atomic.lo.dep
sync/atomic.lo.dep: $(go_sync_atomic_files)
@@ -3363,6 +3394,15 @@
@$(CHECK)
.PHONY: syscall/check
+@go_include@ internal/syscall.lo.dep
+internal/syscall.lo.dep: $(go_internal_syscall_files)
+ $(BUILDDEPS)
+internal/syscall.lo: $(go_internal_syscall_files)
+ $(BUILDPACKAGE)
+internal/syscall/check: $(CHECK_DEPS)
+ @$(CHECK)
+.PHONY: internal/syscall/check
+
# How to build a .gox file from a .lo file.
BUILDGOX = \
f=`echo $< | sed -e 's/.lo$$/.o/'`; \
@@ -3623,6 +3663,9 @@
net/http/pprof.gox: net/http/pprof.lo
$(BUILDGOX)
+net/http/internal.gox: net/http/internal.lo
+ $(BUILDGOX)
+
net/rpc/jsonrpc.gox: net/rpc/jsonrpc.lo
$(BUILDGOX)
@@ -3652,6 +3695,9 @@
sync/atomic.gox: sync/atomic.lo
$(BUILDGOX)
+internal/syscall.gox: internal/syscall.lo
+ $(BUILDGOX)
+
text/scanner.gox: text/scanner.lo
$(BUILDGOX)
text/tabwriter.gox: text/tabwriter.lo
@@ -3774,6 +3820,7 @@
net/http/fcgi/check \
net/http/httptest/check \
net/http/httputil/check \
+ net/http/internal/check \
net/mail/check \
net/rpc/check \
net/smtp/check \
diff -r 0fde0b6a7eb2 libgo/configure.ac
--- a/libgo/configure.ac Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/configure.ac Wed Jan 14 15:56:44 2015 -0800
@@ -551,7 +551,7 @@
AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
-AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv dl_iterate_phdr)
+AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv unsetenv
dl_iterate_phdr)
AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
diff -r 0fde0b6a7eb2 libgo/merge.sh
--- a/libgo/merge.sh Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/merge.sh Wed Jan 14 15:56:44 2015 -0800
@@ -124,11 +124,11 @@
merge_c() {
from=$1
to=$2
- oldfile=${OLDDIR}/src/pkg/runtime/$from
+ oldfile=${OLDDIR}/src/runtime/$from
if test -f ${oldfile}; then
sed -e 's/·/_/g' < ${oldfile} > ${oldfile}.tmp
oldfile=${oldfile}.tmp
- newfile=${NEWDIR}/src/pkg/runtime/$from
+ newfile=${NEWDIR}/src/runtime/$from
sed -e 's/·/_/g' < ${newfile} > ${newfile}.tmp
newfile=${newfile}.tmp
libgofile=runtime/$to
@@ -136,16 +136,16 @@
fi
}
-(cd ${NEWDIR}/src/pkg && find . -name '*.go' -print) | while read f; do
- oldfile=${OLDDIR}/src/pkg/$f
- newfile=${NEWDIR}/src/pkg/$f
+(cd ${NEWDIR}/src && find . -name '*.go' -print) | while read f; do
+ oldfile=${OLDDIR}/src/$f
+ newfile=${NEWDIR}/src/$f
libgofile=go/$f
merge $f ${oldfile} ${newfile} ${libgofile}
done
-(cd ${NEWDIR}/src/pkg && find . -name testdata -print) | while read d; do
- oldtd=${OLDDIR}/src/pkg/$d
- newtd=${NEWDIR}/src/pkg/$d
+(cd ${NEWDIR}/src && find . -name testdata -print) | while read d; do
+ oldtd=${OLDDIR}/src/$d
+ newtd=${NEWDIR}/src/$d
libgotd=go/$d
if ! test -d ${oldtd}; then
continue
@@ -195,15 +195,16 @@
runtime="chan.goc chan.h cpuprof.goc env_posix.c heapdump.c lock_futex.c
lfstack.goc lock_sema.c mcache.c mcentral.c mfixalloc.c mgc0.c mgc0.h mheap.c
msize.c netpoll.goc netpoll_epoll.c netpoll_kqueue.c netpoll_stub.c panic.c
print.c proc.c race.h rdebug.goc runtime.c runtime.h signal_unix.c
signal_unix.h malloc.h malloc.goc mprof.goc parfor.c runtime1.goc sema.goc
sigqueue.goc string.goc time.goc"
for f in $runtime; do
- merge_c $f $f
+ # merge_c $f $f
+ true
done
-merge_c os_linux.c thread-linux.c
-merge_c mem_linux.c mem.c
+# merge_c os_linux.c thread-linux.c
+# merge_c mem_linux.c mem.c
-(cd ${OLDDIR}/src/pkg && find . -name '*.go' -print) | while read f; do
- oldfile=${OLDDIR}/src/pkg/$f
- newfile=${NEWDIR}/src/pkg/$f
+(cd ${OLDDIR}/src && find . -name '*.go' -print) | while read f; do
+ oldfile=${OLDDIR}/src/$f
+ newfile=${NEWDIR}/src/$f
libgofile=go/$f
if test -f ${newfile}; then
continue
diff -r 0fde0b6a7eb2 libgo/runtime/env_posix.c
--- a/libgo/runtime/env_posix.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/env_posix.c Wed Jan 14 15:56:44 2015 -0800
@@ -9,7 +9,7 @@
#include "arch.h"
#include "malloc.h"
-extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
+extern Slice envs;
const byte*
runtime_getenv(const char *s)
@@ -22,8 +22,8 @@
bs = (const byte*)s;
len = runtime_findnull(bs);
- envv = (String*)syscall_Envs.__values;
- envc = syscall_Envs.__count;
+ envv = (String*)envs.__values;
+ envc = envs.__count;
for(i=0; i<envc; i++){
if(envv[i].len <= len)
continue;
diff -r 0fde0b6a7eb2 libgo/runtime/go-assert-interface.c
--- a/libgo/runtime/go-assert-interface.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-assert-interface.c Wed Jan 14 15:56:44 2015 -0800
@@ -36,7 +36,7 @@
/* A type assertion to an empty interface just returns the object
descriptor. */
- __go_assert (lhs_descriptor->__code == GO_INTERFACE);
+ __go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE);
lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
if (lhs_interface->__methods.__count == 0)
return rhs_descriptor;
diff -r 0fde0b6a7eb2 libgo/runtime/go-can-convert-interface.c
--- a/libgo/runtime/go-can-convert-interface.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-can-convert-interface.c Wed Jan 14 15:56:44 2015 -0800
@@ -31,7 +31,7 @@
if (from_descriptor == NULL)
return 0;
- __go_assert (to_descriptor->__code == GO_INTERFACE);
+ __go_assert ((to_descriptor->__code & GO_CODE_MASK) == 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 *)
diff -r 0fde0b6a7eb2 libgo/runtime/go-check-interface.c
--- a/libgo/runtime/go-check-interface.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-check-interface.c Wed Jan 14 15:56:44 2015 -0800
@@ -30,9 +30,9 @@
if (lhs_descriptor != rhs_descriptor
&& !__go_type_descriptors_equal (lhs_descriptor, rhs_descriptor)
- && (lhs_descriptor->__code != GO_UNSAFE_POINTER
+ && ((lhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER
|| !__go_is_pointer_type (rhs_descriptor))
- && (rhs_descriptor->__code != GO_UNSAFE_POINTER
+ && ((rhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER
|| !__go_is_pointer_type (lhs_descriptor)))
{
struct __go_empty_interface panic_arg;
diff -r 0fde0b6a7eb2 libgo/runtime/go-convert-interface.c
--- a/libgo/runtime/go-convert-interface.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-convert-interface.c Wed Jan 14 15:56:44 2015 -0800
@@ -41,7 +41,7 @@
return NULL;
}
- __go_assert (lhs_descriptor->__code == GO_INTERFACE);
+ __go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == 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 *)
diff -r 0fde0b6a7eb2 libgo/runtime/go-make-slice.c
--- a/libgo/runtime/go-make-slice.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-make-slice.c Wed Jan 14 15:56:44 2015 -0800
@@ -30,7 +30,7 @@
uintptr_t size;
struct __go_open_array ret;
- __go_assert (td->__code == GO_SLICE);
+ __go_assert ((td->__code & GO_CODE_MASK) == GO_SLICE);
std = (const struct __go_slice_type *) td;
ilen = (intgo) len;
diff -r 0fde0b6a7eb2 libgo/runtime/go-reflect-map.c
--- a/libgo/runtime/go-reflect-map.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-reflect-map.c Wed Jan 14 15:56:44 2015 -0800
@@ -24,7 +24,7 @@
{
struct __go_map *map = (struct __go_map *) m;
- __go_assert (mt->__common.__code == GO_MAP);
+ __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
if (map == NULL)
return NULL;
else
@@ -40,7 +40,7 @@
struct __go_map *map = (struct __go_map *) m;
void *p;
- __go_assert (mt->__common.__code == GO_MAP);
+ __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
if (map == NULL)
runtime_panicstring ("assignment to entry in nil map");
p = __go_map_index (map, key, 1);
@@ -55,7 +55,7 @@
{
struct __go_map *map = (struct __go_map *) m;
- __go_assert (mt->__common.__code == GO_MAP);
+ __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
if (map == NULL)
return;
__go_map_delete (map, key);
@@ -81,7 +81,7 @@
{
struct __go_hash_iter *it;
- __go_assert (mt->__common.__code == GO_MAP);
+ __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
it = __go_alloc (sizeof (struct __go_hash_iter));
__go_mapiterinit ((struct __go_map *) m, it);
return (unsigned char *) it;
diff -r 0fde0b6a7eb2 libgo/runtime/go-type.h
--- a/libgo/runtime/go-type.h Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-type.h Wed Jan 14 15:56:44 2015 -0800
@@ -54,9 +54,11 @@
#define GO_STRUCT 25
#define GO_UNSAFE_POINTER 26
+#define GO_DIRECT_IFACE (1 << 5)
+#define GO_GC_PROG (1 << 6)
#define GO_NO_POINTERS (1 << 7)
-#define GO_CODE_MASK 0x7f
+#define GO_CODE_MASK 0x1f
/* For each Go type the compiler constructs one of these structures.
This is used for type reflection, interfaces, maps, and reference
@@ -310,7 +312,8 @@
static inline _Bool
__go_is_pointer_type (const struct __go_type_descriptor *td)
{
- return td->__code == GO_PTR || td->__code == GO_UNSAFE_POINTER;
+ return ((td->__code & GO_CODE_MASK) == GO_PTR
+ || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER);
}
extern _Bool
diff -r 0fde0b6a7eb2 libgo/runtime/go-unsafe-pointer.c
--- a/libgo/runtime/go-unsafe-pointer.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/go-unsafe-pointer.c Wed Jan 14 15:56:44 2015 -0800
@@ -44,7 +44,7 @@
const struct __go_type_descriptor unsafe_Pointer =
{
/* __code */
- GO_UNSAFE_POINTER,
+ GO_UNSAFE_POINTER | GO_DIRECT_IFACE,
/* __align */
__alignof (void *),
/* __field_align */
@@ -89,7 +89,7 @@
/* __common */
{
/* __code */
- GO_PTR,
+ GO_PTR | GO_DIRECT_IFACE,
/* __align */
__alignof (void *),
/* __field_align */
diff -r 0fde0b6a7eb2 libgo/runtime/go-unsetenv.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/runtime/go-unsetenv.c Wed Jan 14 15:56:44 2015 -0800
@@ -0,0 +1,54 @@
+/* go-unsetenv.c -- unset an environment variable from Go.
+
+ Copyright 2015 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"
+#include "arch.h"
+#include "malloc.h"
+
+/* Unset an environment variable from Go. This is called by
+ syscall.Unsetenv. */
+
+void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv_c");
+
+void
+unsetenv_c (String k)
+{
+ const byte *ks;
+ unsigned char *kn;
+ intgo len;
+
+ ks = k.str;
+ if (ks == NULL)
+ ks = (const byte *) "";
+ kn = NULL;
+
+#ifdef HAVE_UNSETENV
+
+ if (ks != NULL && ks[k.len] != 0)
+ {
+ // Objects that are explicitly freed must be at least 16 bytes in size,
+ // so that they are not allocated using tiny alloc.
+ len = k.len + 1;
+ if (len < TinySize)
+ len = TinySize;
+ kn = __go_alloc (len);
+ __builtin_memcpy (kn, ks, k.len);
+ ks = kn;
+ }
+
+ unsetenv ((const char *) ks);
+
+#endif /* !defined(HAVE_UNSETENV) */
+
+ if (kn != NULL)
+ __go_free (kn);
+}
diff -r 0fde0b6a7eb2 libgo/runtime/malloc.goc
--- a/libgo/runtime/malloc.goc Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/malloc.goc Wed Jan 14 15:56:44 2015 -0800
@@ -25,6 +25,7 @@
#define string __reflection
#define KindPtr GO_PTR
#define KindNoPointers GO_NO_POINTERS
+#define kindMask GO_CODE_MASK
// GCCGO SPECIFIC CHANGE
//
@@ -935,7 +936,7 @@
runtime_printf("runtime.SetFinalizer: first argument is nil
interface\n");
goto throw;
}
- if(obj.__type_descriptor->__code != GO_PTR) {
+ if((obj.__type_descriptor->kind&kindMask) != GO_PTR) {
runtime_printf("runtime.SetFinalizer: first argument is %S, not
pointer\n", *obj.__type_descriptor->__reflection);
goto throw;
}
@@ -956,14 +957,14 @@
if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object !=
base) {
// As an implementation detail we allow to set finalizers for
an inner byte
// of an object if it could come from tiny alloc (see mallocgc
for details).
- if(ot->__element_type == nil ||
(ot->__element_type->__code&KindNoPointers) == 0 || ot->__element_type->__size
>= TinySize) {
+ if(ot->__element_type == nil ||
(ot->__element_type->kind&KindNoPointers) == 0 || ot->__element_type->__size >=
TinySize) {
runtime_printf("runtime.SetFinalizer: pointer not at
beginning of allocated block (%p)\n", obj.__object);
goto throw;
}
}
if(finalizer.__type_descriptor != nil) {
runtime_createfing();
- if(finalizer.__type_descriptor->__code != GO_FUNC)
+ if((finalizer.__type_descriptor->kind&kindMask) != GO_FUNC)
goto badfunc;
ft = (const FuncType*)finalizer.__type_descriptor;
if(ft->__dotdotdot || ft->__in.__count != 1)
@@ -971,12 +972,12 @@
fint = *(Type**)ft->__in.__values;
if(__go_type_descriptors_equal(fint, obj.__type_descriptor)) {
// ok - same type
- } else if(fint->__code == GO_PTR && (fint->__uncommon == nil ||
fint->__uncommon->__name == nil || obj.type->__uncommon == nil ||
obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const
PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) {
+ } else if((fint->kind&kindMask) == GO_PTR && (fint->__uncommon
== nil || fint->__uncommon->__name == nil || obj.type->__uncommon == nil ||
obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const
PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) {
// ok - not same type, but both pointers,
// one or the other is unnamed, and same element type,
so assignable.
- } else if(fint->kind == GO_INTERFACE && ((const
InterfaceType*)fint)->__methods.__count == 0) {
+ } else if((fint->kind&kindMask) == GO_INTERFACE && ((const
InterfaceType*)fint)->__methods.__count == 0) {
// ok - satisfies empty interface
- } else if(fint->kind == GO_INTERFACE &&
__go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) {
+ } else if((fint->kind&kindMask) == GO_INTERFACE &&
__go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) {
// ok - satisfies non-empty interface
} else
goto badfunc;
diff -r 0fde0b6a7eb2 libgo/runtime/mgc0.c
--- a/libgo/runtime/mgc0.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/mgc0.c Wed Jan 14 15:56:44 2015 -0800
@@ -71,6 +71,7 @@
#define string __reflection
#define KindPtr GO_PTR
#define KindNoPointers GO_NO_POINTERS
+#define kindMask GO_CODE_MASK
// PtrType aka __go_ptr_type
#define elem __element_type
@@ -946,7 +947,7 @@
continue;
obj = eface->__object;
- if((t->__code & ~KindNoPointers) ==
KindPtr) {
+ if((t->__code & kindMask) == KindPtr) {
// Only use type information if
it is a pointer-containing type.
// This matches the GC programs
written by cmd/gc/reflect.c's
// dgcsym1 in case TPTR32/case
TPTR64. See rationale there.
@@ -984,7 +985,7 @@
continue;
obj = iface->__object;
- if((t->__code & ~KindNoPointers) ==
KindPtr) {
+ if((t->__code & kindMask) == KindPtr) {
// Only use type information if
it is a pointer-containing type.
// This matches the GC programs
written by cmd/gc/reflect.c's
// dgcsym1 in case TPTR32/case
TPTR64. See rationale there.
@@ -2369,6 +2370,8 @@
// Sweep all spans eagerly.
while(runtime_sweepone() != (uintptr)-1)
gcstats.npausesweep++;
+ // Do an additional mProf_GC, because all 'free' events are now
real as well.
+ runtime_MProf_GC();
}
runtime_MProf_GC();
@@ -2514,7 +2517,7 @@
f = &fb->fin[i];
fint = ((const Type**)f->ft->__in.array)[0];
- if(fint->__code == KindPtr) {
+ if((fint->__code & kindMask) == KindPtr) {
// direct use of pointer
param = &f->arg;
} else if(((const
InterfaceType*)fint)->__methods.__count == 0) {
diff -r 0fde0b6a7eb2 libgo/runtime/netpoll.goc
--- a/libgo/runtime/netpoll.goc Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/netpoll.goc Wed Jan 14 15:56:44 2015 -0800
@@ -79,9 +79,9 @@
static bool netpollblock(PollDesc*, int32, bool);
static G* netpollunblock(PollDesc*, int32, bool);
-static void deadline(int64, Eface);
-static void readDeadline(int64, Eface);
-static void writeDeadline(int64, Eface);
+static void deadline(Eface, uintptr);
+static void readDeadline(Eface, uintptr);
+static void writeDeadline(Eface, uintptr);
static PollDesc* allocPollDesc(void);
static intgo checkerr(PollDesc *pd, int32 mode);
@@ -197,22 +197,25 @@
// Copy current seq into the timer arg.
// Timer func will check the seq against current descriptor seq,
// if they differ the descriptor was reused or timers were
reset.
- pd->rt.arg.type = (Type*)pd->seq;
+ pd->rt.arg.type = nil; // should be *pollDesc type descriptor.
pd->rt.arg.data = pd;
+ pd->rt.seq = pd->seq;
runtime_addtimer(&pd->rt);
} else {
if(pd->rd > 0) {
pd->rt.fv = &readDeadlineFn;
pd->rt.when = pd->rd;
- pd->rt.arg.type = (Type*)pd->seq;
+ pd->rt.arg.type = nil; // should be *pollDesc type
descriptor.
pd->rt.arg.data = pd;
+ pd->rt.seq = pd->seq;
runtime_addtimer(&pd->rt);
}
if(pd->wd > 0) {
pd->wt.fv = &writeDeadlineFn;
pd->wt.when = pd->wd;
- pd->wt.arg.type = (Type*)pd->seq;
+ pd->wt.arg.type = nil; // should be *pollDesc type
descriptor.
pd->wt.arg.data = pd;
+ pd->wt.seq = pd->seq;
runtime_addtimer(&pd->wt);
}
}
@@ -389,19 +392,16 @@
}
static void
-deadlineimpl(int64 now, Eface arg, bool read, bool write)
+deadlineimpl(Eface arg, uintptr seq, bool read, bool write)
{
PollDesc *pd;
- uint32 seq;
G *rg, *wg;
- USED(now);
pd = (PollDesc*)arg.data;
- // This is the seq when the timer was set.
- // If it's stale, ignore the timer event.
- seq = (uintptr)arg.type;
rg = wg = nil;
runtime_lock(pd);
+ // Seq arg is seq when the timer was set.
+ // If it's stale, ignore the timer event.
if(seq != pd->seq) {
// The descriptor was reused or timers were reset.
runtime_unlock(pd);
@@ -429,21 +429,21 @@
}
static void
-deadline(int64 now, Eface arg)
+deadline(Eface arg, uintptr seq)
{
- deadlineimpl(now, arg, true, true);
+ deadlineimpl(arg, seq, true, true);
}
static void
-readDeadline(int64 now, Eface arg)
+readDeadline(Eface arg, uintptr seq)
{
- deadlineimpl(now, arg, true, false);
+ deadlineimpl(arg, seq, true, false);
}
static void
-writeDeadline(int64 now, Eface arg)
+writeDeadline(Eface arg, uintptr seq)
{
- deadlineimpl(now, arg, false, true);
+ deadlineimpl(arg, seq, false, true);
}
static PollDesc*
diff -r 0fde0b6a7eb2 libgo/runtime/runtime.c
--- a/libgo/runtime/runtime.c Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/runtime.c Wed Jan 14 15:56:44 2015 -0800
@@ -59,8 +59,8 @@
static int32 argc;
static byte** argv;
-extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args");
-extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
+static Slice args;
+Slice envs;
void (*runtime_sysargs)(int32, uint8**);
@@ -92,9 +92,9 @@
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;
+ args.__values = (void*)s;
+ args.__count = argc;
+ args.__capacity = argc;
}
void
@@ -109,9 +109,26 @@
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;
+ envs.__values = (void*)s;
+ envs.__count = n;
+ envs.__capacity = n;
+}
+
+// Called from the syscall package.
+Slice runtime_envs(void) __asm__ (GOSYM_PREFIX "syscall.runtime_envs");
+
+Slice
+runtime_envs()
+{
+ return envs;
+}
+
+Slice os_runtime_args(void) __asm__ (GOSYM_PREFIX "os.runtime_args");
+
+Slice
+os_runtime_args()
+{
+ return args;
}
int32
@@ -127,8 +144,8 @@
static struct root_list runtime_roots =
{ nil,
- { { &syscall_Envs, sizeof syscall_Envs },
- { &os_Args, sizeof os_Args },
+ { { &envs, sizeof envs },
+ { &args, sizeof args },
{ nil, 0 } },
};
diff -r 0fde0b6a7eb2 libgo/runtime/runtime.h
--- a/libgo/runtime/runtime.h Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/runtime.h Wed Jan 14 15:56:44 2015 -0800
@@ -400,7 +400,7 @@
// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer.
struct Timer
{
- int32 i; // heap index
+ intgo 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
@@ -409,6 +409,7 @@
int64 period;
FuncVal *fv;
Eface arg;
+ uintptr seq;
};
// Lock-free stack node.
@@ -774,8 +775,6 @@
__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");
void runtime_newErrorCString(const char*, Eface*)
__asm__ (GOSYM_PREFIX "runtime.NewErrorCString");
diff -r 0fde0b6a7eb2 libgo/runtime/runtime1.goc
--- a/libgo/runtime/runtime1.goc Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/runtime1.goc Wed Jan 14 15:56:44 2015 -0800
@@ -74,3 +74,16 @@
func sync.runtime_procUnpin() {
runtime_m()->locks--;
}
+
+func sync_atomic.runtime_procPin() (p int) {
+ M *mp;
+
+ mp = runtime_m();
+ // Disable preemption.
+ mp->locks++;
+ p = mp->p->id;
+}
+
+func sync_atomic.runtime_procUnpin() {
+ runtime_m()->locks--;
+}
diff -r 0fde0b6a7eb2 libgo/runtime/time.goc
--- a/libgo/runtime/time.goc Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/runtime/time.goc Wed Jan 14 15:56:44 2015 -0800
@@ -66,9 +66,9 @@
// Ready the goroutine e.data.
static void
-ready(int64 now, Eface e)
+ready(Eface e, uintptr seq)
{
- USED(now);
+ USED(seq);
runtime_ready(e.__object);
}
@@ -91,6 +91,7 @@
t.period = 0;
t.fv = &readyv;
t.arg.__object = g;
+ t.seq = 0;
runtime_lock(&timers);
addtimer(&t);
runtime_parkunlock(&timers, reason);
@@ -203,8 +204,9 @@
int64 delta, now;
Timer *t;
FuncVal *fv;
- void (*f)(int64, Eface);
+ void (*f)(Eface, uintptr);
Eface arg;
+ uintptr seq;
for(;;) {
runtime_lock(&timers);
@@ -233,9 +235,10 @@
fv = t->fv;
f = (void*)t->fv->fn;
arg = t->arg;
+ seq = t->seq;
runtime_unlock(&timers);
__go_set_closure(fv);
- f(now, arg);
+ f(arg, seq);
// clear f and arg to avoid leak while sleeping for
next timer
f = nil;
diff -r 0fde0b6a7eb2 libgo/testsuite/gotest
--- a/libgo/testsuite/gotest Fri Jan 09 17:00:26 2015 -0800
+++ b/libgo/testsuite/gotest Wed Jan 14 15:56:44 2015 -0800
@@ -335,6 +335,15 @@
havex=true
fi
+testmain=
+if $havex && fgrep 'func TestMain(' $xgofiles >/dev/null 2>&1; then
+ package=`grep '^package[ ]' $xgofiles | sed 1q | sed -e 's/.* //'`
+ testmain="${package}.TestMain"
+elif test -n "$gofiles" && fgrep 'func TestMain(' $gofiles >/dev/null 2>&1;
then
+ package=`grep '^package[ ]' $gofiles | sed 1q | sed -e 's/.* //'`
+ testmain="${package}.TestMain"
+fi
+
set -e
package=`echo ${srcdir} | sed -e 's|^.*libgo/go/||'`
@@ -415,14 +424,19 @@
fi
echo 'import "testing"'
echo 'import __regexp__ "regexp"' # rename in case tested package is
called regexp
+ if ! test -n "$testmain"; then
+ echo 'import __os__ "os"'
+ fi
# test array
echo
echo 'var tests = []testing.InternalTest {'
for i in $tests
do
n=$(testname $i)
- j=$(localname $i)
- echo ' {"'$n'", '$j'},'
+ if test "$n" != "TestMain"; then
+ j=$(localname $i)
+ echo ' {"'$n'", '$j'},'
+ fi
done
echo '}'
@@ -467,8 +481,15 @@
}
func main() {
- testing.Main(matchString, tests, benchmarks, examples)
-}'
+ m := testing.MainStart(matchString, tests, benchmarks, examples)
+'
+ if test -n "$testmain"; then
+ echo " ${testmain}(m)"
+ else
+ echo ' __os__.Exit(m.Run())'
+ fi
+
+ echo '}'
}>_testmain.go
case "x$dejagnu" in
Index: Makefile.am
===================================================================
--- Makefile.am (revision 219623)
+++ Makefile.am (working copy)
@@ -46,27 +46,28 @@ cmdsrcdir = $(srcdir)/../libgo/go/cmd
go_cmd_go_files = \
$(cmdsrcdir)/go/build.go \
$(cmdsrcdir)/go/clean.go \
- $(cmdsrcdir)/go/main.go \
- $(cmdsrcdir)/go/signal.go \
- $(cmdsrcdir)/go/version.go \
- $(cmdsrcdir)/go/env.go \
- $(cmdsrcdir)/go/help.go \
- $(cmdsrcdir)/go/run.go \
- $(cmdsrcdir)/go/tool.go \
- $(cmdsrcdir)/go/vet.go \
$(cmdsrcdir)/go/context.go \
- $(cmdsrcdir)/go/fix.go \
- $(cmdsrcdir)/go/get.go \
- $(cmdsrcdir)/go/http.go \
- $(cmdsrcdir)/go/signal_unix.go \
- $(cmdsrcdir)/go/vcs.go \
$(cmdsrcdir)/go/discovery.go \
+ $(cmdsrcdir)/go/env.go \
+ $(cmdsrcdir)/go/fix.go \
$(cmdsrcdir)/go/fmt.go \
+ $(cmdsrcdir)/go/generate.go \
+ $(cmdsrcdir)/go/get.go \
$(cmdsrcdir)/go/go11.go \
+ $(cmdsrcdir)/go/help.go \
+ $(cmdsrcdir)/go/http.go \
$(cmdsrcdir)/go/list.go \
+ $(cmdsrcdir)/go/main.go \
$(cmdsrcdir)/go/pkg.go \
+ $(cmdsrcdir)/go/run.go \
+ $(cmdsrcdir)/go/signal.go \
+ $(cmdsrcdir)/go/signal_unix.go \
$(cmdsrcdir)/go/test.go \
- $(cmdsrcdir)/go/testflag.go
+ $(cmdsrcdir)/go/testflag.go \
+ $(cmdsrcdir)/go/tool.go \
+ $(cmdsrcdir)/go/vcs.go \
+ $(cmdsrcdir)/go/version.go \
+ $(cmdsrcdir)/go/vet.go
go_cmd_gofmt_files = \
$(cmdsrcdir)/gofmt/doc.go \