mirror of
https://github.com/golang/go
synced 2024-11-23 09:10:08 -07:00
runtime: convert runtime1.goc, noasm_arm.goc to Go
LGTM=dvyukov R=golang-codereviews, bradfitz, dvyukov CC=golang-codereviews, iant, khr https://golang.org/cl/135070043
This commit is contained in:
parent
b53b47f5ac
commit
6179aca548
@ -1327,7 +1327,7 @@ TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
TEXT bytes·Compare(SB),NOSPLIT,$0-28
|
||||
TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
|
||||
MOVL s1+0(FP), SI
|
||||
MOVL s1+4(FP), BX
|
||||
MOVL s2+12(FP), DI
|
||||
|
@ -1291,7 +1291,7 @@ TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
|
||||
MOVQ AX, ret+32(FP)
|
||||
RET
|
||||
|
||||
TEXT bytes·Compare(SB),NOSPLIT,$0-56
|
||||
TEXT runtime·cmpbytes(SB),NOSPLIT,$0-56
|
||||
MOVQ s1+0(FP), SI
|
||||
MOVQ s1+8(FP), BX
|
||||
MOVQ s2+24(FP), DI
|
||||
|
@ -953,7 +953,7 @@ TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
TEXT bytes·Compare(SB),NOSPLIT,$0-28
|
||||
TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
|
||||
MOVL s1+0(FP), SI
|
||||
MOVL s1+4(FP), BX
|
||||
MOVL s2+12(FP), DI
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Breakpoint executes a breakpoint trap.
|
||||
func Breakpoint()
|
||||
|
||||
@ -21,16 +23,32 @@ func UnlockOSThread()
|
||||
// change the current setting.
|
||||
// The number of logical CPUs on the local machine can be queried with NumCPU.
|
||||
// This call will go away when the scheduler improves.
|
||||
func GOMAXPROCS(n int) int
|
||||
func GOMAXPROCS(n int) int {
|
||||
return int(gomaxprocsfunc(int32(n)))
|
||||
}
|
||||
|
||||
func gomaxprocsfunc(int32) int32 // proc.c
|
||||
|
||||
// NumCPU returns the number of logical CPUs on the local machine.
|
||||
func NumCPU() int
|
||||
func NumCPU() int {
|
||||
return int(ncpu)
|
||||
}
|
||||
|
||||
// NumCgoCall returns the number of cgo calls made by the current process.
|
||||
func NumCgoCall() int64
|
||||
func NumCgoCall() int64 {
|
||||
var n int64
|
||||
for mp := (*m)(atomicloadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
|
||||
n += int64(mp.ncgocall)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// NumGoroutine returns the number of goroutines that currently exist.
|
||||
func NumGoroutine() int
|
||||
func NumGoroutine() int {
|
||||
return int(gcount())
|
||||
}
|
||||
|
||||
func gcount() int32
|
||||
|
||||
// MemProfileRate controls the fraction of memory allocations
|
||||
// that are recorded and reported in the memory profile.
|
||||
|
@ -97,7 +97,10 @@ type stringer interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
func typestring(interface{}) string
|
||||
func typestring(x interface{}) string {
|
||||
e := (*eface)(unsafe.Pointer(&x))
|
||||
return *e._type._string
|
||||
}
|
||||
|
||||
// For calling from C.
|
||||
// Prints an argument passed to panic.
|
||||
|
@ -75,6 +75,8 @@ of the run-time system.
|
||||
*/
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Goexit terminates the goroutine that calls it. No other goroutine is affected.
|
||||
// Goexit runs all deferred calls before terminating the goroutine.
|
||||
//
|
||||
@ -84,28 +86,89 @@ package runtime
|
||||
// If all other goroutines exit, the program crashes.
|
||||
func Goexit()
|
||||
|
||||
// We assume that all architectures turn faults and the like
|
||||
// into apparent calls to runtime.sigpanic. If we see a "call"
|
||||
// to runtime.sigpanic, we do not back up the PC to find the
|
||||
// line number of the CALL instruction, because there is no CALL.
|
||||
var sigpanic byte
|
||||
|
||||
// Caller reports file and line number information about function invocations on
|
||||
// the calling goroutine's stack. The argument skip is the number of stack frames
|
||||
// to ascend, with 0 identifying the caller of Caller. (For historical reasons the
|
||||
// meaning of skip differs between Caller and Callers.) The return values report the
|
||||
// program counter, file name, and line number within the file of the corresponding
|
||||
// call. The boolean ok is false if it was not possible to recover the information.
|
||||
func Caller(skip int) (pc uintptr, file string, line int, ok bool)
|
||||
func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
|
||||
// Ask for two PCs: the one we were asked for
|
||||
// and what it called, so that we can see if it
|
||||
// "called" sigpanic.
|
||||
var rpc [2]uintptr
|
||||
if callers(int32(1+skip-1), &rpc[0], 2) < 2 {
|
||||
return
|
||||
}
|
||||
f := findfunc(rpc[1])
|
||||
if f == nil {
|
||||
// TODO(rsc): Probably a bug?
|
||||
// The C version said "have retpc at least"
|
||||
// but actually returned pc=0.
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
pc = rpc[1]
|
||||
xpc := pc
|
||||
g := findfunc(rpc[0])
|
||||
if xpc > f.entry && (g == nil || g.entry != uintptr(unsafe.Pointer(&sigpanic))) {
|
||||
xpc--
|
||||
}
|
||||
line = int(funcline(f, xpc, &file))
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
func findfunc(uintptr) *_func
|
||||
|
||||
//go:noescape
|
||||
func funcline(*_func, uintptr, *string) int32
|
||||
|
||||
// Callers fills the slice pc with the program counters of function invocations
|
||||
// on the calling goroutine's stack. The argument skip is the number of stack frames
|
||||
// to skip before recording in pc, with 0 identifying the frame for Callers itself and
|
||||
// 1 identifying the caller of Callers.
|
||||
// It returns the number of entries written to pc.
|
||||
func Callers(skip int, pc []uintptr) int
|
||||
func Callers(skip int, pc []uintptr) int {
|
||||
// runtime.callers uses pc.array==nil as a signal
|
||||
// to print a stack trace. Pick off 0-length pc here
|
||||
// so that we don't let a nil pc slice get to it.
|
||||
if len(pc) == 0 {
|
||||
return 0
|
||||
}
|
||||
return int(callers(int32(skip), &pc[0], int32(len(pc))))
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func callers(int32, *uintptr, int32) int32
|
||||
|
||||
func getgoroot() string
|
||||
func environ() []string
|
||||
|
||||
func gogetenv(key string) string {
|
||||
env := environ()
|
||||
if env == nil {
|
||||
gothrow("getenv before env init")
|
||||
}
|
||||
for _, s := range env {
|
||||
if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
|
||||
return s[len(key)+1:]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GOROOT returns the root of the Go tree.
|
||||
// It uses the GOROOT environment variable, if set,
|
||||
// or else the root used during the Go build.
|
||||
func GOROOT() string {
|
||||
s := getgoroot()
|
||||
s := gogetenv("GOROOT")
|
||||
if s != "" {
|
||||
return s
|
||||
}
|
||||
|
54
src/pkg/runtime/noasm_arm.go
Normal file
54
src/pkg/runtime/noasm_arm.go
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// Routines that are implemented in assembly in asm_{amd64,386}.s
|
||||
// but are implemented in Go for arm.
|
||||
|
||||
package runtime
|
||||
|
||||
func cmpstring(s1, s2 string) int {
|
||||
l := len(s1)
|
||||
if l < len(s2) {
|
||||
l = len(s2)
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
c1, c2 := s1[i], s2[i]
|
||||
if c1 < c2 {
|
||||
return -1
|
||||
}
|
||||
if c1 > c2 {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if len(s1) < len(s2) {
|
||||
return -1
|
||||
}
|
||||
if len(s1) > len(s2) {
|
||||
return +1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func cmpbytes(s1, s2 []byte) int {
|
||||
l := len(s1)
|
||||
if l < len(s2) {
|
||||
l = len(s2)
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
c1, c2 := s1[i], s2[i]
|
||||
if c1 < c2 {
|
||||
return -1
|
||||
}
|
||||
if c1 > c2 {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if len(s1) < len(s2) {
|
||||
return -1
|
||||
}
|
||||
if len(s1) > len(s2) {
|
||||
return +1
|
||||
}
|
||||
return 0
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// Routines that are implemented in assembly in asm_{amd64,386}.s
|
||||
// but are implemented in C for arm.
|
||||
|
||||
package runtime
|
||||
#include "runtime.h"
|
||||
#include "../../cmd/ld/textflag.h"
|
||||
|
||||
#pragma textflag NOSPLIT
|
||||
func cmpstring(s1 String, s2 String) (v int) {
|
||||
uintgo i, l;
|
||||
byte c1, c2;
|
||||
|
||||
l = s1.len;
|
||||
if(s2.len < l)
|
||||
l = s2.len;
|
||||
for(i=0; i<l; i++) {
|
||||
c1 = s1.str[i];
|
||||
c2 = s2.str[i];
|
||||
if(c1 < c2) {
|
||||
v = -1;
|
||||
goto done;
|
||||
}
|
||||
if(c1 > c2) {
|
||||
v = +1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if(s1.len < s2.len) {
|
||||
v = -1;
|
||||
goto done;
|
||||
}
|
||||
if(s1.len > s2.len) {
|
||||
v = +1;
|
||||
goto done;
|
||||
}
|
||||
v = 0;
|
||||
done:;
|
||||
}
|
||||
|
||||
#pragma textflag NOSPLIT
|
||||
func bytes·Compare(s1 Slice, s2 Slice) (v int) {
|
||||
uintgo i, l;
|
||||
byte c1, c2;
|
||||
|
||||
l = s1.len;
|
||||
if(s2.len < l)
|
||||
l = s2.len;
|
||||
for(i=0; i<l; i++) {
|
||||
c1 = s1.array[i];
|
||||
c2 = s2.array[i];
|
||||
if(c1 < c2) {
|
||||
v = -1;
|
||||
goto done;
|
||||
}
|
||||
if(c1 > c2) {
|
||||
v = +1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if(s1.len < s2.len) {
|
||||
v = -1;
|
||||
goto done;
|
||||
}
|
||||
if(s1.len > s2.len) {
|
||||
v = +1;
|
||||
goto done;
|
||||
}
|
||||
v = 0;
|
||||
done:;
|
||||
}
|
@ -120,6 +120,12 @@ runtime·goenvs_unix(void)
|
||||
syscall·envs.cap = n;
|
||||
}
|
||||
|
||||
Slice
|
||||
runtime·environ()
|
||||
{
|
||||
return syscall·envs;
|
||||
}
|
||||
|
||||
int32
|
||||
runtime·atoi(byte *p)
|
||||
{
|
||||
@ -275,6 +281,7 @@ runtime·fastrand1(void)
|
||||
static Mutex ticksLock;
|
||||
static int64 ticks;
|
||||
|
||||
// Note: Called by runtime/pprof in addition to runtime code.
|
||||
int64
|
||||
runtime·tickspersecond(void)
|
||||
{
|
||||
|
@ -1,116 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
#include "runtime.h"
|
||||
#include "arch_GOARCH.h"
|
||||
#include "type.h"
|
||||
|
||||
func GOMAXPROCS(n int) (ret int) {
|
||||
ret = runtime·gomaxprocsfunc(n);
|
||||
}
|
||||
|
||||
func NumCPU() (ret int) {
|
||||
ret = runtime·ncpu;
|
||||
}
|
||||
|
||||
func NumCgoCall() (ret int64) {
|
||||
M *mp;
|
||||
|
||||
ret = 0;
|
||||
for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
|
||||
ret += mp->ncgocall;
|
||||
}
|
||||
|
||||
func newParFor(nthrmax uint32) (desc *ParFor) {
|
||||
desc = runtime·parforalloc(nthrmax);
|
||||
}
|
||||
|
||||
func parForSetup(desc *ParFor, nthr uint32, n uint32, ctx *byte, wait bool, body *byte) {
|
||||
runtime·parforsetup(desc, nthr, n, ctx, wait, *(void(**)(ParFor*, uint32))body);
|
||||
}
|
||||
|
||||
func parForDo(desc *ParFor) {
|
||||
runtime·parfordo(desc);
|
||||
}
|
||||
|
||||
func parForIters(desc *ParFor, tid uintptr) (start uintptr, end uintptr) {
|
||||
runtime·parforiters(desc, tid, &start, &end);
|
||||
}
|
||||
|
||||
func gogoBytes() (x int32) {
|
||||
x = RuntimeGogoBytes;
|
||||
}
|
||||
|
||||
func typestring(e Eface) (s String) {
|
||||
s = *e.type->string;
|
||||
}
|
||||
|
||||
func golockedOSThread() (ret bool) {
|
||||
ret = runtime·lockedOSThread();
|
||||
}
|
||||
|
||||
func NumGoroutine() (ret int) {
|
||||
ret = runtime·gcount();
|
||||
}
|
||||
|
||||
func getgoroot() (out String) {
|
||||
byte *p;
|
||||
|
||||
p = runtime·getenv("GOROOT");
|
||||
out = runtime·gostringnocopy(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* We assume that all architectures turn faults and the like
|
||||
* into apparent calls to runtime.sigpanic. If we see a "call"
|
||||
* to runtime.sigpanic, we do not back up the PC to find the
|
||||
* line number of the CALL instruction, because there is no CALL.
|
||||
*/
|
||||
void runtime·sigpanic(void);
|
||||
|
||||
func Caller(skip int) (retpc uintptr, retfile String, retline int, retbool bool) {
|
||||
Func *f, *g;
|
||||
uintptr pc;
|
||||
uintptr rpc[2];
|
||||
|
||||
/*
|
||||
* Ask for two PCs: the one we were asked for
|
||||
* and what it called, so that we can see if it
|
||||
* "called" sigpanic.
|
||||
*/
|
||||
retpc = 0;
|
||||
if(runtime·callers(1+skip-1, rpc, 2) < 2) {
|
||||
retfile = runtime·emptystring;
|
||||
retline = 0;
|
||||
retbool = false;
|
||||
} else if((f = runtime·findfunc(rpc[1])) == nil) {
|
||||
retfile = runtime·emptystring;
|
||||
retline = 0;
|
||||
retbool = true; // have retpc at least
|
||||
} else {
|
||||
retpc = rpc[1];
|
||||
pc = retpc;
|
||||
g = runtime·findfunc(rpc[0]);
|
||||
if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·sigpanic))
|
||||
pc--;
|
||||
retline = runtime·funcline(f, pc, &retfile);
|
||||
retbool = true;
|
||||
}
|
||||
}
|
||||
|
||||
func Callers(skip int, pc Slice) (retn int) {
|
||||
// runtime.callers uses pc.array==nil as a signal
|
||||
// to print a stack trace. Pick off 0-length pc here
|
||||
// so that we don't let a nil pc slice get to it.
|
||||
if(pc.len == 0)
|
||||
retn = 0;
|
||||
else
|
||||
retn = runtime·callers(skip, (uintptr*)pc.array, pc.len);
|
||||
}
|
||||
|
||||
func runtime∕pprof·runtime_cyclesPerSecond() (res int64) {
|
||||
res = runtime·tickspersecond();
|
||||
}
|
||||
|
@ -68,3 +68,8 @@ func reflect·typelinks() (ret Slice) {
|
||||
ret.len = runtime·etypelink - runtime·typelink;
|
||||
ret.cap = ret.len;
|
||||
}
|
||||
|
||||
// For testing.
|
||||
func gogoBytes() (x int32) {
|
||||
x = RuntimeGogoBytes;
|
||||
}
|
||||
|
@ -43,3 +43,9 @@ TEXT net·runtime_Semacquire(SB),NOSPLIT,$0-0
|
||||
|
||||
TEXT net·runtime_Semrelease(SB),NOSPLIT,$0-0
|
||||
JMP runtime·asyncsemrelease(SB)
|
||||
|
||||
TEXT runtime∕pprof·runtime_cyclesPerSecond(SB),NOSPLIT,$0-0
|
||||
JMP runtime·tickspersecond(SB)
|
||||
|
||||
TEXT bytes·Compare(SB),NOSPLIT,$0-0
|
||||
JMP runtime·cmpbytes(SB)
|
||||
|
Loading…
Reference in New Issue
Block a user