]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert print.c to Go
authorRuss Cox <rsc@golang.org>
Fri, 29 Aug 2014 03:26:40 +0000 (23:26 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 29 Aug 2014 03:26:40 +0000 (23:26 -0400)
LGTM=iant
R=golang-codereviews, iant
CC=dvyukov, golang-codereviews, khr, r
https://golang.org/cl/135930043

14 files changed:
src/pkg/runtime/alg.goc
src/pkg/runtime/mprof.go
src/pkg/runtime/os_darwin.c
src/pkg/runtime/os_dragonfly.c
src/pkg/runtime/os_freebsd.c
src/pkg/runtime/panic.c
src/pkg/runtime/print.c [deleted file]
src/pkg/runtime/print.go [deleted file]
src/pkg/runtime/print1.go [new file with mode: 0644]
src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h
src/pkg/runtime/stubs.go
src/pkg/runtime/traceback_arm.c
src/pkg/runtime/traceback_x86.c

index aa0c79d476358273ae8a74ce63772445d1e43689..0c3b3cd4ff95ae105b812e86cc393db9bb228541 100644 (file)
@@ -29,7 +29,7 @@ runtime·memprint(uintptr s, void *a)
                v = *(uint64*)a;
                break;
        }
-       runtime·printint_c(v);
+       runtime·printint(v);
 }
 
 void
@@ -126,7 +126,7 @@ void
 runtime·strprint(uintptr s, void *a)
 {
        USED(s);
-       runtime·printstring_c(*(String*)a);
+       runtime·printstring(*(String*)a);
 }
 
 void
@@ -146,7 +146,7 @@ void
 runtime·interprint(uintptr s, void *a)
 {
        USED(s);
-       runtime·printiface_c(*(Iface*)a);
+       runtime·printiface(*(Iface*)a);
 }
 
 void
@@ -166,7 +166,7 @@ void
 runtime·nilinterprint(uintptr s, void *a)
 {
        USED(s);
-       runtime·printeface_c(*(Eface*)a);
+       runtime·printeface(*(Eface*)a);
 }
 
 void
index 9ee37d0bee219e18c3affceba321b87954e1dcf8..78384f81178ffcfe93f8d6fe170d082a117e279c 100644 (file)
@@ -162,16 +162,14 @@ func Stack(buf []byte, all bool) int {
 
        n := 0
        if len(buf) > 0 {
-               gp.writebuf = &buf[0]
-               gp.writenbuf = int32(len(buf))
+               gp.writebuf = buf
                goroutineheader(gp)
                traceback(pc, sp, 0, gp)
                if all {
                        tracebackothers(gp)
                }
-               n = len(buf) - int(gp.writenbuf)
+               n = len(buf) - len(gp.writebuf)
                gp.writebuf = nil
-               gp.writenbuf = 0
        }
 
        if all {
index 84b69b047ae4ac0c9e25ac42b46e2f3f888d8a0b..c660fb8c10cbfc3a48fbf8700230fa5479e28d75 100644 (file)
@@ -150,7 +150,7 @@ macherror(int32 r, int8 *fn)
        runtime·prints("mach error ");
        runtime·prints(fn);
        runtime·prints(": ");
-       runtime·printint_c(r);
+       runtime·printint(r);
        runtime·prints("\n");
        runtime·throw("mach error");
 }
@@ -218,7 +218,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
                runtime·prints("send:\t");
                for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
                        runtime·prints(" ");
-                       runtime·printpointer_c((void*)p[i]);
+                       runtime·printpointer((void*)p[i]);
                        if(i%8 == 7)
                                runtime·prints("\n\t");
                }
@@ -231,7 +231,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
        if(ret != 0){
                if(DebugMach){
                        runtime·prints("mach_msg error ");
-                       runtime·printint_c(ret);
+                       runtime·printint(ret);
                        runtime·prints("\n");
                }
                return ret;
@@ -242,7 +242,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
                runtime·prints("recv:\t");
                for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
                        runtime·prints(" ");
-                       runtime·printpointer_c((void*)p[i]);
+                       runtime·printpointer((void*)p[i]);
                        if(i%8 == 7)
                                runtime·prints("\n\t");
                }
