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.
|
|
|
|
|
2011-12-19 13:51:13 -07:00
|
|
|
#include "zasm_GOOS_GOARCH.h"
|
2009-06-23 12:54:23 -06:00
|
|
|
|
|
|
|
// using frame size $-4 means do not save LR on stack.
|
|
|
|
TEXT _rt0_arm(SB),7,$-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
|
|
|
|
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
|
|
|
|
|
|
|
// set up m and g registers
|
|
|
|
// g is R10, m is R9
|
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
|
|
|
|
MOVW $runtime·m0(SB), m
|
2009-06-16 12:25:58 -06:00
|
|
|
|
|
|
|
// save m->g0 = g0
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW g, m_g0(m)
|
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
|
|
|
|
MOVW R0, g_stackguard(g) // (w 104b guard)
|
|
|
|
MOVW R13, g_stackbase(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
|
|
|
|
2013-02-28 14:24:38 -07:00
|
|
|
// if there is an _cgo_init, call it.
|
|
|
|
MOVW _cgo_init(SB), R2
|
2012-05-04 04:20:09 -06:00
|
|
|
CMP $0, R2
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW.NE g, R0 // first argument of _cgo_init is g
|
2012-05-04 04:20:09 -06:00
|
|
|
BL.NE (R2) // will clobber R0-R3
|
|
|
|
|
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)
|
|
|
|
GLOBL runtime·main·f(SB),8,$4
|
|
|
|
|
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
|
|
|
TEXT runtime·breakpoint(SB),7,$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.
|
|
|
|
WORD $0xe1200071 // BKPT 0x0001
|
2010-04-05 13:51:09 -06:00
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
2013-02-12 10:00:04 -07:00
|
|
|
GLOBL runtime·goarm(SB), $4
|
2012-02-13 23:23:15 -07:00
|
|
|
TEXT runtime·asminit(SB),7,$0
|
2013-02-12 10:00:04 -07:00
|
|
|
// disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
|
|
|
|
MOVW runtime·goarm(SB), R11
|
|
|
|
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
|
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
|
|
|
TEXT runtime·gosave(SB), 7, $-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)
|
|
|
|
RET
|
|
|
|
|
|
|
|
// void gogo(Gobuf*, uintptr)
|
|
|
|
// restore state from Gobuf; longjmp
|
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
|
|
|
TEXT runtime·gogo(SB), 7, $-4
|
2010-10-08 17:46:05 -06:00
|
|
|
MOVW 0(FP), R1 // gobuf
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW gobuf_g(R1), g
|
|
|
|
MOVW 0(g), R2 // make sure g != nil
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW _cgo_save_gm(SB), R2
|
2012-05-04 04:20:09 -06:00
|
|
|
CMP $0, R2 // if in Cgo, we have to save g and m
|
|
|
|
BL.NE (R2) // this call will clobber R0
|
|
|
|
MOVW 4(FP), R0 // return 2nd arg
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW gobuf_sp(R1), SP // restore SP
|
|
|
|
MOVW gobuf_pc(R1), PC
|
|
|
|
|
2013-02-22 12:25:50 -07:00
|
|
|
// void gogocall(Gobuf*, void (*fn)(void), uintptr r7)
|
2009-06-23 12:54:23 -06:00
|
|
|
// restore state from Gobuf but then call fn.
|
|
|
|
// (call fn, returning to state in Gobuf)
|
|
|
|
// using frame size $-4 means do not save LR on stack.
|
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
|
|
|
TEXT runtime·gogocall(SB), 7, $-4
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW 0(FP), R3 // gobuf
|
2009-09-18 17:45:41 -06:00
|
|
|
MOVW 4(FP), R1 // fn
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW gobuf_g(R3), g
|
|
|
|
MOVW 0(g), R0 // make sure g != nil
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW _cgo_save_gm(SB), R0
|
2012-05-04 04:20:09 -06:00
|
|
|
CMP $0, R0 // if in Cgo, we have to save g and m
|
|
|
|
BL.NE (R0) // this call will clobber R0
|
2013-02-22 12:25:50 -07:00
|
|
|
MOVW 8(FP), R7 // context
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW gobuf_sp(R3), SP // restore SP
|
|
|
|
MOVW gobuf_pc(R3), LR
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW R1, PC
|
|
|
|
|
2013-02-21 15:01:13 -07:00
|
|
|
// void gogocallfn(Gobuf*, FuncVal*)
|
|
|
|
// restore state from Gobuf but then call fn.
|
|
|
|
// (call fn, returning to state in Gobuf)
|
|
|
|
// using frame size $-4 means do not save LR on stack.
|
|
|
|
TEXT runtime·gogocallfn(SB), 7, $-4
|
|
|
|
MOVW 0(FP), R3 // gobuf
|
|
|
|
MOVW 4(FP), R1 // fn
|
|
|
|
MOVW gobuf_g(R3), g
|
|
|
|
MOVW 0(g), R0 // make sure g != nil
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW _cgo_save_gm(SB), R0
|
2013-02-21 15:01:13 -07:00
|
|
|
CMP $0, R0 // if in Cgo, we have to save g and m
|
|
|
|
BL.NE (R0) // this call will clobber R0
|
|
|
|
MOVW gobuf_sp(R3), SP // restore SP
|
|
|
|
MOVW gobuf_pc(R3), LR
|
2013-02-22 12:25:50 -07:00
|
|
|
MOVW R1, R7
|
2013-02-21 15:01:13 -07:00
|
|
|
MOVW 0(R1), PC
|
|
|
|
|
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 mcall(void (*fn)(G*))
|
|
|
|
// 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.
|
|
|
|
TEXT runtime·mcall(SB), 7, $-4
|
|
|
|
MOVW fn+0(FP), R0
|
|
|
|
|
|
|
|
// Save caller state in g->gobuf.
|
|
|
|
MOVW SP, (g_sched+gobuf_sp)(g)
|
|
|
|
MOVW LR, (g_sched+gobuf_pc)(g)
|
|
|
|
MOVW g, (g_sched+gobuf_g)(g)
|
|
|
|
|
|
|
|
// Switch to m->g0 & its stack, call fn.
|
|
|
|
MOVW g, R1
|
|
|
|
MOVW m_g0(m), g
|
|
|
|
CMP g, R1
|
|
|
|
BL.EQ runtime·badmcall(SB)
|
|
|
|
MOVW (g_sched+gobuf_sp)(g), SP
|
|
|
|
SUB $8, SP
|
|
|
|
MOVW R1, 4(SP)
|
|
|
|
BL (R0)
|
|
|
|
BL runtime·badmcall2(SB)
|
|
|
|
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.
|
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
|
|
|
TEXT runtime·morestack(SB),7,$-4
|
2009-06-23 12:54:23 -06:00
|
|
|
// Cannot grow scheduler stack (m->g0).
|
|
|
|
MOVW m_g0(m), R4
|
|
|
|
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
|
|
|
|
2009-06-23 12:54:23 -06:00
|
|
|
// Save in m.
|
2013-02-22 12:25:50 -07:00
|
|
|
MOVW R7, m_cret(m) // function context
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW R1, m_moreframesize(m)
|
|
|
|
MOVW R2, m_moreargsize(m)
|
2009-06-23 12:54:23 -06:00
|
|
|
|
|
|
|
// Called from f.
|
|
|
|
// Set m->morebuf to f's caller.
|
2010-10-13 14:24:14 -06:00
|
|
|
MOVW R3, (m_morebuf+gobuf_pc)(m) // f's caller's PC
|
|
|
|
MOVW SP, (m_morebuf+gobuf_sp)(m) // f's caller's SP
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW $4(SP), R3 // f's argument pointer
|
|
|
|
MOVW R3, m_moreargp(m)
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW g, (m_morebuf+gobuf_g)(m)
|
|
|
|
|
|
|
|
// Set m->morepc to f's PC.
|
|
|
|
MOVW LR, m_morepc(m)
|
|
|
|
|
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.
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW m_g0(m), 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_sched+gobuf_sp)(g), SP
|
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
|
|
|
B runtime·newstack(SB)
|
2009-06-23 12:54:23 -06:00
|
|
|
|
2009-07-08 19:16:09 -06:00
|
|
|
// Called from reflection library. Mimics morestack,
|
|
|
|
// reuses stack growth code to create a frame
|
|
|
|
// with the desired args running the desired function.
|
|
|
|
//
|
|
|
|
// func call(fn *byte, arg *byte, argsize uint32).
|
|
|
|
TEXT reflect·call(SB), 7, $-4
|
|
|
|
// Save our caller's state as the PC and SP to
|
|
|
|
// restore when returning from f.
|
|
|
|
MOVW LR, (m_morebuf+gobuf_pc)(m) // our caller's PC
|
|
|
|
MOVW SP, (m_morebuf+gobuf_sp)(m) // our caller's SP
|
2009-07-12 23:12:19 -06:00
|
|
|
MOVW g, (m_morebuf+gobuf_g)(m)
|
2009-07-08 19:16:09 -06:00
|
|
|
|
|
|
|
// Set up morestack arguments to call f on a new stack.
|
2010-03-29 22:48:22 -06:00
|
|
|
// We set f's frame size to 1, as a hint to newstack
|
|
|
|
// that this is a call from reflect·call.
|
|
|
|
// If it turns out that f needs a larger frame than
|
|
|
|
// the default stack, f's usual stack growth prolog will
|
|
|
|
// allocate a new segment (and recopy the arguments).
|
2010-10-08 17:46:05 -06:00
|
|
|
MOVW 4(SP), R0 // fn
|
|
|
|
MOVW 8(SP), R1 // arg frame
|
|
|
|
MOVW 12(SP), R2 // arg size
|
2009-07-08 19:16:09 -06:00
|
|
|
|
2010-10-08 17:46:05 -06:00
|
|
|
MOVW R0, m_morepc(m) // f's PC
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW R1, m_moreargp(m) // f's argument pointer
|
|
|
|
MOVW R2, m_moreargsize(m) // f's argument size
|
2010-03-29 22:48:22 -06:00
|
|
|
MOVW $1, R3
|
2011-01-14 12:05:20 -07:00
|
|
|
MOVW R3, m_moreframesize(m) // f's frame size
|
2009-07-08 19:16:09 -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.
|
2009-07-08 19:16:09 -06:00
|
|
|
MOVW m_g0(m), 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_sched+gobuf_sp)(g), SP
|
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
|
|
|
B runtime·newstack(SB)
|
2009-07-08 19:16:09 -06:00
|
|
|
|
2009-06-23 12:54:23 -06:00
|
|
|
// Return point when leaving stack.
|
|
|
|
// using frame size $-4 means do not save LR on stack.
|
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
|
|
|
TEXT runtime·lessstack(SB), 7, $-4
|
2009-06-23 12:54:23 -06:00
|
|
|
// Save return value in m->cret
|
|
|
|
MOVW R0, m_cret(m)
|
|
|
|
|
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 oldstack on m->g0's stack.
|
2009-06-23 12:54:23 -06:00
|
|
|
MOVW m_g0(m), 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_sched+gobuf_sp)(g), SP
|
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
|
|
|
B runtime·oldstack(SB)
|
2009-06-16 12:25:58 -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
|
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
|
|
|
TEXT runtime·jmpdefer(SB), 7, $0
|
2009-10-05 22:52:10 -06:00
|
|
|
MOVW 0(SP), LR
|
|
|
|
MOVW $-4(LR), LR // BL deferreturn
|
2013-02-22 12:25:50 -07:00
|
|
|
MOVW fn+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
|
|
|
|
2012-05-04 04:20:09 -06:00
|
|
|
// Dummy function to use in saved gobuf.PC,
|
|
|
|
// to match SP pointing at a return address.
|
|
|
|
// The gobuf.PC is unused by the contortions here
|
|
|
|
// but setting it to return will make the traceback code work.
|
|
|
|
TEXT return<>(SB),7,$0
|
|
|
|
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.
|
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
|
|
|
TEXT runtime·asmcgocall(SB),7,$0
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW fn+0(FP), R1
|
|
|
|
MOVW arg+4(FP), R0
|
|
|
|
MOVW R13, R2
|
|
|
|
MOVW g, R5
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
MOVW m_g0(m), R3
|
|
|
|
CMP R3, g
|
|
|
|
BEQ 7(PC)
|
|
|
|
MOVW R13, (g_sched + gobuf_sp)(g)
|
|
|
|
MOVW $return<>(SB), R4
|
|
|
|
MOVW R4, (g_sched+gobuf_pc)(g)
|
|
|
|
MOVW g, (g_sched+gobuf_g)(g)
|
|
|
|
MOVW R3, g
|
|
|
|
MOVW (g_sched+gobuf_sp)(g), R13
|
|
|
|
|
|
|
|
// Now on a scheduling stack (a pthread-created stack).
|
|
|
|
SUB $24, R13
|
|
|
|
BIC $0x7, R13 // alignment for gcc ABI
|
|
|
|
MOVW R5, 20(R13) // save old g
|
|
|
|
MOVW R2, 16(R13) // save old SP
|
|
|
|
// R0 already contains the first argument
|
|
|
|
BL (R1)
|
|
|
|
|
|
|
|
// Restore registers, g, stack pointer.
|
|
|
|
MOVW 20(R13), g
|
|
|
|
MOVW 16(R13), R13
|
|
|
|
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.
|
|
|
|
TEXT runtime·cgocallback(SB),7,$12
|
|
|
|
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.
|
2013-02-22 14:08:56 -07:00
|
|
|
TEXT runtime·cgocallback_gofunc(SB),7,$16
|
2013-02-20 15:48:23 -07:00
|
|
|
// Load m and g from thread-local storage.
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW _cgo_load_gm(SB), R0
|
2013-02-20 15:48:23 -07:00
|
|
|
CMP $0, R0
|
|
|
|
BL.NE (R0)
|
|
|
|
|
|
|
|
// If m is nil, Go did not create the current thread.
|
|
|
|
// 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.
|
|
|
|
MOVW m, savedm-16(SP)
|
|
|
|
CMP $0, m
|
|
|
|
B.NE havem
|
|
|
|
MOVW $runtime·needm(SB), R0
|
|
|
|
BL (R0)
|
|
|
|
|
|
|
|
havem:
|
|
|
|
// 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.
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW fn+0(FP), R0
|
|
|
|
MOVW frame+4(FP), R1
|
|
|
|
MOVW framesize+8(FP), R2
|
|
|
|
|
|
|
|
MOVW m_g0(m), R3
|
|
|
|
MOVW (g_sched+gobuf_sp)(R3), R4
|
runtime, misc/cgo/test: fix build for Linux/ARM
1. In CL 5989057, I made a mistake in the last minute change.
"MOVW.W R4, -4(SP)" should really be "MOVW.W R4, -4(R13)",
as 5l will rewrite offset for SP.
2. misc/cgo/test/issue1560.go tests for parallel sleep of 1s,
but on ARM, the deadline is frequently missed, so change sleep
time to 2s on ARM.
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/6202043
2012-05-04 11:35:13 -06:00
|
|
|
MOVW.W R4, -4(R13)
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW R13, (g_sched+gobuf_sp)(R3)
|
|
|
|
|
|
|
|
// Switch to m->curg stack and call runtime.cgocallbackg
|
|
|
|
// with the three arguments. 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->gobuf)
|
|
|
|
// so that we can restore it when we're done.
|
|
|
|
// We can restore m->curg->gobuf.sp easily, because calling
|
|
|
|
// runtime.cgocallbackg leaves SP unchanged upon return.
|
|
|
|
// To save m->curg->gobuf.pc, we push it onto the stack.
|
|
|
|
// This has the added benefit that it looks to the traceback
|
|
|
|
// routine like cgocallbackg is going to return to that
|
|
|
|
// PC (because we defined cgocallbackg to have
|
|
|
|
// a frame size of 16, the same amount that we use below),
|
|
|
|
// so that the traceback will seamlessly trace back into
|
|
|
|
// the earlier calls.
|
2013-02-20 15:48:23 -07:00
|
|
|
|
|
|
|
// Save current m->g0->sched.sp on stack and then set it to SP.
|
2012-05-04 04:20:09 -06:00
|
|
|
MOVW m_curg(m), g
|
|
|
|
MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
|
|
|
|
|
|
|
|
// Push gobuf.pc
|
|
|
|
MOVW (g_sched+gobuf_pc)(g), R5
|
|
|
|
SUB $4, R4
|
|
|
|
MOVW R5, 0(R4)
|
|
|
|
|
|
|
|
// Push arguments to cgocallbackg.
|
|
|
|
// Frame size here must match the frame size above
|
|
|
|
// to trick traceback routines into doing the right thing.
|
|
|
|
SUB $16, R4
|
|
|
|
MOVW R0, 4(R4)
|
|
|
|
MOVW R1, 8(R4)
|
|
|
|
MOVW R2, 12(R4)
|
|
|
|
|
|
|
|
// Switch stack and make the call.
|
|
|
|
MOVW R4, R13
|
|
|
|
BL runtime·cgocallbackg(SB)
|
|
|
|
|
|
|
|
// Restore g->gobuf (== m->curg->gobuf) from saved values.
|
|
|
|
MOVW 16(R13), R5
|
|
|
|
MOVW R5, (g_sched+gobuf_pc)(g)
|
|
|
|
ADD $(16+4), R13 // SP clobbered! It is ok!
|
|
|
|
MOVW R13, (g_sched+gobuf_sp)(g)
|
|
|
|
|
|
|
|
// 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.)
|
|
|
|
MOVW m_g0(m), g
|
|
|
|
MOVW (g_sched+gobuf_sp)(g), R13
|
|
|
|
// POP R6
|
|
|
|
MOVW 0(R13), R6
|
|
|
|
ADD $4, R13
|
|
|
|
MOVW R6, (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.
|
|
|
|
MOVW savedm-16(SP), R6
|
|
|
|
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
|
|
|
|
2013-02-20 15:48:23 -07:00
|
|
|
// void setmg(M*, G*); set m and g. for use by needm.
|
|
|
|
TEXT runtime·setmg(SB), 7, $-4
|
|
|
|
MOVW mm+0(FP), m
|
|
|
|
MOVW gg+4(FP), g
|
|
|
|
|
|
|
|
// Save m and g to thread-local storage.
|
2013-02-28 14:24:38 -07:00
|
|
|
MOVW _cgo_save_gm(SB), R0
|
2013-02-20 15:48:23 -07:00
|
|
|
CMP $0, R0
|
|
|
|
BL.NE (R0)
|
|
|
|
|
|
|
|
RET
|
|
|
|
|
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
|
|
|
TEXT runtime·getcallerpc(SB),7,$-4
|
2009-10-19 22:58:16 -06:00
|
|
|
MOVW 0(SP), R0
|
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
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
|
|
|
TEXT runtime·setcallerpc(SB),7,$-4
|
2009-10-19 22:58:16 -06:00
|
|
|
MOVW x+4(FP), R0
|
|
|
|
MOVW R0, 0(SP)
|
|
|
|
RET
|
2009-06-10 12:53:07 -06:00
|
|
|
|
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
|
|
|
TEXT runtime·getcallersp(SB),7,$-4
|
2010-04-05 13:51:09 -06:00
|
|
|
MOVW 0(FP), R0
|
|
|
|
MOVW $-4(R0), R0
|
|
|
|
RET
|
|
|
|
|
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
|
|
|
TEXT runtime·emptyfunc(SB),0,$0
|
2009-06-16 12:25:58 -06:00
|
|
|
RET
|
|
|
|
|
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
|
|
|
TEXT runtime·abort(SB),7,$-4
|
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:
|
|
|
|
//
|
|
|
|
// TEXT runtime·cas(SB),7,$0
|
|
|
|
// B runtime·armcas(SB)
|
|
|
|
//
|
|
|
|
TEXT runtime·armcas(SB),7,$0
|
|
|
|
MOVW valptr+0(FP), R1
|
|
|
|
MOVW old+4(FP), R2
|
|
|
|
MOVW new+8(FP), R3
|
|
|
|
casl:
|
|
|
|
LDREX (R1), R0
|
|
|
|
CMP R0, R2
|
|
|
|
BNE casfail
|
|
|
|
STREX R3, (R1), R0
|
|
|
|
CMP $0, R0
|
|
|
|
BNE casl
|
|
|
|
MOVW $1, R0
|
|
|
|
RET
|
|
|
|
casfail:
|
|
|
|
MOVW $0, R0
|
|
|
|
RET
|
2012-03-15 13:22:30 -06:00
|
|
|
|
|
|
|
TEXT runtime·stackguard(SB),7,$0
|
2012-03-15 15:40:17 -06:00
|
|
|
MOVW R13, R1
|
|
|
|
MOVW g_stackguard(g), R2
|
|
|
|
MOVW R1, sp+0(FP)
|
|
|
|
MOVW R2, limit+4(FP)
|
2012-03-15 13:22:30 -06:00
|
|
|
RET
|