Bug 773548 - Part 1: Modify Paris bindings to specialize methods. (r=peterv)
authorEric Faust <efaust@mozilla.com>
Tue, 07 Aug 2012 22:26:19 -0700
changeset 104908 d84df7edf0ded6a9e87ba72ff9a829df13171bb5
parent 104907 7d9b9f1158a2367ba737ff0f9e3445f68e0c59a9
child 104909 de8febc86738d0b0042e7d96670a48f24fbcb00a
push idunknown
push userunknown
push dateunknown
reviewerspeterv
bugs773548
milestone17.0a1
Bug 773548 - Part 1: Modify Paris bindings to specialize methods. (r=peterv)
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3263,21 +3263,40 @@ class CGNativeMethod(CGAbstractBindingMe
     A class for generating the C++ code for an IDL method..
     """
     def __init__(self, descriptor, method):
         self.method = method
         baseName = method.identifier.name
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         CGAbstractBindingMethod.__init__(self, descriptor, baseName, args)
+
     def generate_code(self):
+        return CGIndenter(CGGeneric(
+            "return specialized_%s(cx, obj, self, argc, vp);" %
+            self.method.identifier.name))
+
+class CGSpecializedMethod(CGAbstractStaticMethod):
+    """
+    A class for generating the C++ code for a specialized method that the JIT
+    can call with lower overhead.
+    """
+    def __init__(self, descriptor, method):
+        self.method = method
+        name = 'specialized_' + method.identifier.name
+        args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
+                Argument('%s*' % descriptor.nativeType, 'self'),
+                Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')]
+        CGAbstractStaticMethod.__init__(self, descriptor, name, 'bool', args)
+
+    def definition_body(self):
         name = self.method.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
         return CGMethodCall([], nativeName, self.method.isStatic(),
-                            self.descriptor, self.method)
+                            self.descriptor, self.method).define()
 
 class CGNativeGetter(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL attribute getter.
     """
     def __init__(self, descriptor, attr):
         self.attr = attr
         name = 'get_' + attr.identifier.name
@@ -3386,55 +3405,65 @@ class CGSpecializedSetter(CGAbstractStat
         name = self.attr.identifier.name
         nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
         return CGIndenter(CGSetterCall(self.attr.type, nativeName,
                                        self.descriptor, self.attr)).define()
 
 def memberIsCreator(member):
     return member.getExtendedAttribute("Creator") is not None
 
-class CGPropertyJITInfo(CGThing):
+class CGMemberJITInfo(CGThing):
     """
     A class for generating the JITInfo for a property that points to
     our specialized getter and setter.
     """
-    def __init__(self, descriptor, attr):
-        self.attr = attr
+    def __init__(self, descriptor, member):
+        self.member = member
         self.descriptor = descriptor
 
     def declare(self):
         return ""
 
     def defineJitInfo(self, infoName, opName, infallible):
         protoID = "prototypes::id::%s" % self.descriptor.interface.identifier.name
         depth = "PrototypeTraits<%s>::Depth" % protoID
         failstr = "true" if infallible else "false"
         return ("\n"
                 "const JSJitInfo %s = {\n"
                 "  %s,\n"
                 "  %s,\n"
                 "  %s,\n"
-                "  %s,  /* isInfallible. False for setters. */\n"
-                "  false  /* isConstant. False for setters. */\n"
+                "  %s,  /* isInfallible. Only relevant for getters. */\n"
+                "  false  /* isConstant. Only relevant for getters. */\n"
                 "};\n" % (infoName, opName, protoID, depth, failstr))
 
     def define(self):
-        getterinfo = ("%s_getterinfo" % self.attr.identifier.name)
-        getter = ("(JSJitPropertyOp)specialized_get_%s" %
-                  self.attr.identifier.name)
-        getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.attr, getter=True)
-        getterinfal = getterinfal and infallibleForAttr(self.attr, self.descriptor)
-        result = self.defineJitInfo(getterinfo, getter, getterinfal)
-        if not self.attr.readonly:
-            setterinfo = ("%s_setterinfo" % self.attr.identifier.name)
-            setter = ("(JSJitPropertyOp)specialized_set_%s" %
-                      self.attr.identifier.name)
-            # Setters are always fallible, since they have to do a typed unwrap.
-            result += self.defineJitInfo(setterinfo, setter, False)
-        return result
+        if self.member.isAttr():
+            getterinfo = ("%s_getterinfo" % self.member.identifier.name)
+            getter = ("(JSJitPropertyOp)specialized_get_%s" %
+                      self.member.identifier.name)
+            getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
+            getterinfal = getterinfal and infallibleForAttr(self.member, self.descriptor)
+            result = self.defineJitInfo(getterinfo, getter, getterinfal)
+            if not self.member.readonly:
+                setterinfo = ("%s_setterinfo" % self.member.identifier.name)
+                setter = ("(JSJitPropertyOp)specialized_set_%s" %
+                          self.member.identifier.name)
+                # Setters are always fallible, since they have to do a typed unwrap.
+                result += self.defineJitInfo(setterinfo, setter, False)
+            return result
+        if self.member.isMethod():
+            methodinfo = ("%s_methodinfo" % self.member.identifier.name)
+            #XXXefaust Should be JSJitMethodOp, after centralization, but lazy for now
+            method = ("(JSJitPropertyOp)specialized_%s" %
+                      self.member.identifier.name)
+            # Method, much like setters, are always fallible
+            result = self.defineJitInfo(methodinfo, method, False)
+            return result
+        raise TypeError("Illegal member type to CGPropertyJITInfo")
 
 def getEnumValueName(value):
     # Some enum values can be empty strings.  Others might have weird
     # characters in them.  Deal with the former by returning "_empty",
     # deal with possible name collisions from that by throwing if the
     # enum value is actually "_empty", and throw on any value
     # containing chars other than [a-z] or '-' for now. Replace '-' with '_'.
     value = value.replace('-', '_')
@@ -4164,24 +4193,26 @@ class CGDescriptor(CGThing):
         CGThing.__init__(self)
 
         assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
 
         cgThings = []
         if descriptor.interface.hasInterfacePrototypeObject():
             for m in descriptor.interface.members:
                 if m.isMethod() and not m.isStatic():
+                    cgThings.append(CGSpecializedMethod(descriptor, m))
                     cgThings.append(CGNativeMethod(descriptor, m))
+                    cgThings.append(CGMemberJITInfo(descriptor, m))
                 elif m.isAttr():
                     cgThings.append(CGSpecializedGetter(descriptor, m))
                     cgThings.append(CGNativeGetter(descriptor, m))
                     if not m.readonly:
                         cgThings.append(CGSpecializedSetter(descriptor, m))
                         cgThings.append(CGNativeSetter(descriptor, m))
-                    cgThings.append(CGPropertyJITInfo(descriptor, m))
+                    cgThings.append(CGMemberJITInfo(descriptor, m))
 
         if descriptor.concrete:
             if not descriptor.workers and descriptor.wrapperCache:
                 cgThings.append(CGAddPropertyHook(descriptor))
 
             # Always have a finalize hook, regardless of whether the class wants a
             # custom hook.
             cgThings.append(CGClassFinalizeHook(descriptor))