Bug 1499507 - Use AUTO_PROFILER_LABEL_DYNAMIC_FAST for WebIDL APIs. r=bzbarsky
authorMarkus Stange <mstange@themasta.com>
Tue, 06 Nov 2018 04:34:58 +0000
changeset 444534 5ec157cbbdd11c216e996e2cc763bd087620cb11
parent 444533 408a37a9e42b9fa9d219641c240a6cc98e9ea756
child 444535 50f1edbfb52c2dd1e8074c29bf0d00c5ad08e2f7
push id34996
push userrgurzau@mozilla.com
push dateTue, 06 Nov 2018 09:53:23 +0000
treeherdermozilla-central@e160f0a60e4f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1499507
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1499507 - Use AUTO_PROFILER_LABEL_DYNAMIC_FAST for WebIDL APIs. r=bzbarsky This means that our binary does not need to include concatenated strings such as "set CanvasRenderingContext2D.fillStyle". It only needs to contain the individual strings "CanvasRenderingContext2D" and "fillStyle" which are most likely already present in the binary. This change reduces the binary size on macOS x64 by around 200KB. Here's a diff of the impact on the code generated for Attr_Binding::get_specified in the Mac build. This change makes us generate slightly more code, which is very much offset by the reduction in the amount of strings we ship. @@ -15,22 +15,23 @@ movl 0x10(%rbx), %r12d cmpl (%rbx), %r12d jae loc_xxxxx movq 0x8(%rbx), %rax movq %r12, %rcx shlq $0x5, %rcx - leaq aGetAttrspecifi, %rdx ; "get Attr.specified" + leaq aAttr, %rdx ; "Attr" movq %rdx, (%rax,%rcx) - movq $0x0, 0x8(%rax,%rcx) + leaq aSpecified, %rdx ; "specified" + movq %rdx, 0x8(%rax,%rcx) leaq -40(%rbp), %rdx movq %rdx, 0x10(%rax,%rcx) - movl $0x71, 0x1c(%rax,%rcx) + movl $0x3a1, 0x1c(%rax,%rcx) leal 0x1(%r12), %eax movl %eax, 0x10(%rbx) movq %r15, %rdi call __ZNK7mozilla3dom4Attr9SpecifiedEv ; mozilla::dom::Attr::Specified() const movzxl %al, %eax movabsq $0xfff9000000000000, %rcx orq %rax, %rcx Depends on D9204 Differential Revision: https://phabricator.services.mozilla.com/D9205
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1581,22 +1581,16 @@ class CGAbstractMethod(CGThing):
         elif self.inline:
             decorators.append('inline')
         if self.static:
             decorators.append('static')
         decorators.append(self.returnType)
         maybeNewline = " " if self.inline else "\n"
         return ' '.join(decorators) + maybeNewline
 
