]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert Stack to Go.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 26 Aug 2014 06:34:46 +0000 (08:34 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 26 Aug 2014 06:34:46 +0000 (08:34 +0200)
LGTM=khr
R=khr, josharian
CC=golang-codereviews
https://golang.org/cl/129510043

src/pkg/runtime/asm_386.s
src/pkg/runtime/asm_amd64.s
src/pkg/runtime/asm_amd64p32.s
src/pkg/runtime/asm_arm.s
src/pkg/runtime/debug.go
src/pkg/runtime/mprof.go
src/pkg/runtime/mprof.goc
src/pkg/runtime/stubs.go

index 741832b4da1fa249cf29cbe51c75daaa0093c295..198a468efea2a7c701f9080841e437007534d037 100644 (file)
@@ -860,6 +860,12 @@ TEXT runtime·getcallersp(SB), NOSPLIT, $0-4
        MOVL    sp+0(FP), AX
        RET
 
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-8
+       MOVL    p+0(FP),AX              // addr of first arg
+       MOVL    AX, ret+4(FP)
+       RET
+
 // int64 runtime·cputicks(void), so really
 // void runtime·cputicks(int64 *ticks)
 TEXT runtime·cputicks(SB),NOSPLIT,$0-4
index 3b63c56a35fb99d192b7c82b751e553ea603ca27..c53e2d350ee1730877879b06a74ab5f45a75ed73 100644 (file)
@@ -946,6 +946,12 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
        MOVQ    sp+0(FP), AX
        RET
 
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
+       MOVQ    p+0(FP),AX              // addr of first arg
+       MOVQ    AX, ret+8(FP)
+       RET
+
 // int64 runtime·cputicks(void)
 TEXT runtime·cputicks(SB),NOSPLIT,$0-0
        RDTSC
index 5c6a73ab9984e80c3ccc32253996b3e4317bff7f..4c039d7767589ba0a6bc5521db7697fa6ca81626 100644 (file)
@@ -747,6 +747,12 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
        MOVL    sp+0(FP), AX
        RET
 
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-12
+       MOVL    p+0(FP),AX              // addr of first arg
+       MOVL    AX, ret+8(FP)
+       RET
+
 // int64 runtime·cputicks(void)
 TEXT runtime·cputicks(SB),NOSPLIT,$0-0
        RDTSC
index 07b99262bb4ac85ae34d7ecfd4ad28d288388b34..551ba0c88cac510206832787be42302734580543 100644 (file)
@@ -644,6 +644,13 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
        MOVW    $-4(R0), R0
        RET
 
+// 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
+
 TEXT runtime·emptyfunc(SB),0,$0-0
        RET
 
index 393598c28a0900dc15672a5d037f75b77ca8b345..af44a64741ea6437c5d61de53e9a22e59568139f 100644 (file)
@@ -133,9 +133,3 @@ type BlockProfileRecord struct {
        Cycles int64
        StackRecord
 }
-
-// Stack formats a stack trace of the calling goroutine into buf
-// and returns the number of bytes written to buf.
-// If all is true, Stack formats stack traces of all other goroutines
-// into buf after the trace for the current goroutine.
-func Stack(buf []byte, all bool) int
index 7c90c21c9854c718154f8f2aa2bf3fb95d02a864..95ea1297edda9c8765b533c36d3a1414784d5827 100644 (file)
@@ -141,6 +141,47 @@ func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
        return
 }
 
+// Stack formats a stack trace of the calling goroutine into buf
+// and returns the number of bytes written to buf.
+// If all is true, Stack formats stack traces of all other goroutines
+// into buf after the trace for the current goroutine.
+func Stack(buf []byte, all bool) int {
+       sp := gogetcallersp(unsafe.Pointer(&buf))
+       pc := gogetcallerpc(unsafe.Pointer(&buf))
+       mp := acquirem()
+       gp := mp.curg
+       if all {
+               semacquire(&worldsema, false)
+               mp.gcing = 1
+               releasem(mp)
+               stoptheworld()
+               if mp != acquirem() {
+                       gothrow("Stack: rescheduled")
+               }
+       }
+
+       n := 0
+       if len(buf) > 0 {
+               gp.writebuf = &buf[0]
+               gp.writenbuf = int32(len(buf))
+               traceback(pc, sp, 0, gp)
+               if all {
+                       tracebackothers(gp)
+               }
+               n = len(buf) - int(gp.writenbuf)
+               gp.writebuf = nil
+               gp.writenbuf = 0
+       }
+
+       if all {
+               mp.gcing = 0
+               semrelease(&worldsema)
+               starttheworld()
+       }
+       releasem(mp)
+       return n
+}
+
 // ThreadCreateProfile returns n, the number of records in the thread creation profile.
 // If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
 // If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
index 57596b2231d513b30d5b955b6244c3bc31bc069f..a79081c72f1d38bae58ea0e6fca64b75db4a70b8 100644 (file)
@@ -256,39 +256,6 @@ struct TRecord {
        uintptr stk[32];
 };
 
-func Stack(b Slice, all bool) (n int) {
-       uintptr pc, sp;
-       
-       sp = runtime·getcallersp(&b);
-       pc = (uintptr)runtime·getcallerpc(&b);
-
-       if(all) {
-               runtime·semacquire(&runtime·worldsema, false);
-               g->m->gcing = 1;
-               runtime·stoptheworld();
-       }
-
-       if(b.len == 0)
-               n = 0;
-       else{
-               g->writebuf = (byte*)b.array;
-               g->writenbuf = b.len;
-               runtime·goroutineheader(g);
-               runtime·traceback(pc, sp, 0, g);
-               if(all)
-                       runtime·tracebackothers(g);
-               n = b.len - g->writenbuf;
-               g->writebuf = nil;
-               g->writenbuf = 0;
-       }
-       
-       if(all) {
-               g->m->gcing = 0;
-               runtime·semrelease(&runtime·worldsema);
-               runtime·starttheworld();
-       }
-}
-
 static void
 saveg(uintptr pc, uintptr sp, G *gp, TRecord *r)
 {
index 6cabed063e689010687440472f8a897468186873..e3e14caab83d05e3b58100ee87eddeffe773a1d9 100644 (file)
@@ -18,6 +18,9 @@ const (
 //go:noescape
 func gogetcallerpc(p unsafe.Pointer) uintptr
 
+//go:noescape
+func gogetcallersp(p unsafe.Pointer) uintptr
+
 //go:noescape
 func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
 
@@ -212,3 +215,6 @@ func gonotetsleepg(n *note, t int64) {
 }
 
 func exitsyscall()
+
+func traceback(pc, sp, lr uintptr, gp *g)
+func tracebackothers(gp *g)