2009-05-26 12:18:42 -06:00
|
|
|
// 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.
|
|
|
|
|
[dev.cc] runtime: convert assembly files for C to Go transition
The main change is that #include "zasm_GOOS_GOARCH.h"
is now #include "go_asm.h" and/or #include "go_tls.h".
Also, because C StackGuard is now Go _StackGuard,
the assembly name changes from const_StackGuard to
const__StackGuard.
In asm_$GOARCH.s, add new function getg, formerly
implemented in C.
The renamed atomics now have Go wrappers, to get
escape analysis annotations right. Those wrappers
are in CL 174860043.
LGTM=r, aram
R=r, aram
CC=austin, dvyukov, golang-codereviews, iant, khr
https://golang.org/cl/168510043
2014-11-11 15:06:22 -07:00
|
|
|
#include "go_asm.h"
|
|
|
|
#include "go_tls.h"
|
2013-07-16 14:24:09 -06:00
|
|
|
#include "funcdata.h"
|
2014-09-04 21:05:18 -06:00
|
|
|
#include "textflag.h"
|
2009-06-23 12:54:23 -06:00
|
|
|
|
|
|
|
// using frame size $-4 means do not save LR on stack.
|
2014-09-03 09:11:16 -06:00
|
|
|
TEXT runtime·rt0_go(SB),NOSPLIT,$-4
|
2010-10-17 09:41:23 -06:00
|
|
|
MOVW $0xcafebabe, R12
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// copy arguments forward on an even stack
|
2009-06-23 12:54:23 -06:00
|
|
|
// use R13 instead of SP to avoid linker rewriting the offsets
|
|
|
|
MOVW 0(R13), R0 // argc
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
MOVW 4(R13), R1 // argv
|
2011-02-22 15:40:40 -07:00
|
|
|
SUB $64, R13 // plenty of scratch
|
2009-06-23 12:54:23 -06:00
|
|
|
AND $~7, R13
|
2011-02-22 15:40:40 -07:00
|
|
|
MOVW R0, 60(R13) // save argc, argv away
|
|
|
|
MOVW R1, 64(R13)
|
2009-06-16 12:25:58 -06:00
|
|
|
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
// set up g register
|
|
|
|
// g is R10
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
MOVW $runtime·g0(SB), g
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW $runtime·m0(SB), R8
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// save m->g0 = g0
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g, m_g0(R8)
|
|
|
|
// save g->m = m0
|
|
|
|
MOVW R8, g_m(g)
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// create istack out of the OS stack
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW $(-8192+104)(R13), R0
|
2015-01-05 09:29:21 -07:00
|
|
|
MOVW R0, g_stackguard0(g)
|
|
|
|
MOVW R0, g_stackguard1(g)
|
runtime: assume precisestack, copystack, StackCopyAlways, ScanStackByFrames
Commit to stack copying for stack growth.
We're carrying around a surprising amount of cruft from older schemes.
I am confident that precise stack scans and stack copying are here to stay.
Delete fallback code for when precise stack info is disabled.
Delete fallback code for when copying stacks is disabled.
Delete fallback code for when StackCopyAlways is disabled.
Delete Stktop chain - there is only one stack segment now.
Delete M.moreargp, M.moreargsize, M.moreframesize, M.cret.
Delete G.writenbuf (unrelated, just dead).
Delete runtime.lessstack, runtime.oldstack.
Delete many amd64 morestack variants.
Delete initialization of morestack frame/arg sizes (shortens split prologue!).
Replace G's stackguard/stackbase/stack0/stacksize/
syscallstack/syscallguard/forkstackguard with simple stack
bounds (lo, hi).
Update liblink, runtime/cgo for adjustments to G.
LGTM=khr
R=khr, bradfitz
CC=golang-codereviews, iant, r
https://golang.org/cl/137410043
2014-09-09 11:39:57 -06:00
|
|
|
MOVW R0, (g_stack+stack_lo)(g)
|
|
|
|
MOVW R13, (g_stack+stack_hi)(g)
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL runtime·emptyfunc(SB) // fault if stack check is wrong
|
2009-06-16 12:25:58 -06:00
|
|
|
|
2014-07-10 13:14:49 -06:00
|
|
|
#ifndef GOOS_nacl
|
2013-02-28 14:24:38 -07:00
|
|
|
// if there is an _cgo_init, call it.
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
MOVW _cgo_init(SB), R4
|
|
|
|
CMP $0, R4
|
|
|
|
B.EQ nocgo
|
cmd/go, cmd/ld, runtime, os/user: TLS emulation for android
Based on cl/69170045 by Elias Naur.
There are currently several schemes for acquiring a TLS
slot to save the g register. None of them appear to work
for android. The closest are linux and darwin.
Linux uses a linker TLS relocation. This is not supported
by the android linker.
Darwin uses a fixed offset, and calls pthread_key_create
until it gets the slot it wants. As the runtime loads
late in the android process lifecycle, after an
arbitrary number of other libraries, we cannot rely on
any particular slot being available.
So we call pthread_key_create, take the first slot we are
given, and put it in runtime.tlsg, which we turn into a
regular variable in cmd/ld.
Makes android/arm cgo binaries work.
LGTM=minux
R=elias.naur, minux, dave, josharian
CC=golang-codereviews
https://golang.org/cl/106380043
2014-07-03 14:14:34 -06:00
|
|
|
MRC 15, 0, R0, C13, C0, 3 // load TLS base pointer
|
|
|
|
MOVW R0, R3 // arg 3: TLS base pointer
|
|
|
|
MOVW $runtime·tlsg(SB), R2 // arg 2: tlsg
|
|
|
|
MOVW $setg_gcc<>(SB), R1 // arg 1: setg
|
|
|
|
MOVW g, R0 // arg 0: G
|
|
|
|
BL (R4) // will clobber R0-R3
|
2014-07-10 13:14:49 -06:00
|
|
|
#endif
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
|
|
|
|
nocgo:
|
2013-06-03 02:28:24 -06:00
|
|
|
// update stackguard after _cgo_init
|
runtime: assume precisestack, copystack, StackCopyAlways, ScanStackByFrames
Commit to stack copying for stack growth.
We're carrying around a surprising amount of cruft from older schemes.
I am confident that precise stack scans and stack copying are here to stay.
Delete fallback code for when precise stack info is disabled.
Delete fallback code for when copying stacks is disabled.
Delete fallback code for when StackCopyAlways is disabled.
Delete Stktop chain - there is only one stack segment now.
Delete M.moreargp, M.moreargsize, M.moreframesize, M.cret.
Delete G.writenbuf (unrelated, just dead).
Delete runtime.lessstack, runtime.oldstack.
Delete many amd64 morestack variants.
Delete initialization of morestack frame/arg sizes (shortens split prologue!).
Replace G's stackguard/stackbase/stack0/stacksize/
syscallstack/syscallguard/forkstackguard with simple stack
bounds (lo, hi).
Update liblink, runtime/cgo for adjustments to G.
LGTM=khr
R=khr, bradfitz
CC=golang-codereviews, iant, r
https://golang.org/cl/137410043
2014-09-09 11:39:57 -06:00
|
|
|
MOVW (g_stack+stack_lo)(g), R0
|
2014-11-11 20:30:02 -07:00
|
|
|
ADD $const__StackGuard, R0
|
2015-01-05 09:29:21 -07:00
|
|
|
MOVW R0, g_stackguard0(g)
|
|
|
|
MOVW R0, g_stackguard1(g)
|
2012-05-04 04:20:09 -06:00
|
|
|
|
2012-09-06 22:26:42 -06:00
|
|
|
BL runtime·checkgoarm(SB)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL runtime·check(SB)
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// saved argc, argv
|
2011-02-22 15:40:40 -07:00
|
|
|
MOVW 60(R13), R0
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW R0, 4(R13)
|
2011-02-22 15:40:40 -07:00
|
|
|
MOVW 64(R13), R1
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW R1, 8(R13)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL runtime·args(SB)
|
|
|
|
BL runtime·osinit(SB)
|
|
|
|
BL runtime·schedinit(SB)
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// create a new goroutine to start program
|
2013-02-21 15:01:13 -07:00
|
|
|
MOVW $runtime·main·f(SB), R0
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW.W R0, -4(R13)
|
2009-06-16 12:25:58 -06:00
|
|
|
MOVW $8, R0
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW.W R0, -4(R13)
|
2009-06-16 12:25:58 -06:00
|
|
|
MOVW $0, R0
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW.W R0, -4(R13) // push $0 as guard
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL runtime·newproc(SB)
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW $12(R13), R13 // pop args and LR
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// start this M
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL runtime·mstart(SB)
|
2009-06-16 12:25:58 -06:00
|
|
|
|
2009-10-29 22:21:14 -06:00
|
|
|
MOVW $1234, R0
|
|
|
|
MOVW $1000, R1
|
|
|
|
MOVW R0, (R1) // fail hard
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2013-02-21 15:01:13 -07:00
|
|
|
DATA runtime·main·f+0(SB)/4,$runtime·main(SB)
|
2013-08-07 11:23:24 -06:00
|
|
|
GLOBL runtime·main·f(SB),RODATA,$4
|
2013-02-21 15:01:13 -07:00
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
|
2012-04-24 09:19:44 -06:00
|
|
|
// gdb won't skip this breakpoint instruction automatically,
|
|
|
|
// so you must manually "set $pc+=4" to skip it and continue.
|
2014-07-10 13:14:49 -06:00
|
|
|
#ifdef GOOS_nacl
|
|
|
|
WORD $0xe125be7f // BKPT 0x5bef, NACL_INSTR_ARM_BREAKPOINT
|
|
|
|
#else
|
2014-09-22 23:34:38 -06:00
|
|
|
WORD $0xe7f001f0 // undefined instruction that gdb understands is a software breakpoint
|
2014-07-10 13:14:49 -06:00
|
|
|
#endif
|
2010-04-05 13:51:09 -06:00
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·asminit(SB),NOSPLIT,$0-0
|
2013-02-12 10:00:04 -07:00
|
|
|
// disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
|
2013-12-28 21:25:34 -07:00
|
|
|
MOVB runtime·goarm(SB), R11
|
2013-08-12 11:36:33 -06:00
|
|
|
CMP $5, R11
|
|
|
|
BLE 4(PC)
|
|
|
|
WORD $0xeef1ba10 // vmrs r11, fpscr
|
|
|
|
BIC $(1<<24), R11
|
|
|
|
WORD $0xeee1ba10 // vmsr fpscr, r11
|
2012-02-13 23:23:15 -07:00
|
|
|
RET
|
|
|
|
|
2009-06-23 12:54:23 -06:00
|
|
|
/*
|
|
|
|
* go-routine
|
|
|
|
*/
|
2009-06-10 12:53:07 -06:00
|
|
|
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
// void gosave(Gobuf*)
|
2009-06-23 12:54:23 -06:00
|
|
|
// save state in Gobuf; setjmp
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·gosave(SB),NOSPLIT,$-4-4
|
2010-10-08 17:46:05 -06:00
|
|
|
MOVW 0(FP), R0 // gobuf
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW SP, gobuf_sp(R0)
|
|
|
|
MOVW LR, gobuf_pc(R0)
|
|
|
|
MOVW g, gobuf_g(R0)
|
2013-06-12 13:22:26 -06:00
|
|
|
MOVW $0, R11
|
|
|
|
MOVW R11, gobuf_lr(R0)
|
|
|
|
MOVW R11, gobuf_ret(R0)
|
|
|
|
MOVW R11, gobuf_ctxt(R0)
|
2009-06-23 12:54:23 -06:00
|
|
|
RET
|
|
|
|
|
2013-06-12 16:05:10 -06:00
|
|
|
// void gogo(Gobuf*)
|
2009-06-23 12:54:23 -06:00
|
|
|
// restore state from Gobuf; longjmp
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·gogo(SB),NOSPLIT,$-4-4
|
2010-10-08 17:46:05 -06:00
|
|
|
MOVW 0(FP), R1 // gobuf
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW gobuf_g(R1), R0
|
|
|
|
BL setg<>(SB)
|
|
|
|
|
|
|
|
// NOTE: We updated g above, and we are about to update SP.
|
|
|
|
// Until LR and PC are also updated, the g/SP/LR/PC quadruple
|
|
|
|
// are out of sync and must not be used as the basis of a traceback.
|
|
|
|
// Sigprof skips the traceback when SP is not within g's bounds,
|
|
|
|
// and when the PC is inside this function, runtime.gogo.
|
|
|
|
// Since we are about to update SP, until we complete runtime.gogo
|
|
|
|
// we must not leave this function. In particular, no calls
|
|
|
|
// after this point: it must be straight-line code until the
|
|
|
|
// final B instruction.
|
|
|
|
// See large comment in sigprof for more details.
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW gobuf_sp(R1), SP // restore SP
|
2013-06-12 13:22:26 -06:00
|
|
|
MOVW gobuf_lr(R1), LR
|
|
|
|
MOVW gobuf_ret(R1), R0
|
|
|
|
MOVW gobuf_ctxt(R1), R7
|
|
|
|
MOVW $0, R11
|
|
|
|
MOVW R11, gobuf_sp(R1) // clear to help garbage collector
|
|
|
|
MOVW R11, gobuf_ret(R1)
|
|
|
|
MOVW R11, gobuf_lr(R1)
|
|
|
|
MOVW R11, gobuf_ctxt(R1)
|
2014-07-10 13:14:49 -06:00
|
|
|
MOVW gobuf_pc(R1), R11
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
CMP R11, R11 // set condition codes for == test, needed by stack split
|
2014-07-10 13:14:49 -06:00
|
|
|
B (R11)
|
2009-06-23 12:54:23 -06:00
|
|
|
|
2014-09-03 09:35:22 -06:00
|
|
|
// func mcall(fn func(*g))
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
// Switch to m->g0's stack, call fn(g).
|
runtime: stack split + garbage collection bug
The g->sched.sp saved stack pointer and the
g->stackbase and g->stackguard stack bounds
can change even while "the world is stopped",
because a goroutine has to call functions (and
therefore might split its stack) when exiting a
system call to check whether the world is stopped
(and if so, wait until the world continues).
That means the garbage collector cannot access
those values safely (without a race) for goroutines
executing system calls. Instead, save a consistent
triple in g->gcsp, g->gcstack, g->gcguard during
entersyscall and have the garbage collector refer
to those.
The old code was occasionally seeing (because of
the race) an sp and stk that did not correspond to
each other, so that stk - sp was not the number of
stack bytes following sp. In that case, if sp < stk
then the call scanblock(sp, stk - sp) scanned too
many bytes (anything between the two pointers,
which pointed into different allocation blocks).
If sp > stk then stk - sp wrapped around.
On 32-bit, stk - sp is a uintptr (uint32) converted
to int64 in the call to scanblock, so a large (~4G)
but positive number. Scanblock would try to scan
that many bytes and eventually fault accessing
unmapped memory. On 64-bit, stk - sp is a uintptr (uint64)
promoted to int64 in the call to scanblock, so a negative
number. Scanblock would not scan anything, possibly
causing in-use blocks to be freed.
In short, 32-bit platforms would have seen either
ineffective garbage collection or crashes during garbage
collection, while 64-bit platforms would have seen
either ineffective or incorrect garbage collection.
You can see the invalid arguments to scanblock in the
stack traces in issue 1620.
Fixes #1620.
Fixes #1746.
R=iant, r
CC=golang-dev
https://golang.org/cl/4437075
2011-04-27 21:21:12 -06:00
|
|
|
// Fn must never return. It should gogo(&g->sched)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
// to keep running g.
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·mcall(SB),NOSPLIT,$-4-4
|
2013-06-05 05:16:53 -06:00
|
|
|
// Save caller state in g->sched.
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
MOVW SP, (g_sched+gobuf_sp)(g)
|
|
|
|
MOVW LR, (g_sched+gobuf_pc)(g)
|
runtime: record proper goroutine state during stack split
Until now, the goroutine state has been scattered during the
execution of newstack and oldstack. It's all there, and those routines
know how to get back to a working goroutine, but other pieces of
the system, like stack traces, do not. If something does interrupt
the newstack or oldstack execution, the rest of the system can't
understand the goroutine. For example, if newstack decides there
is an overflow and calls throw, the stack tracer wouldn't dump the
goroutine correctly.
For newstack to save a useful state snapshot, it needs to be able
to rewind the PC in the function that triggered the split back to
the beginning of the function. (The PC is a few instructions in, just
after the call to morestack.) To make that possible, we change the
prologues to insert a jmp back to the beginning of the function
after the call to morestack. That is, the prologue used to be roughly:
TEXT myfunc
check for split
jmpcond nosplit
call morestack
nosplit:
sub $xxx, sp
Now an extra instruction is inserted after the call:
TEXT myfunc
start:
check for split
jmpcond nosplit
call morestack
jmp start
nosplit:
sub $xxx, sp
The jmp is not executed directly. It is decoded and simulated by
runtime.rewindmorestack to discover the beginning of the function,
and then the call to morestack returns directly to the start label
instead of to the jump instruction. So logically the jmp is still
executed, just not by the cpu.
The prologue thus repeats in the case of a function that needs a
stack split, but against the cost of the split itself, the extra few
instructions are noise. The repeated prologue has the nice effect of
making a stack split double-check that the new stack is big enough:
if morestack happens to return on a too-small stack, we'll now notice
before corruption happens.
The ability for newstack to rewind to the beginning of the function
should help preemption too. If newstack decides that it was called
for preemption instead of a stack split, it now has the goroutine state
correctly paused if rescheduling is needed, and when the goroutine
can run again, it can return to the start label on its original stack
and re-execute the split check.
Here is an example of a split stack overflow showing the full
trace, without any special cases in the stack printer.
(This one was triggered by making the split check incorrect.)
runtime: newstack framesize=0x0 argsize=0x18 sp=0x6aebd0 stack=[0x6b0000, 0x6b0fa0]
morebuf={pc:0x69f5b sp:0x6aebd8 lr:0x0}
sched={pc:0x68880 sp:0x6aebd0 lr:0x0 ctxt:0x34e700}
runtime: split stack overflow: 0x6aebd0 < 0x6b0000
fatal error: runtime: split stack overflow
goroutine 1 [stack split]:
runtime.mallocgc(0x290, 0x100000000, 0x1)
/Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:21 fp=0x6aebd8
runtime.new()
/Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:682 +0x5b fp=0x6aec08
go/build.(*Context).Import(0x5ae340, 0xc210030c71, 0xa, 0xc2100b4380, 0x1b, ...)
/Users/rsc/g/go/src/pkg/go/build/build.go:424 +0x3a fp=0x6b00a0
main.loadImport(0xc210030c71, 0xa, 0xc2100b4380, 0x1b, 0xc2100b42c0, ...)
/Users/rsc/g/go/src/cmd/go/pkg.go:249 +0x371 fp=0x6b01a8
main.(*Package).load(0xc21017c800, 0xc2100b42c0, 0xc2101828c0, 0x0, 0x0, ...)
/Users/rsc/g/go/src/cmd/go/pkg.go:431 +0x2801 fp=0x6b0c98
main.loadPackage(0x369040, 0x7, 0xc2100b42c0, 0x0)
/Users/rsc/g/go/src/cmd/go/pkg.go:709 +0x857 fp=0x6b0f80
----- stack segment boundary -----
main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc2100e6c00, 0xc2100e5750, ...)
/Users/rsc/g/go/src/cmd/go/build.go:539 +0x437 fp=0x6b14a0
main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc21015b400, 0x2, ...)
/Users/rsc/g/go/src/cmd/go/build.go:528 +0x1d2 fp=0x6b1658
main.(*builder).test(0xc2100902a0, 0xc210092000, 0x0, 0x0, 0xc21008ff60, ...)
/Users/rsc/g/go/src/cmd/go/test.go:622 +0x1b53 fp=0x6b1f68
----- stack segment boundary -----
main.runTest(0x5a6b20, 0xc21000a020, 0x2, 0x2)
/Users/rsc/g/go/src/cmd/go/test.go:366 +0xd09 fp=0x6a5cf0
main.main()
/Users/rsc/g/go/src/cmd/go/main.go:161 +0x4f9 fp=0x6a5f78
runtime.main()
/Users/rsc/g/go/src/pkg/runtime/proc.c:183 +0x92 fp=0x6a5fa0
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1266 fp=0x6a5fa8
And here is a seg fault during oldstack:
SIGSEGV: segmentation violation
PC=0x1b2a6
runtime.oldstack()
/Users/rsc/g/go/src/pkg/runtime/stack.c:159 +0x76
runtime.lessstack()
/Users/rsc/g/go/src/pkg/runtime/asm_amd64.s:270 +0x22
goroutine 1 [stack unsplit]:
fmt.(*pp).printArg(0x2102e64e0, 0xe5c80, 0x2102c9220, 0x73, 0x0, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:818 +0x3d3 fp=0x221031e6f8
fmt.(*pp).doPrintf(0x2102e64e0, 0x12fb20, 0x2, 0x221031eb98, 0x1, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:1183 +0x15cb fp=0x221031eaf0
fmt.Sprintf(0x12fb20, 0x2, 0x221031eb98, 0x1, 0x1, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:234 +0x67 fp=0x221031eb40
flag.(*stringValue).String(0x2102c9210, 0x1, 0x0)
/Users/rsc/g/go/src/pkg/flag/flag.go:180 +0xb3 fp=0x221031ebb0
flag.(*FlagSet).Var(0x2102f6000, 0x293d38, 0x2102c9210, 0x143490, 0xa, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:633 +0x40 fp=0x221031eca0
flag.(*FlagSet).StringVar(0x2102f6000, 0x2102c9210, 0x143490, 0xa, 0x12fa60, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:550 +0x91 fp=0x221031ece8
flag.(*FlagSet).String(0x2102f6000, 0x143490, 0xa, 0x12fa60, 0x0, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:563 +0x87 fp=0x221031ed38
flag.String(0x143490, 0xa, 0x12fa60, 0x0, 0x161950, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:570 +0x6b fp=0x221031ed80
testing.init()
/Users/rsc/g/go/src/pkg/testing/testing.go:-531 +0xbb fp=0x221031edc0
strings_test.init()
/Users/rsc/g/go/src/pkg/strings/strings_test.go:1115 +0x62 fp=0x221031ef70
main.init()
strings/_test/_testmain.go:90 +0x3d fp=0x221031ef78
runtime.main()
/Users/rsc/g/go/src/pkg/runtime/proc.c:180 +0x8a fp=0x221031efa0
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1269 fp=0x221031efa8
goroutine 2 [runnable]:
runtime.MHeap_Scavenger()
/Users/rsc/g/go/src/pkg/runtime/mheap.c:438
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1269
created by runtime.main
/Users/rsc/g/go/src/pkg/runtime/proc.c:166
rax 0x23ccc0
rbx 0x23ccc0
rcx 0x0
rdx 0x38
rdi 0x2102c0170
rsi 0x221032cfe0
rbp 0x221032cfa0
rsp 0x7fff5fbff5b0
r8 0x2102c0120
r9 0x221032cfa0
r10 0x221032c000
r11 0x104ce8
r12 0xe5c80
r13 0x1be82baac718
r14 0x13091135f7d69200
r15 0x0
rip 0x1b2a6
rflags 0x10246
cs 0x2b
fs 0x0
gs 0x0
Fixes #5723.
R=r, dvyukov, go.peter.90, dave, iant
CC=golang-dev
https://golang.org/cl/10360048
2013-06-27 09:32:01 -06:00
|
|
|
MOVW $0, R11
|
|
|
|
MOVW R11, (g_sched+gobuf_lr)(g)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
MOVW g, (g_sched+gobuf_g)(g)
|
|
|
|
|
|
|
|
// Switch to m->g0 & its stack, call fn.
|
|
|
|
MOVW g, R1
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g_m(g), R8
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW m_g0(R8), R0
|
|
|
|
BL setg<>(SB)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
CMP g, R1
|
2013-08-29 16:53:34 -06:00
|
|
|
B.NE 2(PC)
|
|
|
|
B runtime·badmcall(SB)
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVB runtime·iscgo(SB), R11
|
|
|
|
CMP $0, R11
|
|
|
|
BL.NE runtime·save_g(SB)
|
|
|
|
MOVW fn+0(FP), R0
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), SP
|
|
|
|
SUB $8, SP
|
|
|
|
MOVW R1, 4(SP)
|
2014-09-03 09:35:22 -06:00
|
|
|
MOVW R0, R7
|
|
|
|
MOVW 0(R0), R0
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
BL (R0)
|
2013-08-29 16:53:34 -06:00
|
|
|
B runtime·badmcall2(SB)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
RET
|
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// systemstack_switch is a dummy routine that systemstack leaves at the bottom
|
2014-07-30 10:01:52 -06:00
|
|
|
// of the G stack. We need to distinguish the routine that
|
|
|
|
// lives at the bottom of the G stack from the one that lives
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// at the top of the system stack because the one at the top of
|
|
|
|
// the system stack terminates the stack walk (see topofstack()).
|
|
|
|
TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0
|
2014-07-30 10:01:52 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
BL (R0) // clobber lr to ensure push {lr} is kept
|
|
|
|
RET
|
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// func systemstack(fn func())
|
|
|
|
TEXT runtime·systemstack(SB),NOSPLIT,$0-4
|
2014-07-30 10:01:52 -06:00
|
|
|
MOVW fn+0(FP), R0 // R0 = fn
|
|
|
|
MOVW g_m(g), R1 // R1 = m
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
MOVW m_gsignal(R1), R2 // R2 = gsignal
|
|
|
|
CMP g, R2
|
|
|
|
B.EQ noswitch
|
|
|
|
|
2014-07-30 10:01:52 -06:00
|
|
|
MOVW m_g0(R1), R2 // R2 = g0
|
|
|
|
CMP g, R2
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
B.EQ noswitch
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
|
2014-09-03 23:05:32 -06:00
|
|
|
MOVW m_curg(R1), R3
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
CMP g, R3
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
B.EQ switch
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// Bad: g is not gsignal, not g0, not curg. What is it?
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
// Hide call from linker nosplit analysis.
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
MOVW $runtime·badsystemstack(SB), R0
|
runtime: reject onM calls from gsignal stack
The implementation and use patterns of onM assume
that they run on either the m->curg or m->g0 stack.
Calling onM from m->gsignal has two problems:
(1) When not on g0, onM switches to g0 and then "back" to curg.
If we didn't start at curg, bad things happen.
(2) The use of scalararg/ptrarg to pass C arguments and results
assumes that there is only one onM call at a time.
If a gsignal starts running, it may have interrupted the
setup/teardown of the args for an onM on the curg or g0 stack.
Using scalararg/ptrarg itself would smash those.
We can fix (1) by remembering what g was running before the switch.
We can fix (2) by requiring that uses of onM that might happen
on a signal handling stack must save the old scalararg/ptrarg
and restore them after the call, instead of zeroing them.
The only sane way to do this is to introduce a separate
onM_signalsafe that omits the signal check, and then if you
see a call to onM_signalsafe you know the surrounding code
must preserve the old scalararg/ptrarg values.
(The implementation would be that onM_signalsafe just calls
fn if on the signal stack or else jumps to onM. It's not necessary
to have two whole copies of the function.)
(2) is not a problem if the caller and callee are both Go and
a closure is used instead of the scalararg/ptrarg slots.
For now, I think we can avoid calling onM from code executing
on gsignal stacks, so just reject it.
In the long term, (2) goes away (as do the scalararg/ptrarg slots)
once everything is in Go, and at that point fixing (1) would be
trivial and maybe worth doing just for regularity.
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135400043
2014-09-03 22:10:10 -06:00
|
|
|
BL (R0)
|
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
switch:
|
2014-07-30 10:01:52 -06:00
|
|
|
// save our state in g->sched. Pretend to
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// be systemstack_switch if the G stack is scanned.
|
|
|
|
MOVW $runtime·systemstack_switch(SB), R3
|
2014-07-30 10:01:52 -06:00
|
|
|
ADD $4, R3, R3 // get past push {lr}
|
|
|
|
MOVW R3, (g_sched+gobuf_pc)(g)
|
|
|
|
MOVW SP, (g_sched+gobuf_sp)(g)
|
|
|
|
MOVW LR, (g_sched+gobuf_lr)(g)
|
|
|
|
MOVW g, (g_sched+gobuf_g)(g)
|
|
|
|
|
|
|
|
// switch to g0
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW R0, R5
|
|
|
|
MOVW R2, R0
|
|
|
|
BL setg<>(SB)
|
|
|
|
MOVW R5, R0
|
runtime: do not stop traceback at onM
Behavior before this CL:
1. If onM is called on a g0 stack, it just calls the given function.
2. If onM is called on a gsignal stack, it calls badonm.
3. If onM is called on a curg stack, it switches to the g0 stack
and then calls the function.
In cases 1 and 2, if the program then crashes (and badonm always does),
we want to see what called onM, but the traceback stops at onM.
In case 3, the traceback must stop at onM, because the g0
stack we are renting really does stop at onM.
The current code stops the traceback at onM to handle 3,
at the cost of making 1 and 2 crash with incomplete traces.
Change traceback to scan past onM but in case 3 make it look
like on the rented g0 stack, onM was called from mstart.
The traceback already knows that mstart is a top-of-stack function.
Alternate fix at CL 132610043 but I think this one is cleaner.
This CL makes 3 the exception, while that CL makes 1 and 2 the exception.
Submitting TBR to try to get better stack traces out of the
freebsd/amd64 builder, but happy to make changes in a
followup CL.
TBR=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/133620043
2014-09-04 20:48:08 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(R2), R3
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// make it look like mstart called systemstack on g0, to stop traceback
|
runtime: do not stop traceback at onM
Behavior before this CL:
1. If onM is called on a g0 stack, it just calls the given function.
2. If onM is called on a gsignal stack, it calls badonm.
3. If onM is called on a curg stack, it switches to the g0 stack
and then calls the function.
In cases 1 and 2, if the program then crashes (and badonm always does),
we want to see what called onM, but the traceback stops at onM.
In case 3, the traceback must stop at onM, because the g0
stack we are renting really does stop at onM.
The current code stops the traceback at onM to handle 3,
at the cost of making 1 and 2 crash with incomplete traces.
Change traceback to scan past onM but in case 3 make it look
like on the rented g0 stack, onM was called from mstart.
The traceback already knows that mstart is a top-of-stack function.
Alternate fix at CL 132610043 but I think this one is cleaner.
This CL makes 3 the exception, while that CL makes 1 and 2 the exception.
Submitting TBR to try to get better stack traces out of the
freebsd/amd64 builder, but happy to make changes in a
followup CL.
TBR=khr
R=khr
CC=golang-codereviews
https://golang.org/cl/133620043
2014-09-04 20:48:08 -06:00
|
|
|
SUB $4, R3, R3
|
|
|
|
MOVW $runtime·mstart(SB), R4
|
|
|
|
MOVW R4, 0(R3)
|
|
|
|
MOVW R3, SP
|
2014-07-30 10:01:52 -06:00
|
|
|
|
|
|
|
// call target function
|
2014-09-03 09:35:22 -06:00
|
|
|
MOVW R0, R7
|
|
|
|
MOVW 0(R0), R0
|
2014-07-30 10:01:52 -06:00
|
|
|
BL (R0)
|
|
|
|
|
|
|
|
// switch back to g
|
|
|
|
MOVW g_m(g), R1
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW m_curg(R1), R0
|
|
|
|
BL setg<>(SB)
|
2014-07-30 10:01:52 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), SP
|
|
|
|
MOVW $0, R3
|
|
|
|
MOVW R3, (g_sched+gobuf_sp)(g)
|
|
|
|
RET
|
|
|
|
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
noswitch:
|
2014-09-03 09:35:22 -06:00
|
|
|
MOVW R0, R7
|
|
|
|
MOVW 0(R0), R0
|
2014-07-30 10:01:52 -06:00
|
|
|
BL (R0)
|
|
|
|
RET
|
|
|
|
|
2009-06-23 12:54:23 -06:00
|
|
|
/*
|
|
|
|
* support for morestack
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Called during function prolog when more stack is needed.
|
|
|
|
// R1 frame size
|
|
|
|
// R2 arg size
|
|
|
|
// R3 prolog's LR
|
2010-04-05 13:51:09 -06:00
|
|
|
// NB. we do not save R0 because we've forced 5c to pass all arguments
|
2009-10-23 11:59:31 -06:00
|
|
|
// on the stack.
|
2009-06-23 12:54:23 -06:00
|
|
|
// using frame size $-4 means do not save LR on stack.
|
2013-07-18 14:53:45 -06:00
|
|
|
//
|
|
|
|
// The traceback routines see morestack on a g0 as being
|
|
|
|
// the top of a stack (for example, morestack calling newstack
|
|
|
|
// calling the scheduler calling newm calling gc), so we must
|
|
|
|
// record an argument size. For that purpose, it has no arguments.
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·morestack(SB),NOSPLIT,$-4-0
|
2009-06-23 12:54:23 -06:00
|
|
|
// Cannot grow scheduler stack (m->g0).
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g_m(g), R8
|
|
|
|
MOVW m_g0(R8), R4
|
2009-06-23 12:54:23 -06:00
|
|
|
CMP g, R4
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
BL.EQ runtime·abort(SB)
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2014-09-05 14:51:45 -06:00
|
|
|
// Cannot grow signal stack (m->gsignal).
|
|
|
|
MOVW m_gsignal(R8), R4
|
|
|
|
CMP g, R4
|
|
|
|
BL.EQ runtime·abort(SB)
|
|
|
|
|
runtime: record proper goroutine state during stack split
Until now, the goroutine state has been scattered during the
execution of newstack and oldstack. It's all there, and those routines
know how to get back to a working goroutine, but other pieces of
the system, like stack traces, do not. If something does interrupt
the newstack or oldstack execution, the rest of the system can't
understand the goroutine. For example, if newstack decides there
is an overflow and calls throw, the stack tracer wouldn't dump the
goroutine correctly.
For newstack to save a useful state snapshot, it needs to be able
to rewind the PC in the function that triggered the split back to
the beginning of the function. (The PC is a few instructions in, just
after the call to morestack.) To make that possible, we change the
prologues to insert a jmp back to the beginning of the function
after the call to morestack. That is, the prologue used to be roughly:
TEXT myfunc
check for split
jmpcond nosplit
call morestack
nosplit:
sub $xxx, sp
Now an extra instruction is inserted after the call:
TEXT myfunc
start:
check for split
jmpcond nosplit
call morestack
jmp start
nosplit:
sub $xxx, sp
The jmp is not executed directly. It is decoded and simulated by
runtime.rewindmorestack to discover the beginning of the function,
and then the call to morestack returns directly to the start label
instead of to the jump instruction. So logically the jmp is still
executed, just not by the cpu.
The prologue thus repeats in the case of a function that needs a
stack split, but against the cost of the split itself, the extra few
instructions are noise. The repeated prologue has the nice effect of
making a stack split double-check that the new stack is big enough:
if morestack happens to return on a too-small stack, we'll now notice
before corruption happens.
The ability for newstack to rewind to the beginning of the function
should help preemption too. If newstack decides that it was called
for preemption instead of a stack split, it now has the goroutine state
correctly paused if rescheduling is needed, and when the goroutine
can run again, it can return to the start label on its original stack
and re-execute the split check.
Here is an example of a split stack overflow showing the full
trace, without any special cases in the stack printer.
(This one was triggered by making the split check incorrect.)
runtime: newstack framesize=0x0 argsize=0x18 sp=0x6aebd0 stack=[0x6b0000, 0x6b0fa0]
morebuf={pc:0x69f5b sp:0x6aebd8 lr:0x0}
sched={pc:0x68880 sp:0x6aebd0 lr:0x0 ctxt:0x34e700}
runtime: split stack overflow: 0x6aebd0 < 0x6b0000
fatal error: runtime: split stack overflow
goroutine 1 [stack split]:
runtime.mallocgc(0x290, 0x100000000, 0x1)
/Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:21 fp=0x6aebd8
runtime.new()
/Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:682 +0x5b fp=0x6aec08
go/build.(*Context).Import(0x5ae340, 0xc210030c71, 0xa, 0xc2100b4380, 0x1b, ...)
/Users/rsc/g/go/src/pkg/go/build/build.go:424 +0x3a fp=0x6b00a0
main.loadImport(0xc210030c71, 0xa, 0xc2100b4380, 0x1b, 0xc2100b42c0, ...)
/Users/rsc/g/go/src/cmd/go/pkg.go:249 +0x371 fp=0x6b01a8
main.(*Package).load(0xc21017c800, 0xc2100b42c0, 0xc2101828c0, 0x0, 0x0, ...)
/Users/rsc/g/go/src/cmd/go/pkg.go:431 +0x2801 fp=0x6b0c98
main.loadPackage(0x369040, 0x7, 0xc2100b42c0, 0x0)
/Users/rsc/g/go/src/cmd/go/pkg.go:709 +0x857 fp=0x6b0f80
----- stack segment boundary -----
main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc2100e6c00, 0xc2100e5750, ...)
/Users/rsc/g/go/src/cmd/go/build.go:539 +0x437 fp=0x6b14a0
main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc21015b400, 0x2, ...)
/Users/rsc/g/go/src/cmd/go/build.go:528 +0x1d2 fp=0x6b1658
main.(*builder).test(0xc2100902a0, 0xc210092000, 0x0, 0x0, 0xc21008ff60, ...)
/Users/rsc/g/go/src/cmd/go/test.go:622 +0x1b53 fp=0x6b1f68
----- stack segment boundary -----
main.runTest(0x5a6b20, 0xc21000a020, 0x2, 0x2)
/Users/rsc/g/go/src/cmd/go/test.go:366 +0xd09 fp=0x6a5cf0
main.main()
/Users/rsc/g/go/src/cmd/go/main.go:161 +0x4f9 fp=0x6a5f78
runtime.main()
/Users/rsc/g/go/src/pkg/runtime/proc.c:183 +0x92 fp=0x6a5fa0
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1266 fp=0x6a5fa8
And here is a seg fault during oldstack:
SIGSEGV: segmentation violation
PC=0x1b2a6
runtime.oldstack()
/Users/rsc/g/go/src/pkg/runtime/stack.c:159 +0x76
runtime.lessstack()
/Users/rsc/g/go/src/pkg/runtime/asm_amd64.s:270 +0x22
goroutine 1 [stack unsplit]:
fmt.(*pp).printArg(0x2102e64e0, 0xe5c80, 0x2102c9220, 0x73, 0x0, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:818 +0x3d3 fp=0x221031e6f8
fmt.(*pp).doPrintf(0x2102e64e0, 0x12fb20, 0x2, 0x221031eb98, 0x1, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:1183 +0x15cb fp=0x221031eaf0
fmt.Sprintf(0x12fb20, 0x2, 0x221031eb98, 0x1, 0x1, ...)
/Users/rsc/g/go/src/pkg/fmt/print.go:234 +0x67 fp=0x221031eb40
flag.(*stringValue).String(0x2102c9210, 0x1, 0x0)
/Users/rsc/g/go/src/pkg/flag/flag.go:180 +0xb3 fp=0x221031ebb0
flag.(*FlagSet).Var(0x2102f6000, 0x293d38, 0x2102c9210, 0x143490, 0xa, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:633 +0x40 fp=0x221031eca0
flag.(*FlagSet).StringVar(0x2102f6000, 0x2102c9210, 0x143490, 0xa, 0x12fa60, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:550 +0x91 fp=0x221031ece8
flag.(*FlagSet).String(0x2102f6000, 0x143490, 0xa, 0x12fa60, 0x0, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:563 +0x87 fp=0x221031ed38
flag.String(0x143490, 0xa, 0x12fa60, 0x0, 0x161950, ...)
/Users/rsc/g/go/src/pkg/flag/flag.go:570 +0x6b fp=0x221031ed80
testing.init()
/Users/rsc/g/go/src/pkg/testing/testing.go:-531 +0xbb fp=0x221031edc0
strings_test.init()
/Users/rsc/g/go/src/pkg/strings/strings_test.go:1115 +0x62 fp=0x221031ef70
main.init()
strings/_test/_testmain.go:90 +0x3d fp=0x221031ef78
runtime.main()
/Users/rsc/g/go/src/pkg/runtime/proc.c:180 +0x8a fp=0x221031efa0
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1269 fp=0x221031efa8
goroutine 2 [runnable]:
runtime.MHeap_Scavenger()
/Users/rsc/g/go/src/pkg/runtime/mheap.c:438
runtime.goexit()
/Users/rsc/g/go/src/pkg/runtime/proc.c:1269
created by runtime.main
/Users/rsc/g/go/src/pkg/runtime/proc.c:166
rax 0x23ccc0
rbx 0x23ccc0
rcx 0x0
rdx 0x38
rdi 0x2102c0170
rsi 0x221032cfe0
rbp 0x221032cfa0
rsp 0x7fff5fbff5b0
r8 0x2102c0120
r9 0x221032cfa0
r10 0x221032c000
r11 0x104ce8
r12 0xe5c80
r13 0x1be82baac718
r14 0x13091135f7d69200
r15 0x0
rip 0x1b2a6
rflags 0x10246
cs 0x2b
fs 0x0
gs 0x0
Fixes #5723.
R=r, dvyukov, go.peter.90, dave, iant
CC=golang-dev
https://golang.org/cl/10360048
2013-06-27 09:32:01 -06:00
|
|
|
// Called from f.
|
|
|
|
// Set g->sched to context in f.
|
|
|
|
MOVW R7, (g_sched+gobuf_ctxt)(g)
|
|
|
|
MOVW SP, (g_sched+gobuf_sp)(g)
|
|
|
|
MOVW LR, (g_sched+gobuf_pc)(g)
|
|
|
|
MOVW R3, (g_sched+gobuf_lr)(g)
|
|
|
|
|
2009-06-23 12:54:23 -06:00
|
|
|
// Called from f.
|
|
|
|
// Set m->morebuf to f's caller.
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC
|
|
|
|
MOVW SP, (m_morebuf+gobuf_sp)(R8) // f's caller's SP
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW $4(SP), R3 // f's argument pointer
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g, (m_morebuf+gobuf_g)(R8)
|
2009-06-23 12:54:23 -06:00
|
|
|
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
// Call newstack on m->g0's stack.
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW m_g0(R8), R0
|
|
|
|
BL setg<>(SB)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), SP
|
2013-07-18 14:53:45 -06:00
|
|
|
BL runtime·newstack(SB)
|
2009-06-23 12:54:23 -06:00
|
|
|
|
2013-08-01 16:51:55 -06:00
|
|
|
// Not reached, but make sure the return PC from the call to newstack
|
|
|
|
// is still in this function, and not the beginning of the next.
|
|
|
|
RET
|
|
|
|
|
2014-03-04 11:53:08 -07:00
|
|
|
TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0
|
|
|
|
MOVW $0, R7
|
2014-03-04 12:03:39 -07:00
|
|
|
B runtime·morestack(SB)
|
2014-03-04 11:53:08 -07:00
|
|
|
|
2014-09-08 11:14:41 -06:00
|
|
|
// reflectcall: call a function with the given argument list
|
2014-12-30 11:59:55 -07:00
|
|
|
// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
|
2013-08-02 14:03:14 -06:00
|
|
|
// we don't have variable-sized frames, so we use a small number
|
|
|
|
// of constant-sized-frame functions to encode a few bits of size in the pc.
|
|
|
|
// Caution: ugly multiline assembly macros in your future!
|
|
|
|
|
|
|
|
#define DISPATCH(NAME,MAXSIZE) \
|
|
|
|
CMP $MAXSIZE, R0; \
|
|
|
|
B.HI 3(PC); \
|
2014-09-05 14:51:45 -06:00
|
|
|
MOVW $NAME(SB), R1; \
|
2013-08-02 14:03:14 -06:00
|
|
|
B (R1)
|
|
|
|
|
2014-12-22 11:27:53 -07:00
|
|
|
TEXT reflect·call(SB), NOSPLIT, $0-0
|
|
|
|
B ·reflectcall(SB)
|
|
|
|
|
2014-12-30 11:59:55 -07:00
|
|
|
TEXT ·reflectcall(SB),NOSPLIT,$-4-20
|
|
|
|
MOVW argsize+12(FP), R0
|
2014-07-30 11:11:44 -06:00
|
|
|
DISPATCH(runtime·call16, 16)
|
|
|
|
DISPATCH(runtime·call32, 32)
|
|
|
|
DISPATCH(runtime·call64, 64)
|
|
|
|
DISPATCH(runtime·call128, 128)
|
|
|
|
DISPATCH(runtime·call256, 256)
|
|
|
|
DISPATCH(runtime·call512, 512)
|
|
|
|
DISPATCH(runtime·call1024, 1024)
|
|
|
|
DISPATCH(runtime·call2048, 2048)
|
|
|
|
DISPATCH(runtime·call4096, 4096)
|
|
|
|
DISPATCH(runtime·call8192, 8192)
|
|
|
|
DISPATCH(runtime·call16384, 16384)
|
|
|
|
DISPATCH(runtime·call32768, 32768)
|
|
|
|
DISPATCH(runtime·call65536, 65536)
|
|
|
|
DISPATCH(runtime·call131072, 131072)
|
|
|
|
DISPATCH(runtime·call262144, 262144)
|
|
|
|
DISPATCH(runtime·call524288, 524288)
|
|
|
|
DISPATCH(runtime·call1048576, 1048576)
|
|
|
|
DISPATCH(runtime·call2097152, 2097152)
|
|
|
|
DISPATCH(runtime·call4194304, 4194304)
|
|
|
|
DISPATCH(runtime·call8388608, 8388608)
|
|
|
|
DISPATCH(runtime·call16777216, 16777216)
|
|
|
|
DISPATCH(runtime·call33554432, 33554432)
|
|
|
|
DISPATCH(runtime·call67108864, 67108864)
|
|
|
|
DISPATCH(runtime·call134217728, 134217728)
|
|
|
|
DISPATCH(runtime·call268435456, 268435456)
|
|
|
|
DISPATCH(runtime·call536870912, 536870912)
|
|
|
|
DISPATCH(runtime·call1073741824, 1073741824)
|
2013-08-02 14:03:14 -06:00
|
|
|
MOVW $runtime·badreflectcall(SB), R1
|
|
|
|
B (R1)
|
|
|
|
|
2013-08-06 15:33:55 -06:00
|
|
|
#define CALLFN(NAME,MAXSIZE) \
|
2014-12-30 11:59:55 -07:00
|
|
|
TEXT NAME(SB), WRAPPER, $MAXSIZE-20; \
|
2014-10-15 11:12:16 -06:00
|
|
|
NO_LOCAL_POINTERS; \
|
2013-08-02 14:03:14 -06:00
|
|
|
/* copy arguments to stack */ \
|
2014-12-30 11:59:55 -07:00
|
|
|
MOVW argptr+8(FP), R0; \
|
|
|
|
MOVW argsize+12(FP), R2; \
|
2013-08-02 14:03:14 -06:00
|
|
|
ADD $4, SP, R1; \
|
|
|
|
CMP $0, R2; \
|
|
|
|
B.EQ 5(PC); \
|
|
|
|
MOVBU.P 1(R0), R5; \
|
|
|
|
MOVBU.P R5, 1(R1); \
|
|
|
|
SUB $1, R2, R2; \
|
|
|
|
B -5(PC); \
|
|
|
|
/* call function */ \
|
2014-12-30 11:59:55 -07:00
|
|
|
MOVW f+4(FP), R7; \
|
2013-08-02 14:03:14 -06:00
|
|
|
MOVW (R7), R0; \
|
2014-05-21 15:28:34 -06:00
|
|
|
PCDATA $PCDATA_StackMapIndex, $0; \
|
2013-08-02 14:03:14 -06:00
|
|
|
BL (R0); \
|
|
|
|
/* copy return values back */ \
|
2014-12-30 11:59:55 -07:00
|
|
|
MOVW argptr+8(FP), R0; \
|
|
|
|
MOVW argsize+12(FP), R2; \
|
|
|
|
MOVW retoffset+16(FP), R3; \
|
2013-08-02 14:03:14 -06:00
|
|
|
ADD $4, SP, R1; \
|
reflect, runtime: fix crash in GC due to reflect.call + precise GC
Given
type Outer struct {
*Inner
...
}
the compiler generates the implementation of (*Outer).M dispatching to
the embedded Inner. The implementation is logically:
func (p *Outer) M() {
(p.Inner).M()
}
but since the only change here is the replacement of one pointer
receiver with another, the actual generated code overwrites the
original receiver with the p.Inner pointer and then jumps to the M
method expecting the *Inner receiver.
During reflect.Value.Call, we create an argument frame and the
associated data structures to describe it to the garbage collector,
populate the frame, call reflect.call to run a function call using
that frame, and then copy the results back out of the frame. The
reflect.call function does a memmove of the frame structure onto the
stack (to set up the inputs), runs the call, and the memmoves the
stack back to the frame structure (to preserve the outputs).
Originally reflect.call did not distinguish inputs from outputs: both
memmoves were for the full stack frame. However, in the case where the
called function was one of these wrappers, the rewritten receiver is
almost certainly a different type than the original receiver. This is
not a problem on the stack, where we use the program counter to
determine the type information and understand that during (*Outer).M
the receiver is an *Outer while during (*Inner).M the receiver in the
same memory word is now an *Inner. But in the statically typed
argument frame created by reflect, the receiver is always an *Outer.
Copying the modified receiver pointer off the stack into the frame
will store an *Inner there, and then if a garbage collection happens
to scan that argument frame before it is discarded, it will scan the
*Inner memory as if it were an *Outer. If the two have different
memory layouts, the collection will intepret the memory incorrectly.
Fix by only copying back the results.
Fixes #7725.
LGTM=khr
R=khr
CC=dave, golang-codereviews
https://golang.org/cl/85180043
2014-04-08 09:11:35 -06:00
|
|
|
ADD R3, R1; \
|
|
|
|
ADD R3, R0; \
|
|
|
|
SUB R3, R2; \
|
2014-12-30 11:59:55 -07:00
|
|
|
loop:
|
2013-08-02 14:03:14 -06:00
|
|
|
CMP $0, R2; \
|
2014-12-30 11:59:55 -07:00
|
|
|
B.EQ end; \
|
2013-08-02 14:03:14 -06:00
|
|
|
MOVBU.P 1(R1), R5; \
|
|
|
|
MOVBU.P R5, 1(R0); \
|
|
|
|
SUB $1, R2, R2; \
|
2014-12-30 11:59:55 -07:00
|
|
|
B loop; \
|
|
|
|
end: \
|
|
|
|
/* execute write barrier updates */ \
|
|
|
|
MOVW argtype+0(FP), R1; \
|
|
|
|
MOVW argptr+8(FP), R0; \
|
|
|
|
MOVW argsize+12(FP), R2; \
|
|
|
|
MOVW retoffset+16(FP), R3; \
|
|
|
|
MOVW R1, 4(R13); \
|
|
|
|
MOVW R0, 8(R13); \
|
|
|
|
MOVW R2, 12(R13); \
|
|
|
|
MOVW R3, 16(R13); \
|
|
|
|
BL runtime·callwritebarrier(SB); \
|
|
|
|
RET
|
2013-08-02 14:03:14 -06:00
|
|
|
|
2014-10-15 11:12:16 -06:00
|
|
|
CALLFN(·call16, 16)
|
|
|
|
CALLFN(·call32, 32)
|
|
|
|
CALLFN(·call64, 64)
|
|
|
|
CALLFN(·call128, 128)
|
|
|
|
CALLFN(·call256, 256)
|
|
|
|
CALLFN(·call512, 512)
|
|
|
|
CALLFN(·call1024, 1024)
|
|
|
|
CALLFN(·call2048, 2048)
|
|
|
|
CALLFN(·call4096, 4096)
|
|
|
|
CALLFN(·call8192, 8192)
|
|
|
|
CALLFN(·call16384, 16384)
|
|
|
|
CALLFN(·call32768, 32768)
|
|
|
|
CALLFN(·call65536, 65536)
|
|
|
|
CALLFN(·call131072, 131072)
|
|
|
|
CALLFN(·call262144, 262144)
|
|
|
|
CALLFN(·call524288, 524288)
|
|
|
|
CALLFN(·call1048576, 1048576)
|
|
|
|
CALLFN(·call2097152, 2097152)
|
|
|
|
CALLFN(·call4194304, 4194304)
|
|
|
|
CALLFN(·call8388608, 8388608)
|
|
|
|
CALLFN(·call16777216, 16777216)
|
|
|
|
CALLFN(·call33554432, 33554432)
|
|
|
|
CALLFN(·call67108864, 67108864)
|
|
|
|
CALLFN(·call134217728, 134217728)
|
|
|
|
CALLFN(·call268435456, 268435456)
|
|
|
|
CALLFN(·call536870912, 536870912)
|
|
|
|
CALLFN(·call1073741824, 1073741824)
|
2013-08-02 14:03:14 -06:00
|
|
|
|
2009-06-10 12:53:07 -06:00
|
|
|
// void jmpdefer(fn, sp);
|
|
|
|
// called from deferreturn.
|
2009-10-05 22:52:10 -06:00
|
|
|
// 1. grab stored LR for caller
|
|
|
|
// 2. sub 4 bytes to get back to BL deferreturn
|
|
|
|
// 3. B to fn
|
2014-06-12 14:34:54 -06:00
|
|
|
// TODO(rsc): Push things on stack and then use pop
|
|
|
|
// to load all registers simultaneously, so that a profiling
|
|
|
|
// interrupt can never see mismatched SP/LR/PC.
|
|
|
|
// (And double-check that pop is atomic in that way.)
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
|
2009-10-05 22:52:10 -06:00
|
|
|
MOVW 0(SP), LR
|
|
|
|
MOVW $-4(LR), LR // BL deferreturn
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVW fv+0(FP), R7
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW argp+4(FP), SP
|
|
|
|
MOVW $-4(SP), SP // SP is 4 below argp, due to saved LR
|
2013-02-22 12:25:50 -07:00
|
|
|
MOVW 0(R7), R1
|
2013-02-21 15:01:13 -07:00
|
|
|
B (R1)
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2013-06-12 13:22:26 -06:00
|
|
|
// Save state of caller into g->sched. Smashes R11.
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT gosave<>(SB),NOSPLIT,$0
|
2013-06-12 13:22:26 -06:00
|
|
|
MOVW LR, (g_sched+gobuf_pc)(g)
|
|
|
|
MOVW R13, (g_sched+gobuf_sp)(g)
|
|
|
|
MOVW $0, R11
|
|
|
|
MOVW R11, (g_sched+gobuf_lr)(g)
|
|
|
|
MOVW R11, (g_sched+gobuf_ret)(g)
|
|
|
|
MOVW R11, (g_sched+gobuf_ctxt)(g)
|
2012-05-04 04:20:09 -06:00
|
|
|
RET
|
|
|
|
|
|
|
|
// asmcgocall(void(*fn)(void*), void *arg)
|
|
|
|
// Call fn(arg) on the scheduler stack,
|
|
|
|
// aligned appropriately for the gcc ABI.
|
|
|
|
// See cgocall.c for more details.
|
2014-09-16 15:39:55 -06:00
|
|
|
TEXT ·asmcgocall(SB),NOSPLIT,$0-8
|
2014-09-03 09:36:14 -06:00
|
|
|
MOVW fn+0(FP), R1
|
2014-09-03 22:01:55 -06:00
|
|
|
MOVW arg+4(FP), R0
|
|
|
|
BL asmcgocall<>(SB)
|
2014-09-03 09:36:14 -06:00
|
|
|
RET
|
|
|
|
|
2014-09-16 15:39:55 -06:00
|
|
|
TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW fn+0(FP), R1
|
|
|
|
MOVW arg+4(FP), R0
|
2014-09-03 22:01:55 -06:00
|
|
|
BL asmcgocall<>(SB)
|
|
|
|
MOVW R0, ret+8(FP)
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT asmcgocall<>(SB),NOSPLIT,$0-0
|
|
|
|
// fn in R1, arg in R0.
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW R13, R2
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW g, R4
|
2012-05-04 04:20:09 -06:00
|
|
|
|
|
|
|
// Figure out if we need to switch to m->g0 stack.
|
|
|
|
// We get called to create new OS threads too, and those
|
|
|
|
// come in on the m->g0 stack already.
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g_m(g), R8
|
|
|
|
MOVW m_g0(R8), R3
|
2012-05-04 04:20:09 -06:00
|
|
|
CMP R3, g
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
BEQ g0
|
2013-06-12 13:22:26 -06:00
|
|
|
BL gosave<>(SB)
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW R0, R5
|
|
|
|
MOVW R3, R0
|
|
|
|
BL setg<>(SB)
|
|
|
|
MOVW R5, R0
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), R13
|
|
|
|
|
|
|
|
// Now on a scheduling stack (a pthread-created stack).
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
g0:
|
2012-05-04 04:20:09 -06:00
|
|
|
SUB $24, R13
|
|
|
|
BIC $0x7, R13 // alignment for gcc ABI
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW R4, 20(R13) // save old g
|
2014-09-11 21:36:23 -06:00
|
|
|
MOVW (g_stack+stack_hi)(R4), R4
|
|
|
|
SUB R2, R4
|
|
|
|
MOVW R4, 16(R13) // save depth in stack (can't just save SP, as stack might be copied during a callback)
|
2012-05-04 04:20:09 -06:00
|
|
|
BL (R1)
|
|
|
|
|
|
|
|
// Restore registers, g, stack pointer.
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW R0, R5
|
|
|
|
MOVW 20(R13), R0
|
|
|
|
BL setg<>(SB)
|
2014-09-11 21:36:23 -06:00
|
|
|
MOVW (g_stack+stack_hi)(g), R1
|
|
|
|
MOVW 16(R13), R2
|
|
|
|
SUB R2, R1
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW R5, R0
|
2014-09-11 21:36:23 -06:00
|
|
|
MOVW R1, R13
|
2012-05-04 04:20:09 -06:00
|
|
|
RET
|
|
|
|
|
|
|
|
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
|
2013-02-22 14:08:56 -07:00
|
|
|
// Turn the fn into a Go func (by taking its address) and call
|
|
|
|
// cgocallback_gofunc.
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
|
2013-02-22 14:08:56 -07:00
|
|
|
MOVW $fn+0(FP), R0
|
|
|
|
MOVW R0, 4(R13)
|
|
|
|
MOVW frame+4(FP), R0
|
|
|
|
MOVW R0, 8(R13)
|
|
|
|
MOVW framesize+8(FP), R0
|
|
|
|
MOVW R0, 12(R13)
|
2013-02-22 14:38:44 -07:00
|
|
|
MOVW $runtime·cgocallback_gofunc(SB), R0
|
2013-02-22 14:08:56 -07:00
|
|
|
BL (R0)
|
|
|
|
RET
|
|
|
|
|
|
|
|
// cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
|
2012-05-04 04:20:09 -06:00
|
|
|
// See cgocall.c for more details.
|
2014-09-16 15:39:55 -06:00
|
|
|
TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-12
|
2014-09-12 05:46:11 -06:00
|
|
|
NO_LOCAL_POINTERS
|
|
|
|
|
2013-02-20 15:48:23 -07:00
|
|
|
// Load m and g from thread-local storage.
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
MOVB runtime·iscgo(SB), R0
|
2013-02-20 15:48:23 -07:00
|
|
|
CMP $0, R0
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
BL.NE runtime·load_g(SB)
|
2013-02-20 15:48:23 -07:00
|
|
|
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
// If g is nil, Go did not create the current thread.
|
2013-02-20 15:48:23 -07:00
|
|
|
// Call needm to obtain one for temporary use.
|
|
|
|
// In this case, we're running on the thread stack, so there's
|
|
|
|
// lots of space, but the linker doesn't know. Hide the call from
|
|
|
|
// the linker analysis by using an indirect call.
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
CMP $0, g
|
2013-08-12 11:36:33 -06:00
|
|
|
B.NE havem
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g, savedm-4(SP) // g is zero, so is m.
|
2013-02-20 15:48:23 -07:00
|
|
|
MOVW $runtime·needm(SB), R0
|
|
|
|
BL (R0)
|
|
|
|
|
2014-10-28 19:53:09 -06:00
|
|
|
// Set m->sched.sp = SP, so that if a panic happens
|
|
|
|
// during the function we are about to execute, it will
|
|
|
|
// have a valid SP to run on the g0 stack.
|
|
|
|
// The next few lines (after the havem label)
|
|
|
|
// will save this SP onto the stack and then write
|
|
|
|
// the same SP back to m->sched.sp. That seems redundant,
|
|
|
|
// but if an unrecovered panic happens, unwindm will
|
|
|
|
// restore the g->sched.sp from the stack location
|
[dev.cc] runtime: delete scalararg, ptrarg; rename onM to systemstack
Scalararg and ptrarg are not "signal safe".
Go code filling them out can be interrupted by a signal,
and then the signal handler runs, and if it also ends up
in Go code that uses scalararg or ptrarg, now the old
values have been smashed.
For the pieces of code that do need to run in a signal handler,
we introduced onM_signalok, which is really just onM
except that the _signalok is meant to convey that the caller
asserts that scalarg and ptrarg will be restored to their old
values after the call (instead of the usual behavior, zeroing them).
Scalararg and ptrarg are also untyped and therefore error-prone.
Go code can always pass a closure instead of using scalararg
and ptrarg; they were only really necessary for C code.
And there's no more C code.
For all these reasons, delete scalararg and ptrarg, converting
the few remaining references to use closures.
Once those are gone, there is no need for a distinction between
onM and onM_signalok, so replace both with a single function
equivalent to the current onM_signalok (that is, it can be called
on any of the curg, g0, and gsignal stacks).
The name onM and the phrase 'm stack' are misnomers,
because on most system an M has two system stacks:
the main thread stack and the signal handling stack.
Correct the misnomer by naming the replacement function systemstack.
Fix a few references to "M stack" in code.
The main motivation for this change is to eliminate scalararg/ptrarg.
Rick and I have already seen them cause problems because
the calling sequence m.ptrarg[0] = p is a heap pointer assignment,
so it gets a write barrier. The write barrier also uses onM, so it has
all the same problems as if it were being invoked by a signal handler.
We worked around this by saving and restoring the old values
and by calling onM_signalok, but there's no point in keeping this nice
home for bugs around any longer.
This CL also changes funcline to return the file name as a result
instead of filling in a passed-in *string. (The *string signature is
left over from when the code was written in and called from C.)
That's arguably an unrelated change, except that once I had done
the ptrarg/scalararg/onM cleanup I started getting false positives
about the *string argument escaping (not allowed in package runtime).
The compiler is wrong, but the easiest fix is to write the code like
Go code instead of like C code. I am a bit worried that the compiler
is wrong because of some use of uninitialized memory in the escape
analysis. If that's the reason, it will go away when we convert the
compiler to Go. (And if not, we'll debug it the next time.)
LGTM=khr
R=r, khr
CC=austin, golang-codereviews, iant, rlh
https://golang.org/cl/174950043
2014-11-12 12:54:31 -07:00
|
|
|
// and then systemstack will try to use it. If we don't set it here,
|
2014-10-28 19:53:09 -06:00
|
|
|
// that restored SP will be uninitialized (typically 0) and
|
|
|
|
// will not be usable.
|
|
|
|
MOVW g_m(g), R8
|
|
|
|
MOVW m_g0(R8), R3
|
|
|
|
MOVW R13, (g_sched+gobuf_sp)(R3)
|
|
|
|
|
2013-02-20 15:48:23 -07:00
|
|
|
havem:
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g_m(g), R8
|
|
|
|
MOVW R8, savedm-4(SP)
|
2013-02-20 15:48:23 -07:00
|
|
|
// Now there's a valid m, and we're running on its m->g0.
|
|
|
|
// Save current m->g0->sched.sp on stack and then set it to SP.
|
|
|
|
// Save current sp in m->g0->sched.sp in preparation for
|
|
|
|
// switch back to m->curg stack.
|
2013-07-23 16:40:02 -06:00
|
|
|
// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP).
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW m_g0(R8), R3
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(R3), R4
|
2013-07-23 16:40:02 -06:00
|
|
|
MOVW R4, savedsp-8(SP)
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW R13, (g_sched+gobuf_sp)(R3)
|
|
|
|
|
2013-07-23 16:40:02 -06:00
|
|
|
// Switch to m->curg stack and call runtime.cgocallbackg.
|
|
|
|
// Because we are taking over the execution of m->curg
|
|
|
|
// but *not* resuming what had been running, we need to
|
|
|
|
// save that information (m->curg->sched) so we can restore it.
|
2013-06-05 05:16:53 -06:00
|
|
|
// We can restore m->curg->sched.sp easily, because calling
|
2012-05-04 04:20:09 -06:00
|
|
|
// runtime.cgocallbackg leaves SP unchanged upon return.
|
2013-06-05 05:16:53 -06:00
|
|
|
// To save m->curg->sched.pc, we push it onto the stack.
|
2012-05-04 04:20:09 -06:00
|
|
|
// This has the added benefit that it looks to the traceback
|
|
|
|
// routine like cgocallbackg is going to return to that
|
2013-07-23 16:40:02 -06:00
|
|
|
// PC (because the frame we allocate below has the same
|
|
|
|
// size as cgocallback_gofunc's frame declared above)
|
2012-05-04 04:20:09 -06:00
|
|
|
// so that the traceback will seamlessly trace back into
|
|
|
|
// the earlier calls.
|
2013-07-23 16:40:02 -06:00
|
|
|
//
|
|
|
|
// In the new goroutine, -8(SP) and -4(SP) are unused.
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW m_curg(R8), R0
|
|
|
|
BL setg<>(SB)
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
|
|
|
|
MOVW (g_sched+gobuf_pc)(g), R5
|
2013-07-23 16:40:02 -06:00
|
|
|
MOVW R5, -12(R4)
|
|
|
|
MOVW $-12(R4), R13
|
2012-05-04 04:20:09 -06:00
|
|
|
BL runtime·cgocallbackg(SB)
|
|
|
|
|
2013-06-05 05:16:53 -06:00
|
|
|
// Restore g->sched (== m->curg->sched) from saved values.
|
2013-03-25 15:10:28 -06:00
|
|
|
MOVW 0(R13), R5
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW R5, (g_sched+gobuf_pc)(g)
|
2013-07-23 16:40:02 -06:00
|
|
|
MOVW $12(R13), R4
|
2013-03-25 15:10:28 -06:00
|
|
|
MOVW R4, (g_sched+gobuf_sp)(g)
|
2012-05-04 04:20:09 -06:00
|
|
|
|
|
|
|
// Switch back to m->g0's stack and restore m->g0->sched.sp.
|
|
|
|
// (Unlike m->curg, the g0 goroutine never uses sched.pc,
|
|
|
|
// so we do not have to restore it.)
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVW g_m(g), R8
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW m_g0(R8), R0
|
|
|
|
BL setg<>(SB)
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW (g_sched+gobuf_sp)(g), R13
|
2013-07-23 16:40:02 -06:00
|
|
|
MOVW savedsp-8(SP), R4
|
|
|
|
MOVW R4, (g_sched+gobuf_sp)(g)
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
|
2013-02-20 15:48:23 -07:00
|
|
|
// If the m on entry was nil, we called needm above to borrow an m
|
|
|
|
// for the duration of the call. Since the call is over, return it with dropm.
|
2013-07-23 16:40:02 -06:00
|
|
|
MOVW savedm-4(SP), R6
|
2013-02-20 15:48:23 -07:00
|
|
|
CMP $0, R6
|
|
|
|
B.NE 3(PC)
|
|
|
|
MOVW $runtime·dropm(SB), R0
|
|
|
|
BL (R0)
|
|
|
|
|
2012-05-04 04:20:09 -06:00
|
|
|
// Done!
|
|
|
|
RET
|
runtime: scheduler, cgo reorganization
* Change use of m->g0 stack (aka scheduler stack).
* Provide runtime.mcall(f) to invoke f() on m->g0 stack.
* Replace scheduler loop entry with runtime.mcall(schedule).
Runtime.mcall eliminates the need for fake scheduler states that
exist just to run a bit of code on the m->g0 stack
(Grecovery, Gstackalloc).
The elimination of the scheduler as a loop that stops and
starts using gosave and gogo fixes a bad interaction with the
way cgo uses the m->g0 stack. Cgo runs external (gcc-compiled)
C functions on that stack, and then when calling back into Go,
it sets m->g0->sched.sp below the added call frames, so that
other uses of m->g0's stack will not interfere with those frames.
Unfortunately, gogo (longjmp) back to the scheduler loop at
this point would end up running scheduler with the lower
sp, which no longer points at a valid stack frame for
a call to scheduler. If scheduler then wrote any function call
arguments or local variables to where it expected the stack
frame to be, it would overwrite other data on the stack.
I realized this possibility while debugging a problem with
calling complex Go code in a Go -> C -> Go cgo callback.
This wasn't the bug I was looking for, it turns out, but I believe
it is a real bug nonetheless. Switching to runtime.mcall, which
only adds new frames to the stack and never jumps into
functions running in existing ones, fixes this bug.
* Move cgo-related code out of proc.c into cgocall.c.
* Add very large comment describing cgo call sequences.
* Simpilify, regularize cgo function implementations and names.
* Add test suite as misc/cgo/test.
Now the Go -> C path calls cgocall, which calls asmcgocall,
and the C -> Go path calls cgocallback, which calls cgocallbackg.
The shuffling, which affects mainly the callback case, moves
most of the callback implementation to cgocallback running
on the m->curg stack (not the m->g0 scheduler stack) and
only while accounted for with $GOMAXPROCS (between calls
to exitsyscall and entersyscall).
The previous callback code did not block in startcgocallback's
approximation to exitsyscall, so if, say, the garbage collector
were running, it would still barge in and start doing things
like call malloc. Similarly endcgocallback's approximation of
entersyscall did not call matchmg to kick off new OS threads
when necessary, which caused the bug in issue 1560.
Fixes #1560.
R=iant
CC=golang-dev
https://golang.org/cl/4253054
2011-03-07 08:37:42 -07:00
|
|
|
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
// void setg(G*); set g. for use by needm.
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
TEXT runtime·setg(SB),NOSPLIT,$-4-4
|
|
|
|
MOVW gg+0(FP), R0
|
|
|
|
B setg<>(SB)
|
|
|
|
|
|
|
|
TEXT setg<>(SB),NOSPLIT,$-4-0
|
|
|
|
MOVW R0, g
|
2013-02-20 15:48:23 -07:00
|
|
|
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
// Save g to thread-local storage.
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
MOVB runtime·iscgo(SB), R0
|
2013-02-20 15:48:23 -07:00
|
|
|
CMP $0, R0
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
B.EQ 2(PC)
|
|
|
|
B runtime·save_g(SB)
|
2013-02-20 15:48:23 -07:00
|
|
|
|
runtime: save g to TLS more aggressively
This is one of those "how did this ever work?" bugs.
The current build failures are happening because
a fault comes up while executing on m->curg on a
system-created thread using an m obtained from needm,
but TLS is set to m->g0, not m->curg. On fault,
sigtramp starts executing, assumes r10 (g) might be
incorrect, reloads it from TLS, and gets m->g0, not
m->curg. Then sighandler dutifully pushes a call to
sigpanic onto the stack and returns to it.
We're now executing on the m->curg stack but with
g=m->g0. Sigpanic does a stack split check, sees that
the SP is not in range (50% chance depending on relative
ordering of m->g0's and m->curg's stacks), and then
calls morestack. Morestack sees that g=m->g0 and
crashes the program.
The fix is to replace every change of g in asm_arm.s
with a call to a function that both updates g and
saves the updated g to TLS.
Why did it start happening? That's unclear.
Unfortunately there were other bugs in the initial
checkin that mask exactly which of a sequence of
CLs started the behavior where sigpanic would end
up tripping the stack split.
Fixes arm build.
Fixes #8675.
LGTM=iant
R=golang-codereviews, iant
CC=dave, golang-codereviews, khr, minux, r
https://golang.org/cl/135570043
2014-09-07 17:47:40 -06:00
|
|
|
MOVW g, R0
|
2013-02-20 15:48:23 -07:00
|
|
|
RET
|
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
|
2009-10-19 22:58:16 -06:00
|
|
|
MOVW 0(SP), R0
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVW R0, ret+4(FP)
|
2009-10-19 22:58:16 -06:00
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2014-06-17 00:03:03 -06:00
|
|
|
TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-4-8
|
2014-06-17 22:59:50 -06:00
|
|
|
MOVW R14, ret+4(FP)
|
2014-06-17 00:03:03 -06:00
|
|
|
RET
|
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVW pc+4(FP), R0
|
2009-10-19 22:58:16 -06:00
|
|
|
MOVW R0, 0(SP)
|
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
|
2010-04-05 13:51:09 -06:00
|
|
|
MOVW 0(FP), R0
|
|
|
|
MOVW $-4(R0), R0
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVW R0, ret+4(FP)
|
2010-04-05 13:51:09 -06:00
|
|
|
RET
|
|
|
|
|
2014-08-26 00:34:46 -06:00
|
|
|
// func gogetcallersp(p unsafe.Pointer) uintptr
|
|
|
|
TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8
|
|
|
|
MOVW 0(FP), R0
|
|
|
|
MOVW $-4(R0), R0
|
|
|
|
MOVW R0, ret+4(FP)
|
|
|
|
RET
|
|
|
|
|
2013-07-16 14:24:09 -06:00
|
|
|
TEXT runtime·emptyfunc(SB),0,$0-0
|
2009-06-16 12:25:58 -06:00
|
|
|
RET
|
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·abort(SB),NOSPLIT,$-4-0
|
2009-06-16 12:25:58 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVW (R0), R1
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2011-02-25 12:29:55 -07:00
|
|
|
// bool armcas(int32 *val, int32 old, int32 new)
|
|
|
|
// Atomically:
|
|
|
|
// if(*val == old){
|
|
|
|
// *val = new;
|
|
|
|
// return 1;
|
|
|
|
// }else
|
|
|
|
// return 0;
|
|
|
|
//
|
2012-01-22 11:34:17 -07:00
|
|
|
// To implement runtime·cas in sys_$GOOS_arm.s
|
2011-02-25 12:29:55 -07:00
|
|
|
// using the native instructions, use:
|
|
|
|
//
|
2013-08-07 11:23:24 -06:00
|
|
|
// TEXT runtime·cas(SB),NOSPLIT,$0
|
2011-02-25 12:29:55 -07:00
|
|
|
// B runtime·armcas(SB)
|
|
|
|
//
|
cmd/cc, runtime: preserve C runtime type names in generated Go
uintptr or uint64 in the runtime C were turning into uint in the Go,
bool was turning into uint8, and so on. Fix that.
Also delete Go wrappers for C functions.
The C functions can be called directly now
(but still eventually need to be converted to Go).
LGTM=bradfitz, minux, iant
R=golang-codereviews, bradfitz, iant, minux
CC=golang-codereviews, khr, r
https://golang.org/cl/138740043
2014-08-27 19:59:49 -06:00
|
|
|
TEXT runtime·armcas(SB),NOSPLIT,$0-13
|
2011-02-25 12:29:55 -07:00
|
|
|
MOVW valptr+0(FP), R1
|
|
|
|
MOVW old+4(FP), R2
|
|
|
|
MOVW new+8(FP), R3
|
|
|
|
casl:
|
|
|
|
LDREX (R1), R0
|
2013-08-12 11:36:33 -06:00
|
|
|
CMP R0, R2
|
|
|
|
BNE casfail
|
2011-02-25 12:29:55 -07:00
|
|
|
STREX R3, (R1), R0
|
2013-08-12 11:36:33 -06:00
|
|
|
CMP $0, R0
|
|
|
|
BNE casl
|
2011-02-25 12:29:55 -07:00
|
|
|
MOVW $1, R0
|
cmd/cc, runtime: preserve C runtime type names in generated Go
uintptr or uint64 in the runtime C were turning into uint in the Go,
bool was turning into uint8, and so on. Fix that.
Also delete Go wrappers for C functions.
The C functions can be called directly now
(but still eventually need to be converted to Go).
LGTM=bradfitz, minux, iant
R=golang-codereviews, bradfitz, iant, minux
CC=golang-codereviews, khr, r
https://golang.org/cl/138740043
2014-08-27 19:59:49 -06:00
|
|
|
MOVB R0, ret+12(FP)
|
2011-02-25 12:29:55 -07:00
|
|
|
RET
|
|
|
|
casfail:
|
|
|
|
MOVW $0, R0
|
cmd/cc, runtime: preserve C runtime type names in generated Go
uintptr or uint64 in the runtime C were turning into uint in the Go,
bool was turning into uint8, and so on. Fix that.
Also delete Go wrappers for C functions.
The C functions can be called directly now
(but still eventually need to be converted to Go).
LGTM=bradfitz, minux, iant
R=golang-codereviews, bradfitz, iant, minux
CC=golang-codereviews, khr, r
https://golang.org/cl/138740043
2014-08-27 19:59:49 -06:00
|
|
|
MOVB R0, ret+12(FP)
|
2011-02-25 12:29:55 -07:00
|
|
|
RET
|
2012-03-15 13:22:30 -06:00
|
|
|
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·casuintptr(SB),NOSPLIT,$0-13
|
2014-08-27 20:03:32 -06:00
|
|
|
B runtime·cas(SB)
|
cmd/cc, runtime: preserve C runtime type names in generated Go
uintptr or uint64 in the runtime C were turning into uint in the Go,
bool was turning into uint8, and so on. Fix that.
Also delete Go wrappers for C functions.
The C functions can be called directly now
(but still eventually need to be converted to Go).
LGTM=bradfitz, minux, iant
R=golang-codereviews, bradfitz, iant, minux
CC=golang-codereviews, khr, r
https://golang.org/cl/138740043
2014-08-27 19:59:49 -06:00
|
|
|
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·atomicloaduintptr(SB),NOSPLIT,$0-8
|
2014-08-29 14:20:48 -06:00
|
|
|
B runtime·atomicload(SB)
|
|
|
|
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·atomicloaduint(SB),NOSPLIT,$0-8
|
2014-08-30 12:03:28 -06:00
|
|
|
B runtime·atomicload(SB)
|
|
|
|
|
2014-10-07 21:27:25 -06:00
|
|
|
TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
|
|
|
|
B runtime·atomicstore(SB)
|
|
|
|
|
2013-04-02 17:26:15 -06:00
|
|
|
// AES hashing not implemented for ARM
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·aeshash(SB),NOSPLIT,$-4-0
|
2013-03-12 11:47:44 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVW (R0), R1
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0
|
2013-03-12 11:47:44 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVW (R0), R1
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0
|
2013-03-12 11:47:44 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVW (R0), R1
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0
|
2013-03-12 11:47:44 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVW (R0), R1
|
2013-04-02 17:26:15 -06:00
|
|
|
|
2014-08-07 15:52:55 -06:00
|
|
|
TEXT runtime·memeq(SB),NOSPLIT,$-4-13
|
2014-07-16 15:16:19 -06:00
|
|
|
MOVW a+0(FP), R1
|
|
|
|
MOVW b+4(FP), R2
|
|
|
|
MOVW size+8(FP), R3
|
|
|
|
ADD R1, R3, R6
|
|
|
|
MOVW $1, R0
|
|
|
|
MOVB R0, ret+12(FP)
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
loop:
|
2014-07-16 15:16:19 -06:00
|
|
|
CMP R1, R6
|
|
|
|
RET.EQ
|
|
|
|
MOVBU.P 1(R1), R4
|
|
|
|
MOVBU.P 1(R2), R5
|
|
|
|
CMP R4, R5
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
BEQ loop
|
2014-07-16 15:16:19 -06:00
|
|
|
|
|
|
|
MOVW $0, R0
|
|
|
|
MOVB R0, ret+12(FP)
|
|
|
|
RET
|
|
|
|
|
2014-06-16 22:00:37 -06:00
|
|
|
// eqstring tests whether two strings are equal.
|
|
|
|
// See runtime_test.go:eqstring_generic for
|
2014-08-19 09:50:35 -06:00
|
|
|
// equivalent Go code.
|
2014-06-16 22:00:37 -06:00
|
|
|
TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
|
|
|
|
MOVW s1len+4(FP), R0
|
|
|
|
MOVW s2len+12(FP), R1
|
|
|
|
MOVW $0, R7
|
|
|
|
CMP R0, R1
|
|
|
|
MOVB.NE R7, v+16(FP)
|
|
|
|
RET.NE
|
|
|
|
MOVW s1str+0(FP), R2
|
|
|
|
MOVW s2str+8(FP), R3
|
|
|
|
MOVW $1, R8
|
|
|
|
MOVB R8, v+16(FP)
|
|
|
|
CMP R2, R3
|
|
|
|
RET.EQ
|
|
|
|
ADD R2, R0, R6
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
loop:
|
2014-06-16 22:00:37 -06:00
|
|
|
CMP R2, R6
|
|
|
|
RET.EQ
|
|
|
|
MOVBU.P 1(R2), R4
|
|
|
|
MOVBU.P 1(R3), R5
|
|
|
|
CMP R4, R5
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
BEQ loop
|
2014-06-16 22:00:37 -06:00
|
|
|
MOVB R7, v+16(FP)
|
|
|
|
RET
|
|
|
|
|
2014-06-30 17:10:41 -06:00
|
|
|
// void setg_gcc(G*); set g called from gcc.
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
TEXT setg_gcc<>(SB),NOSPLIT,$0
|
|
|
|
MOVW R0, g
|
|
|
|
B runtime·save_g(SB)
|
runtime.cmd/ld: Add ARM external linking and implement -shared in terms of external linking
This CL is an aggregate of 10271047, 10499043, 9733044. Descriptions of each follow:
10499043
runtime,cmd/ld: Merge TLS symbols and teach 5l about ARM TLS
This CL prepares for external linking support to ARM.
The pseudo-symbols runtime.g and runtime.m are merged into a single
runtime.tlsgm symbol. When external linking, the offset of a thread local
variable is stored at a memory location instead of being embedded into a offset
of a ldr instruction. With a single runtime.tlsgm symbol for both g and m, only
one such offset is needed.
The larger part of this CL moves TLS code from gcc compiled to internally
compiled. The TLS code now uses the modern MRC instruction, and 5l is taught
about TLS fallbacks in case the instruction is not available or appropriate.
10271047
This CL adds support for -linkmode external to 5l.
For 5l itself, use addrel to allow for D_CALL relocations to be handled by the
host linker. Of the cases listed in rsc's comment in issue 4069, only case 5 and
63 needed an update. One of the TODO: addrel cases was since replaced, and the
rest of the cases are either covered by indirection through addpool (cases with
LTO or LFROM flags) or stubs (case 74). The addpool cases are covered because
addpool emits AWORD instructions, which in turn are handled by case 11.
In the runtime, change the argv argument in the rt0* functions slightly to be a
pointer to the argv list, instead of relying on a particular location of argv.
9733044
The -shared flag to 6l outputs a shared library, implemented in Go
and callable from non-Go programs such as C.
The main part of this CL change the thread local storage model.
Go uses the fastest and least general mode, local exec. TLS data in shared
libraries normally requires at least the local dynamic mode, however, this CL
instead opts for using the initial exec mode. Initial exec mode is faster than
local dynamic mode and can be used in linux since the linker has reserved a
limited amount of TLS space for performance sensitive TLS code.
Initial exec mode requires an extra load from the GOT table to determine the
TLS offset. This penalty will not be paid if ld is not in -shared mode, since
TLS accesses will be reduced to local exec.
The elf sections .init_array and .rela.init_array are added to register the Go
runtime entry with cgo at library load time.
The "hidden" attribute is added to Cgo functions called from Go, since Go
does not generate call through the GOT table, and adding non-GOT relocations for
a global function is not supported by gcc. Cgo symbols don't need to be global
and avoiding the GOT table is also faster.
The changes to 8l are only removes code relevant to the old -shared mode where
internal linking was used.
This CL only address the low level linker work. It can be submitted by itself,
but to be useful, the runtime changes in CL 9738047 is also needed.
Design discussion at
https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/zmjXkGrEx6Q
Fixes #5590.
R=rsc
CC=golang-dev
https://golang.org/cl/12871044
2013-08-14 09:38:54 -06:00
|
|
|
|
2013-08-01 17:11:19 -06:00
|
|
|
// TODO: share code with memeq?
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT bytes·Equal(SB),NOSPLIT,$0
|
2013-08-01 17:11:19 -06:00
|
|
|
MOVW a_len+4(FP), R1
|
|
|
|
MOVW b_len+16(FP), R3
|
|
|
|
|
|
|
|
CMP R1, R3 // unequal lengths are not equal
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
B.NE notequal
|
2013-08-01 17:11:19 -06:00
|
|
|
|
|
|
|
MOVW a+0(FP), R0
|
|
|
|
MOVW b+12(FP), R2
|
|
|
|
ADD R0, R1 // end
|
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
loop:
|
2013-08-01 17:11:19 -06:00
|
|
|
CMP R0, R1
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
B.EQ equal // reached the end
|
2013-08-01 17:11:19 -06:00
|
|
|
MOVBU.P 1(R0), R4
|
|
|
|
MOVBU.P 1(R2), R5
|
|
|
|
CMP R4, R5
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
B.EQ loop
|
2013-08-01 17:11:19 -06:00
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
notequal:
|
2013-08-01 17:11:19 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
MOVBU R0, ret+24(FP)
|
|
|
|
RET
|
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
equal:
|
2013-08-01 17:11:19 -06:00
|
|
|
MOVW $1, R0
|
|
|
|
MOVBU R0, ret+24(FP)
|
|
|
|
RET
|
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT bytes·IndexByte(SB),NOSPLIT,$0
|
2013-08-01 17:11:19 -06:00
|
|
|
MOVW s+0(FP), R0
|
|
|
|
MOVW s_len+4(FP), R1
|
|
|
|
MOVBU c+12(FP), R2 // byte to find
|
|
|
|
MOVW R0, R4 // store base for later
|
|
|
|
ADD R0, R1 // end
|
|
|
|
|
|
|
|
_loop:
|
|
|
|
CMP R0, R1
|
|
|
|
B.EQ _notfound
|
|
|
|
MOVBU.P 1(R0), R3
|
|
|
|
CMP R2, R3
|
|
|
|
B.NE _loop
|
|
|
|
|
|
|
|
SUB $1, R0 // R0 will be one beyond the position we want
|
|
|
|
SUB R4, R0 // remove base
|
|
|
|
MOVW R0, ret+16(FP)
|
|
|
|
RET
|
|
|
|
|
|
|
|
_notfound:
|
|
|
|
MOVW $-1, R0
|
|
|
|
MOVW R0, ret+16(FP)
|
|
|
|
RET
|
2013-08-05 16:04:05 -06:00
|
|
|
|
2013-08-07 11:23:24 -06:00
|
|
|
TEXT strings·IndexByte(SB),NOSPLIT,$0
|
2013-08-05 16:04:05 -06:00
|
|
|
MOVW s+0(FP), R0
|
|
|
|
MOVW s_len+4(FP), R1
|
|
|
|
MOVBU c+8(FP), R2 // byte to find
|
|
|
|
MOVW R0, R4 // store base for later
|
|
|
|
ADD R0, R1 // end
|
|
|
|
|
|
|
|
_sib_loop:
|
|
|
|
CMP R0, R1
|
|
|
|
B.EQ _sib_notfound
|
|
|
|
MOVBU.P 1(R0), R3
|
|
|
|
CMP R2, R3
|
|
|
|
B.NE _sib_loop
|
|
|
|
|
|
|
|
SUB $1, R0 // R0 will be one beyond the position we want
|
|
|
|
SUB R4, R0 // remove base
|
|
|
|
MOVW R0, ret+12(FP)
|
|
|
|
RET
|
|
|
|
|
|
|
|
_sib_notfound:
|
|
|
|
MOVW $-1, R0
|
|
|
|
MOVW R0, ret+12(FP)
|
|
|
|
RET
|
2014-05-02 10:32:42 -06:00
|
|
|
|
2014-05-07 14:17:10 -06:00
|
|
|
// A Duff's device for zeroing memory.
|
|
|
|
// The compiler jumps to computed addresses within
|
|
|
|
// this routine to zero chunks of memory. Do not
|
|
|
|
// change this code without also changing the code
|
|
|
|
// in ../../cmd/5g/ggen.c:clearfat.
|
|
|
|
// R0: zero
|
|
|
|
// R1: ptr to memory to be zeroed
|
|
|
|
// R1 is updated as a side effect.
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·duffzero(SB),NOSPLIT,$0-0
|
2014-05-07 14:17:10 -06:00
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
MOVW.P R0, 4(R1)
|
|
|
|
RET
|
|
|
|
|
|
|
|
// A Duff's device for copying memory.
|
|
|
|
// The compiler jumps to computed addresses within
|
|
|
|
// this routine to copy chunks of memory. Source
|
|
|
|
// and destination must not overlap. Do not
|
|
|
|
// change this code without also changing the code
|
|
|
|
// in ../../cmd/5g/cgen.c:sgen.
|
|
|
|
// R0: scratch space
|
|
|
|
// R1: ptr to source memory
|
|
|
|
// R2: ptr to destination memory
|
|
|
|
// R1 and R2 are updated as a side effect
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·duffcopy(SB),NOSPLIT,$0-0
|
2014-05-07 14:17:10 -06:00
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
MOVW.P 4(R1), R0
|
|
|
|
MOVW.P R0, 4(R2)
|
|
|
|
RET
|
2014-07-16 15:16:19 -06:00
|
|
|
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·fastrand1(SB),NOSPLIT,$-4-4
|
2014-07-16 15:16:19 -06:00
|
|
|
MOVW g_m(g), R1
|
|
|
|
MOVW m_fastrand(R1), R0
|
|
|
|
ADD.S R0, R0
|
|
|
|
EOR.MI $0x88888eef, R0
|
|
|
|
MOVW R0, m_fastrand(R1)
|
|
|
|
MOVW R0, ret+0(FP)
|
|
|
|
RET
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
|
2014-09-04 19:12:31 -06:00
|
|
|
TEXT runtime·return0(SB),NOSPLIT,$0
|
2014-09-03 09:49:43 -06:00
|
|
|
MOVW $0, R0
|
|
|
|
RET
|
2014-09-04 19:12:31 -06:00
|
|
|
|
|
|
|
TEXT runtime·procyield(SB),NOSPLIT,$-4
|
|
|
|
MOVW cycles+0(FP), R1
|
|
|
|
MOVW $0, R0
|
|
|
|
yieldloop:
|
|
|
|
CMP R0, R1
|
|
|
|
B.NE 2(PC)
|
|
|
|
RET
|
|
|
|
SUB $1, R1
|
|
|
|
B yieldloop
|
2014-09-25 08:59:01 -06:00
|
|
|
|
|
|
|
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
|
|
|
|
// Must obey the gcc calling convention.
|
2014-09-29 00:52:08 -06:00
|
|
|
TEXT _cgo_topofstack(SB),NOSPLIT,$8
|
|
|
|
// R11 and g register are clobbered by load_g. They are
|
|
|
|
// callee-save in the gcc calling convention, so save them here.
|
|
|
|
MOVW R11, saveR11-4(SP)
|
|
|
|
MOVW g, saveG-8(SP)
|
|
|
|
|
2014-09-25 09:37:04 -06:00
|
|
|
BL runtime·load_g(SB)
|
2014-09-25 08:59:01 -06:00
|
|
|
MOVW g_m(g), R0
|
|
|
|
MOVW m_curg(R0), R0
|
|
|
|
MOVW (g_stack+stack_hi)(R0), R0
|
2014-09-29 00:52:08 -06:00
|
|
|
|
|
|
|
MOVW saveG-8(SP), g
|
|
|
|
MOVW saveR11-4(SP), R11
|
2014-09-25 08:59:01 -06:00
|
|
|
RET
|
2014-10-29 18:37:44 -06:00
|
|
|
|
|
|
|
// The top-most function running on a goroutine
|
|
|
|
// returns to goexit+PCQuantum.
|
|
|
|
TEXT runtime·goexit(SB),NOSPLIT,$-4-0
|
|
|
|
MOVW R0, R0 // NOP
|
|
|
|
BL runtime·goexit1(SB) // does not return
|
[dev.cc] runtime: convert assembly files for C to Go transition
The main change is that #include "zasm_GOOS_GOARCH.h"
is now #include "go_asm.h" and/or #include "go_tls.h".
Also, because C StackGuard is now Go _StackGuard,
the assembly name changes from const_StackGuard to
const__StackGuard.
In asm_$GOARCH.s, add new function getg, formerly
implemented in C.
The renamed atomics now have Go wrappers, to get
escape analysis annotations right. Those wrappers
are in CL 174860043.
LGTM=r, aram
R=r, aram
CC=austin, dvyukov, golang-codereviews, iant, khr
https://golang.org/cl/168510043
2014-11-11 15:06:22 -07:00
|
|
|
|
|
|
|
TEXT runtime·getg(SB),NOSPLIT,$-4-4
|
|
|
|
MOVW g, ret+0(FP)
|
|
|
|
RET
|
2014-11-21 13:57:10 -07:00
|
|
|
|
|
|
|
TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
|
|
|
|
RET
|