-    def _auto_profiler_label(self):
-        profiler_label_and_jscontext = self.profiler_label_and_jscontext()
-        if profiler_label_and_jscontext:
-            return 'AUTO_PROFILER_LABEL_FAST("%s", DOM, %s);' % profiler_label_and_jscontext
-        return None
-
     def declare(self):
         if self.inline:
             return self._define(True)
         return "%s%s%s(%s);\n" % (self._template(), self._decorators(), self.name, self._argstring(True))
 
     def indent_body(self, body):
         """
         Indent the code returned by self.definition_body(). Most classes
@@ -1611,33 +1605,33 @@ class CGAbstractMethod(CGThing):
                 self.definition_epilogue())
 
     def define(self):
         return "" if self.inline else self._define()
 
     def definition_prologue(self, fromDeclare):
         prologue = "%s%s%s(%s)\n{\n" % (self._template(), self._decorators(),
                                         self.name, self._argstring(fromDeclare))
-        profiler_label = self._auto_profiler_label()
+        profiler_label = self.auto_profiler_label()
         if profiler_label:
-            prologue += "  %s\n\n" % profiler_label
+            prologue += indent(profiler_label) + "\n"
 
         return prologue
 
     def definition_epilogue(self):
         return "}\n"
 
     def definition_body(self):
         assert False  # Override me!
 
     """
     Override this method to return a pair of (descriptive string, name of a
     JSContext* variable) in order to generate a profiler label for this method.
     """
-    def profiler_label_and_jscontext(self):
+    def auto_profiler_label(self):
         return None # Override me!
 
 class CGAbstractStaticMethod(CGAbstractMethod):
     """
     Abstract base class for codegen of implementation-only (no
     declaration) static methods.
     """
     def __init__(self, descriptor, name, returnType, args, canRunScript=False):
@@ -1870,23 +1864,27 @@ class CGClassConstructor(CGAbstractStati
 
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
         callGenerator = CGMethodCall(nativeName, True, self.descriptor,
                                      self._ctor, isConstructor=True,
                                      constructorName=ctorName)
         return preamble + "\n" + callGenerator.define()
 
-    def profiler_label_and_jscontext(self):
+    def auto_profiler_label(self):
         name = self._ctor.identifier.name
         if name != "constructor":
             ctorName = name
         else:
             ctorName = self.descriptor.interface.identifier.name
-        return ("%s constructor" % ctorName, "cx")
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST("${ctorName}", "constructor", DOM, cx, 0);
+            """,
+            ctorName=ctorName)
 
 # Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
 class CGConstructNavigatorObject(CGAbstractMethod):
     """
     Construct a new JS-implemented WebIDL DOM object, for use on navigator.
     """
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'),
@@ -8666,27 +8664,19 @@ class CGAbstractStaticBindingMethod(CGAb
         # later use it to wrap return values.
         unwrap = dedent("""
             JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
             JS::Rooted<JSObject*> obj(cx, &args.callee());
 
             """)
         return unwrap + self.generate_code().define()
 
-    def profiler_label_and_jscontext(self):
-        # Our args are JSNativeArguments() which contain a "JSContext* cx"
-        # argument. We let our subclasses choose the label.
-        return (self.profiler_label(), "cx")
-
     def generate_code(self):
         assert False  # Override me
 
-    def profiler_label(self):
-        assert False # Override me
-
 
 def MakeNativeName(name):
     return name[0].upper() + IDLToCIdentifier(name[1:])
 
 
 class CGSpecializedMethod(CGAbstractStaticMethod):
     """
     A class for generating the C++ code for a specialized method that the JIT
@@ -8703,20 +8693,27 @@ class CGSpecializedMethod(CGAbstractStat
                                         canRunScript=True)
 
     def definition_body(self):
         nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                         self.method)
         return CGMethodCall(nativeName, self.method.isStatic(), self.descriptor,
                             self.method).define()
 
-    def profiler_label_and_jscontext(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         method_name = self.method.identifier.name
-        return ("%s.%s" % (interface_name, method_name), "cx")
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${method_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD));
+            """,
+            interface_name=interface_name,
+            method_name=method_name)
 
     @staticmethod
     def makeNativeName(descriptor, method):
         name = method.identifier.name
         return MakeNativeName(descriptor.binaryNameFor(name))
 
 
 class CGMethodPromiseWrapper(CGAbstractStaticMethod):
@@ -8963,20 +8960,27 @@ class CGStaticMethod(CGAbstractStaticBin
         name = CppKeywords.checkMethodName(IDLToCIdentifier(method.identifier.name))
         CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
 
     def generate_code(self):
         nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
                                                         self.method)
         return CGMethodCall(nativeName, True, self.descriptor, self.method)
 
