Bug 1321014 - Switch Tag to Annotate, r=nika
authorSteve Fink <sfink@mozilla.com>
Thu, 19 Jul 2018 21:16:48 -0700
changeset 489832 d05f029a29ad2adc1d2d952d91f440a3f571e679
parent 489831 4ddc76989782be51553a2fb904c7c6284908fa72
child 489833 a188327354ab83702eb9c2fec439f3a7cc019883
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersnika
bugs1321014
milestone64.0a1
Bug 1321014 - Switch Tag to Annotate, r=nika
js/public/GCAnnotations.h
js/src/devtools/rootAnalysis/computeCallgraph.js
js/src/devtools/rootAnalysis/computeGCTypes.js
js/src/devtools/rootAnalysis/t/exceptions/source.cpp
js/src/devtools/rootAnalysis/t/hazards/source.cpp
js/src/devtools/rootAnalysis/t/sixgill-tree/source.cpp
js/src/devtools/rootAnalysis/t/sixgill-tree/test.py
js/src/devtools/rootAnalysis/t/suppression/source.cpp
js/src/devtools/rootAnalysis/t/virtual/source.cpp
taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh
--- a/js/public/GCAnnotations.h
+++ b/js/public/GCAnnotations.h
@@ -7,55 +7,55 @@
 #ifndef js_GCAnnotations_h
 #define js_GCAnnotations_h
 
 // Set of annotations for the rooting hazard analysis, used to categorize types
 // and functions.
 #ifdef XGILL_PLUGIN
 
 // Mark a type as being a GC thing (eg js::gc::Cell has this annotation).
-# define JS_HAZ_GC_THING __attribute__((tag("GC Thing")))
+# define JS_HAZ_GC_THING __attribute__((annotate("GC Thing")))
 
 // Mark a type as holding a pointer to a GC thing (eg JS::Value has this
 // annotation.)
-# define JS_HAZ_GC_POINTER __attribute__((tag("GC Pointer")))
+# define JS_HAZ_GC_POINTER __attribute__((annotate("GC Pointer")))
 
 // Mark a type as a rooted pointer, suitable for use on the stack (eg all
 // Rooted<T> instantiations should have this.)
-# define JS_HAZ_ROOTED __attribute__((tag("Rooted Pointer")))
+# define JS_HAZ_ROOTED __attribute__((annotate("Rooted Pointer")))
 
 // Mark a type as something that should not be held live across a GC, but which
 // is not itself a GC pointer.
-# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC")))
+# define JS_HAZ_GC_INVALIDATED __attribute__((annotate("Invalidated by GC")))
 
 // Mark a class as a base class of rooted types, eg CustomAutoRooter. All
 // descendants of this class will be considered rooted, though classes that
 // merely contain these as a field member will not be. "Inherited" by
 // templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS
-# define JS_HAZ_ROOTED_BASE __attribute__((tag("Rooted Base")))
+# define JS_HAZ_ROOTED_BASE __attribute__((annotate("Rooted Base")))
 
 // Mark a type that would otherwise be considered a GC Pointer (eg because it
 // contains a JS::Value field) as a non-GC pointer. It is handled almost the
 // same in the analysis as a rooted pointer, except it will not be reported as
 // an unnecessary root if used across a GC call. This should rarely be used,
 // but makes sense for something like ErrorResult, which only contains a GC
 // pointer when it holds an exception (and it does its own rooting,
 // conditionally.)
-# define JS_HAZ_NON_GC_POINTER __attribute__((tag("Suppressed GC Pointer")))
+# define JS_HAZ_NON_GC_POINTER __attribute__((annotate("Suppressed GC Pointer")))
 
 // Mark a function as something that runs a garbage collection, potentially
 // invalidating GC pointers.
-# define JS_HAZ_GC_CALL __attribute__((tag("GC Call")))
+# define JS_HAZ_GC_CALL __attribute__((annotate("GC Call")))
 
 // Mark an RAII class as suppressing GC within its scope.
-# define JS_HAZ_GC_SUPPRESSED __attribute__((tag("Suppress GC")))
+# define JS_HAZ_GC_SUPPRESSED __attribute__((annotate("Suppress GC")))
 
 // Mark a function as one that can run script if called.  This obviously
 // subsumes JS_HAZ_GC_CALL, since anything that can run script can GC.`
-# define JS_HAZ_CAN_RUN_SCRIPT __attribute__((tag("Can run script")))
+# define JS_HAZ_CAN_RUN_SCRIPT __attribute__((annotate("Can run script")))
 
 #else
 
 # define JS_HAZ_GC_THING
 # define JS_HAZ_GC_POINTER
 # define JS_HAZ_ROOTED
 # define JS_HAZ_GC_INVALIDATED
 # define JS_HAZ_ROOTED_BASE
