v = *(uint64*)a;
break;
}
- runtime·printint(v);
+ runtime·printint_c(v);
}
void
runtime·strprint(uintptr s, void *a)
{
USED(s);
- runtime·printstring(*(String*)a);
+ runtime·printstring_c(*(String*)a);
}
void
runtime·interprint(uintptr s, void *a)
{
USED(s);
- runtime·printiface(*(Iface*)a);
+ runtime·printiface_c(*(Iface*)a);
}
void
runtime·nilinterprint(uintptr s, void *a)
{
USED(s);
- runtime·printeface(*(Eface*)a);
+ runtime·printeface_c(*(Eface*)a);
}
void
<-result
}
}
+
+func TestPrintGC(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping in short mode")
+ }
+ defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+ done := make(chan bool)
+ go func() {
+ for {
+ select {
+ case <-done:
+ return
+ default:
+ runtime.GC()
+ }
+ }
+ }()
+ for i := 0; i < 1e4; i++ {
+ func() {
+ defer print("")
+ }()
+ }
+ close(done)
+}
#include "malloc.h"
#include "../../cmd/ld/textflag.h"
-func printiface(i Iface) {
- runtime·printf("(%p,%p)", i.tab, i.data);
-}
-
-func printeface(e Eface) {
- runtime·printf("(%p,%p)", e.type, e.data);
-}
-
static Itab* hash[1009];
static Lock ifacelock;
runtime·prints("mach error ");
runtime·prints(fn);
runtime·prints(": ");
- runtime·printint(r);
+ runtime·printint_c(r);
runtime·prints("\n");
runtime·throw("mach error");
}
runtime·prints("send:\t");
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
runtime·prints(" ");
- runtime·printpointer((void*)p[i]);
+ runtime·printpointer_c((void*)p[i]);
if(i%8 == 7)
runtime·prints("\n\t");
}
if(ret != 0){
if(DebugMach){
runtime·prints("mach_msg error ");
- runtime·printint(ret);
+ runtime·printint_c(ret);
runtime·prints("\n");
}
return ret;
runtime·prints("recv:\t");
for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
runtime·prints(" ");
- runtime·printpointer((void*)p[i]);
+ runtime·printpointer_c((void*)p[i]);
if(i%8 == 7)
runtime·prints("\n\t");
}
if(h->msgh_id != id+Reply){
if(DebugMach){
runtime·prints("mach_msg reply id mismatch ");
- runtime·printint(h->msgh_id);
+ runtime·printint_c(h->msgh_id);
runtime·prints(" != ");
- runtime·printint(id+Reply);
+ runtime·printint_c(id+Reply);
runtime·prints("\n");
}
return -303; // MIG_REPLY_MISMATCH
&& !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
if(DebugMach){
runtime·prints("mig result ");
- runtime·printint(c->code);
+ runtime·printint_c(c->code);
runtime·prints("\n");
}
return c->code;
if(h->msgh_size != rxsize){
if(DebugMach){
runtime·prints("mach_msg reply size mismatch ");
- runtime·printint(h->msgh_size);
+ runtime·printint_c(h->msgh_size);
runtime·prints(" != ");
- runtime·printint(rxsize);
+ runtime·printint_c(rxsize);
runtime·prints("\n");
}
return -307; // MIG_ARRAY_TOO_LARGE
return;
runtime·prints("umtx_wait addr=");
- runtime·printpointer(addr);
+ runtime·printpointer_c(addr);
runtime·prints(" val=");
- runtime·printint(val);
+ runtime·printint_c(val);
runtime·prints(" ret=");
- runtime·printint(ret);
+ runtime·printint_c(ret);
runtime·prints("\n");
*(int32*)0x1005 = 0x1005;
}
fail:
runtime·prints("umtx_wait addr=");
- runtime·printpointer(addr);
+ runtime·printpointer_c(addr);
runtime·prints(" val=");
- runtime·printint(val);
+ runtime·printint_c(val);
runtime·prints(" ret=");
- runtime·printint(ret);
+ runtime·printint_c(ret);
runtime·prints("\n");
*(int32*)0x1005 = 0x1005;
}
int32 i;
for(i=0; i<n; i++) {
- runtime·printpointer((byte*)(p[i]>>4));
- runtime·printpointer((byte*)(p[i]&0xf));
+ runtime·printpointer_c((byte*)(p[i]>>4));
+ runtime·printpointer_c((byte*)(p[i]&0xf));
if((i&15) == 15)
runtime·prints("\n");
else
v = (byte*)arg;
switch(*p) {
case 'a':
- runtime·printslice(*(Slice*)v);
+ runtime·printslice_c(*(Slice*)v);
break;
case 'c':
- runtime·printbyte(*(int8*)v);
+ runtime·printbyte_c(*(int8*)v);
break;
case 'd':
- runtime·printint(*(int32*)v);
+ runtime·printint_c(*(int32*)v);
break;
case 'D':
- runtime·printint(*(int64*)v);
+ runtime·printint_c(*(int64*)v);
break;
case 'e':
- runtime·printeface(*(Eface*)v);
+ runtime·printeface_c(*(Eface*)v);
break;
case 'f':
- runtime·printfloat(*(float64*)v);
+ runtime·printfloat_c(*(float64*)v);
break;
case 'C':
- runtime·printcomplex(*(Complex128*)v);
+ runtime·printcomplex_c(*(Complex128*)v);
break;
case 'i':
- runtime·printiface(*(Iface*)v);
+ runtime·printiface_c(*(Iface*)v);
break;
case 'p':
- runtime·printpointer(*(void**)v);
+ runtime·printpointer_c(*(void**)v);
break;
case 's':
runtime·prints(*(int8**)v);
break;
case 'S':
- runtime·printstring(*(String*)v);
+ runtime·printstring_c(*(String*)v);
break;
case 't':
- runtime·printbool(*(bool*)v);
+ runtime·printbool_c(*(bool*)v);
break;
case 'U':
- runtime·printuint(*(uint64*)v);
+ runtime·printuint_c(*(uint64*)v);
break;
case 'x':
- runtime·printhex(*(uint32*)v);
+ runtime·printhex_c(*(uint32*)v);
break;
case 'X':
- runtime·printhex(*(uint64*)v);
+ runtime·printhex_c(*(uint64*)v);
break;
}
arg += siz;
//runtime·unlock(&debuglock);
}
-#pragma textflag NOSPLIT
-void
-runtime·goprintf(String s, ...)
+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((int8*)s.str, (byte*)(&s+1));
+ 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(void *p)
+runtime·printpc_c(void *p)
{
runtime·prints("PC=");
- runtime·printhex((uint64)runtime·getcallerpc(p));
+ runtime·printhex_c((uint64)runtime·getcallerpc(p));
}
void
-runtime·printbool(bool v)
+runtime·printbool_c(bool v)
{
if(v) {
gwrite((byte*)"true", 4);
}
void
-runtime·printbyte(int8 c)
+runtime·printbyte_c(int8 c)
{
gwrite(&c, 1);
}
void
-runtime·printfloat(float64 v)
+runtime·printfloat_c(float64 v)
{
byte buf[20];
int32 e, s, i, n;
}
void
-runtime·printcomplex(Complex128 v)
+runtime·printcomplex_c(Complex128 v)
{
gwrite("(", 1);
- runtime·printfloat(v.real);
- runtime·printfloat(v.imag);
+ runtime·printfloat_c(v.real);
+ runtime·printfloat_c(v.imag);
gwrite("i)", 2);
}
void
-runtime·printuint(uint64 v)
+runtime·printuint_c(uint64 v)
{
byte buf[100];
int32 i;
}
void
-runtime·printint(int64 v)
+runtime·printint_c(int64 v)
{
if(v < 0) {
gwrite("-", 1);
v = -v;
}
- runtime·printuint(v);
+ runtime·printuint_c(v);
}
void
-runtime·printhex(uint64 v)
+runtime·printhex_c(uint64 v)
{
static int8 *dig = "0123456789abcdef";
byte buf[100];
}
void
-runtime·printpointer(void *p)
+runtime·printpointer_c(void *p)
{
- runtime·printhex((uintptr)p);
+ runtime·printhex_c((uintptr)p);
}
void
-runtime·printstring(String v)
+runtime·printstring_c(String v)
{
if(v.len > runtime·maxstring) {
gwrite("[string too long]", 17);
}
void
-runtime·printsp(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)
{
- gwrite(" ", 1);
+ runtime·printhex_c(g->m->scalararg[0]);
}
void
-runtime·printnl(void)
+runtime·printfloat_m(void)
{
- gwrite("\n", 1);
+ runtime·printfloat_c(*(float64*)(&g->m->scalararg[0]));
}
--- /dev/null
+// 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 byte
+var printuint_m byte
+var printhex_m byte
+var printfloat_m byte
+
+func printstring(s string) {
+ mp := acquirem()
+ mp.scalararg[0] = uint(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] = uint(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])
+}
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);
/*
* runtime go-called
*/
-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);
void runtime·newstackcall(FuncVal*, byte*, uint32);
void reflect·call(FuncVal*, byte*, uint32, uint32);
void runtime·panic(Eface);
+++ /dev/null
-// 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.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-
-void
-runtime·printslice_m(G *gp)
-{
- void *array;
- uintptr len, cap;
-
- array = g->m->ptrarg[0];
- g->m->ptrarg[0] = nil;
- len = g->m->scalararg[0];
- cap = g->m->scalararg[1];
-
- runtime·prints("[");
- runtime·printint(len);
- runtime·prints("/");
- runtime·printint(cap);
- runtime·prints("]");
- runtime·printpointer(array);
-
- runtime·gogo(&gp->sched);
-}
memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n))
return n
}
-
-var printslice_m byte
-
-func printslice(a sliceStruct) {
- mp := acquirem()
- mp.ptrarg[0] = a.array
- mp.scalararg[0] = uint(a.len)
- mp.scalararg[1] = uint(a.cap)
- mcall(&printslice_m)
- releasem(mp)
-}
}
if(i != 0)
runtime·prints(", ");
- runtime·printhex(((uintptr*)frame.argp)[i]);
+ runtime·printhex_c(((uintptr*)frame.argp)[i]);
}
runtime·prints(")\n");
line = runtime·funcline(f, tracepc, &file);
}
if(i != 0)
runtime·prints(", ");
- runtime·printhex(((uintptr*)frame.argp)[i]);
+ runtime·printhex_c(((uintptr*)frame.argp)[i]);
}
runtime·prints(")\n");
line = runtime·funcline(f, tracepc, &file);
--- /dev/null
+// cmpout
+
+// 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.
+
+// Test internal print routines that are generated
+// by the print builtin. This test is not exhaustive,
+// we're just checking that the formatting is correct.
+
+package main
+
+func main() {
+ println((interface{})(nil)) // printeface
+ println((interface { // printiface
+ f()
+ })(nil))
+ println((map[int]int)(nil)) // printpointer
+ println(([]int)(nil)) // printslice
+ println(int64(-7)) // printint
+ println(uint64(7)) // printuint
+ println(8.0) // printfloat
+ println(complex(9.0, 10.0)) // printcomplex
+ println(true) // printbool
+ println(false) // printbool
+ println("hello") // printstring
+ println("one", "two") // printsp
+
+ // test goprintf
+ defer println((interface{})(nil))
+ defer println((interface{f()})(nil))
+ defer println((map[int]int)(nil))
+ defer println(([]int)(nil))
+ defer println(int64(-11))
+ defer println(uint64(12))
+ defer println(13.0)
+ defer println(complex(14.0, 15.0))
+ defer println(true)
+ defer println(false)
+ defer println("hello")
+ defer println("one", "two")
+}
--- /dev/null
+(0x0,0x0)
+(0x0,0x0)
+0x0
+[0/0]0x0
+-7
+7
++8.000000e+000
+(+9.000000e+000+1.000000e+001i)
+true
+false
+hello
+one two
+one two
+hello
+false
+true
+(+1.400000e+001+1.500000e+001i)
++1.300000e+001
+12
+-11
+[0/0]0x0
+0x0
+(0x0,0x0)
+(0x0,0x0)