]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
runtime: implement cheaper context switch on Linux/AMD64
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 31 May 2019 17:56:36 +0000 (17:56 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 31 May 2019 17:56:36 +0000 (17:56 +0000)
    Currently, goroutine switches are implemented with libc
    getcontext/setcontext functions, which saves/restores the machine
    register states and also the signal context. This does more than
    what we need, and performs an expensive syscall.

    This CL implements a simplified version of getcontext/setcontext,
    in assembly, that only saves/restores the necessary part, i.e.
    the callee-save registers, and the PC, SP. A simplified version
    of makecontext, written in C, is also added. Currently this is
    only implemented on Linux/AMD64.

    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/178298

From-SVN: r271818

gcc/go/gofrontend/MERGE
libgo/Makefile.am
libgo/Makefile.in
libgo/aclocal.m4
libgo/configure
libgo/configure.ac
libgo/runtime/go-context.S [new file with mode: 0644]
libgo/runtime/proc.c
libgo/runtime/runtime.h
libgo/testsuite/Makefile.in

index b7b0f5027b830a400011628f39b5b73a332d6556..72268229fbcc0ad6d17d73aa1971b1221731502e 100644 (file)
@@ -1,4 +1,4 @@
-4dc60d989293d070702024e7dea52b9849f74775
+8402f6ac021ba20163ab4fcdb10ab7bb642de6dc
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index ebbdee81b228fe6f39c4bbc0976ea6a12fa4f907..8a3844c1fc70061cdb9bb995362f2536980a0b70 100644 (file)
@@ -481,6 +481,7 @@ runtime_files = \
        runtime/runtime_c.c \
        runtime/stack.c \
        runtime/yield.c \
        runtime/runtime_c.c \
        runtime/stack.c \
        runtime/yield.c \
+       runtime/go-context.S \
        $(rtems_task_variable_add_file) \
        $(runtime_getncpu_file)
 
        $(rtems_task_variable_add_file) \
        $(runtime_getncpu_file)
 
index 737b01e90d8c013b4aeb44aa6f3462bfaf169083..20e2a496d778f8c5f12cafbddb6c76f6260a6032 100644 (file)
@@ -253,7 +253,8 @@ am__objects_3 = runtime/aeshash.lo runtime/go-assert.lo \
        runtime/go-unwind.lo runtime/go-varargs.lo \
        runtime/env_posix.lo runtime/panic.lo runtime/print.lo \
        runtime/proc.lo runtime/runtime_c.lo runtime/stack.lo \
        runtime/go-unwind.lo runtime/go-varargs.lo \
        runtime/env_posix.lo runtime/panic.lo runtime/print.lo \
        runtime/proc.lo runtime/runtime_c.lo runtime/stack.lo \
-       runtime/yield.lo $(am__objects_1) $(am__objects_2)
+       runtime/yield.lo runtime/go-context.lo $(am__objects_1) \
+       $(am__objects_2)
 am_libgo_llgo_la_OBJECTS = $(am__objects_3)
 libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am_libgo_llgo_la_OBJECTS = $(am__objects_3)
 libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -287,6 +288,16 @@ DEFAULT_INCLUDES = -I.@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/../depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 depcomp = $(SHELL) $(top_srcdir)/../depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CCASFLAGS) $(CCASFLAGS)
+AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
+am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
+am__v_CPPAS_0 = @echo "  CPPAS   " $@;
+am__v_CPPAS_1 = 
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -380,6 +391,9 @@ AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 CC = @CC@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
 CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CCDEPMODE = @CCDEPMODE@
 CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
@@ -512,6 +526,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -901,6 +916,7 @@ runtime_files = \
        runtime/runtime_c.c \
        runtime/stack.c \
        runtime/yield.c \
        runtime/runtime_c.c \
        runtime/stack.c \
        runtime/yield.c \
+       runtime/go-context.S \
        $(rtems_task_variable_add_file) \
        $(runtime_getncpu_file)
 
        $(rtems_task_variable_add_file) \
        $(runtime_getncpu_file)
 
@@ -1158,7 +1174,7 @@ all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .c .go .gox .o .obj .lo .a
+.SUFFIXES: .c .go .gox .o .obj .lo .a .S
 am--refresh: Makefile
        @:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../multilib.am $(am__configure_deps)
 am--refresh: Makefile
        @:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../multilib.am $(am__configure_deps)
