Bug 942631 part 7. Move INSTANCE_RESERVED_SLOTS into the C++, so it's closer to the things it depends on. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 04 Dec 2013 08:02:19 -0500
changeset 174463 cb8aa9f8396867bf7567ca65ca4a0e7782353e61
parent 174462 f96a77402a2684a9d86716cb62fe147e79d3c42c
child 174464 1426ffa9caf2bbae538668fcd09d4411061a1a8e
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs942631
milestone28.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 942631 part 7. Move INSTANCE_RESERVED_SLOTS into the C++, so it's closer to the things it depends on. r=peterv
dom/bindings/Codegen.py
dom/bindings/JSSlots.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -22,17 +22,17 @@ CONSTRUCT_HOOK_NAME = '_constructor'
 LEGACYCALLER_HOOK_NAME = '_legacycaller'
 HASINSTANCE_HOOK_NAME = '_hasInstance'
 NEWRESOLVE_HOOK_NAME = '_newResolve'
 ENUMERATE_HOOK_NAME= '_enumerate'
 ENUM_ENTRY_VARIABLE_NAME = 'strings'
 INSTANCE_RESERVED_SLOTS = 3
 
 def memberReservedSlot(member):
-    return INSTANCE_RESERVED_SLOTS + member.slotIndex
+    return "(DOM_INSTANCE_RESERVED_SLOTS + %d)" % member.slotIndex
 
 def replaceFileIfChanged(filename, newContents):
     """
     Read a copy of the old file, so that we don't touch it if it hasn't changed.
     Returns True if the file was updated, false otherwise.
     """
     oldFileContents = ""
     try:
