Backed out changeset c22b643cdf51 (bug 1479961, bug 1480129)
authorSteve Fink <sfink@mozilla.com>
Tue, 16 Oct 2018 14:35:44 -0700
changeset 489840 06ffaf98e1e97cf3ad13d9e752f05f4f4e44c129
parent 489839 18c5d2a69f2d9748977bdbe6686889ff7fcc72ef
child 489841 f2e06bf4ba8e7a8fbcab9e83d1eabb03c94d3cb0
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
bugs1479961, 1480129
milestone64.0a1
backs outc22b643cdf5168be413948a2437584426bfd8c06
Backed out changeset c22b643cdf51 (bug 1479961, bug 1480129)
js/public/GCAnnotations.h
js/src/devtools/rootAnalysis/annotations.js
js/src/devtools/rootAnalysis/computeCallgraph.js
js/src/jit/Jit.cpp
js/src/vm/Interpreter.cpp
--- a/js/public/GCAnnotations.h
+++ b/js/public/GCAnnotations.h
@@ -50,29 +50,23 @@
 
 // Mark an RAII class as suppressing GC within its scope.
 # 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__((annotate("Can run script")))
 
-// Mark a function as able to call JSNatives. Otherwise, JSNatives don't show
-// up in the callgraph. This doesn't matter for the can-GC analysis, but it is
-// very nice for other uses of the callgraph.
-# define JS_HAZ_JSNATIVE_CALLER __attribute__((annotate("Calls JSNatives")))
-
 #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
 # define JS_HAZ_NON_GC_POINTER
 # define JS_HAZ_GC_CALL
 # define JS_HAZ_GC_SUPPRESSED
 # define JS_HAZ_CAN_RUN_SCRIPT
-# define JS_HAZ_JSNATIVE_CALLER
 
 #endif
 
 #endif /* js_GCAnnotations_h */
--- a/js/src/devtools/rootAnalysis/annotations.js
+++ b/js/src/devtools/rootAnalysis/annotations.js
@@ -422,20 +422,8 @@ function isOverridableField(initialCSU, 
 }
 
 function listNonGCPointers() {
     return [
         // Safe only because jsids are currently only made from pinned strings.
         'NPIdentifier',
     ];
 }
