From 597b266eafe7d63e9be8da1c1b4813bd2998a11c Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 28 Aug 2014 23:26:40 -0400 Subject: [PATCH] runtime: convert print.c to Go LGTM=iant R=golang-codereviews, iant CC=dvyukov, golang-codereviews, khr, r https://golang.org/cl/135930043 --- src/pkg/runtime/alg.goc | 8 +- src/pkg/runtime/mprof.go | 6 +- src/pkg/runtime/os_darwin.c | 18 +- src/pkg/runtime/os_dragonfly.c | 6 +- src/pkg/runtime/os_freebsd.c | 6 +- src/pkg/runtime/panic.c | 7 +- src/pkg/runtime/print.c | 443 -------------------------------- src/pkg/runtime/print.go | 111 -------- src/pkg/runtime/print1.go | 338 ++++++++++++++++++++++++ src/pkg/runtime/proc.c | 5 +- src/pkg/runtime/runtime.h | 30 +-- src/pkg/runtime/stubs.go | 4 +- src/pkg/runtime/traceback_arm.c | 2 +- src/pkg/runtime/traceback_x86.c | 2 +- 14 files changed, 387 insertions(+), 599 deletions(-) delete mode 100644 src/pkg/runtime/print.c delete mode 100644 src/pkg/runtime/print.go create mode 100644 src/pkg/runtime/print1.go diff --git a/src/pkg/runtime/alg.goc b/src/pkg/runtime/alg.goc index aa0c79d476..0c3b3cd4ff 100644 --- a/src/pkg/runtime/alg.goc +++ b/src/pkg/runtime/alg.goc @@ -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 diff --git a/src/pkg/runtime/mprof.go b/src/pkg/runtime/mprof.go index 9ee37d0bee..78384f8117 100644 --- a/src/pkg/runtime/mprof.go +++ b/src/pkg/runtime/mprof.go @@ -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 { diff --git a/src/pkg/runtime/os_darwin.c b/src/pkg/runtime/os_darwin.c index 84b69b047a..c660fb8c10 100644 --- a/src/pkg/runtime/os_darwin.c +++ b/src/pkg/runtime/os_darwin.c @@ -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; imsgh_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; imsgh_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 diff --git a/src/pkg/runtime/os_dragonfly.c b/src/pkg/runtime/os_dragonfly.c index 1132f5741d..65121d3273 100644 --- a/src/pkg/runtime/os_dragonfly.c +++ b/src/pkg/runtime/os_dragonfly.c @@ -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; } diff --git a/src/pkg/runtime/os_freebsd.c b/src/pkg/runtime/os_freebsd.c index 20f71c41e8..d360f6712d 100644 --- a/src/pkg/runtime/os_freebsd.c +++ b/src/pkg/runtime/os_freebsd.c @@ -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; } diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index 00c780bf55..39027a77c2 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c @@ -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 index 57dfdabb6d..0000000000 --- a/src/pkg/runtime/print.c +++ /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>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= 10) { - e++; - v /= 10; - } - } - - // format +d.dddd+edd - buf[0] = '+'; - if(s) - buf[0] = '-'; - for(i=0; i0; 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 index fd79bc8dd6..0000000000 --- a/src/pkg/runtime/print.go +++ /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 index 0000000000..94ba9e4733 --- /dev/null +++ b/src/pkg/runtime/print1.go @@ -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, ")") +} diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 8263202e93..194928373c 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -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; diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 90cb3cbd7f..4dfc4f2c42 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -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 diff --git a/src/pkg/runtime/stubs.go b/src/pkg/runtime/stubs.go index f69a0410fa..26126fcf9a 100644 --- a/src/pkg/runtime/stubs.go +++ b/src/pkg/runtime/stubs.go @@ -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 diff --git a/src/pkg/runtime/traceback_arm.c b/src/pkg/runtime/traceback_arm.c index 0ae40a6484..5e937cbfb6 100644 --- a/src/pkg/runtime/traceback_arm.c +++ b/src/pkg/runtime/traceback_arm.c @@ -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); diff --git a/src/pkg/runtime/traceback_x86.c b/src/pkg/runtime/traceback_x86.c index 7c76daf4cf..f3ba702b9b 100644 --- a/src/pkg/runtime/traceback_x86.c +++ b/src/pkg/runtime/traceback_x86.c @@ -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); -- 2.48.1