@@ -1375,6 +1391,8 @@ runtime/stack.lo: runtime/$(am__dirstamp) \
        runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/yield.lo: runtime/$(am__dirstamp) \
        runtime/$(DEPDIR)/$(am__dirstamp)
        runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/yield.lo: runtime/$(am__dirstamp) \
        runtime/$(DEPDIR)/$(am__dirstamp)
+runtime/go-context.lo: runtime/$(am__dirstamp) \
+       runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/rtems-task-variable-add.lo: runtime/$(am__dirstamp) \
        runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/getncpu-none.lo: runtime/$(am__dirstamp) \
 runtime/rtems-task-variable-add.lo: runtime/$(am__dirstamp) \
        runtime/$(DEPDIR)/$(am__dirstamp)
 runtime/getncpu-none.lo: runtime/$(am__dirstamp) \
@@ -1421,6 +1439,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cdiv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cgo.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-construct-map.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cdiv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-cgo.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-construct-map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-context.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-fieldtrack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-matherr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-fieldtrack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-matherr.Plo@am__quote@
@@ -1451,6 +1470,30 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/stack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/yield.Plo@am__quote@
 
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/stack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/yield.Plo@am__quote@
 
+.S.o:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
+
 .c.o:
 @am__fastdepCC_TRUE@   $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
 @am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
 .c.o:
 @am__fastdepCC_TRUE@   $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
 @am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
index b55bb82a48243bf0679dbd8286af2690c4959927..951aed3a81b27a09897f61098ba159ccabfb05d9 100644 (file)
@@ -56,6 +56,26 @@ m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
+# Figure out how to run the assembler.                      -*- Autoconf -*-
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AS
+# ----------
+AC_DEFUN([AM_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+AC_ARG_VAR([CCAS],      [assembler compiler command (defaults to CC)])
+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
+])
+
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
 # Copyright (C) 2001-2017 Free Software Foundation, Inc.
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
 # Copyright (C) 2001-2017 Free Software Foundation, Inc.
index 1e33a5769e0d9ba3f5fe324b0ec2a0420620231a..837f6fec053a942da7cfc7764cbd5357a0368e78 100755 (executable)
@@ -729,6 +729,11 @@ SED
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+am__fastdepCCAS_FALSE
+am__fastdepCCAS_TRUE
+CCASDEPMODE
+CCASFLAGS
+CCAS
 GOFLAGS
 GOC
 am__fastdepCC_FALSE
 GOFLAGS
 GOC
 am__fastdepCC_FALSE
@@ -808,6 +813,7 @@ infodir
 docdir
 oldincludedir
 includedir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -889,6 +895,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1141,6 +1148,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1278,7 +1294,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1431,6 +1447,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1510,6 +1527,8 @@ Some influential environment variables:
               you have headers in a nonstandard directory <include dir>
   GOC         Go compiler command
   GOFLAGS     Go compiler flags
               you have headers in a nonstandard directory <include dir>
   GOC         Go compiler command
   GOFLAGS     Go compiler flags
+  CCAS        assembler compiler command (defaults to CC)
+  CCASFLAGS   assembler compiler flags (defaults to CFLAGS)
   CPP         C preprocessor
 
 Use these variables to override the choices made by `configure' or to help
   CPP         C preprocessor
 
 Use these variables to override the choices made by `configure' or to help
@@ -4556,6 +4575,139 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+# By default we simply use the C compiler to build assembly code.
+
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+
+
+
+depcc="$CCAS"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CCAS_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CCAS_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CCAS_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CCAS_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; }
+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then
+  am__fastdepCCAS_TRUE=
+  am__fastdepCCAS_FALSE='#'
+else
+  am__fastdepCCAS_TRUE='#'
+  am__fastdepCCAS_FALSE=
+fi
+
+
 
 
 
 
 
 
@@ -11344,7 +11496,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11347 "configure"
+#line 11499 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11450,7 +11602,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11453 "configure"
+#line 11605 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15838,6 +15990,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
   as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
   as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
index 0bd328c618b255aa09d4389eb5c37180ea631efa..0ae8162a1bafce4cfa633ed8a63e961b1857561a 100644 (file)
@@ -26,6 +26,7 @@ m4_rename([_AC_ARG_VAR_PRECIOUS],[glibgo_PRECIOUS])
 m4_define([_AC_ARG_VAR_PRECIOUS],[])
 AC_PROG_CC
 AC_PROG_GO
 m4_define([_AC_ARG_VAR_PRECIOUS],[])
 AC_PROG_CC
 AC_PROG_GO