@@ -253,9 +253,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
        if(h->msgh_id != id+Reply){
                if(DebugMach){
                        runtime·prints("mach_msg reply id mismatch ");
-                       runtime·printint_c(h->msgh_id);
+                       runtime·printint(h->msgh_id);
                        runtime·prints(" != ");
-                       runtime·printint_c(id+Reply);
+                       runtime·printint(id+Reply);
                        runtime·prints("\n");
                }
                return -303;    // MIG_REPLY_MISMATCH
@@ -272,7 +272,7 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
        && !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
                if(DebugMach){
                        runtime·prints("mig result ");
-                       runtime·printint_c(c->code);
+                       runtime·printint(c->code);
                        runtime·prints("\n");
                }
                return c->code;
@@ -281,9 +281,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize)
        if(h->msgh_size != rxsize){
                if(DebugMach){
                        runtime·prints("mach_msg reply size mismatch ");
-                       runtime·printint_c(h->msgh_size);
+                       runtime·printint(h->msgh_size);
                        runtime·prints(" != ");
-                       runtime·printint_c(rxsize);
+                       runtime·printint(rxsize);
                        runtime·prints("\n");
                }
                return -307;    // MIG_ARRAY_TOO_LARGE
index 1132f5741d79f3147eb1e997f15433fef825d54a..65121d32734e8e66b7a834a7bf363e557b786fea 100644 (file)
@@ -63,11 +63,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
                return;
 
        runtime·prints("umtx_wait addr=");
-       runtime·printpointer_c(addr);
+       runtime·printpointer(addr);
        runtime·prints(" val=");
-       runtime·printint_c(val);
+       runtime·printint(val);
        runtime·prints(" ret=");
-       runtime·printint_c(ret);
+       runtime·printint(ret);
        runtime·prints("\n");
        *(int32*)0x1005 = 0x1005;
 }
index 20f71c41e87da9716722b4c2b7121bc0ba483eab..d360f6712d028625d423c48faac96d671f443bee 100644 (file)
@@ -64,11 +64,11 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
 
 fail:
        runtime·prints("umtx_wait addr=");
-       runtime·printpointer_c(addr);
+       runtime·printpointer(addr);
        runtime·prints(" val=");
-       runtime·printint_c(val);
+       runtime·printint(val);
        runtime·prints(" ret=");
-       runtime·printint_c(ret);
+       runtime·printint(ret);
        runtime·prints("\n");
        *(int32*)0x1005 = 0x1005;
 }
