Bug 1002737 - Convert PropDesc::pd_ to a JSObject *. (r=jorendorff)
authorEric Faust <efaustbmo@gmail.com>
Tue, 03 Jun 2014 12:37:44 -0700
changeset 207301 c14b461b3c244c41cfed02a753b83a1407ac86bf
parent 207300 d1a3b8ee7c7e017aa684eb42b82fe62ed68ed811
child 207302 a98a39b58a54faf6e343c947e7a5dce23d3b6a72
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [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
@@ -5329,17 +5329,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,14 @@ 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");
+    if (descObj_)
+        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)
     {
     }
@@ -75,17 +75,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)
@@ -133,18 +133,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());
     }
 
@@ -256,17 +259,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(); }
@@ -316,30 +319,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()));
     }
 };