diff options
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 71 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 31 | ||||
-rw-r--r-- | libgo/Makefile.am | 1 | ||||
-rw-r--r-- | libgo/Makefile.in | 11 | ||||
-rw-r--r-- | libgo/go/runtime/print.go | 28 | ||||
-rw-r--r-- | libgo/go/runtime/runtime2.go | 22 | ||||
-rw-r--r-- | libgo/go/runtime/stubs.go | 3 | ||||
-rw-r--r-- | libgo/runtime/mprof.goc | 12 | ||||
-rw-r--r-- | libgo/runtime/panic.c | 9 | ||||
-rw-r--r-- | libgo/runtime/print.c | 301 | ||||
-rw-r--r-- | libgo/runtime/proc.c | 5 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 29 |
13 files changed, 174 insertions, 351 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e22f79e4766..c987dc90eb7 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f3658aea2493c7f1c4a72502f9e7da562c7764c4 +ecf9b645cefc5c3b4e6339adeb452b2d8642cf3e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 36000ead4ae..4f8a519f4fd 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7018,6 +7018,26 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, } } break; + + case BUILTIN_PRINT: + case BUILTIN_PRINTLN: + // Force all the arguments into temporary variables, so that we + // don't try to evaluate something while holding the print lock. + if (this->args() == NULL) + break; + for (Expression_list::iterator pa = this->args()->begin(); + pa != this->args()->end(); + ++pa) + { + if (!(*pa)->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, *pa, loc); + inserter->insert(temp); + *pa = Expression::make_temporary_reference(temp, loc); + } + } + break; } return this; @@ -8336,7 +8356,9 @@ Builtin_call_expression::do_get_backend(Translate_context* context) case BUILTIN_PRINTLN: { const bool is_ln = this->code_ == BUILTIN_PRINTLN; - Expression* print_stmts = NULL; + + Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK, + location, 0); const Expression_list* call_args = this->args(); if (call_args != NULL) @@ -8348,8 +8370,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context) if (is_ln && p != call_args->begin()) { Expression* print_space = - Runtime::make_call(Runtime::PRINT_SPACE, - this->location(), 0); + Runtime::make_call(Runtime::PRINTSP, location, 0); print_stmts = Expression::make_compound(print_stmts, print_space, @@ -8360,51 +8381,51 @@ Builtin_call_expression::do_get_backend(Translate_context* context) Type* type = arg->type(); Runtime::Function code; if (type->is_string_type()) - code = Runtime::PRINT_STRING; + code = Runtime::PRINTSTRING; else if (type->integer_type() != NULL && type->integer_type()->is_unsigned()) { Type* itype = Type::lookup_integer_type("uint64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_UINT64; + code = Runtime::PRINTUINT; } else if (type->integer_type() != NULL) { Type* itype = Type::lookup_integer_type("int64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_INT64; + code = Runtime::PRINTINT; } else if (type->float_type() != NULL) { Type* dtype = Type::lookup_float_type("float64"); arg = Expression::make_cast(dtype, arg, location); - code = Runtime::PRINT_DOUBLE; + code = Runtime::PRINTFLOAT; } else if (type->complex_type() != NULL) { Type* ctype = Type::lookup_complex_type("complex128"); arg = Expression::make_cast(ctype, arg, location); - code = Runtime::PRINT_COMPLEX; + code = Runtime::PRINTCOMPLEX; } else if (type->is_boolean_type()) - code = Runtime::PRINT_BOOL; + code = Runtime::PRINTBOOL; else if (type->points_to() != NULL || type->channel_type() != NULL || type->map_type() != NULL || type->function_type() != NULL) { arg = Expression::make_cast(type, arg, location); - code = Runtime::PRINT_POINTER; + code = Runtime::PRINTPOINTER; } else if (type->interface_type() != NULL) { if (type->interface_type()->is_empty()) - code = Runtime::PRINT_EMPTY_INTERFACE; + code = Runtime::PRINTEFACE; else - code = Runtime::PRINT_INTERFACE; + code = Runtime::PRINTIFACE; } else if (type->is_slice_type()) - code = Runtime::PRINT_SLICE; + code = Runtime::PRINTSLICE; else { go_assert(saw_errors()); @@ -8412,30 +8433,22 @@ Builtin_call_expression::do_get_backend(Translate_context* context) } Expression* call = Runtime::make_call(code, location, 1, arg); - if (print_stmts == NULL) - print_stmts = call; - else - print_stmts = Expression::make_compound(print_stmts, call, - location); + print_stmts = Expression::make_compound(print_stmts, call, + location); } } if (is_ln) { Expression* print_nl = - Runtime::make_call(Runtime::PRINT_NL, location, 0); - if (print_stmts == NULL) - print_stmts = print_nl; - else - print_stmts = Expression::make_compound(print_stmts, print_nl, - location); + Runtime::make_call(Runtime::PRINTNL, location, 0); + print_stmts = Expression::make_compound(print_stmts, print_nl, + location); } - // There aren't any arguments to the print builtin. The compiler - // issues a warning for this so we should avoid getting the backend - // representation for this call. Instead, perform a no-op. - if (print_stmts == NULL) - return context->backend()->boolean_constant_expression(false); + Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK, + location, 0); + print_stmts = Expression::make_compound(print_stmts, unlock, location); return print_stmts->get_backend(context); } diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 168f473933f..e7edfa652f3 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -299,42 +299,47 @@ DEF_GO_RUNTIME(INTERFACE_EMPTY_COMPARE, "__go_interface_empty_compare", P2(IFACE, EFACE), R1(INT)) +// Lock the printer (for print/println). +DEF_GO_RUNTIME(PRINTLOCK, "runtime.printlock", P0(), R0()) + +// Unlock the printer (for print/println). +DEF_GO_RUNTIME(PRINTUNLOCK, "runtime.printunlock", P0(), R0()) + // Print a string (for print/println). -DEF_GO_RUNTIME(PRINT_STRING, "__go_print_string", P1(STRING), R0()) +DEF_GO_RUNTIME(PRINTSTRING, "runtime.printstring", P1(STRING), R0()) // Print a uint64 (for print/println). -DEF_GO_RUNTIME(PRINT_UINT64, "__go_print_uint64", P1(UINT64), R0()) +DEF_GO_RUNTIME(PRINTUINT, "runtime.printuint", P1(UINT64), R0()) // Print a int64 (for print/println). -DEF_GO_RUNTIME(PRINT_INT64, "__go_print_int64", P1(INT64), R0()) +DEF_GO_RUNTIME(PRINTINT, "runtime.printint", P1(INT64), R0()) // Print a float64 (for print/println). -DEF_GO_RUNTIME(PRINT_DOUBLE, "__go_print_double", P1(FLOAT64), R0()) +DEF_GO_RUNTIME(PRINTFLOAT, "runtime.printfloat", P1(FLOAT64), R0()) // Print a complex128 (for print/println). -DEF_GO_RUNTIME(PRINT_COMPLEX, "__go_print_complex", P1(COMPLEX128), R0()) +DEF_GO_RUNTIME(PRINTCOMPLEX, "runtime.printcomplex", P1(COMPLEX128), R0()) // Print a bool (for print/println). -DEF_GO_RUNTIME(PRINT_BOOL, "__go_print_bool", P1(BOOL), R0()) +DEF_GO_RUNTIME(PRINTBOOL, "runtime.printbool", P1(BOOL), R0()) // Print a pointer/map/channel/function (for print/println). -DEF_GO_RUNTIME(PRINT_POINTER, "__go_print_pointer", P1(POINTER), R0()) +DEF_GO_RUNTIME(PRINTPOINTER, "runtime.printpointer", P1(POINTER), R0()) // Print an empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_EMPTY_INTERFACE, "__go_print_empty_interface", - P1(EFACE), R0()) +DEF_GO_RUNTIME(PRINTEFACE, "runtime.printeface", P1(EFACE), R0()) // Print a non-empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_INTERFACE, "__go_print_interface", P1(IFACE), R0()) +DEF_GO_RUNTIME(PRINTIFACE, "runtime.printiface", P1(IFACE), R0()) // Print a slice (for print/println). -DEF_GO_RUNTIME(PRINT_SLICE, "__go_print_slice", P1(SLICE), R0()) +DEF_GO_RUNTIME(PRINTSLICE, "runtime.printslice", P1(SLICE), R0()) // Print a space (for println). -DEF_GO_RUNTIME(PRINT_SPACE, "__go_print_space", P0(), R0()) +DEF_GO_RUNTIME(PRINTSP, "runtime.printsp", P0(), R0()) // Print a newline (for println). -DEF_GO_RUNTIME(PRINT_NL, "__go_print_nl", P0(), R0()) +DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0()) // Used for field tracking for data analysis. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index bc47be6773a..b7c3e1810dc 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -474,7 +474,6 @@ runtime_files = \ runtime/go-new.c \ runtime/go-nosys.c \ runtime/go-panic.c \ - runtime/go-print.c \ runtime/go-recover.c \ runtime/go-reflect-call.c \ runtime/go-rune.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 5806d75f77b..e6571cd6d0c 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -251,7 +251,7 @@ am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \ go-interface-val-compare.lo go-make-slice.lo go-matherr.lo \ go-memclr.lo go-memcmp.lo go-memequal.lo go-memmove.lo \ go-nanotime.lo go-now.lo go-new.lo go-nosys.lo go-panic.lo \ - go-print.lo go-recover.lo go-reflect-call.lo go-rune.lo \ + go-recover.lo go-reflect-call.lo go-rune.lo \ go-runtime-error.lo go-setenv.lo go-signal.lo go-strcmp.lo \ go-string-to-byte-array.lo go-string-to-int-array.lo \ go-strplus.lo go-strslice.lo go-traceback.lo \ @@ -875,7 +875,6 @@ runtime_files = \ runtime/go-new.c \ runtime/go-nosys.c \ runtime/go-panic.c \ - runtime/go-print.c \ runtime/go-recover.c \ runtime/go-reflect-call.c \ runtime/go-rune.c \ @@ -1600,7 +1599,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-nosys.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-now.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-panic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-print.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-recover.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-reflect-call.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-rune.Plo@am__quote@ @@ -1979,13 +1977,6 @@ go-panic.lo: runtime/go-panic.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-panic.lo `test -f 'runtime/go-panic.c' || echo '$(srcdir)/'`runtime/go-panic.c -go-print.lo: runtime/go-print.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-print.lo -MD -MP -MF $(DEPDIR)/go-print.Tpo -c -o go-print.lo `test -f 'runtime/go-print.c' || echo '$(srcdir)/'`runtime/go-print.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-print.Tpo $(DEPDIR)/go-print.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-print.c' object='go-print.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-print.lo `test -f 'runtime/go-print.c' || echo '$(srcdir)/'`runtime/go-print.c - go-recover.lo: runtime/go-recover.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-recover.lo -MD -MP -MF $(DEPDIR)/go-recover.Tpo -c -o go-recover.lo `test -f 'runtime/go-recover.c' || echo '$(srcdir)/'`runtime/go-recover.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-recover.Tpo $(DEPDIR)/go-recover.Plo diff --git a/libgo/go/runtime/print.go b/libgo/go/runtime/print.go index 97d595fb2fb..371cec50587 100644 --- a/libgo/go/runtime/print.go +++ b/libgo/go/runtime/print.go @@ -2,12 +2,32 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build ignore - package runtime import "unsafe" +// For gccgo, use go:linkname to rename compiler-called functions to +// themselves, so that the compiler will export them. +// +//go:linkname printbool runtime.printbool +//go:linkname printfloat runtime.printfloat +//go:linkname printint runtime.printint +//go:linkname printhex runtime.printhex +//go:linkname printuint runtime.printuint +//go:linkname printcomplex runtime.printcomplex +//go:linkname printstring runtime.printstring +//go:linkname printpointer runtime.printpointer +//go:linkname printiface runtime.printiface +//go:linkname printeface runtime.printeface +//go:linkname printslice runtime.printslice +//go:linkname printnl runtime.printnl +//go:linkname printsp runtime.printsp +//go:linkname printlock runtime.printlock +//go:linkname printunlock runtime.printunlock +// Temporary for C code to call: +//go:linkname gwrite runtime.gwrite +//go:linkname printhex runtime.printhex + // The compiler knows that a print of a value of this type // should use printhex instead of printuint (decimal). type hex uint64 @@ -201,10 +221,6 @@ func printpointer(p unsafe.Pointer) { } func printstring(s string) { - if uintptr(len(s)) > maxstring { - gwrite(bytes("[string too long]")) - return - } gwrite(bytes(s)) } diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index 688efcdcb83..25b5b79de20 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -347,20 +347,14 @@ type g struct { tracelastp puintptr // last P emitted an event for this goroutine lockedm *m sig uint32 - - // Temporary gccgo field. - writenbuf int32 - // Not for gccgo yet: writebuf []byte - // Temporary different type for gccgo. - writebuf *byte - - sigcode0 uintptr - sigcode1 uintptr - sigpc uintptr - gopc uintptr // pc of go statement that created this goroutine - startpc uintptr // pc of goroutine function - racectx uintptr - waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr); in lock order + writebuf []byte + sigcode0 uintptr + sigcode1 uintptr + sigpc uintptr + gopc uintptr // pc of go statement that created this goroutine + startpc uintptr // pc of goroutine function + racectx uintptr + waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr); in lock order // Not for gccgo: cgoCtxt []uintptr // cgo traceback context // Per-G GC state diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go index c687cbf6220..f014610841f 100644 --- a/libgo/go/runtime/stubs.go +++ b/libgo/go/runtime/stubs.go @@ -445,6 +445,3 @@ func releaseSudog(s *sudog) { // Temporary hack for gccgo until we port the garbage collector. func typeBitsBulkBarrier(typ *_type, p, size uintptr) {} - -// Temporary for gccgo until we port print.go. -type hex uint64 diff --git a/libgo/runtime/mprof.goc b/libgo/runtime/mprof.goc index bb3f9e8c8e0..be2c17eb22d 100644 --- a/libgo/runtime/mprof.goc +++ b/libgo/runtime/mprof.goc @@ -419,17 +419,19 @@ func Stack(b Slice, all bool) (n int) { n = 0; else{ G* g = runtime_g(); - g->writebuf = (byte*)b.__values; - g->writenbuf = b.__count; + g->writebuf.__values = b.__values; + g->writebuf.__count = 0; + g->writebuf.__capacity = b.__count; USED(pc); runtime_goroutineheader(g); runtime_traceback(); runtime_printcreatedby(g); if(all) runtime_tracebackothers(g); - n = b.__count - g->writenbuf; - g->writebuf = nil; - g->writenbuf = 0; + n = g->writebuf.__count; + g->writebuf.__values = nil; + g->writebuf.__count = 0; + g->writebuf.__capacity = 0; } if(all) { diff --git a/libgo/runtime/panic.c b/libgo/runtime/panic.c index d493b54a509..cd1ae9673c6 100644 --- a/libgo/runtime/panic.c +++ b/libgo/runtime/panic.c @@ -72,9 +72,11 @@ __go_rundefer(void) void runtime_startpanic(void) { + G *g; M *m; - m = runtime_m(); + g = runtime_g(); + m = g->m; if(runtime_mheap.cachealloc.size == 0) { // very early runtime_printf("runtime: panic before malloc heap initialized\n"); m->mallocing = 1; // tell rest of panic not to try to malloc @@ -83,8 +85,9 @@ runtime_startpanic(void) switch(m->dying) { case 0: m->dying = 1; - if(runtime_g() != nil) - runtime_g()->writebuf = nil; + g->writebuf.__values = nil; + g->writebuf.__count = 0; + g->writebuf.__capacity = 0; runtime_xadd(&runtime_panicking, 1); runtime_lock(&paniclk); if(runtime_debug.schedtrace > 0 || runtime_debug.scheddetail > 0) diff --git a/libgo/runtime/print.c b/libgo/runtime/print.c index 69b1f81fb42..4da879620c7 100644 --- a/libgo/runtime/print.c +++ b/libgo/runtime/print.c @@ -9,58 +9,60 @@ #include "array.h" #include "go-type.h" -//static Lock debuglock; +extern void runtime_printlock(void) + __asm__(GOSYM_PREFIX "runtime.printlock"); +extern void runtime_printunlock(void) + __asm__(GOSYM_PREFIX "runtime.printunlock"); +extern void gwrite(Slice) + __asm__(GOSYM_PREFIX "runtime.gwrite"); +extern void runtime_printint(int64) + __asm__(GOSYM_PREFIX "runtime.printint"); +extern void runtime_printuint(uint64) + __asm__(GOSYM_PREFIX "runtime.printuint"); +extern void runtime_printhex(uint64) + __asm__(GOSYM_PREFIX "runtime.printhex"); +extern void runtime_printfloat(float64) + __asm__(GOSYM_PREFIX "runtime.printfloat"); +extern void runtime_printcomplex(complex double) + __asm__(GOSYM_PREFIX "runtime.printcomplex"); +extern void runtime_printbool(_Bool) + __asm__(GOSYM_PREFIX "runtime.printbool"); +extern void runtime_printstring(String) + __asm__(GOSYM_PREFIX "runtime.printstring"); +extern void runtime_printpointer(void *) + __asm__(GOSYM_PREFIX "runtime.printpointer"); +extern void runtime_printslice(Slice) + __asm__(GOSYM_PREFIX "runtime.printslice"); +extern void runtime_printeface(Eface) + __asm__(GOSYM_PREFIX "runtime.printeface"); +extern void runtime_printiface(Iface) + __asm__(GOSYM_PREFIX "runtime.printiface"); // Clang requires this function to not be inlined (see below). static void go_vprintf(const char*, va_list) __attribute__((noinline)); -// write to goroutine-local buffer if diverting output, -// or else standard error. static void -gwrite(const void *v, intgo n) +runtime_prints(const char *s) { - G* g = runtime_g(); - - if(g == nil || g->writebuf == nil) { - // Avoid -D_FORTIFY_SOURCE problems. - int rv __attribute__((unused)); - - rv = runtime_write(2, v, n); - return; - } - - if(g->writenbuf == 0) - return; + Slice sl; - if(n > g->writenbuf) - n = g->writenbuf; - runtime_memmove(g->writebuf, v, n); - g->writebuf += n; - g->writenbuf -= n; + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &s, sizeof(char*)); + sl.__count = runtime_findnull((const byte*)s); + sl.__capacity = sl.__count; + gwrite(sl); } -void -runtime_dump(byte *p, int32 n) +static void +runtime_printbyte(int8 c) { - int32 i; - - for(i=0; i<n; i++) { - runtime_printpointer((byte*)(uintptr)(p[i]>>4)); - runtime_printpointer((byte*)(uintptr)(p[i]&0xf)); - if((i&15) == 15) - runtime_prints("\n"); - else - runtime_prints(" "); - } - if(n & 15) - runtime_prints("\n"); -} + Slice sl; -void -runtime_prints(const char *s) -{ - gwrite(s, runtime_findnull((const byte*)s)); + sl.__values = &c; + sl.__count = 1; + sl.__capacity = 1; + gwrite(sl); } #if defined (__clang__) && (defined (__i386__) || defined (__x86_64__)) @@ -104,15 +106,17 @@ runtime_snprintf(byte *buf, int32 n, const char *s, ...) va_list va; int32 m; - g->writebuf = buf; - g->writenbuf = n-1; + g->writebuf.__values = buf; + g->writebuf.__count = 0; + g->writebuf.__capacity = n-1; va_start(va, s); go_vprintf(s, va); va_end(va); - *g->writebuf = '\0'; - m = g->writebuf - buf; - g->writenbuf = 0; - g->writebuf = nil; + m = g->writebuf.__count; + ((byte*)g->writebuf.__values)[m] = '\0'; + g->writebuf.__values = nil; + g->writebuf.__count = 0; + g->writebuf.__capacity = 0; return m; } @@ -122,15 +126,21 @@ static void go_vprintf(const char *s, va_list va) { const char *p, *lp; + Slice sl; - //runtime_lock(&debuglock); + runtime_printlock(); lp = p = s; for(; *p; p++) { if(*p != '%') continue; - if(p > lp) - gwrite(lp, p-lp); + if(p > lp) { + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &lp, sizeof(char*)); + sl.__count = p - lp; + sl.__capacity = p - lp; + gwrite(sl); + } p++; switch(*p) { case 'a': @@ -181,192 +191,13 @@ go_vprintf(const char *s, va_list va) } lp = p+1; } - if(p > lp) - gwrite(lp, p-lp); - - //runtime_unlock(&debuglock); -} - -void -runtime_printpc(void *p __attribute__ ((unused))) -{ - runtime_prints("PC="); - runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p)); -} - -void -runtime_printbool(_Bool v) -{ - if(v) { - gwrite("true", 4); - return; - } - gwrite("false", 5); -} - -void -runtime_printbyte(int8 c) -{ - gwrite(&c, 1); -} - -void -runtime_printfloat(double v) -{ - byte buf[20]; - int32 e, s, i, n; - float64 h; - - if(ISNAN(v)) { - gwrite("NaN", 3); - return; - } - if(isinf(v)) { - if(signbit(v)) { - gwrite("-Inf", 4); - } else { - gwrite("+Inf", 4); - } - return; + if(p > lp) { + // Use memcpy to avoid const-cast warning. + memcpy(&sl.__values, &lp, sizeof(char*)); + sl.__count = p - lp; + sl.__capacity = p - lp; + gwrite(sl); } - n = 7; // digits printed - e = 0; // exp - s = 0; // sign - if(v == 0) { - if(isinf(1/v) && 1/v < 0) - 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(complex double v) -{ - gwrite("(", 1); - runtime_printfloat(creal(v)); - runtime_printfloat(cimag(v)); - gwrite("i)", 2); -} - -void -runtime_printuint(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(int64 v) -{ - if(v < 0) { - gwrite("-", 1); - v = -v; - } - runtime_printuint(v); -} - -void -runtime_printhex(uint64 v) -{ - static const char *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(void *p) -{ - runtime_printhex((uintptr)p); -} - -void -runtime_printstring(String v) -{ - // if(v.len > runtime_maxstring) { - // gwrite("[string too long]", 17); - // return; - // } - if(v.len > 0) - gwrite(v.str, v.len); -} - -void -__go_print_space(void) -{ - gwrite(" ", 1); -} - -void -__go_print_nl(void) -{ - gwrite("\n", 1); + runtime_printunlock(); } diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 02b62bef44e..98c18a726af 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -2037,8 +2037,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.__values = nil; + gp->writebuf.__count = 0; + gp->writebuf.__capacity = 0; gp->waitreason = runtime_gostringnocopy(nil); gp->param = nil; m->curg = nil; diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 6f96b2bde6c..3304215e9ed 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -309,7 +309,6 @@ extern bool runtime_isarchive; #define runtime_strstr(s1, s2) __builtin_strstr((s1), (s2)) intgo runtime_findnull(const byte*); intgo runtime_findnullw(const uint16*); -void runtime_dump(byte*, int32); void runtime_gogo(G*); struct __go_func_type; @@ -324,7 +323,6 @@ void runtime_goenvs_unix(void) void runtime_throw(const char*) __attribute__ ((noreturn)); void runtime_panicstring(const char*) __attribute__ ((noreturn)); bool runtime_canpanic(G*); -void runtime_prints(const char*); void runtime_printf(const char*, ...); int32 runtime_snprintf(byte*, int32, const char*, ...); #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s)) @@ -534,35 +532,8 @@ void __wrap_rtems_task_variable_add(void **); #endif /* - * Names generated by gccgo. - */ -#define runtime_printbool __go_print_bool -#define runtime_printfloat __go_print_double -#define runtime_printint __go_print_int64 -#define runtime_printiface __go_print_interface -#define runtime_printeface __go_print_empty_interface -#define runtime_printstring __go_print_string -#define runtime_printpointer __go_print_pointer -#define runtime_printuint __go_print_uint64 -#define runtime_printslice __go_print_slice -#define runtime_printcomplex __go_print_complex - -/* * runtime go-called */ -void runtime_printbool(_Bool); -void runtime_printbyte(int8); -void runtime_printfloat(double); -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(complex double); void reflect_call(const struct __go_func_type *, FuncVal *, _Bool, _Bool, void **, void **) __asm__ (GOSYM_PREFIX "reflect.call"); |