Bug 988751 - Remove DNP_DONT_PURGE. r=Waldo.
authorJason Orendorff <jorendorff@mozilla.com>
Fri, 25 Apr 2014 16:11:04 -0500
changeset 199912 33c51d23c9af194817934984d4fe80cfea2d9c17
parent 199911 8f91c4ac176bca51a81f013eca692de30dc483c8
child 199913 97fc047681a2e47741fe604119ee331eac531a1c
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs988751
milestone31.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 988751 - Remove DNP_DONT_PURGE. r=Waldo.
js/src/jit/IonCaches.cpp
js/src/jit/ParallelFunctions.cpp
js/src/jit/VMFunctions.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -2851,35 +2851,35 @@ SetPropertyParIC::update(ForkJoinContext
     IonScript *ion = GetTopIonJSScript(cx)->parallelIonScript();
     SetPropertyParIC &cache = ion->getCache(cacheIndex).toSetPropertyPar();
 
     RootedValue v(cx, value);
     RootedId id(cx, AtomToId(cache.name()));
 
     // Avoid unnecessary locking if cannot attach stubs.
     if (!cache.canAttachStub()) {
-        return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0,
-                                                             &v, cache.strict());
+        return baseops::SetPropertyHelper<ParallelExecution>(
+            cx, obj, obj, id, baseops::Qualified, &v, cache.strict());
     }
 
     SetPropertyIC::NativeSetPropCacheability canCache = SetPropertyIC::CanAttachNone;
     bool attachedStub = false;
 
     {
         // See note about locking context in GetPropertyParIC::update.
         LockedJSContext ncx(cx);
         AutoFlushCache afc("SetPropertyParCache", cx->runtime()->jitRuntime());
 
         if (cache.canAttachStub()) {
             bool alreadyStubbed;
             if (!cache.hasOrAddStubbedShape(ncx, obj->lastProperty(), &alreadyStubbed))
                 return cx->setPendingAbortFatal(ParallelBailoutFailedIC);
             if (alreadyStubbed) {
-                return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0,
-                                                                     &v, cache.strict());
+                return baseops::SetPropertyHelper<ParallelExecution>(
+                    cx, obj, obj, id, baseops::Qualified, &v, cache.strict());
             }
 
             // If the object has a lazy type, we need to de-lazify it, but
             // this is not safe in parallel.
             if (obj->hasLazyType())
                 return false;
 
             {
@@ -2896,18 +2896,21 @@ SetPropertyParIC::update(ForkJoinContext
                 }
             }
         }
     }
 
     uint32_t oldSlots = obj->numDynamicSlots();
     RootedShape oldShape(cx, obj->lastProperty());
 