@@ -2437,17 +2437,17 @@ class CGUpdateMemberSlotsMethod(CGAbstra
                 Argument(descriptor.nativeType + '*' , 'aObject')]
         CGAbstractStaticMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
 
     def definition_body(self):
         slotMembers = (m for m in self.descriptor.interface.members if
                        m.isAttr() and m.getExtendedAttribute("StoreInSlot"))
         storeSlots = (
             CGGeneric(
-                'static_assert(%d < js::shadow::Object::MAX_FIXED_SLOTS,\n'
+                'static_assert(%s < js::shadow::Object::MAX_FIXED_SLOTS,\n'
                 '              "Not enough fixed slots to fit \'%s.%s\'");\n'
                 "if (!get_%s(aCx, aWrapper, aObject, args)) {\n"
                 "  return false;\n"
                 "}\n"
                 "// Getter handled setting our reserved slots" %
                 (memberReservedSlot(m),
                  self.descriptor.interface.identifier.name,
                  m.identifier.name, m.identifier.name))
@@ -2476,23 +2476,23 @@ class CGClearCachedValueMethod(CGAbstrac
     def definition_body(self):
         slotIndex = memberReservedSlot(self.member)
         if self.member.getExtendedAttribute("StoreInSlot"):
             # We have to root things and save the old value in case
             # regetting fails, so we can restore it.
             declObj = "JS::Rooted<JSObject*> obj(aCx);"
             noopRetval = " true"
             saveMember = (
-                "JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %d));\n" %
+                "JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %s));\n" %
                 slotIndex)
             regetMember = ("\n"
                            "JS::Rooted<JS::Value> temp(aCx);\n"
                            "JSJitGetterCallArgs args(&temp);\n"
                            "if (!get_%s(aCx, obj, aObject, args)) {\n"
-                           "  js::SetReservedSlot(obj, %d, oldValue);\n"
+                           "  js::SetReservedSlot(obj, %s, oldValue);\n"
                            "  nsJSUtils::ReportPendingException(aCx);\n"
                            "  return false;\n"
                            "}\n"
                            "return true;" % (self.member.identifier.name, slotIndex))
         else:
             declObj = "JSObject* obj;"
             noopRetval = ""
             saveMember = ""
@@ -2500,17 +2500,17 @@ class CGClearCachedValueMethod(CGAbstrac
 
         return CGIndenter(CGGeneric(
                 "%s\n"
                 "obj = aObject->GetWrapper();\n"
                 "if (!obj) {\n"
                 "  return%s;\n"
                 "}\n"
                 "%s"
-                "js::SetReservedSlot(obj, %d, JS::UndefinedValue());"
+                "js::SetReservedSlot(obj, %s, JS::UndefinedValue());"
                 "%s"
                 % (declObj, noopRetval, saveMember, slotIndex, regetMember)
                 )).define()
 
 builtinNames = {
     IDLType.Tags.bool: 'bool',
     IDLType.Tags.int8: 'int8_t',
     IDLType.Tags.int16: 'int16_t',
@@ -5096,17 +5096,17 @@ if (!${obj}) {
                 "// be coming in via Xrays and the value is already in the\n"
                 "// caller compartment.\n"
                 "{ // Scope for tempVal\n"
                 "  JS::Rooted<JS::Value> tempVal(cx, args.rval());\n"
                 "  JSAutoCompartment ac(cx, reflector);\n"
                 "  if (!%s(cx, &tempVal)) {\n"
                 "    return false;\n"
                 "  }\n"
-                "  js::SetReservedSlot(reflector, %d, tempVal);\n"
+                "  js::SetReservedSlot(reflector, %s, tempVal);\n"
                 "%s"
                 "}\n"
                 "return true;" %
                 (getMaybeWrapValueFuncForType(self.idlNode.type),
                  memberReservedSlot(self.idlNode), preserveWrapper))
         else:
             successCode = None
 
@@ -5960,17 +5960,17 @@ class CGSpecializedGetter(CGAbstractStat
                 "  // Have to either root across the getter call or reget after.\n"
                 "  JS::Rooted<JSObject*> reflector(cx);\n"
                 "  // Safe to do an unchecked unwrap, since we've gotten this far.\n"
                 "  // Also make sure to unwrap outer windows, since we want the\n"
                 "  // real DOM object.\n"
                 "  reflector = IsDOMObject(obj) ? obj : js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);\n"
                 "  {\n"
                 "    // Scope for cachedVal\n"
-                "    JS::Value cachedVal = js::GetReservedSlot(reflector, %d);\n"
+                "    JS::Value cachedVal = js::GetReservedSlot(reflector, %s);\n"
                 "    if (!cachedVal.isUndefined()) {\n"
                 "      args.rval().set(cachedVal);\n"
                 "      // The cached value is in the compartment of reflector,\n"
                 "      // so wrap into the caller compartment as needed.\n"
                 "      return %s(cx, args.rval());\n"
                 "    }\n"
                 "  }\n\n" % (memberReservedSlot(self.attr),
                              getMaybeWrapValueFuncForType(self.attr.type)))
@@ -6181,17 +6181,17 @@ class CGMemberJITInfo(CGThing):
                 "  { %s },\n"
                 "  %s,\n"
                 "  %s,\n"
                 "  JSJitInfo::%s,\n"
                 "  %s,  /* isInfallible. False in setters. */\n"
                 "  %s,  /* isMovable.  Not relevant for setters. */\n"
                 "  JSJitInfo::%s,  /* aliasSet.  Not relevant for setters. */\n"
                 "  %s,  /* hasSlot.  Only relevant for getters. */\n"
-                "  %d,  /* Reserved slot index, if we're stored in a slot, else 0. */\n"
+                "  %s,  /* Reserved slot index, if we're stored in a slot, else 0. */\n"
                 "  %s,  /* returnType.  Not relevant for setters. */\n"
                 "  %s,  /* argTypes.  Only relevant for methods */\n"
                 "  nullptr /* parallelNative */\n"
                 "};\n" % (argTypesDecl, infoName, opName, protoID, depth,
                           opType, failstr, movablestr, aliasSet, slotStr,
                           slotIndex, returnType, argTypes))
 
     def define(self):
@@ -6211,37 +6211,36 @@ class CGMemberJITInfo(CGThing):
             else:
                 aliasSet = "AliasEverything"
             movable = getterpure and getterinfal
 
             getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
             isInSlot = self.member.getExtendedAttribute("StoreInSlot")
             if isInSlot:
                 slotIndex = memberReservedSlot(self.member);
-                if slotIndex >= 16 : # JS engine currently allows 16 fixed slots
-                    raise TypeError("Make sure we can actually have this many "
-                                    "fixed slots, please!")
+                # We'll statically assert that this is not too big in
+                # CGUpdateMemberSlotsMethod
             else:
-                slotIndex = 0
+                slotIndex = "0"
 
             result = self.defineJitInfo(getterinfo, getter, "Getter",
                                         getterinfal, movable, aliasSet,
                                         isInSlot, slotIndex,
                                         [self.member.type], None)
             if (not self.member.readonly or
                 self.member.getExtendedAttribute("PutForwards") is not None or
                 self.member.getExtendedAttribute("Replaceable") is not None):
                 setterinfo = ("%s_setterinfo" % self.member.identifier.name)
                 # Actually a JSJitSetterOp, but JSJitGetterOp is first in the
                 # union.
                 setter = ("(JSJitGetterOp)set_%s" % self.member.identifier.name)
                 # Setters are always fallible, since they have to do a typed unwrap.
                 result += self.defineJitInfo(setterinfo, setter, "Setter",
                                              False, False, "AliasEverything",
-                                             False, 0,
+                                             False, "0",
                                              [BuiltinTypes[IDLBuiltinType.Types.void]],
                                              None)
             return result
         if self.member.isMethod():
             methodinfo = ("%s_methodinfo" % self.member.identifier.name)
             name = CppKeywords.checkMethodName(self.member.identifier.name)
             # Actually a JSJitMethodOp, but JSJitGetterOp is first in the union.
             method = ("(JSJitGetterOp)%s" % name)
@@ -6272,17 +6271,17 @@ class CGMemberJITInfo(CGThing):
                 else:
                     args = None
 
             if args:
                 aliasSet = "AliasDOMSets"
             else:
                 aliasSet = "AliasEverything"
             result = self.defineJitInfo(methodinfo, method, "Method",
-                                        methodInfal, False, aliasSet, False, 0,
+                                        methodInfal, False, aliasSet, False, "0",
                                         [s[0] for s in sigs], args)
             return result
         raise TypeError("Illegal member type to CGPropertyJITInfo")
 
     @staticmethod
     def getJSReturnTypeTag(t):
         if t.nullable():
             # Sometimes it might return null, sometimes not
--- a/dom/bindings/JSSlots.h
+++ b/dom/bindings/JSSlots.h
@@ -20,16 +20,20 @@
 #define DOM_XRAY_EXPANDO_SLOT 1
 
 // We use slot 2 for holding either a JS::ObjectValue which points to the cached
 // SOW or JS::UndefinedValue if this class doesn't need SOWs. This is not safe
 // for globals until bug 760095 is fixed, so that bug blocks converting Window
 // to new bindings.
 #define DOM_OBJECT_SLOT_SOW 2
 
+// The total number of slots non-proxy DOM objects use by default.
+// Specific objects may have more for storing cached values.
+#define DOM_INSTANCE_RESERVED_SLOTS 3
+
 // NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
 // LSetDOMProperty. Those constants need to be changed accordingly if this value
 // changes.
 #define DOM_PROTO_INSTANCE_CLASS_SLOT 0
 
 // Interface objects store a number of reserved slots equal to
 // DOM_INTERFACE_SLOTS_BASE + number of named constructors.
 #define DOM_INTERFACE_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)