Bug 1002737 - Convert PropDesc::pd_ to a JSObject *. (r=jorendorff)
☠☠ backed out by b922ed24938f ☠ ☠
authorEric Faust <efaustbmo@gmail.com>
Tue, 03 Jun 2014 12:37:44 -0700
changeset 205656 6d4043272a0a2084ad587fda3bae0e625911cc83
parent 205655 ad09630ae9a35a1aaec723d0df1ebc5b0569dee0
child 205657 5afce70dad1fb3411d40fb5043aa02df9bb0a3ef
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1002737
milestone32.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 1002737 - Convert PropDesc::pd_ to a JSObject *. (r=jorendorff)
js/src/jsobj.cpp
js/src/jsobjinlines.h
js/src/jsproxy.cpp
js/src/vm/Debugger.cpp
js/src/vm/ObjectImpl.cpp
js/src/vm/PropDesc.h
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -263,25 +263,25 @@ js::NewPropertyDescriptorObject(JSContex
         return true;
     }
 
     Rooted<PropDesc> d(cx);
 
     d.initFromPropertyDescriptor(desc);
     if (!d.makeObject(cx))
         return false;
-    vp.set(d.pd());
+    vp.set(d.descriptorValue());
     return true;
 }
 
 void
 PropDesc::initFromPropertyDescriptor(Handle<PropertyDescriptor> desc)
 {
     isUndefined_ = false;
-    pd_.setUndefined();
+    descObj_ = nullptr;
     attrs = uint8_t(desc.attributes());
     JS_ASSERT_IF(attrs & JSPROP_READONLY, !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
     if (desc.hasGetterOrSetterObject()) {
         hasGet_ = true;
         get_ = desc.hasGetterObject() && desc.getterObject()
                ? ObjectValue(*desc.getterObject())
                : UndefinedValue();
         hasSet_ = true;
@@ -328,17 +328,17 @@ PropDesc::makeObject(JSContext *cx)
         (hasValue() &&
          !JSObject::defineProperty(cx, obj, names.value, value())) ||
         (hasWritable() &&
          !JSObject::defineProperty(cx, obj, names.writable, writableVal)))
     {
         return false;
     }
 
-    pd_.setObject(*obj);
+    descObj_ = obj;
     return true;
 }
 
 bool
 js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
                              MutableHandle<PropertyDescriptor> desc)
 {
     // FIXME: Call TrapGetOwnProperty directly once ScriptedIndirectProxies is removed
@@ -438,17 +438,17 @@ PropDesc::initialize(JSContext *cx, cons
     /* 8.10.5 step 1 */
     if (v.isPrimitive()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT);
         return false;
     }
     RootedObject desc(cx, &v.toObject());
 
     /* Make a copy of the descriptor. We might need it later. */
-    pd_ = v;
+    descObj_ = desc;
 
     isUndefined_ = false;
 
     /*
      * Start with the proper defaults.  XXX shouldn't be necessary when we get
      * rid of PropDesc::attributes()
      */
     attrs = JSPROP_PERMANENT | JSPROP_READONLY;
@@ -1043,17 +1043,17 @@ js::DefineProperty(JSContext *cx, Handle
     }
 
     if (obj->getOps()->lookupGeneric) {
         /*
          * FIXME: Once ScriptedIndirectProxies are removed, this code should call
          * TrapDefineOwnProperty directly
          */
         if (obj->is<ProxyObject>()) {
-            RootedValue pd(cx, desc.pd());
+            RootedValue pd(cx, desc.descriptorValue());
             return Proxy::defineProperty(cx, obj, id, pd);
         }
         return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
     }
 
     return DefinePropertyOnObject(cx, obj, id, desc, throwError, rval);
 }
 
