summaryrefslogtreecommitdiff
path: root/libgo/runtime
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-29 18:11:17 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-29 18:11:17 +0000
commit149eabc5939978456047a0b83c65c530c580b71d (patch)
treed146677ebcdb05c9d7a8c8b84cab5fb7fa9a0f99 /libgo/runtime
parent29b7e0553a6cf87b81466b337bbebfb334b2c9e5 (diff)
downloadgcc-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/runtime')
-rw-r--r--libgo/runtime/go-fieldtrack.c101
1 files changed, 101 insertions, 0 deletions
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;
+ }
+}