+AM_PROG_AS
 m4_rename_force([glibgo_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
 
 AC_SUBST(CFLAGS)
 m4_rename_force([glibgo_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
 
 AC_SUBST(CFLAGS)
diff --git a/libgo/runtime/go-context.S b/libgo/runtime/go-context.S
new file mode 100644 (file)
index 0000000..0cd2242
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2019 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 provides a simplified version of getcontext and
+// setcontext. They are like the corresponding functions
+// in libc, but we only save/restore the callee-save
+// registers and PC, SP. Unlike the libc functions, we
+// don't save/restore the signal masks and floating point
+// environment.
+
+#if defined(__x86_64__) && defined(__linux__) && !defined(__CET__)
+
+#define RBP_OFF        (0*8)
+#define RBX_OFF        (1*8)
+#define R12_OFF        (2*8)
+#define R13_OFF        (3*8)
+#define R14_OFF        (4*8)
+#define R15_OFF        (5*8)
+#define SP_OFF (6*8)
+#define PC_OFF (7*8)
+
+.globl __go_getcontext
+.text
+__go_getcontext:
+       movq    %rbx, RBX_OFF(%rdi)
+       movq    %rbp, RBP_OFF(%rdi)
+       movq    %r12, R12_OFF(%rdi)
+       movq    %r13, R13_OFF(%rdi)
+       movq    %r14, R14_OFF(%rdi)
+       movq    %r15, R15_OFF(%rdi)
+
+       movq    (%rsp), %rax    // return PC
+       movq    %rax, PC_OFF(%rdi)
+       leaq    8(%rsp), %rax   // the SP before pushing return PC
+       movq    %rax, SP_OFF(%rdi)
+
+       ret
+
+.globl __go_setcontext
+.text
+__go_setcontext:
+       movq    RBX_OFF(%rdi), %rbx
+       movq    RBP_OFF(%rdi), %rbp
+       movq    R12_OFF(%rdi), %r12
+       movq    R13_OFF(%rdi), %r13
+       movq    R14_OFF(%rdi), %r14
+       movq    R15_OFF(%rdi), %r15
+       movq    SP_OFF(%rdi), %rsp
+       movq    PC_OFF(%rdi), %rdx
+
+       jmp     *%rdx
+
+.globl __go_makecontext
+.text
+__go_makecontext:
+       addq    %rcx, %rdx
+
+       // Align the SP, and push a dummy return address.
+       andq    $~0xfULL, %rdx
+       subq    $8, %rdx
+       movq    $0, (%rdx)
+
+       movq    %rdx, SP_OFF(%rdi)
+       movq    %rsi, PC_OFF(%rdi)
+
+       ret
+
+#endif
index 1569b5bb898c189aa95271d52ba3dbbdff83fbf1..5ef421f862498e8a8315571fdf9d2bb53a348aa3 100644 (file)
@@ -75,7 +75,7 @@ initcontext(void)
 }
 
 static inline void
 }
 
 static inline void
-fixcontext(ucontext_t *c __attribute__ ((unused)))
+fixcontext(__go_context_t *c __attribute__ ((unused)))
 {
 }
 
 {
 }
 
@@ -182,18 +182,18 @@ fixcontext(ucontext_t* c)
 // Go, and Go has no simple way to align a field to such a boundary.
 // So we make the field larger in runtime2.go and pick an appropriate
 // offset within the field here.
 // Go, and Go has no simple way to align a field to such a boundary.
 // So we make the field larger in runtime2.go and pick an appropriate
 // offset within the field here.
-static ucontext_t*
+static __go_context_t*
 ucontext_arg(uintptr_t* go_ucontext)
 {
        uintptr_t p = (uintptr_t)go_ucontext;
 ucontext_arg(uintptr_t* go_ucontext)
 {
        uintptr_t p = (uintptr_t)go_ucontext;
-       size_t align = __alignof__(ucontext_t);
+       size_t align = __alignof__(__go_context_t);
        if(align > 16) {
                // We only ensured space for up to a 16 byte alignment
                // in libgo/go/runtime/runtime2.go.
        if(align > 16) {
                // We only ensured space for up to a 16 byte alignment
                // in libgo/go/runtime/runtime2.go.
-               runtime_throw("required alignment of ucontext_t too large");
+               runtime_throw("required alignment of __go_context_t too large");
        }
        p = (p + align - 1) &~ (uintptr_t)(align - 1);
        }
        p = (p + align - 1) &~ (uintptr_t)(align - 1);
-       return (ucontext_t*)p;
+       return (__go_context_t*)p;
 }
 
 // We can not always refer to the TLS variables directly.  The
 }
 
 // We can not always refer to the TLS variables directly.  The
@@ -289,7 +289,7 @@ runtime_gogo(G* newg)
        g = newg;
        newg->fromgogo = true;
        fixcontext(ucontext_arg(&newg->context[0]));
        g = newg;
        newg->fromgogo = true;
        fixcontext(ucontext_arg(&newg->context[0]));
-       setcontext(ucontext_arg(&newg->context[0]));
+       __go_setcontext(ucontext_arg(&newg->context[0]));
        runtime_throw("gogo setcontext returned");
 }
 
        runtime_throw("gogo setcontext returned");
 }
 