-    if (!baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0, &v, cache.strict()))
+    if (!baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
+                                                       cache.strict()))
+    {
         return false;
+    }
 
     bool checkTypeset;
     if (!attachedStub && canCache == SetPropertyIC::MaybeCanAttachAddSlot &&
         IsPropertyAddInlineable(obj, id, cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(),
                                 &checkTypeset))
     {
         LockedJSContext ncx(cx);
         if (cache.canAttachStub() && !cache.attachAddSlot(ncx, ion, obj, oldShape, checkTypeset))
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -251,34 +251,36 @@ jit::SetPropertyPar(ForkJoinContext *cx,
     }
 
     // Fail early on hooks.
     if (obj->getOps()->setProperty)
         return TP_RETRY_SEQUENTIALLY;
 
     RootedValue v(cx, value);
     RootedId id(cx, NameToId(name));
-    return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0, &v, strict);
+    return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
+                                                         strict);
 }
 
 bool
 jit::SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index, HandleValue value,
                    bool strict)
 {
     RootedId id(cx);
     if (!ValueToIdPure(index, id.address()))
         return false;
 
     // SetObjectElementOperation, the sequential version, has several checks
     // for certain deoptimizing behaviors, such as marking having written to
     // holes and non-indexed element accesses. We don't do that here, as we
     // can't modify any TI state anyways. If we need to add a new type, we
     // would bail out.
     RootedValue v(cx, value);
-    return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, 0, &v, strict);
+    return baseops::SetPropertyHelper<ParallelExecution>(cx, obj, obj, id, baseops::Qualified, &v,
+                                                         strict);
 }
 
 bool
 jit::SetDenseElementPar(ForkJoinContext *cx, HandleObject obj, int32_t index, HandleValue value,
                         bool strict)
 {
     RootedValue indexVal(cx, Int32Value(index));
     return SetElementPar(cx, obj, indexVal, value, strict);
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -492,19 +492,23 @@ SetProperty(JSContext *cx, HandleObject 
         // required for initializing 'const' closure variables.
         Shape *shape = obj->nativeLookup(cx, name);
         JS_ASSERT(shape && shape->hasSlot());
         obj->nativeSetSlotWithType(cx, shape, value);
         return true;
     }
 
     if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
-        unsigned defineHow = (op == JSOP_SETNAME || op == JSOP_SETGNAME) ? DNP_UNQUALIFIED : 0;
-        return baseops::SetPropertyHelper<SequentialExecution>(cx, obj, obj, id, defineHow, &v,
-                                                               strict);
+        return baseops::SetPropertyHelper<SequentialExecution>(
+            cx, obj, obj, id,
+            (op == JSOP_SETNAME || op == JSOP_SETGNAME)
+            ? baseops::Unqualified
+            : baseops::Qualified,
+            &v,
+            strict);
     }
 
     return JSObject::setGeneric(cx, obj, obj, id, &v, strict);
 }
 
 bool
 InterruptCheck(JSContext *cx)
 {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3767,20 +3767,18 @@ DefinePropertyOrElement(typename Executi
 }
 
 static bool
 NativeLookupOwnProperty(ExclusiveContext *cx, HandleObject obj, HandleId id,
                         MutableHandle<Shape*> shapep);
 
 bool
 js::DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
-                         PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
-                         unsigned defineHow /* = 0 */)
-{
-    JS_ASSERT((defineHow & ~DNP_DONT_PURGE) == 0);
+                         PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
+{
     JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
     /*
      * If defining a getter or setter, we must check for its counterpart and
      * update the attributes and property ops.  A getter or setter is really
      * only half of a property.
@@ -3817,23 +3815,20 @@ js::DefineNativeProperty(ExclusiveContex
             } else {
                 shape = nullptr;
             }
         }
     }
 
     /*
      * Purge the property cache of any properties named by id that are about
-     * to be shadowed in obj's scope chain unless it is known a priori that it
-     * is not possible.
+     * to be shadowed in obj's scope chain.
      */
-    if (!(defineHow & DNP_DONT_PURGE)) {
-        if (!PurgeScopeChain(cx, obj, id))
-            return false;
-    }
+    if (!PurgeScopeChain(cx, obj, id))
+        return false;
 
     /* Use the object's class getter and setter by default. */
     const Class *clasp = obj->getClass();
     if (!getter && !(attrs & JSPROP_GETTER))
         getter = clasp->getProperty;
     if (!setter && !(attrs & JSPROP_SETTER))
         setter = clasp->setProperty;
 
@@ -4823,20 +4818,19 @@ JSObject::callMethod(JSContext *cx, Hand
         return false;
     return Invoke(cx, ObjectValue(*obj), fval, argc, argv, vp);
 }
 
 template <ExecutionMode mode>
 bool
 baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg,
                            HandleObject obj, HandleObject receiver, HandleId id,
-                           unsigned defineHow, MutableHandleValue vp, bool strict)
+                           QualifiedBool qualified, MutableHandleValue vp, bool strict)
 {
     JS_ASSERT(cxArg->isThreadLocal(obj));
-    JS_ASSERT((defineHow & ~DNP_UNQUALIFIED) == 0);
 
     if (MOZ_UNLIKELY(obj->watched())) {
         if (mode == ParallelExecution)
             return false;
 
         /* Fire watchpoints, if any. */
         JSContext *cx = cxArg->asJSContext();
         WatchpointMap *wpmap = cx->compartment()->watchpointMap;
@@ -4880,17 +4874,17 @@ baseops::SetPropertyHelper(typename Exec
             }
 
             shape = nullptr;
         }
     } else {
         /* We should never add properties to lexical blocks. */
         JS_ASSERT(!obj->is<BlockObject>());
 
-        if (obj->is<GlobalObject>() && (defineHow & DNP_UNQUALIFIED)) {
+        if (obj->is<GlobalObject>() && !qualified) {
             if (mode == ParallelExecution)
                 return false;
 
             if (!MaybeReportUndeclaredVarAssignment(cxArg->asJSContext(), JSID_TO_STRING(id)))
                 return false;
         }
     }
 
@@ -5061,33 +5055,33 @@ baseops::SetPropertyHelper(typename Exec
                                              attrs, vp, true, strict);
     }
 
     return NativeSet<mode>(cxArg, obj, receiver, shape, strict, vp);
 }
 
 template bool
 baseops::SetPropertyHelper<SequentialExecution>(JSContext *cx, HandleObject obj,
-                                                HandleObject receiver,
-                                                HandleId id, unsigned defineHow,
+                                                HandleObject receiver, HandleId id,
+                                                QualifiedBool qualified,
                                                 MutableHandleValue vp, bool strict);
 template bool
 baseops::SetPropertyHelper<ParallelExecution>(ForkJoinContext *cx, HandleObject obj,
-                                              HandleObject receiver,
-                                              HandleId id, unsigned defineHow,
+                                              HandleObject receiver, HandleId id,
+                                              QualifiedBool qualified,
                                               MutableHandleValue vp, bool strict);
 
 bool
 baseops::SetElementHelper(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
-                          unsigned defineHow, MutableHandleValue vp, bool strict)
+                          MutableHandleValue vp, bool strict)
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, &id))
         return false;