-    def profiler_label(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         method_name = self.method.identifier.name
-        return "%s.%s" % (interface_name, method_name)
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${method_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD));
+            """,
+            interface_name=interface_name,
+            method_name=method_name)
 
 
 class CGSpecializedGetter(CGAbstractStaticMethod):
     """
     A class for generating the code for a specialized attribute getter
     that the JIT can call with lower overhead.
     """
     def __init__(self, descriptor, attr):
@@ -9070,20 +9074,27 @@ class CGSpecializedGetter(CGAbstractStat
         if self.attr.navigatorObjectGetter:
             cgGetterCall = CGNavigatorGetterCall
         else:
             cgGetterCall = CGGetterCall
         return (prefix +
                 cgGetterCall(self.attr.type, nativeName,
                              self.descriptor, self.attr).define())
 
-    def profiler_label_and_jscontext(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         attr_name = self.attr.identifier.name
-        return ("get %s.%s" % (interface_name, attr_name), "cx")
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${attr_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER));
+            """,
+            interface_name=interface_name,
+            attr_name=attr_name)
 
     @staticmethod
     def makeNativeName(descriptor, attr):
         name = attr.identifier.name
         nativeName = MakeNativeName(descriptor.binaryNameFor(name))
         _, resultOutParam, _, _, _ = getRetvalDeclarationForType(attr.type,
                                                                  descriptor)
         extendedAttrs = descriptor.getExtendedAttributes(attr, getter=True)
@@ -9133,20 +9144,27 @@ class CGStaticGetter(CGAbstractStaticBin
         CGAbstractStaticBindingMethod.__init__(self, descriptor, name)
 
     def generate_code(self):
         nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
                                                         self.attr)
         return CGGetterCall(self.attr.type, nativeName, self.descriptor,
                             self.attr)
 
-    def profiler_label(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         attr_name = self.attr.identifier.name
-        return "get %s.%s" % (interface_name, attr_name)
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${attr_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER));
+            """,
+            interface_name=interface_name,
+            attr_name=attr_name)
 
 
 class CGSpecializedSetter(CGAbstractStaticMethod):
     """
     A class for generating the code for a specialized attribute setter
     that the JIT can call with lower overhead.
     """
     def __init__(self, descriptor, attr):
@@ -9160,20 +9178,27 @@ class CGSpecializedSetter(CGAbstractStat
                                         canRunScript=True)
 
     def definition_body(self):
         nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
                                                         self.attr)
         return CGSetterCall(self.attr.type, nativeName, self.descriptor,
                             self.attr).define()
 
-    def profiler_label_and_jscontext(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         attr_name = self.attr.identifier.name
-        return ("set %s.%s" % (interface_name, attr_name), "cx")
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${attr_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER));
+            """,
+            interface_name=interface_name,
+            attr_name=attr_name)
 
     @staticmethod
     def makeNativeName(descriptor, attr):
         name = attr.identifier.name
         return "Set" + MakeNativeName(descriptor.binaryNameFor(name))
 
 
 class CGStaticSetter(CGAbstractStaticBindingMethod):
@@ -9194,20 +9219,27 @@ class CGStaticSetter(CGAbstractStaticBin
               return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "${name} setter");
             }
             """,
             name=self.attr.identifier.name))
         call = CGSetterCall(self.attr.type, nativeName, self.descriptor,
                             self.attr)
         return CGList([checkForArg, call])
 
-    def profiler_label(self):
+    def auto_profiler_label(self):
         interface_name = self.descriptor.interface.identifier.name
         attr_name = self.attr.identifier.name
-        return "set %s.%s" % (interface_name, attr_name)
+        return fill(
+            """
+            AUTO_PROFILER_LABEL_DYNAMIC_FAST(
+              "${interface_name}", "${attr_name}", DOM, cx,
+              uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER));
+            """,
+            interface_name=interface_name,
+            attr_name=attr_name)
 
 
 class CGSpecializedForwardingSetter(CGSpecializedSetter):
     """
     A class for generating the code for a specialized attribute setter with
     PutForwards that the JIT can call with lower overhead.
     """
     def __init__(self, descriptor, attr):