--- a/js/src/devtools/rootAnalysis/computeCallgraph.js
+++ b/js/src/devtools/rootAnalysis/computeCallgraph.js
@@ -39,17 +39,17 @@ function printOnce(line)
 
 // Returns a table mapping function name to lists of
 // [annotation-name, annotation-value] pairs:
 //   { function-name => [ [annotation-name, annotation-value] ] }
 //
 // Note that sixgill will only store certain attributes (annotation-names), so
 // this won't be *all* the attributes in the source, just the ones that sixgill
 // watches for.
-function getAnnotations(body)
+function getAllAttributes(body)
 {
     var all_annotations = {};
     for (var v of (body.DefineVariable || [])) {
         if (v.Variable.Kind != 'Func')
             continue;
         var name = v.Variable.Name[0];
         var annotations = all_annotations[name] = [];
 
@@ -57,36 +57,37 @@ function getAnnotations(body)
             annotations.push(ann.Name);
         }
     }
 
     return all_annotations;
 }
 
 // Get just the annotations understood by the hazard analysis.
-function getTags(functionName, body) {
+function getAnnotations(functionName, body) {
     var tags = new Set();
-    var annotations = getAnnotations(body);
-    if (functionName in annotations) {
-        for (var [ annName, annValue ] of annotations[functionName]) {
-            if (annName == 'Tag')
+    var attributes = getAllAttributes(body);
+    if (functionName in attributes) {
+        for (var [ annName, annValue ] of attributes[functionName]) {
+            if (annName == 'annotate')
                 tags.add(annValue);
         }
     }
     return tags;
 }
 
 // Scan through a function body, pulling out all annotations and calls and
 // recording them in callgraph.txt.
 function processBody(functionName, body)
 {
     if (!('PEdge' in body))
         return;
 
-    for (var tag of getTags(functionName, body).values())
+
+    for (var tag of getAnnotations(functionName, body).values())
         print("T " + memo(functionName) + " " + tag);
 
     // Set of all callees that have been output so far, in order to suppress
     // repeated callgraph edges from being recorded. This uses a Map from
     // callees to limit sets, because we don't want a limited edge to prevent
     // an unlimited edge from being recorded later. (So an edge will be skipped
     // if it exists and is at least as limited as the previously seen edge.)
     //
--- a/js/src/devtools/rootAnalysis/computeGCTypes.js
+++ b/js/src/devtools/rootAnalysis/computeGCTypes.js
@@ -33,17 +33,17 @@ var gcTypes = {}; // map from parent str
 var gcPointers = {}; // map from parent struct => Set of GC typed children
 var gcFields = new Map;
 
 var rootedPointers = {};
 
 function processCSU(csu, body)
 {
     for (let { 'Name': [ annType, tag ] } of (body.Annotation || [])) {
-        if (annType != 'Tag')
+        if (annType != 'annotate')
             continue;
 
         if (tag == 'GC Pointer')
             typeInfo.GCPointers.push(csu);
         else if (tag == 'Invalidated by GC')
             typeInfo.GCPointers.push(csu);
         else if (tag == 'GC Thing')
             typeInfo.GCThings.push(csu);
--- a/js/src/devtools/rootAnalysis/t/exceptions/source.cpp
+++ b/js/src/devtools/rootAnalysis/t/exceptions/source.cpp
@@ -1,9 +1,9 @@
-#define ANNOTATE(property) __attribute__((tag(property)))
+#define ANNOTATE(property) __attribute__((annotate(property)))
 
 struct Cell { int f; } ANNOTATE("GC Thing");
 
 extern void GC() ANNOTATE("GC Call");
 
 void GC()
 {
     // If the implementation is too trivial, the function body won't be emitted at all.
--- a/js/src/devtools/rootAnalysis/t/hazards/source.cpp
+++ b/js/src/devtools/rootAnalysis/t/hazards/source.cpp
@@ -1,9 +1,9 @@
-#define ANNOTATE(property) __attribute__((tag(property)))
+#define ANNOTATE(property) __attribute__((annotate(property)))
 
 struct Cell { int f; } ANNOTATE("GC Thing");
 
 struct RootedCell { RootedCell(Cell*) {} } ANNOTATE("Rooted Pointer");
 
 class AutoSuppressGC_Base {
   public:
     AutoSuppressGC_Base() {}
--- a/js/src/devtools/rootAnalysis/t/sixgill-tree/source.cpp
+++ b/js/src/devtools/rootAnalysis/t/sixgill-tree/source.cpp
@@ -1,9 +1,9 @@
-#define ANNOTATE(property) __attribute__((tag(property)))
+#define ANNOTATE(property) __attribute__((annotate(property)))
 
 namespace js {
 namespace gc {
 struct Cell { int f; } ANNOTATE("GC Thing");
 }
 }
 
 struct Bogon {
--- a/js/src/devtools/rootAnalysis/t/sixgill-tree/test.py
+++ b/js/src/devtools/rootAnalysis/t/sixgill-tree/test.py
@@ -17,32 +17,32 @@ assert('obj' in body['Variables'])
 assert('random' in body['Variables'])
 assert('other1' in body['Variables'])
 assert('other2' in body['Variables'])
 
 # Test function annotations
 js_GC = test.process_body(test.load_db_entry("src_body", re.compile(r'js_GC'))[0])
 annotations = js_GC['Variables']['void js_GC()']['Annotation']
 assert(annotations)
-found_call_tag = False
+found_call_annotate = False
 for annotation in annotations:
     (annType, value) = annotation['Name']
-    if annType == 'Tag' and value == 'GC Call':
-        found_call_tag = True
-assert(found_call_tag)
+    if annType == 'annotate' and value == 'GC Call':
+        found_call_annotate = True
+assert(found_call_annotate)
 
 # Test type annotations
 
 # js::gc::Cell first
 cell = test.load_db_entry("src_comp", 'js::gc::Cell')[0]
 assert(cell['Kind'] == 'Struct')
 annotations = cell['Annotation']
 assert(len(annotations) == 1)
 (tag, value) = annotations[0]['Name']
-assert(tag == 'Tag')
+assert(tag == 'annotate')
 assert(value == 'GC Thing')
 
 # Check JSObject inheritance.
 JSObject = test.load_db_entry("src_comp", 'JSObject')[0]
 bases = [b['Base'] for b in JSObject['CSUBaseClass']]
 assert('js::gc::Cell' in bases)
 assert('Bogon' in bases)
 assert(len(bases) == 2)
--- a/js/src/devtools/rootAnalysis/t/suppression/source.cpp
+++ b/js/src/devtools/rootAnalysis/t/suppression/source.cpp
@@ -1,9 +1,9 @@
-#define ANNOTATE(property) __attribute__((tag(property)))
+#define ANNOTATE(property) __attribute__((annotate(property)))
 
 struct Cell { int f; } ANNOTATE("GC Thing");
 
 class AutoSuppressGC_Base {
   public:
     AutoSuppressGC_Base() {}
     ~AutoSuppressGC_Base() {}
 } ANNOTATE("Suppress GC");
--- a/js/src/devtools/rootAnalysis/t/virtual/source.cpp
+++ b/js/src/devtools/rootAnalysis/t/virtual/source.cpp
@@ -1,9 +1,9 @@
-#define ANNOTATE(property) __attribute__((tag(property)))
+#define ANNOTATE(property) __attribute__((annotate(property)))
 
 extern void GC() ANNOTATE("GC Call");
 
 void GC()
 {
     // If the implementation is too trivial, the function body won't be emitted at all.
     asm("");
 }
@@ -11,21 +11,39 @@ void GC()
 struct Cell { int f; } ANNOTATE("GC Thing");
 
 extern void foo();
 
 typedef void (*func_t)();
 
 class Base {
   public:
-    int dummy;
+    int ANNOTATE("field annotation") dummy;
     virtual void someGC() = 0;
     func_t functionField;
+
+    // For now, this is just to verify that the plugin doesn't crash. The
+    // analysis code does not yet look at this annotation or output it anywhere
+    // (though it *is* being recorded.)
+    static float testAnnotations() ANNOTATE("static func");
+
+    // Similar, though sixgill currently completely ignores parameter annotations.
+    static double testParamAnnotations(Cell& ANNOTATE("param annotation") ANNOTATE("second param annot") cell) ANNOTATE("static func") ANNOTATE("second func");
 };
 
+float Base::testAnnotations()
+{
+    asm("");
+}
+
+double Base::testParamAnnotations(Cell& cell)
+{
+    asm("");
+}
+
 class Super : public Base {
   public:
     virtual void noneGC() = 0;
     virtual void allGC() = 0;
 };
 
 void bar() {
     GC();
--- a/taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh
+++ b/taskcluster/scripts/misc/build-gcc-sixgill-plugin-linux.sh
@@ -17,17 +17,17 @@ data_dir=$HOME_DIR/src/build/unix/build-
 
 # Download and unpack upstream toolchain artifacts (ie, the gcc binary).
 . $(dirname $0)/tooltool-download.sh
 
 gcc_version=6.4.0
 gcc_ext=xz
 binutils_version=2.28.1
 binutils_ext=xz
-sixgill_rev=630e2025191d
+sixgill_rev=bc0ef9258470
 sixgill_repo=https://hg.mozilla.org/users/sfink_mozilla.com/sixgill
 
 . $data_dir/build-gcc.sh
 
 pushd $root_dir/gcc-$gcc_version
 ln -sf ../binutils-2.28.1 binutils
 ln -sf ../gmp-5.1.3 gmp
 ln -sf ../isl-0.15 isl