@@ -1130,17 +1130,17 @@ js::DefineProperties(JSContext *cx, Hand
 
     if (obj->getOps()->lookupGeneric) {
         /*
          * FIXME: Once ScriptedIndirectProxies are removed, this code should call
          * TrapDefineOwnProperty directly
          */
         if (obj->is<ProxyObject>()) {
             for (size_t i = 0, len = ids.length(); i < len; i++) {
-                RootedValue pd(cx, descs[i].pd());
+                RootedValue pd(cx, descs[i].descriptorValue());
                 if (!Proxy::defineProperty(cx, obj, ids[i], pd))
                     return false;
             }
             return true;
         }
         bool dummy;
         return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, true, &dummy);
     }
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -639,17 +639,17 @@ JSObject::isOwnGlobal() const
 {
     return &global() == this;
 }
 
 namespace js {
 
 PropDesc::PropDesc(const Value &getter, const Value &setter,
                    Enumerability enumerable, Configurability configurable)
-  : pd_(UndefinedValue()),
+  : descObj_(nullptr),
     value_(UndefinedValue()),
     get_(getter), set_(setter),
     attrs(JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED |
           (enumerable ? JSPROP_ENUMERATE : 0) |
           (configurable ? 0 : JSPROP_PERMANENT)),
     hasGet_(true), hasSet_(true),
     hasValue_(false), hasWritable_(false), hasEnumerable_(true), hasConfigurable_(true),
     isUndefined_(false)
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -1106,17 +1106,17 @@ FromGenericPropertyDescriptor(JSContext 
     if (desc.isUndefined()) {
         rval.setUndefined();
         return true;
     }
 
     // steps 3-9
     if (!desc.makeObject(cx))
         return false;
-    rval.set(desc.pd());
+    rval.set(desc.descriptorValue());
     return true;
 }
 
 /*
  * Aux.3 NormalizePropertyDescriptor(Attributes)
  *
  * NOTE: to minimize code duplication, the code for this function is shared with
  * that for Aux.4 NormalizeAndCompletePropertyDescriptor (see below). The
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5312,17 +5312,17 @@ DebuggerObject_defineProperty(JSContext 
 
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, args[0], &id))
         return false;
 
     Rooted<PropDesc> desc(cx);
     if (!desc.initialize(cx, args[1], false))
         return false;
-    desc.clearPd();
+    desc.clearDescriptorObject();
 
     if (!dbg->unwrapPropDescInto(cx, obj, desc, &desc))
         return false;
     if (!desc.checkGetter(cx) || !desc.checkSetter(cx))
         return false;
 
     {
         RootedId wrappedId(cx);
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -20,17 +20,17 @@ using JS::GenericNaN;
 PropDesc::PropDesc()
 {
     setUndefined();
 }
 
 void
 PropDesc::setUndefined()
 {
-    pd_ = UndefinedValue();
+    descObj_ = nullptr;
     value_ = UndefinedValue();
     get_ = UndefinedValue();
     set_ = UndefinedValue();
     attrs = 0;
     hasGet_ = false;
     hasSet_ = false;
     hasValue_ = false;
     hasWritable_ = false;
@@ -328,13 +328,13 @@ js::ObjectImpl::markChildren(JSTracer *t
         MarkObjectSlots(trc, obj, 0, obj->slotSpan());
         gc::MarkArraySlots(trc, obj->getDenseInitializedLength(), obj->getDenseElements(), "objectElements");
     }
 }
 
 void
 PropDesc::trace(JSTracer *trc)
 {
-    gc::MarkValueRoot(trc, &pd_, "PropDesc pd");
+    gc::MarkObjectRoot(trc, &descObj_, "PropDesc descriptor object");
     gc::MarkValueRoot(trc, &value_, "PropDesc value");
     gc::MarkValueRoot(trc, &get_, "PropDesc get");
     gc::MarkValueRoot(trc, &set_, "PropDesc set");
 }
--- a/js/src/vm/PropDesc.h
+++ b/js/src/vm/PropDesc.h
@@ -29,17 +29,17 @@ CastAsStrictPropertyOp(JSObject *object)
  * structure.
  */
 struct PropDesc {
   private:
     /*
      * Original object from which this descriptor derives, passed through for
      * the benefit of proxies.
      */
-    Value pd_;
+    JSObject *descObj_;
 
     Value value_, get_, set_;
 
     /* Property descriptor boolean fields. */
     uint8_t attrs;
 
     /* Bits indicating which values are set. */
     bool hasGet_ : 1;
@@ -48,17 +48,17 @@ struct PropDesc {
     bool hasWritable_ : 1;
     bool hasEnumerable_ : 1;
     bool hasConfigurable_ : 1;
 
     /* Or maybe this represents a property's absence, and it's undefined. */
     bool isUndefined_ : 1;
 
     explicit PropDesc(const Value &v)
-      : pd_(UndefinedValue()),
+      : descObj_(nullptr),
         value_(v),
         get_(UndefinedValue()), set_(UndefinedValue()),
         attrs(0),
         hasGet_(false), hasSet_(false),
         hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
         isUndefined_(false)
     {
     }
@@ -74,17 +74,17 @@ struct PropDesc {
 
     PropDesc();
 
     static PropDesc undefined() { return PropDesc(); }
     static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
 
     PropDesc(const Value &v, Writability writable,
              Enumerability enumerable, Configurability configurable)
-      : pd_(UndefinedValue()),
+      : descObj_(nullptr),
         value_(v),
         get_(UndefinedValue()), set_(UndefinedValue()),
         attrs((writable ? 0 : JSPROP_READONLY) |
               (enumerable ? JSPROP_ENUMERATE : 0) |
               (configurable ? 0 : JSPROP_PERMANENT)),
         hasGet_(false), hasSet_(false),
         hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
         isUndefined_(false)
@@ -132,18 +132,21 @@ struct PropDesc {
 
     bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
     bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
     bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
     bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
     bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
     bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
 
-    Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
-    void clearPd() { pd_ = UndefinedValue(); }
+    Value descriptorValue() const {
+        MOZ_ASSERT(!isUndefined());
+        return descObj_ ? ObjectValue(*descObj_) : UndefinedValue();
+    }
+    void clearDescriptorObject() { descObj_ = nullptr; }
 
     uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
 
     /* 8.10.1 IsAccessorDescriptor(desc) */
     bool isAccessorDescriptor() const {
         return !isUndefined() && (hasGet() || hasSet());
     }
 
@@ -255,17 +258,17 @@ class PropDescOperations
 
     bool hasGet() const { return desc()->hasGet(); }
     bool hasSet() const { return desc()->hasSet(); }
     bool hasValue() const { return desc()->hasValue(); }
     bool hasWritable() const { return desc()->hasWritable(); }
     bool hasEnumerable() const { return desc()->hasEnumerable(); }
     bool hasConfigurable() const { return desc()->hasConfigurable(); }
 
-    Value pd() const { return desc()->pd(); }
+    Value descriptorValue() const { return desc()->descriptorValue(); }
 
     uint8_t attributes() const { return desc()->attributes(); }
 
     bool isAccessorDescriptor() const { return desc()->isAccessorDescriptor(); }
     bool isDataDescriptor() const { return desc()->isDataDescriptor(); }
     bool isGenericDescriptor() const { return desc()->isGenericDescriptor(); }
     bool configurable() const { return desc()->configurable(); }
     bool enumerable() const { return desc()->enumerable(); }
@@ -315,30 +318,29 @@ class MutablePropDescOperations : public
     void setGetter(const Value &getter) {
         desc()->setGetter(getter);
     }
     void setSetter(const Value &setter) {
         desc()->setSetter(setter);
     }
 
     void setUndefined() { desc()->setUndefined(); }
-    void clearPd() { desc()->clearPd(); }
+    void clearDescriptorObject() { desc()->clearDescriptorObject(); }
 };
 
 } /* namespace JS */
 
 namespace js {
 
 template <>
 struct GCMethods<PropDesc> {
     static PropDesc initial() { return PropDesc(); }
     static ThingRootKind kind() { return THING_ROOT_PROP_DESC; }
     static bool poisoned(const PropDesc &desc) {
-        return (desc.pd_.isGCThing() &&
-                JS::IsPoisonedPtr(desc.pd_.toGCThing())) ||
+        return JS::IsPoisonedPtr(desc.descObj_) ||
                (desc.value_.isGCThing() &&
                 JS::IsPoisonedPtr(desc.value_.toGCThing())) ||
                (desc.get_.isGCThing() &&
                 JS::IsPoisonedPtr(desc.get_.toGCThing())) ||
                (desc.set_.isGCThing() &&
                 JS::IsPoisonedPtr(desc.set_.toGCThing()));
     }
 };