@@ -328,7 +328,7 @@ runtime_mcall(FuncVal *fv)
                gp->gcnextsp2 = (uintptr)(secondary_stack_pointer());
 #endif
                gp->fromgogo = false;
                gp->gcnextsp2 = (uintptr)(secondary_stack_pointer());
 #endif
                gp->fromgogo = false;
-               getcontext(ucontext_arg(&gp->context[0]));
+               __go_getcontext(ucontext_arg(&gp->context[0]));
 
                // When we return from getcontext, we may be running
                // in a new thread.  That means that g may have
 
                // When we return from getcontext, we may be running
                // in a new thread.  That means that g may have
@@ -358,7 +358,7 @@ runtime_mcall(FuncVal *fv)
                g = mp->g0;
 
                fixcontext(ucontext_arg(&mp->g0->context[0]));
                g = mp->g0;
 
                fixcontext(ucontext_arg(&mp->g0->context[0]));
-               setcontext(ucontext_arg(&mp->g0->context[0]));
+               __go_setcontext(ucontext_arg(&mp->g0->context[0]));
                runtime_throw("runtime: mcall function returned");
        }
 }
                runtime_throw("runtime: mcall function returned");
        }
 }
@@ -450,7 +450,7 @@ void getTraceback(G* me, G* gp)
 #ifdef USING_SPLIT_STACK
        __splitstack_getcontext((void*)(&me->stackcontext[0]));
 #endif
 #ifdef USING_SPLIT_STACK
        __splitstack_getcontext((void*)(&me->stackcontext[0]));
 #endif
