Viewing file: go-fieldtrack.c (2.34 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* 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"
/* 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 void *mapassign (const struct maptype *, void *hmap, const void *key) __asm__ (GOSYM_PREFIX "runtime.mapassign");
// The type descriptor for map[string] bool. */ extern const char map_string_bool[] __attribute__ ((weak)); extern const char map_string_bool[] __asm__ (GOSYM_PREFIX "type..map_6string_7bool");
void runtime_Fieldtrack (void *) __asm__ (GOSYM_PREFIX "runtime.Fieldtrack");
void runtime_Fieldtrack (void *m) { const char *p; const char *pend; const char *prefix; size_t prefix_len;
if (map_string_bool == NULL) return;
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 *p;
s.str = (const byte *) q1; s.len = q2 - q1; p = mapassign((const void*) map_string_bool, m, &s); *(_Bool*)p = 1; }
p = q2; } }
|