Bug 841059 - Do not use the ArenaHeader for getAllocKind on JSObject; r=billm
authorTerrence Cole <terrence@mozilla.com>
Thu, 14 Feb 2013 14:51:07 -0800
changeset 125938 5a97d33c3a071db58dd6b1d1f24d531e103bdb03
parent 125937 c4a29b7a2ead0b062b1f1c7c8846fc3e74cdbd09
child 125939 b170e3ee24c07c764325ca6e4e9d9a6c2b2a3d8e
push id25180
push userwmccloskey@mozilla.com
push dateFri, 22 Mar 2013 18:01:41 +0000
treeherdermozilla-inbound@4b3ba25df1af [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs841059
milestone22.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 841059 - Do not use the ArenaHeader for getAllocKind on JSObject; r=billm
dom/base/nsGlobalWindow.cpp
dom/bindings/Codegen.py
js/src/gc/Heap.h
js/src/jsapi-tests/testBug604087.cpp
js/src/jsfun.h
js/src/jsgcinlines.h
js/src/jsobjinlines.h
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/ObjectImpl.h
js/src/vm/String.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -524,17 +524,17 @@ class nsOuterWindowProxy : public js::Wr
 {
 public:
   nsOuterWindowProxy() : js::Wrapper(0) { }
 
   virtual bool isOuterWindow() {
     return true;
   }
 
-  virtual bool finalizeInBackground(JS::HandleValue priv) {
+  virtual bool finalizeInBackground(JS::Value priv) {
     return false;
   }
 
   virtual JSString *obj_toString(JSContext *cx,
                                  JS::Handle<JSObject*> wrapper) MOZ_OVERRIDE;
   virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
 
   // Fundamental traps
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6432,17 +6432,17 @@ class CGDOMJSProxyHandler_obj_toString(C
         args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'proxy')]
         ClassMethod.__init__(self, "obj_toString", "JSString*", args)
         self.descriptor = descriptor
     def getBody(self):
         return "return mozilla::dom::DOMProxyHandler::obj_toString(cx, \"%s\");" % self.descriptor.name
 
 class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod):
     def __init__(self, descriptor):
-        args = [Argument('JS::HandleValue', 'priv')]
+        args = [Argument('JS::Value', 'priv')]
         ClassMethod.__init__(self, "finalizeInBackground", "bool", args)
         self.descriptor = descriptor
     def getBody(self):
         return ("return false;")
 
 class CGDOMJSProxyHandler_finalize(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -81,16 +81,17 @@ static const size_t MAX_BACKGROUND_FINAL
 
 /*
  * A GC cell is the base class for all GC things.
  */
 struct Cell
 {
     inline ArenaHeader *arenaHeader() const;
     inline AllocKind getAllocKind() const;
+    inline AllocKind tenuredGetAllocKind() const;
     MOZ_ALWAYS_INLINE bool isMarked(uint32_t color = BLACK) const;
     MOZ_ALWAYS_INLINE bool markIfUnmarked(uint32_t color = BLACK) const;
     MOZ_ALWAYS_INLINE void unmark(uint32_t color) const;
 
     inline JSRuntime *runtime() const;
     inline Zone *tenuredZone() const;
 
 #ifdef DEBUG
@@ -950,16 +951,22 @@ Cell::runtime() const
 }
 
 AllocKind
 Cell::getAllocKind() const
 {
     return arenaHeader()->getAllocKind();
 }
 
+AllocKind
+Cell::tenuredGetAllocKind() const
+{
+    return arenaHeader()->getAllocKind();
+}
+
 bool
 Cell::isMarked(uint32_t color /* = BLACK */) const
 {
     JS_ASSERT(isTenured());
     AssertValidColor(this, color);
     return chunk()->bitmap.isMarked(this, color);
 }
 
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -17,17 +17,17 @@
 struct OuterWrapper : js::Wrapper
 {
     OuterWrapper() : Wrapper(0) {}
 
     virtual bool isOuterWindow() {
         return true;
     }
 
-    virtual bool finalizeInBackground(JS::HandleValue priv) {
+    virtual bool finalizeInBackground(JS::Value priv) {
         return false;
     }
 
     static OuterWrapper singleton;
 };
 
 OuterWrapper
 OuterWrapper::singleton;
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -268,30 +268,39 @@ class JSFunction : public JSObject
     inline size_t getBoundFunctionArgumentCount() const;
 
   private:
     inline js::FunctionExtended *toExtended();
     inline const js::FunctionExtended *toExtended() const;
 
     inline bool isExtended() const {
         JS_STATIC_ASSERT(FinalizeKind != ExtendedFinalizeKind);
-        JS_ASSERT(!!(flags & EXTENDED) == (getAllocKind() == ExtendedFinalizeKind));
+        JS_ASSERT_IF(isTenured(), !!(flags & EXTENDED) == (tenuredGetAllocKind() == ExtendedFinalizeKind));
         return !!(flags & EXTENDED);
     }
 
   public:
     /* Accessors for data stored in extended functions. */
     inline void initializeExtended();
     inline void setExtendedSlot(size_t which, const js::Value &val);
     inline const js::Value &getExtendedSlot(size_t which) const;
 
     /* Constructs a new type for the function if necessary. */
     static bool setTypeForScriptedFunction(JSContext *cx, js::HandleFunction fun,
                                            bool singleton = false);
 
+    /* GC support. */
+    js::gc::AllocKind getAllocKind() const {
+        js::gc::AllocKind kind = FinalizeKind;
+        if (isExtended())
+            kind = ExtendedFinalizeKind;
+        JS_ASSERT_IF(isTenured(), kind == tenuredGetAllocKind());
+        return kind;
+    }
+
   private:
     /*
      * These member functions are inherited from JSObject, but should never be applied to
      * a value statically known to be a JSFunction.
      */
     inline JSFunction *toFunction() MOZ_DELETE;
     inline const JSFunction *toFunction() const MOZ_DELETE;
 };
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -198,17 +198,17 @@ inline JSGCTraceKind
 GetGCThingTraceKind(const void *thing)
 {
     JS_ASSERT(thing);
     const Cell *cell = static_cast<const Cell *>(thing);
 #ifdef JSGC_GENERATIONAL
     if (IsInsideNursery(cell->runtime(), cell))
         return JSTRACE_OBJECT;
 #endif
-    return MapAllocToTraceKind(cell->getAllocKind());
+    return MapAllocToTraceKind(cell->tenuredGetAllocKind());
 }
 
 static inline void
 GCPoke(JSRuntime *rt)
 {
     rt->gcPoke = true;
 
 #ifdef JS_GC_ZEAL
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -230,17 +230,17 @@ JSObject::deleteSpecial(JSContext *cx, j
 }
 
 inline void
 JSObject::finalize(js::FreeOp *fop)
 {
     js::Probes::finalizeObject(this);
 
 #ifdef DEBUG
-    if (!IsBackgroundFinalized(getAllocKind())) {
+    if (!IsBackgroundFinalized(tenuredGetAllocKind())) {
         /* Assert we're on the main thread. */
         fop->runtime()->assertValidThread();
     }
 #endif
     js::Class *clasp = getClass();
     if (clasp->finalize)
         clasp->finalize(fop, this);
 
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -72,17 +72,17 @@ class JS_FRIEND_API(BaseProxyHandler) {
     inline void *family() {
         return mFamily;
     }
 
     virtual bool isOuterWindow() {
         return false;
     }
 
-    virtual bool finalizeInBackground(HandleValue priv) {
+    virtual bool finalizeInBackground(Value priv) {
         /*
          * Called on creation of a proxy to determine whether its finalize
          * method can be finalized on the background thread.
          */
         return true;
     }
 
     /* Policy enforcement traps.
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -195,17 +195,17 @@ CrossCompartmentWrapper::CrossCompartmen
   : Wrapper(CROSS_COMPARTMENT | flags, hasPrototype)
 {
 }
 
 CrossCompartmentWrapper::~CrossCompartmentWrapper()
 {
 }
 
-bool CrossCompartmentWrapper::finalizeInBackground(HandleValue priv)
+bool CrossCompartmentWrapper::finalizeInBackground(Value priv)
 {
     if (!priv.isObject())
         return true;
 
     /*
      * Make the 'background-finalized-ness' of the wrapper the same as the
      * wrapped object, to allow transplanting between them.
      */
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -78,17 +78,17 @@ class JS_FRIEND_API(Wrapper) : public Di
 /* Base class for all cross compartment wrapper handlers. */
 class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
 {
   public:
     CrossCompartmentWrapper(unsigned flags, bool hasPrototype = false);
 
     virtual ~CrossCompartmentWrapper();
 
-    virtual bool finalizeInBackground(HandleValue priv) MOZ_OVERRIDE;
+    virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE;
 
     /* ES5 Harmony fundamental wrapper traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -1089,16 +1089,17 @@ class ObjectImpl : public gc::Cell
                           "shadow type must match actual type");
         MOZ_STATIC_ASSERT(offsetof(ObjectImpl, slots) == offsetof(shadow::Object, slots),
                           "shadow slots must match actual slots");
         MOZ_STATIC_ASSERT(offsetof(ObjectImpl, elements) == offsetof(shadow::Object, _1),
                           "shadow placeholder must match actual elements");
     }
 
     JSObject * asObjectPtr() { return reinterpret_cast<JSObject *>(this); }
+    const JSObject * asObjectPtr() const { return reinterpret_cast<const JSObject *>(this); }
 
     friend inline Value ObjectValue(ObjectImpl &obj);
 
     /* These functions are public, and they should remain public. */
 
   public:
     JSObject * getProto() const {
         return type_->proto;
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -410,16 +410,17 @@ class JSString : public js::gc::Cell
         return offsetof(JSString, d.lengthAndFlags);
     }
 
     static size_t offsetOfChars() {
         return offsetof(JSString, d.u1.chars);
     }
 
     JS::Zone *zone() const { return tenuredZone(); }
+    js::gc::AllocKind getAllocKind() const { return tenuredGetAllocKind(); }
 
     static inline void writeBarrierPre(JSString *str);
     static inline void writeBarrierPost(JSString *str, void *addr);
     static inline bool needWriteBarrierPre(JS::Zone *zone);
     static inline void readBarrier(JSString *str);
 
     static inline js::ThingRootKind rootKind() { return js::THING_ROOT_STRING; }