-       getcontext(ucontext_arg(&me->context[0]));
+       __go_getcontext(ucontext_arg(&me->context[0]));
 
        if (gp->traceback != 0) {
                runtime_gogo(gp);
 
        if (gp->traceback != 0) {
                runtime_gogo(gp);
@@ -493,7 +493,7 @@ doscanstackswitch(G* me, G* gp)
 #ifdef USING_SPLIT_STACK
        __splitstack_getcontext((void*)(&me->stackcontext[0]));
 #endif
 #ifdef USING_SPLIT_STACK
        __splitstack_getcontext((void*)(&me->stackcontext[0]));
 #endif
-       getcontext(ucontext_arg(&me->context[0]));
+       __go_getcontext(ucontext_arg(&me->context[0]));
 
        if(me->entry != nil) {
                // Got here from mcall.
 
        if(me->entry != nil) {
                // Got here from mcall.
@@ -574,7 +574,7 @@ runtime_mstart(void *arg)
 
        // Save the currently active context.  This will return
        // multiple times via the setcontext call in mcall.
 
        // Save the currently active context.  This will return
        // multiple times via the setcontext call in mcall.
-       getcontext(ucontext_arg(&gp->context[0]));
+       __go_getcontext(ucontext_arg(&gp->context[0]));
 
        if(gp->traceback != 0) {
                // Got here from getTraceback.
 
        if(gp->traceback != 0) {
                // Got here from getTraceback.
@@ -652,7 +652,7 @@ setGContext(void)
        gp->gcinitialsp2 = secondary_stack_pointer();
        gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
 #endif
        gp->gcinitialsp2 = secondary_stack_pointer();
        gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
 #endif
-       getcontext(ucontext_arg(&gp->context[0]));
+       __go_getcontext(ucontext_arg(&gp->context[0]));
 
        if(gp->entry != nil) {
                // Got here from mcall.
 
        if(gp->entry != nil) {
                // Got here from mcall.
@@ -672,13 +672,11 @@ void makeGContext(G*, byte*, uintptr)
 // makeGContext makes a new context for a g.
 void
 makeGContext(G* gp, byte* sp, uintptr spsize) {
 // makeGContext makes a new context for a g.
 void
 makeGContext(G* gp, byte* sp, uintptr spsize) {
-       ucontext_t *uc;
+       __go_context_t *uc;
 
        uc = ucontext_arg(&gp->context[0]);
 
        uc = ucontext_arg(&gp->context[0]);
-       getcontext(uc);
-       uc->uc_stack.ss_sp = sp;
-       uc->uc_stack.ss_size = (size_t)spsize;
-       makecontext(uc, kickoff, 0);
+       __go_getcontext(uc);
+       __go_makecontext(uc, kickoff, sp, (size_t)spsize);
 }
 
 // The goroutine g is about to enter a system call.
 }
 
 // The goroutine g is about to enter a system call.
@@ -700,7 +698,7 @@ runtime_entersyscall()
        // Save the registers in the g structure so that any pointers
        // held in registers will be seen by the garbage collector.
        if (!runtime_usestackmaps)
        // Save the registers in the g structure so that any pointers
        // held in registers will be seen by the garbage collector.
        if (!runtime_usestackmaps)
-               getcontext(ucontext_arg(&g->gcregs[0]));
+               __go_getcontext(ucontext_arg(&g->gcregs[0]));
 
        // Note that if this function does save any registers itself,
        // we might store the wrong value in the call to getcontext.
 
        // Note that if this function does save any registers itself,
        // we might store the wrong value in the call to getcontext.
@@ -747,7 +745,7 @@ runtime_entersyscallblock()
        // Save the registers in the g structure so that any pointers
        // held in registers will be seen by the garbage collector.
        if (!runtime_usestackmaps)
        // Save the registers in the g structure so that any pointers
        // held in registers will be seen by the garbage collector.
        if (!runtime_usestackmaps)
-               getcontext(ucontext_arg(&g->gcregs[0]));
+               __go_getcontext(ucontext_arg(&g->gcregs[0]));
 
        // See comment in runtime_entersyscall.
        doentersyscallblock((uintptr)runtime_getcallerpc(),
 
        // See comment in runtime_entersyscall.
        doentersyscallblock((uintptr)runtime_getcallerpc(),
index 71c1a3ee303bfabb0aaabe1eca6454740f37c795..a421dead67edaa950d3ef6b0469cefb15e65689e 100644 (file)
@@ -510,3 +510,20 @@ bool probestackmaps(void)
 // older versions of glibc when a SIGPROF signal arrives while
 // collecting a backtrace.
 extern uint32 __go_runtime_in_callers;
 // older versions of glibc when a SIGPROF signal arrives while
 // collecting a backtrace.
 extern uint32 __go_runtime_in_callers;
+
+// Cheaper context switch functions.  Currently only defined on
+// Linux/AMD64.
+#if defined(__x86_64__) && defined(__linux__) && !defined(__CET__)
+typedef struct {
+       uint64 regs[8];
+} __go_context_t;
+int __go_getcontext(__go_context_t*);
+int __go_setcontext(__go_context_t*);
+void __go_makecontext(__go_context_t*, void (*)(), void*, size_t);
+#else
+#define __go_context_t ucontext_t
+#define __go_getcontext(c)     getcontext(c)
+#define __go_setcontext(c)     setcontext(c)
+#define __go_makecontext(c, fn, sp, size) \
+       ((c)->uc_stack.ss_sp = sp, (c)->uc_stack.ss_size = size, makecontext(c, fn, 0))
+#endif
index 130758927053c631e16f096767e3734bd3d6ca5c..4b4d07dbd4e1d7aa355c96ecc5c09b077389f0c4 100644 (file)
@@ -141,6 +141,9 @@ AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 CC = @CC@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
 CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CCDEPMODE = @CCDEPMODE@
 CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
@@ -273,6 +276,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@