Bug 1004457 - Remove unused mutable value operations from BarrieredBase; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Fri, 02 May 2014 16:33:18 -0700
changeset 181815 728803659bcbdbb59611ba6c8a4f03e938c12977
parent 181814 8b48386fc22687fb97c787c8bb4e435f5a2a9fe9
child 181816 bb50d61e7777360430155b246dc89b4c8da2902b
child 181837 8d591a3f6feadb1723a5e864361ad2ca6e71e6ee
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersjonco
bugs1004457
milestone32.0a1
Bug 1004457 - Remove unused mutable value operations from BarrieredBase; r=jonco
js/src/gc/Barrier.h
js/src/jit-test/tests/gc/bug-1004457.js
js/src/vm/ArgumentsObject.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -402,21 +402,24 @@ struct InternalGCMethods<jsid>
     }
     static void preBarrier(Zone *zone, jsid id) { preBarrier(id); }
 
     static void postBarrier(jsid *idp) {}
     static void postBarrierRelocate(jsid *idp) {}
     static void postBarrierRemove(jsid *idp) {}
 };
 
+template <typename T>
+class BarrieredBaseMixins {};
+
 /*
  * Base class for barriered pointer types.
  */
 template <class T>
-class BarrieredBase : public HeapBase<T>
+class BarrieredBase : public BarrieredBaseMixins<T>
 {
   protected:
     T value;
 
     BarrieredBase(T v) : value(v) {}
     ~BarrieredBase() { pre(); }
 
   public:
@@ -431,31 +434,41 @@ class BarrieredBase : public HeapBase<T>
     /* Use this if the automatic coercion to T isn't working. */
     const T &get() const { return value; }
 
     /*
      * Use these if you want to change the value without invoking the barrier.
      * Obviously this is dangerous unless you know the barrier is not needed.
      */
     T *unsafeGet() { return &value; }
+    const T *unsafeGet() const { return &value; }
     void unsafeSet(T v) { value = v; }
 
     T operator->() const { return value; }
 
     operator const T &() const { return value; }
 
     /* For users who need to manually barrier the raw types. */
     static void writeBarrierPre(const T &v) { InternalGCMethods<T>::preBarrier(v); }
     static void writeBarrierPost(const T &v, T *vp) { InternalGCMethods<T>::postBarrier(vp); }
 
   protected:
     void pre() { InternalGCMethods<T>::preBarrier(value); }
     void pre(Zone *zone) { InternalGCMethods<T>::preBarrier(zone, value); }
 };
 
+template <>
+class BarrieredBaseMixins<JS::Value> : public ValueOperations<BarrieredBase<JS::Value> >
+{
+    friend class ValueOperations<BarrieredBase<JS::Value> >;
+    const JS::Value * extract() const {
+        return static_cast<const BarrieredBase<JS::Value>*>(this)->unsafeGet();
+    }
+};
+
 /*
  * PreBarriered only automatically handles pre-barriers. Post-barriers must
  * be manually implemented when using this class. HeapPtr and RelocatablePtr
  * should be used in all cases that do not require explicit low-level control
  * of moving behavior, e.g. for HashMap keys.
  */
 template <class T>
 class PreBarriered : public BarrieredBase<T>
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1004457.js
@@ -0,0 +1,3 @@
+var argObj = (function () { return arguments })();
+gczeal(4);
+delete argObj.callee;
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -290,17 +290,17 @@ class NormalArgumentsObject : public Arg
      * been cleared.
      */
     const js::Value &callee() const {
         return data()->callee;
     }
 
     /* Clear the location storing arguments.callee's initial value. */
     void clearCallee() {
-        data()->callee.setMagic(JS_OVERWRITTEN_CALLEE);
+        data()->callee = MagicValue(JS_OVERWRITTEN_CALLEE);
     }
 };
 
 class StrictArgumentsObject : public ArgumentsObject
 {
   public:
     static const Class class_;
 };