-
-function isJSNative(mangled)
-{
-    // _Z...E = function
-    // 9JSContext = JSContext*
-    // j = uint32
-    // PN2JS5Value = JS::Value*
-    //   P = pointer
-    //   N2JS = JS::
-    //   5Value = Value
-    return mangled.endsWith("P9JSContextjPN2JS5ValueE") && mangled.startsWith("_Z");
-}
--- a/js/src/devtools/rootAnalysis/computeCallgraph.js
+++ b/js/src/devtools/rootAnalysis/computeCallgraph.js
@@ -13,19 +13,16 @@ if (scriptArgs[0] == '--function') {
 var typeInfo_filename = scriptArgs[0] || "typeInfo.txt";
 var callgraphOut_filename = scriptArgs[1] || "callgraph.txt";
 
 var origOut = os.file.redirect(callgraphOut_filename);
 
 var memoized = new Map();
 var memoizedCount = 0;
 
-var JSNativeCaller = Object.create(null);
-var JSNatives = [];
-
 var unmangled2id = new Set();
 
 function getId(name)
 {
     let id = memoized.get(name);
     if (id !== undefined)
         return id;
 
@@ -100,21 +97,18 @@ function getAnnotations(functionName, bo
 // 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 getAnnotations(functionName, body).values()) {
+    for (var tag of getAnnotations(functionName, body).values())
         print("T " + functionId(functionName) + " " + tag);
-        if (tag == "Calls JSNatives")
-            JSNativeCaller[functionName] = true;
-    }
 
     // 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.)
     //
     // Limit sets are implemented as integers interpreted as bitfields.
@@ -223,18 +217,16 @@ function process(functionName, functionB
     // This is slightly conservative in the case where they are *not*
     // identical, but that should be rare enough that we don't care.
     var markerPos = functionName.indexOf(internalMarker);
     if (markerPos > 0) {
         var inChargeXTor = functionName.replace(internalMarker, "");
         printOnce("D " + functionId(inChargeXTor) + " " + functionId(functionName));
     }
 
-    const [ mangled, unmangled ] = splitFunction(functionName);
-
     // Further note: from https://itanium-cxx-abi.github.io/cxx-abi/abi.html the
     // different kinds of constructors/destructors are:
     // C1	# complete object constructor
     // C2	# base object constructor
     // C3	# complete object allocating constructor
     // D0	# deleting destructor
     // D1	# complete object destructor
     // D2	# base object destructor
@@ -259,16 +251,17 @@ function process(functionName, functionB
     //                ::= D2 # base object (not-in-charge) destructor
     // <special-name> ::= C1   # complete object constructor
     //                ::= C2   # base object constructor
     //                ::= C3   # complete object allocating constructor
     //
     // Currently, allocating constructors are never used.
     //
     if (functionName.indexOf("C4") != -1) {
+        var [ mangled, unmangled ] = splitFunction(functionName);
         // E terminates the method name (and precedes the method parameters).
         // If eg "C4E" shows up in the mangled name for another reason, this
         // will create bogus edges in the callgraph. But it will affect little
         // and is somewhat difficult to avoid, so we will live with it.
         //
         // Another possibility! A templatized constructor will contain C4I...E
         // for template arguments.
         //
@@ -307,32 +300,19 @@ function process(functionName, functionB
         const not_in_charge_dtor = functionName.replace("(int32)", "()");
         const D0 = not_in_charge_dtor.replace("D4Ev", "D0Ev") + " [[deleting_dtor]]";
         const D1 = not_in_charge_dtor.replace("D4Ev", "D1Ev") + " [[complete_dtor]]";
         const D2 = not_in_charge_dtor.replace("D4Ev", "D2Ev") + " [[base_dtor]]";
         printOnce("D " + functionId(D0) + " " + functionId(D1));
         printOnce("D " + functionId(D1) + " " + functionId(D2));
         printOnce("D " + functionId(D2) + " " + functionId(functionName));
     }
-
-    if (isJSNative(mangled))
-        JSNatives.push(functionName);
-}
-
-function postprocess_callgraph() {
-    for (const caller of Object.keys(JSNativeCaller)) {
-        const caller_id = functionId(caller);
-        for (const callee of JSNatives)
-            printOnce(`D ${caller_id} ${functionId(callee)}`);
-    }
 }
 
 for (var nameIndex = minStream; nameIndex <= maxStream; nameIndex++) {
     var name = xdb.read_key(nameIndex);
     var data = xdb.read_entry(name);
     process(name.readString(), JSON.parse(data.readString()));
     xdb.free_string(name);
     xdb.free_string(data);
 }
 
-postprocess_callgraph();
-
 os.file.close(os.file.redirect(origOut));
--- a/js/src/jit/Jit.cpp
+++ b/js/src/jit/Jit.cpp
@@ -12,17 +12,17 @@
 #include "jit/JitRealm.h"
 #include "vm/Interpreter.h"
 
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
-static EnterJitStatus JS_HAZ_JSNATIVE_CALLER
+static EnterJitStatus
 EnterJit(JSContext* cx, RunState& state, uint8_t* code)
 {
     MOZ_ASSERT(state.script()->hasBaselineScript());
     MOZ_ASSERT(code);
     MOZ_ASSERT(IsBaselineEnabled(cx));
 
     if (!CheckRecursionLimit(cx)) {
         return EnterJitStatus::Error;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -363,17 +363,17 @@ MaybeCreateThisForConstructor(JSContext*
 
     RootedObject callee(cx, &args.callee());
     RootedObject newTarget(cx, &args.newTarget().toObject());
     NewObjectKind newKind = createSingleton ? SingletonObject : GenericObject;
 
     return CreateThis(cx, callee, calleeScript, newTarget, newKind, args.mutableThisv());
 }
 
-static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_CALLER bool
+static MOZ_NEVER_INLINE bool
 Interpret(JSContext* cx, RunState& state);
 
 InterpreterFrame*
 InvokeState::pushInterpreterFrame(JSContext* cx)
 {
     return cx->interpreterStack().pushInvokeFrame(cx, args_, construct_);
 }
 
@@ -1987,17 +1987,17 @@ js::ReportInNotObjectError(JSContext* cx
                                  lbytes.get(), rbytes.get());
         return;
     }
 
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_IN_NOT_OBJECT,
                               InformalValueTypeName(rref));
 }
 
-static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_CALLER bool
+static MOZ_NEVER_INLINE bool
 Interpret(JSContext* cx, RunState& state)
 {
 /*
  * Define macros for an interpreter loop. Opcode dispatch may be either by a
  * switch statement or by indirect goto (aka a threaded interpreter), depending
  * on compiler support.
  *
  * Threaded interpretation appears to be well-supported by GCC 3 and higher.