-    return baseops::SetPropertyHelper<SequentialExecution>(cx, obj, receiver, id, defineHow, vp,
+    return baseops::SetPropertyHelper<SequentialExecution>(cx, obj, receiver, id, Qualified, vp,
                                                            strict);
 }
 
 bool
 baseops::GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     RootedObject nobj(cx);
     RootedShape shape(cx);
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -114,35 +114,37 @@ GetProperty(JSContext *cx, HandleObject 
 }
 
 inline bool
 GetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
 {
     return GetElement(cx, obj, obj, index, vp);
 }
 
+/*
+ * Indicates whether an assignment operation is qualified (`x.y = 0`) or
+ * unqualified (`y = 0`). In strict mode, the latter is an error if no such
+ * variable already exists.
+ *
+ * Used as an argument to baseops::SetPropertyHelper.
+ */
+enum QualifiedBool {
+    Unqualified = 0,
+    Qualified = 1
+};
+
 template <ExecutionMode mode>
 extern bool
 SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cx, HandleObject obj,
-                  HandleObject receiver, HandleId id, unsigned defineHow,
+                  HandleObject receiver, HandleId id, QualifiedBool qualified,
                   MutableHandleValue vp, bool strict);
 
-template <ExecutionMode mode>
-inline bool
-SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cx, HandleObject obj,
-                  HandleObject receiver, PropertyName *name, unsigned defineHow,
-                  MutableHandleValue vp, bool strict)
-{
-    Rooted<jsid> id(cx, NameToId(name));
-    return SetPropertyHelper<mode>(cx, obj, receiver, id, defineHow, vp, strict);
-}
-
 extern bool
 SetElementHelper(JSContext *cx, HandleObject obj, HandleObject Receiver, uint32_t index,
-                 unsigned defineHow, MutableHandleValue vp, bool strict);
+                 MutableHandleValue vp, bool strict);
 
 extern bool
 GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
 
 extern bool
 SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
 
 extern bool