index 00c780bf55e6f76e9e9c79f575a994d55088afbd..39027a77c2eae30da4f65e89c6a097c952f3465a 100644 (file)
@@ -390,8 +390,11 @@ runtime·startpanic(void)
        switch(g->m->dying) {
        case 0:
                g->m->dying = 1;
-               if(g != nil)
-                       g->writebuf = nil;
+               if(g != nil) {
+                       g->writebuf.array = nil;
+                       g->writebuf.len = 0;
+                       g->writebuf.cap = 0;
+               }
                runtime·xadd(&runtime·panicking, 1);
                runtime·lock(&paniclk);
                if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c
deleted file mode 100644 (file)
index 57dfdab..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-//static Mutex debuglock;
-
-static void vprintf(int8*, byte*);
-
-// write to goroutine-local buffer if diverting output,
-// or else standard error.
-static void
-gwrite(void *v, intgo n)
-{
-       if(g == nil || g->writebuf == nil) {
-               runtime·write(2, v, n);
-               return;
-       }
-
-       if(g->writenbuf == 0)
-               return;
-
-       if(n > g->writenbuf)
-               n = g->writenbuf;
-       runtime·memmove(g->writebuf, v, n);
-       g->writebuf += n;
-       g->writenbuf -= n;
-}
-
-void
-runtime·dump(byte *p, int32 n)
-{
-       int32 i;
-
-       for(i=0; i<n; i++) {
-               runtime·printpointer_c((byte*)(p[i]>>4));
-               runtime·printpointer_c((byte*)(p[i]&0xf));
-               if((i&15) == 15)
-                       runtime·prints("\n");
-               else
-                       runtime·prints(" ");
-       }
-       if(n & 15)
-               runtime·prints("\n");
-}
-
-void
-runtime·prints(int8 *s)
-{
-       gwrite(s, runtime·findnull((byte*)s));
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·printf(int8 *s, ...)
-{
-       byte *arg;
-
-       arg = (byte*)(&s+1);
-       vprintf(s, arg);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·snprintf(byte *buf, int32 n, int8 *s, ...)
-{
-       byte *arg;
-       int32 m;
-
-       arg = (byte*)(&s+1);
-       g->writebuf = buf;
-       g->writenbuf = n-1;
-       vprintf(s, arg);
-       *g->writebuf = '\0';
-       m = g->writebuf - buf;
-       g->writenbuf = 0;
-       g->writebuf = nil;
-       return m;
-}
-
-// Very simple printf.  Only for debugging prints.
-// Do not add to this without checking with Rob.
-static void
-vprintf(int8 *s, byte *base)
-{
-       int8 *p, *lp;
-       uintptr arg, siz;
-       byte *v;
-
-       //runtime·lock(&debuglock);
-
-       lp = p = s;
-       arg = (uintptr)base;
-       for(; *p; p++) {
-               if(*p != '%')
-                       continue;
-               if(p > lp)
-                       gwrite(lp, p-lp);
-               p++;
-               siz = 0;
-               switch(*p) {
-               case 't':
-               case 'c':
-                       siz = 1;
-                       break;
-               case 'd':       // 32-bit
-               case 'x':
-                       arg = ROUND(arg, 4);
-                       siz = 4;
-                       break;
-               case 'D':       // 64-bit
-               case 'U':
-               case 'X':
-               case 'f':
-                       arg = ROUND(arg, sizeof(uintreg));
-                       siz = 8;
-                       break;
-               case 'C':
-                       arg = ROUND(arg, sizeof(uintreg));
-                       siz = 16;
-                       break;
-               case 'p':       // pointer-sized
-               case 's':
-                       arg = ROUND(arg, sizeof(uintptr));
-                       siz = sizeof(uintptr);
-                       break;
-               case 'S':       // pointer-aligned but bigger
-                       arg = ROUND(arg, sizeof(uintptr));
-                       siz = sizeof(String);
-                       break;
-               case 'a':       // pointer-aligned but bigger
-                       arg = ROUND(arg, sizeof(uintptr));
-                       siz = sizeof(Slice);
-                       break;
-               case 'i':       // pointer-aligned but bigger
-               case 'e':
-                       arg = ROUND(arg, sizeof(uintptr));
-                       siz = sizeof(Eface);
-                       break;
-               }
-               v = (byte*)arg;
-               switch(*p) {
-               case 'a':
-                       runtime·printslice_c(*(Slice*)v);
-                       break;
-               case 'c':
-                       runtime·printbyte_c(*(int8*)v);
-                       break;
-               case 'd':
-                       runtime·printint_c(*(int32*)v);
-                       break;
-               case 'D':
-                       runtime·printint_c(*(int64*)v);
-                       break;
-               case 'e':
-                       runtime·printeface_c(*(Eface*)v);
-                       break;
-               case 'f':
-                       runtime·printfloat_c(*(float64*)v);
-                       break;
-               case 'C':
-                       runtime·printcomplex_c(*(Complex128*)v);
-                       break;
-               case 'i':
-                       runtime·printiface_c(*(Iface*)v);
-                       break;
-               case 'p':
-                       runtime·printpointer_c(*(void**)v);
-                       break;
-               case 's':
-                       runtime·prints(*(int8**)v);
-                       break;
-               case 'S':
-                       runtime·printstring_c(*(String*)v);
-                       break;
-               case 't':
-                       runtime·printbool_c(*(bool*)v);
-                       break;
-               case 'U':
-                       runtime·printuint_c(*(uint64*)v);
-                       break;
-               case 'x':
-                       runtime·printhex_c(*(uint32*)v);
-                       break;
-               case 'X':
-                       runtime·printhex_c(*(uint64*)v);
-                       break;
-               }
-               arg += siz;
-               lp = p+1;
-       }
-       if(p > lp)
-               gwrite(lp, p-lp);
-
-       //runtime·unlock(&debuglock);
-}
-
-static void
-goprintf_m(void)
-{
-       // Can assume s has terminating NUL because only
-       // the Go compiler generates calls to runtime·goprintf, using
-       // string constants, and all the string constants have NULs.
-       vprintf(g->m->ptrarg[0], g->m->ptrarg[1]);
-       g->m->ptrarg[0] = nil;
-       g->m->ptrarg[1] = nil;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·goprintf(String s, ...)
-{
-       g->m->ptrarg[0] = s.str;
-       g->m->ptrarg[1] = (byte*)(&s+1);
-       runtime·onM(goprintf_m);
-}
-
-void
-runtime·printpc_c(void *p)
-{
-       runtime·prints("PC=");
-       runtime·printhex_c((uint64)runtime·getcallerpc(p));
-}
-
-void
-runtime·printbool_c(bool v)
-{
-       if(v) {
-               gwrite((byte*)"true", 4);
-               return;
-       }
-       gwrite((byte*)"false", 5);
-}
-
-void
-runtime·printbyte_c(int8 c)
-{
-       gwrite(&c, 1);
-}
-
-void
-runtime·printfloat_c(float64 v)
-{
-       byte buf[20];
-       int32 e, s, i, n;
-       float64 h;
-
-       if(ISNAN(v)) {
-               gwrite("NaN", 3);
-               return;
-       }
-       if(v == runtime·posinf) {
-               gwrite("+Inf", 4);
-               return;
-       }
-       if(v == runtime·neginf) {
-               gwrite("-Inf", 4);
-               return;
-       }
-
-       n = 7;  // digits printed
-       e = 0;  // exp
-       s = 0;  // sign
-       if(v == 0) {
-               if(1/v == runtime·neginf)
-                       s = 1;
-       } else {
-               // sign
-               if(v < 0) {
-                       v = -v;
-                       s = 1;
-               }
-
-               // normalize
-               while(v >= 10) {
-                       e++;
-                       v /= 10;
-               }
-               while(v < 1) {
-                       e--;
-                       v *= 10;
-               }
-
-               // round
-               h = 5;
-               for(i=0; i<n; i++)
-                       h /= 10;
-
-               v += h;
-               if(v >= 10) {
-                       e++;
-                       v /= 10;
-               }
-       }
-
-       // format +d.dddd+edd
-       buf[0] = '+';
-       if(s)
-               buf[0] = '-';
-       for(i=0; i<n; i++) {
-               s = v;
-               buf[i+2] = s+'0';
-               v -= s;
-               v *= 10.;
-       }
-       buf[1] = buf[2];
-       buf[2] = '.';
-
-       buf[n+2] = 'e';
-       buf[n+3] = '+';
-       if(e < 0) {
-               e = -e;
-               buf[n+3] = '-';
-       }
-
-       buf[n+4] = (e/100) + '0';
-       buf[n+5] = (e/10)%10 + '0';
-       buf[n+6] = (e%10) + '0';
-       gwrite(buf, n+7);
-}
-
-void
-runtime·printcomplex_c(Complex128 v)
-{
-       gwrite("(", 1);
-       runtime·printfloat_c(v.real);
-       runtime·printfloat_c(v.imag);
-       gwrite("i)", 2);
-}
-
-void
-runtime·printuint_c(uint64 v)
-{
-       byte buf[100];
-       int32 i;
-
-       for(i=nelem(buf)-1; i>0; i--) {
-               buf[i] = v%10 + '0';
-               if(v < 10)
-                       break;
-               v = v/10;
-       }
-       gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime·printint_c(int64 v)
-{
-       if(v < 0) {
-               gwrite("-", 1);
-               v = -v;
-       }
-       runtime·printuint_c(v);
-}
-
-void
-runtime·printhex_c(uint64 v)
-{
-       static int8 *dig = "0123456789abcdef";
-       byte buf[100];
-       int32 i;
-
-       i=nelem(buf);
-       for(; v>0; v/=16)
-               buf[--i] = dig[v%16];
-       if(i == nelem(buf))
-               buf[--i] = '0';
-       buf[--i] = 'x';
-       buf[--i] = '0';
-       gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime·printpointer_c(void *p)
-{
-       runtime·printhex_c((uintptr)p);
-}
-
-void
-runtime·printstring_c(String v)
-{
-       if(v.len > runtime·maxstring) {
-               gwrite("[string too long]", 17);
-               return;
-       }
-       if(v.len > 0)
-               gwrite(v.str, v.len);
-}
-
-void
-runtime·printslice_c(Slice s)
-{
-       runtime·prints("[");
-       runtime·printint_c(s.len);
-       runtime·prints("/");
-       runtime·printint_c(s.cap);
-       runtime·prints("]");
-       runtime·printpointer_c(s.array);
-}
-
-void
-runtime·printeface_c(Eface e)
-{
-       runtime·printf("(%p,%p)", e.type, e.data);
-}
-
-void
-runtime·printiface_c(Iface i)
-{
-       runtime·printf("(%p,%p)", i.tab, i.data);
-}
-
-void
-runtime·printstring_m(void)
-{
-       String s;
-
-       s.str = g->m->ptrarg[0];
-       g->m->ptrarg[0] = nil;
-       s.len = g->m->scalararg[0];
-       runtime·printstring_c(s);
-}
-
-void
-runtime·printuint_m(void)
-{
-       runtime·printuint_c(*(uint64*)(&g->m->scalararg[0]));
-}
-
-void
-runtime·printhex_m(void)
-{
-       runtime·printhex_c(g->m->scalararg[0]);
-}
-
-void
-runtime·printfloat_m(void)
-{
-       runtime·printfloat_c(*(float64*)(&g->m->scalararg[0]));
-}
diff --git a/src/pkg/runtime/print.go b/src/pkg/runtime/print.go
deleted file mode 100644 (file)
index fd79bc8..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2014 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
-
-import (
-       "unsafe"
-)
-
-// these 4 functions are complicated enough that we will share
-// the print logic with the C printf.
-var (
-       printstring_m,
-       printuint_m,
-       printhex_m,
-       printfloat_m mFunction
-)
-
-func printstring(s string) {
-       mp := acquirem()
-       mp.scalararg[0] = uintptr(len(s))
-       mp.ptrarg[0] = (*stringStruct)(unsafe.Pointer(&s)).str
-       onM(&printstring_m)
-       releasem(mp)
-}
-
-func printuint(x uint64) {
-       mp := acquirem()
-       *(*uint64)(unsafe.Pointer(&mp.scalararg[0])) = x
-       onM(&printuint_m)
-       releasem(mp)
-}
-
-func printhex(x uintptr) {
-       mp := acquirem()
-       mp.scalararg[0] = uintptr(x)
-       onM(&printhex_m)
-       releasem(mp)
-}
-
-func printfloat(x float64) {
-       mp := acquirem()
-       *(*float64)(unsafe.Pointer(&mp.scalararg[0])) = x
-       onM(&printfloat_m)
-       releasem(mp)
-}
-
-// all other print functions are expressible as combinations
-// of the above 4 functions.
-func printnl() {
-       printstring("\n")
-}
-
-func printsp() {
-       printstring(" ")
-}
-
-func printbool(b bool) {
-       if b {
-               printstring("true")
-       } else {
-               printstring("false")
-       }
-}
-
-func printpointer(p unsafe.Pointer) {
-       printhex(uintptr(p))
-}
-
-func printint(x int64) {
-       if x < 0 {
-               printstring("-")
-               x = -x
-       }
-       printuint(uint64(x))
-}
-
-func printcomplex(x complex128) {
-       printstring("(")
-       printfloat(real(x))
-       printfloat(imag(x))
-       printstring("i)")
-}
-
-func printiface(i interface {
-       f()
-}) {
-       printstring("(")
-       printhex((*[2]uintptr)(unsafe.Pointer(&i))[0])
-       printstring(",")
-       printhex((*[2]uintptr)(unsafe.Pointer(&i))[1])
-       printstring(")")
-}
-
-func printeface(e interface{}) {
-       printstring("(")
-       printhex((*[2]uintptr)(unsafe.Pointer(&e))[0])
-       printstring(",")
-       printhex((*[2]uintptr)(unsafe.Pointer(&e))[1])
-       printstring(")")
-}
-
-func printslice(b []byte) {
-       printstring("[")
-       printint(int64(len(b)))
-       printstring("/")
-       printint(int64(cap(b)))
-       printstring("]")
-       printhex((*[3]uintptr)(unsafe.Pointer(&b))[0])
-}
diff --git a/src/pkg/runtime/print1.go b/src/pkg/runtime/print1.go
new file mode 100644 (file)
index 0000000..94ba9e4
--- /dev/null
@@ -0,0 +1,338 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+//go:noescape
+func gostring(*byte) string
+
+func bytes(s string) (ret []byte) {
+       rp := (*slice)(unsafe.Pointer(&ret))
+       sp := (*_string)(noescape(unsafe.Pointer(&s)))
+       rp.array = sp.str
+       rp.len = uint(sp.len)
+       rp.cap = uint(sp.len)
+       return
+}
+
+// goprintf is the function call that is actually deferred when you write
+//     defer print(...)
+// It is otherwise unused. In particular it is not used for ordinary prints.
+// Right now a dynamically allocated string that is being passed as an
+// argument is invisible to the garbage collector and might be collected
+// if that argument list is the only reference. For now we ignore that possibility.
+// To fix, we should change to defer a call to vprintf with a pointer to
+// an argument list on the stack, stored in an appropriately typed
+// struct. golang.org/issue/8614.
+//go:nosplit
+func goprintf(s string) {
+       vprintf(s, add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
+}
+
+// printf is only called from C code. It has the same problem as goprintf
+// with strings possibly being collected from underneath.
+// However, the runtime never prints dynamically allocated
+// Go strings using printf. The strings it prints come from the symbol
+// and type tables.
+//go:nosplit
+func printf(s *byte) {
+       vprintf(gostring(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
+}
+
+// sprintf is only called from C code.
+// It has the same problem as goprintf.
+//go:nosplit
+func snprintf(dst *byte, n int32, s *byte) {
+       buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:0:n]
+
+       gp := getg()
+       gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
+       vprintf(gostring(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
+       buf[len(gp.writebuf)] = '\x00'
+       gp.writebuf = nil
+}
+
+//var debuglock mutex
+
+// write to goroutine-local buffer if diverting output,
+// or else standard error.
+func gwrite(b []byte) {
+       if len(b) == 0 {
+               return
+       }
+       gp := getg()
+       if gp == nil || gp.writebuf == nil {
+               write(2, unsafe.Pointer(&b[0]), int32(len(b)))
+               return
+       }
+
+       n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
+       gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
+}
+
+func prints(s *byte) {
+       b := (*[1 << 30]byte)(unsafe.Pointer(s))
+       for i := 0; ; i++ {
+               if b[i] == 0 {
+                       gwrite(b[:i])
+                       return
+               }
+       }
+}
+
+func printsp() {
+       print(" ")
+}
+
+func printnl() {
+       print("\n")
+}
+
+// Very simple printf.  Only for debugging prints.
+// Do not add to this without checking with Rob.
+func vprintf(str string, arg unsafe.Pointer) {
+       //lock(&debuglock);
+
+       s := bytes(str)
+       start := 0
+       i := 0
+       for ; i < len(s); i++ {
+               if s[i] != '%' {
+                       continue
+               }
+               if i > start {
+                       gwrite(s[start:i])
+               }
+               if i++; i >= len(s) {
+                       break
+               }
+               var siz uintptr
+               switch s[i] {
+               case 't', 'c':
+                       siz = 1
+               case 'd', 'x': // 32-bit
+                       arg = roundup(arg, 4)
+                       siz = 4
+               case 'D', 'U', 'X', 'f': // 64-bit
+                       arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
+                       siz = 8
+               case 'C':
+                       arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
+                       siz = 16
+               case 'p', 's': // pointer-sized
+                       arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+                       siz = unsafe.Sizeof(uintptr(0))
+               case 'S': // pointer-aligned but bigger
+                       arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+                       siz = unsafe.Sizeof(string(""))
+               case 'a': // pointer-aligned but bigger
+                       arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+                       siz = unsafe.Sizeof([]byte{})
+               case 'i', 'e': // pointer-aligned but bigger
+                       arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+                       siz = unsafe.Sizeof(interface{}(nil))
+               }
+               switch s[i] {
+               case 'a':
+                       printslice(*(*[]byte)(arg))
+               case 'c':
+                       printbyte(*(*byte)(arg))
+               case 'd':
+                       printint(int64(*(*int32)(arg)))
+               case 'D':
+                       printint(int64(*(*int64)(arg)))
+               case 'e':
+                       printeface(*(*interface{})(arg))
+               case 'f':
+                       printfloat(*(*float64)(arg))
+               case 'C':
+                       printcomplex(*(*complex128)(arg))
+               case 'i':
+                       printiface(*(*fInterface)(arg))
+               case 'p':
+                       printpointer(*(*unsafe.Pointer)(arg))
+               case 's':
+                       prints(*(**byte)(arg))
+               case 'S':
+                       printstring(*(*string)(arg))
+               case 't':
+                       printbool(*(*bool)(arg))
+               case 'U':
+                       printuint(*(*uint64)(arg))
+               case 'x':
+                       printhex(uint64(*(*uint32)(arg)))
+               case 'X':
+                       printhex(*(*uint64)(arg))
+               }
+               arg = add(arg, siz)
+               start = i + 1
+       }
+       if start < i {
+               gwrite(s[start:i])
+       }
+
+       //unlock(&debuglock);
+}
+
+func printpc(p unsafe.Pointer) {
+       print("PC=")
+       printhex(uint64(getcallerpc(p)))
+}
+
+func printbool(v bool) {
+       if v {
+               print("true")
+       } else {
+               print("false")
+       }
+}
+
+func printbyte(c byte) {
+       gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
+}
+
+func printfloat(v float64) {
+       switch {
+       case v != v:
+               print("NaN")
+               return
+       case v+v == v && v > 0:
+               print("+Inf")
+               return
+       case v+v == v && v < 0:
+               print("-Inf")
+               return
+       }
+
+       const n = 7 // digits printed
+       var buf [n + 7]byte
+       buf[0] = '+'
+       e := 0 // exp
+       if v == 0 {
+               if 1/v < 0 {
+                       buf[0] = '-'
+               }
+       } else {
+               if v < 0 {
+                       v = -v
+                       buf[0] = '-'
+               }
+
+               // normalize
+               for v >= 10 {
+                       e++
+                       v /= 10
+               }
+               for v < 1 {
+                       e--
+                       v *= 10
+               }
+
+               // round
+               h := 5.0
+               for i := 0; i < n; i++ {
+                       h /= 10
+               }
+               v += h
+               if v >= 10 {
+                       e++
+                       v /= 10
+               }
+       }
+
+       // format +d.dddd+edd
+       for i := 0; i < n; i++ {
+               s := int(v)
+               buf[i+2] = byte(s + '0')
+               v -= float64(s)
+               v *= 10
+       }
+       buf[1] = buf[2]
+       buf[2] = '.'
+
+       buf[n+2] = 'e'
+       buf[n+3] = '+'
+       if e < 0 {
+               e = -e
+               buf[n+3] = '-'
+       }
+
+       buf[n+4] = byte(e/100) + '0'
+       buf[n+5] = byte(e/10)%10 + '0'
+       buf[n+6] = byte(e%10) + '0'
+       gwrite(buf[:])
+}
+
+func printcomplex(c complex128) {
+       print("(", real(c), imag(c), "i)")
+}
+
+func printuint(v uint64) {
+       var buf [100]byte
+       i := len(buf)
+       for i--; i > 0; i-- {
+               buf[i] = byte(v%10 + '0')
+               if v < 10 {
+                       break
+               }
+               v /= 10
+       }
+       gwrite(buf[i:])
+}
+
+func printint(v int64) {
+       if v < 0 {
+               print("-")
+               v = -v
+       }
+       printuint(uint64(v))
+}
+
+func printhex(v uint64) {
+       const dig = "0123456789abcdef"
+       var buf [100]byte
+       i := len(buf)
+       for i--; i > 0; i-- {
+               buf[i] = dig[v%16]
+               if v < 16 {
+                       break
+               }
+               v /= 16
+       }
+       i--
+       buf[i] = 'x'
+       i--
+       buf[i] = '0'
+       gwrite(buf[i:])
+}
+
+func printpointer(p unsafe.Pointer) {
+       printhex(uint64(uintptr(p)))
+}
+
+func printstring(s string) {
+       if uintptr(len(s)) > maxstring {
+               gwrite(bytes("[string too long]"))
+               return
+       }
+       gwrite(bytes(s))
+}
+
+func printslice(s []byte) {
+       sp := (*slice)(unsafe.Pointer(&s))
+       print("[", len(s), "/", cap(s), "]")
+       printpointer(unsafe.Pointer(sp.array))
+}
+
+func printeface(e interface{}) {
+       ep := (*eface)(unsafe.Pointer(&e))
+       print("(", ep._type, ",", ep.data, ")")
+}
+
+func printiface(i fInterface) {
+       ip := (*iface)(unsafe.Pointer(&i))
+       print("(", ip.tab, ",", ip.data, ")")
+}
index 8263202e93c1b5d697758d84b69f8dd648dc83e4..194928373c4d82130e4caebece8d7b1766cd60ee 100644 (file)
@@ -1648,8 +1648,9 @@ goexit0(G *gp)
        gp->paniconfault = 0;
        gp->defer = nil; // should be true already but just in case.
        gp->panic = nil; // non-nil for Goexit during panic. points at stack-allocated data.
-       gp->writenbuf = 0;
-       gp->writebuf = nil;
+       gp->writebuf.array = nil;
+       gp->writebuf.len = 0;
+       gp->writebuf.cap = 0;
        gp->waitreason.str = nil;
        gp->waitreason.len = 0;
        gp->param = nil;
index 90cb3cbd7f92a0e54914bc39eb94bd02b3ee5c74..4dfc4f2c42b3fde26fe461a5ed29cd6df308c8ac 100644 (file)
@@ -297,7 +297,7 @@ struct      G
        M*      lockedm;
        int32   sig;
        int32   writenbuf;
-       byte*   writebuf;
+       Slice   writebuf;
        uintptr sigcode0;
        uintptr sigcode1;
        uintptr sigpc;
@@ -828,7 +828,7 @@ void        runtime·panicstring(int8*);
 bool   runtime·canpanic(G*);
 void   runtime·prints(int8*);
 void   runtime·printf(int8*, ...);
-int32  runtime·snprintf(byte*, int32, int8*, ...);
+void   runtime·snprintf(byte*, int32, int8*, ...);
 byte*  runtime·mchr(byte*, byte, byte*);
 int32  runtime·mcmp(byte*, byte*, uintptr);
 void   runtime·memmove(void*, void*, uintptr);
@@ -1063,19 +1063,19 @@ void    runtime·madvise(byte*, uintptr, int32);
 void   runtime·memclr(byte*, uintptr);
 void   runtime·setcallerpc(void*, void*);
 void*  runtime·getcallerpc(void*);
-void   runtime·printbool_c(bool);
-void   runtime·printbyte_c(int8);
-void   runtime·printfloat_c(float64);
-void   runtime·printint_c(int64);
-void   runtime·printiface_c(Iface);
-void   runtime·printeface_c(Eface);
-void   runtime·printstring_c(String);
-void   runtime·printpc_c(void*);
-void   runtime·printpointer_c(void*);
-void   runtime·printuint_c(uint64);
-void   runtime·printhex_c(uint64);
-void   runtime·printslice_c(Slice);
-void   runtime·printcomplex_c(Complex128);
+void   runtime·printbool(bool);
+void   runtime·printbyte(int8);
+void   runtime·printfloat(float64);
+void   runtime·printint(int64);
+void   runtime·printiface(Iface);
+void   runtime·printeface(Eface);
+void   runtime·printstring(String);
+void   runtime·printpc(void*);
+void   runtime·printpointer(void*);
+void   runtime·printuint(uint64);
+void   runtime·printhex(uint64);
+void   runtime·printslice(Slice);
+void   runtime·printcomplex(Complex128);
 
 /*
  * runtime go-called
index f69a0410fa3a766e2e6627affb91dd6af8b4b7f2..26126fcf9a49adcdad571add4fe3fdf49c6aa6a1 100644 (file)
@@ -173,7 +173,6 @@ func gogo(buf *gobuf)
 func gosave(buf *gobuf)
 func open(name *byte, mode, perm int32) int32
 func read(fd int32, p unsafe.Pointer, n int32) int32
-func write(fd uintptr, p unsafe.Pointer, n int32) int32
 func close(fd int32) int32
 func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
 func jmpdefer(fv *funcval, argp unsafe.Pointer)
@@ -205,6 +204,9 @@ func lock(lk *mutex)
 func unlock(lk *mutex)
 func purgecachedstats(c *mcache)
 
+//go:noescape
+func write(fd uintptr, p unsafe.Pointer, n int32) int32
+
 //go:noescape
 func cas(ptr *uint32, old, new uint32) bool
 
index 0ae40a64847a26bd8a9eb57b2668f902a9f216ad..5e937cbfb67414dab49f5682a8c87557c341aa63 100644 (file)
@@ -234,7 +234,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
                                        }
                                        if(i != 0)
                                                runtime·prints(", ");
-                                       runtime·printhex_c(((uintptr*)frame.argp)[i]);
+                                       runtime·printhex(((uintptr*)frame.argp)[i]);
                                }
                                runtime·prints(")\n");
                                line = runtime·funcline(f, tracepc, &file);
index 7c76daf4cfb3208ca25d25fa0400788fb329603c..f3ba702b9b886f130db9227ad503fb08acd48c66 100644 (file)
@@ -270,7 +270,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
                                        }
                                        if(i != 0)
                                                runtime·prints(", ");
-                                       runtime·printhex_c(((uintptr*)frame.argp)[i]);
+                                       runtime·printhex(((uintptr*)frame.argp)[i]);
                                }
                                runtime·prints(")\n");
                                line = runtime·funcline(f, tracepc, &file);