diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-29 18:11:17 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-29 18:11:17 +0000 |
commit | 149eabc5939978456047a0b83c65c530c580b71d (patch) | |
tree | d146677ebcdb05c9d7a8c8b84cab5fb7fa9a0f99 /libgo | |
parent | 29b7e0553a6cf87b81466b337bbebfb334b2c9e5 (diff) | |
download | gcc-149eabc5939978456047a0b83c65c530c580b71d.tar.gz |
compiler, runtime: Track fields with tag go:"track".
* go-gcc.cc: Include "output.h".
(global_variable): Add is_unique_section parameter.
(global_variable_set_init): Adjust unique section if necessary.
* Make-lang.in (go/go-gcc.o): Add dependency on output.h.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193945 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/Makefile.am | 1 | ||||
-rw-r--r-- | libgo/Makefile.in | 11 | ||||
-rw-r--r-- | libgo/go/runtime/debug.go | 7 | ||||
-rw-r--r-- | libgo/runtime/go-fieldtrack.c | 101 |
4 files changed, 119 insertions, 1 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am index fc0d9917ebe..50a21b8cd1b 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -450,6 +450,7 @@ runtime_files = \ runtime/go-deferred-recover.c \ runtime/go-eface-compare.c \ runtime/go-eface-val-compare.c \ + runtime/go-fieldtrack.c \ runtime/go-getgoroot.c \ runtime/go-int-array-to-string.c \ runtime/go-int-to-string.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 147d9c8e6dc..38b8ddfcc4d 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -196,7 +196,7 @@ am__objects_5 = go-append.lo go-assert.lo go-assert-interface.lo \ go-check-interface.lo go-construct-map.lo \ go-convert-interface.lo go-copy.lo go-defer.lo \ go-deferred-recover.lo go-eface-compare.lo \ - go-eface-val-compare.lo go-getgoroot.lo \ + go-eface-val-compare.lo go-fieldtrack.lo go-getgoroot.lo \ go-int-array-to-string.lo go-int-to-string.lo \ go-interface-compare.lo go-interface-eface-compare.lo \ go-interface-val-compare.lo go-make-slice.lo go-map-delete.lo \ @@ -781,6 +781,7 @@ runtime_files = \ runtime/go-deferred-recover.c \ runtime/go-eface-compare.c \ runtime/go-eface-val-compare.c \ + runtime/go-fieldtrack.c \ runtime/go-getgoroot.c \ runtime/go-int-array-to-string.c \ runtime/go-int-to-string.c \ @@ -2421,6 +2422,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-deferred-recover.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-eface-compare.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-eface-val-compare.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-fieldtrack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-getgoroot.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-array-to-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-int-to-string.Plo@am__quote@ @@ -2657,6 +2659,13 @@ go-eface-val-compare.lo: runtime/go-eface-val-compare.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-eface-val-compare.lo `test -f 'runtime/go-eface-val-compare.c' || echo '$(srcdir)/'`runtime/go-eface-val-compare.c +go-fieldtrack.lo: runtime/go-fieldtrack.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-fieldtrack.lo -MD -MP -MF $(DEPDIR)/go-fieldtrack.Tpo -c -o go-fieldtrack.lo `test -f 'runtime/go-fieldtrack.c' || echo '$(srcdir)/'`runtime/go-fieldtrack.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-fieldtrack.Tpo $(DEPDIR)/go-fieldtrack.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-fieldtrack.c' object='go-fieldtrack.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-fieldtrack.lo `test -f 'runtime/go-fieldtrack.c' || echo '$(srcdir)/'`runtime/go-fieldtrack.c + go-getgoroot.lo: runtime/go-getgoroot.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-getgoroot.lo -MD -MP -MF $(DEPDIR)/go-getgoroot.Tpo -c -o go-getgoroot.lo `test -f 'runtime/go-getgoroot.c' || echo '$(srcdir)/'`runtime/go-getgoroot.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-getgoroot.Tpo $(DEPDIR)/go-getgoroot.Plo diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index 0211ce61b88..9da71a7857c 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -168,3 +168,10 @@ func BlockProfile(p []BlockProfileRecord) (n int, ok bool) // If all is true, Stack formats stack traces of all other goroutines // into buf after the trace for the current goroutine. func Stack(buf []byte, all bool) int + +// Get field tracking information. Only fields with a tag go:"track" +// are tracked. This function will add every such field that is +// referenced to the map. The keys in the map will be +// PkgPath.Name.FieldName. The value will be true for each field +// added. +func Fieldtrack(map[string]bool) diff --git a/libgo/runtime/go-fieldtrack.c b/libgo/runtime/go-fieldtrack.c new file mode 100644 index 00000000000..62b36dc7bc0 --- /dev/null +++ b/libgo/runtime/go-fieldtrack.c @@ -0,0 +1,101 @@ +/* go-fieldtrack.c -- structure field data analysis. + + Copyright 2012 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 "go-type.h" +#include "map.h" + +/* The compiler will track fields that have the tag go:"track". Any + function that refers to such a field will call this function with a + string + fieldtrack "package.type.field" + + This function does not actually do anything. Instead, we gather + the field tracking information by looking for strings of that form + in the read-only data section. This is, of course, a horrible + hack, but it's good enough for now. We can improve it, e.g., by a + linker plugin, if this turns out to be useful. */ + +void +__go_fieldtrack (byte *p __attribute__ ((unused))) +{ +} + +/* A runtime function to add all the tracked fields to a + map[string]bool. */ + +extern const char _etext[] __attribute__ ((weak)); +extern const char __etext[] __attribute__ ((weak)); +extern const char __data_start[] __attribute__ ((weak)); +extern const char _edata[] __attribute__ ((weak)); +extern const char __edata[] __attribute__ ((weak)); +extern const char __bss_start[] __attribute__ ((weak)); + +void runtime_Fieldtrack (struct __go_map *) __asm__ ("runtime.Fieldtrack"); + +void +runtime_Fieldtrack (struct __go_map *m) +{ + const char *p; + const char *pend; + const char *prefix; + size_t prefix_len; + + p = __data_start; + if (p == NULL) + p = __etext; + if (p == NULL) + p = _etext; + if (p == NULL) + return; + + pend = __edata; + if (pend == NULL) + pend = _edata; + if (pend == NULL) + pend = __bss_start; + if (pend == NULL) + return; + + prefix = "fieldtrack "; + prefix_len = __builtin_strlen (prefix); + + while (p < pend) + { + const char *q1; + const char *q2; + + q1 = __builtin_memchr (p + prefix_len, '"', pend - (p + prefix_len)); + if (q1 == NULL) + break; + + if (__builtin_memcmp (q1 - prefix_len, prefix, prefix_len) != 0) + { + p = q1 + 1; + continue; + } + + q1++; + q2 = __builtin_memchr (q1, '"', pend - q1); + if (q2 == NULL) + break; + + if (__builtin_memchr (q1, '\0', q2 - q1) == NULL) + { + String s; + void *v; + _Bool *pb; + + s.str = (const byte *) q1; + s.len = q2 - q1; + v = __go_map_index (m, &s, 1); + pb = (_Bool *) v; + *pb = 1; + } + + p = q2; + } +} |