@@ -1013,34 +1015,34 @@ class JSObject : public js::ObjectImpl
     static inline bool getElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver,
                                       uint32_t index, js::Value *vp);
 
     static bool setGeneric(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
                            js::HandleId id, js::MutableHandleValue vp, bool strict)
     {
         if (obj->getOps()->setGeneric)
             return nonNativeSetProperty(cx, obj, id, vp, strict);
-        return js::baseops::SetPropertyHelper<js::SequentialExecution>(cx, obj, receiver, id, 0,
-                                                                       vp, strict);
+        return js::baseops::SetPropertyHelper<js::SequentialExecution>(
+            cx, obj, receiver, id, js::baseops::Qualified, vp, strict);
     }
 
     static bool setProperty(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
                             js::PropertyName *name,
                             js::MutableHandleValue vp, bool strict)
     {
         JS::RootedId id(cx, js::NameToId(name));
         return setGeneric(cx, obj, receiver, id, vp, strict);
     }
 
     static bool setElement(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
                            uint32_t index, js::MutableHandleValue vp, bool strict)
     {
         if (obj->getOps()->setElement)
             return nonNativeSetElement(cx, obj, index, vp, strict);
-        return js::baseops::SetElementHelper(cx, obj, receiver, index, 0, vp, strict);
+        return js::baseops::SetElementHelper(cx, obj, receiver, index, vp, strict);
     }
 
     static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj,
                                      js::HandleId id, js::MutableHandleValue vp, bool strict);
     static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj,
                                     uint32_t index, js::MutableHandleValue vp, bool strict);
 
     static bool getGenericAttributes(JSContext *cx, js::HandleObject obj,
@@ -1360,36 +1362,21 @@ CreateThis(JSContext *cx, const js::Clas
 
 extern JSObject *
 CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent);
 
 extern JSObject *
 DeepCloneObjectLiteral(JSContext *cx, HandleObject obj, NewObjectKind newKind = GenericObject);
 
 /*
- * Flags for the defineHow parameter of DefineNativeProperty.
- */
-enum {
-    /* Suppress js_PurgeScopeChain. */
-    DNP_DONT_PURGE   = 1,
-
-    /*
-     * Unqualified property set.  Only used in the defineHow argument of
-     * js_SetPropertyHelper.
-     */
-    DNP_UNQUALIFIED  = 2
-};
-
-/*
  * Return successfully added or changed shape or nullptr on error.
  */
 extern bool
 DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
-                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
-                     unsigned defineHow = 0);
+                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
 
 extern bool
 LookupNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id,
                      js::MutableHandleObject objp, js::MutableHandleShape propp);
 
 /*
  * Call the [[DefineOwnProperty]] internal method of obj.
  *
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1067,21 +1067,20 @@ NewObjectMetadata(ExclusiveContext *cxAr
                 return false;
         }
     }
     return true;
 }
 
 inline bool
 DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
-                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
-                     unsigned defineHow = 0)
+                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
 {
     Rooted<jsid> id(cx, NameToId(name));
-    return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, defineHow);
+    return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs);
 }
 
 namespace baseops {
 
 inline bool
 LookupProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name,
                MutableHandleObject objp, MutableHandleShape propp)
 {
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -234,23 +234,24 @@ SetNameOperation(JSContext *cx, JSScript
 
     bool strict = script->strict();
     RootedPropertyName name(cx, script->getName(pc));
     RootedValue valCopy(cx, val);
 
     /*
      * In strict-mode, we need to trigger an error when trying to assign to an
      * undeclared global variable. To do this, we call SetPropertyHelper
-     * directly and pass DNP_UNQUALIFIED.
+     * directly and pass Unqualified.
      */
     if (scope->is<GlobalObject>()) {
         JS_ASSERT(!scope->getOps()->setProperty);
         RootedId id(cx, NameToId(name));
         return baseops::SetPropertyHelper<SequentialExecution>(cx, scope, scope, id,
-                                                               DNP_UNQUALIFIED, &valCopy, strict);
+                                                               baseops::Unqualified, &valCopy,
+                                                               strict);
     }
 
     return JSObject::setProperty(cx, scope, scope, name, &valCopy, strict);
 }
 
 inline bool
 DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn, unsigned attrs)
 {
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -326,17 +326,17 @@ SetPropertyOperation(JSContext *cx, Hand
     RootedObject obj(cx, ToObjectFromStack(cx, lval));
     if (!obj)
         return false;
 
     RootedValue rref(cx, rval);
 
     RootedId id(cx, NameToId(script->getName(pc)));
     if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
-        if (!baseops::SetPropertyHelper<SequentialExecution>(cx, obj, obj, id, 0,
+        if (!baseops::SetPropertyHelper<SequentialExecution>(cx, obj, obj, id, baseops::Qualified,
                                                              &rref, script->strict()))
         {
             return false;
         }
     } else {
         if (!JSObject::setGeneric(cx, obj, obj, id, &rref, script->strict()))
             return false;
     }