runtime: copy print/println support from Go 1.7
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 10 Oct 2016 23:13:39 +0000 (23:13 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 10 Oct 2016 23:13:39 +0000 (23:13 +0000)
    Update the compiler to use the new names.  Add calls to printlock and
    printunlock around print statements.  Move expression evaluation before
    the call to printlock.  Update g's writebuf field to a slice, and adjust
    C code accordingly.

    Reviewed-on: https://go-review.googlesource.com/30717

From-SVN: r240956

13 files changed:
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/runtime.def
libgo/Makefile.am
libgo/Makefile.in
libgo/go/runtime/print.go
libgo/go/runtime/runtime2.go
libgo/go/runtime/stubs.go
libgo/runtime/mprof.goc
libgo/runtime/panic.c
libgo/runtime/print.c
libgo/runtime/proc.c
libgo/runtime/runtime.h

index e22f79e4766f7e6aae95be2aff6cc88cc7cf0073..c987dc90eb720bd5dfd9fd1041c27a01b2a6df2a 100644 (file)
@@ -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.
index 36000ead4aeafc4141a150e5b3b0fe3ff6cfb4b4..4f8a519f4fdacc2ebd1fcfeecbe8f039f442f90e 100644 (file)
@@ -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);
       }
index 168f473933f5ec0383ea023dcd8669d9b2c73d45..e7edfa652f36fbb20653ebbeed1b153820c22b04 100644 (file)
@@ -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.
index bc47be6773af59a5746320c0091a1fcdd71da0f0..b7c3e1810dc1cc91b22af4cc0d78b5e8d2db698e 100644 (file)
@@ -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 \
index 5806d75f77bc8d494efbe999bb2fe8a83580a087..e6571cd6d0cb47e5f63484b4df8352071b36ebca 100644 (file)
@@ -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
index 97d595fb2fbd33a5626fb7ee6f17908ecfc58f0e..371cec505870987f378991b8596c290007ee0886 100644 (file)
@@ -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))
 }
 
index 688efcdcb83712fa995ae4819efefe1c11dd6b6d..25b5b79de20a650ae59dd90870b0b7ae45c785d8 100644 (file)
@@ -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
index c687cbf6220417fa7ce934ec2ea1d42549620d2f..f014610841f38de86706918c59a4b5d46718c258 100644 (file)
@@ -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
index bb3f9e8c8e0abb06f1349ee22c22f3cdd8bbb1e2..be2c17eb22deb1fe14f452aba8fed700b1b56c6e 100644 (file)
@@ -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) {
index d493b54a5093d3314fe02eeb4d3fa571475c5623..cd1ae9673c61cef4eb04e9f2031541e844557362 100644 (file)
@@ -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)
index 69b1f81fb421966b3cfdcc02bf8aaff733c2575e..4da879620c7ba4bb277d7757201bac57422f1d4c 100644 (file)
@@ -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();
 }
index 02b62bef44e2772cbdc7add7ff8f2f097eb1fb25..98c18a726af481d82eca5e6e0d0ae2331c7862b8 100644 (file)
@@ -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;
index 6f96b2bde6c814be8a8bb12d6a7ba6381358a9a5..3304215e9ed70132ba8608315d4237879674d02a 100644 (file)
@@ -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))
@@ -533,36 +531,9 @@ void       runtime_parforiters(ParFor*, uintptr, uintptr*, uintptr*);
 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");