Skip to content

Commit

Permalink
runtime: copy print/println support from Go 1.7
Browse files Browse the repository at this point in the history
    
    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


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240956 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
ian committed Oct 10, 2016
1 parent dff001e commit 88b03a7
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 351 deletions.
2 changes: 1 addition & 1 deletion gcc/go/gofrontend/MERGE
Original file line number Diff line number Diff line change
@@ -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.
71 changes: 42 additions & 29 deletions gcc/go/gofrontend/expressions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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,
Expand All @@ -8360,82 +8381,74 @@ 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());
return context->backend()->error_expression();
}

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);
}
Expand Down
31 changes: 18 additions & 13 deletions gcc/go/gofrontend/runtime.def
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion libgo/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
11 changes: 1 addition & 10 deletions libgo/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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@
Expand Down Expand Up @@ -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
Expand Down
28 changes: 22 additions & 6 deletions libgo/go/runtime/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
}

Expand Down
22 changes: 8 additions & 14 deletions libgo/go/runtime/runtime2.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions libgo/go/runtime/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 7 additions & 5 deletions libgo/runtime/mprof.goc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 6 additions & 3 deletions libgo/runtime/panic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
Loading

0 comments on commit 88b03a7

Please sign in to comment.