Bug 914032 (part 2) - Move a bunch of stuff out of -inl.h files. r=terrence.
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 09 Sep 2013 15:50:06 -0700
changeset 146316 ea1af870680c7ec875f0bce61c8541cc37a3b9d6
parent 146315 c8175c00be1e28f7e4321d0f4caea8b5740a7b38
child 146317 ea33604f6232a07d3e4be77718226d569490407f
push id25251
push userMs2ger@gmail.com
push dateTue, 10 Sep 2013 08:13:39 +0000
treeherdermozilla-central@25bfaa953892 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs914032
milestone26.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 914032 (part 2) - Move a bunch of stuff out of -inl.h files. r=terrence.
js/src/builtin/Iterator-inl.h
js/src/builtin/RegExp.cpp
js/src/gc/Barrier.cpp
js/src/gc/Barrier.h
js/src/gc/Heap.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobj.h
js/src/vm/ObjectImpl-inl.h
js/src/vm/ObjectImpl.cpp
js/src/vm/ObjectImpl.h
js/src/vm/RegExpObject-inl.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
deleted file mode 100644
--- a/js/src/builtin/Iterator-inl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef builtin_Iterator_inl_h
-#define builtin_Iterator_inl_h
-
-#include "jsiter.h"
-
-#include "vm/ObjectImpl-inl.h"
-
-inline void
-js::PropertyIteratorObject::setNativeIterator(js::NativeIterator *ni)
-{
-    setPrivate(ni);
-}
-
-#endif /* builtin_Iterator_inl_h */
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -8,17 +8,16 @@
 
 #include "jscntxt.h"
 
 #include "vm/RegExpStatics.h"
 #include "vm/StringBuffer.h"
 
 #include "jsobjinlines.h"
 
-#include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 
 using namespace js;
 using namespace js::types;
 
 using mozilla::ArrayLength;
 
 static inline bool
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -44,11 +44,16 @@ HeapSlot::preconditionForSet(Zone *zone,
 void
 HeapSlot::preconditionForWriteBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target)
 {
     JS_ASSERT_IF(kind == Slot, obj->getSlotAddressUnchecked(slot)->get() == target);
     JS_ASSERT_IF(kind == Element,
                  static_cast<HeapSlot *>(obj->getDenseElements() + slot)->get() == target);
 }
 
+bool
+RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone *shadowZone)
+{
+    return shadowZone->runtimeFromMainThread()->isHeapMajorCollecting();
+}
 #endif // DEBUG
 
 } // namespace js
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -917,11 +917,16 @@ class ReadBarrieredValue
 
     inline const Value &get() const;
     Value *unsafeGet() { return &value; }
     inline operator const Value &() const;
 
     inline JSObject &toObject() const;
 };
 
+#ifdef DEBUG
+bool
+RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone *shadowZone);
+#endif
+
 } /* namespace js */
 
 #endif /* gc_Barrier_h */
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -94,16 +94,17 @@ struct Cell
   public:
     inline ArenaHeader *arenaHeader() 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 *runtimeFromMainThread() const;
+    inline JS::shadow::Runtime *shadowRuntimeFromMainThread() const;
     inline JS::Zone *tenuredZone() const;
     inline bool tenuredIsInsideZone(JS::Zone *zone) const;
 
     // Note: Unrestricted access to the runtime of a GC thing from an arbitrary
     // thread can easily lead to races. Use this method very carefully.
     inline JSRuntime *runtimeFromAnyThread() const;
     inline JS::shadow::Runtime *shadowRuntimeFromAnyThread() const;
 
@@ -958,16 +959,22 @@ Cell::arenaHeader() const
 inline JSRuntime *
 Cell::runtimeFromMainThread() const
 {
     JSRuntime *rt = chunk()->info.runtime;
     JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
     return rt;
 }
 
+inline JS::shadow::Runtime *
+Cell::shadowRuntimeFromMainThread() const
+{
+    return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread());
+}
+
 inline JSRuntime *
 Cell::runtimeFromAnyThread() const
 {
     return chunk()->info.runtime;
 }
 
 inline JS::shadow::Runtime *
 Cell::shadowRuntimeFromAnyThread() const
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -30,17 +30,16 @@
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/Shape.h"
 #include "vm/StopIterationObject.h"
 
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
-#include "builtin/Iterator-inl.h"
 #include "vm/Stack-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::ArrayLength;
 #ifdef JS_MORE_DETERMINISTIC
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -117,17 +117,19 @@ struct NativeIterator
 class PropertyIteratorObject : public JSObject
 {
   public:
     static Class class_;
 
     NativeIterator *getNativeIterator() const {
         return static_cast<js::NativeIterator *>(getPrivate());
     }
-    inline void setNativeIterator(js::NativeIterator *ni);
+    void setNativeIterator(js::NativeIterator *ni) {
+        setPrivate(ni);
+    }
 
     size_t sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const;
 
   private:
     static void trace(JSTracer *trc, JSObject *obj);
     static void finalize(FreeOp *fop, JSObject *obj);
 };
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -360,18 +360,18 @@ class JSObject : public js::ObjectImpl
         JS_ASSERT(end <= getDenseInitializedLength());
         for (size_t i = start; i < end; i++)
             elements[i].js::HeapSlot::~HeapSlot();
     }
 
     void rollbackProperties(js::ExclusiveContext *cx, uint32_t slotSpan);
 
     void nativeSetSlot(uint32_t slot, const js::Value &value) {
-        JS_ASSERT(uninlinedIsNative());
-        JS_ASSERT(slot < uninlinedSlotSpan());
+        JS_ASSERT(isNative());
+        JS_ASSERT(slot < slotSpan());
         return setSlot(slot, value);
     }
 
     static inline void nativeSetSlotWithType(js::ExclusiveContext *cx,
                                              js::HandleObject, js::Shape *shape,
                                              const js::Value &value);
 
     inline const js::Value &getReservedSlot(uint32_t index) const {
@@ -558,37 +558,37 @@ class JSObject : public js::ObjectImpl
     void shrinkElements(js::ThreadSafeContext *cx, uint32_t cap);
     void setDynamicElements(js::ObjectElements *header) {
         JS_ASSERT(!hasDynamicElements());
         elements = header->elements();
         JS_ASSERT(hasDynamicElements());
     }
 
     uint32_t getDenseCapacity() {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         JS_ASSERT(getElementsHeader()->capacity >= getElementsHeader()->initializedLength);
         return getElementsHeader()->capacity;
     }
 
     void setDenseInitializedLength(uint32_t length) {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         JS_ASSERT(length <= getDenseCapacity());
         prepareElementRangeForOverwrite(length, getElementsHeader()->initializedLength);
         getElementsHeader()->initializedLength = length;
     }
 
     inline void ensureDenseInitializedLength(js::ExclusiveContext *cx,
                                              uint32_t index, uint32_t extra);
     void setDenseElement(uint32_t index, const js::Value &val) {
-        JS_ASSERT(uninlinedIsNative() && index < getDenseInitializedLength());
+        JS_ASSERT(isNative() && index < getDenseInitializedLength());
         elements[index].set(this, js::HeapSlot::Element, index, val);
     }
 
     void initDenseElement(uint32_t index, const js::Value &val) {
-        JS_ASSERT(uninlinedIsNative() && index < getDenseInitializedLength());
+        JS_ASSERT(isNative() && index < getDenseInitializedLength());
         elements[index].init(this, js::HeapSlot::Element, index, val);
     }
 
     void setDenseElementMaybeConvertDouble(uint32_t index, const js::Value &val) {
         if (val.isInt32() && shouldConvertDoubleElements())
             setDenseElement(index, js::DoubleValue(val.toInt32()));
         else
             setDenseElement(index, val);
@@ -610,17 +610,17 @@ class JSObject : public js::ObjectImpl
         for (uint32_t i = 0; i < count; ++i)
             elements[dstStart + i].init(rt, this, js::HeapSlot::Element, dstStart + i, src[i]);
     }
 
     inline void moveDenseElements(uint32_t dstStart, uint32_t srcStart, uint32_t count);
     inline void moveDenseElementsUnbarriered(uint32_t dstStart, uint32_t srcStart, uint32_t count);
 
     bool shouldConvertDoubleElements() {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         return getElementsHeader()->shouldConvertDoubleElements();
     }
 
     inline void setShouldConvertDoubleElements();
 
     /* Packed information for this object's elements. */
     inline void markDenseElementsNotPacked(js::ExclusiveContext *cx);
 
--- a/js/src/vm/ObjectImpl-inl.h
+++ b/js/src/vm/ObjectImpl-inl.h
@@ -14,154 +14,24 @@
 #include "jsgc.h"
 #include "jsproxy.h"
 
 #include "gc/Marking.h"
 #include "vm/ProxyObject.h"
 
 #include "gc/Barrier-inl.h"
 
-inline JSCompartment *
-js::ObjectImpl::compartment() const
-{
-    return lastProperty()->base()->compartment();
-}
-
-inline bool
-js::ObjectImpl::nativeContains(ExclusiveContext *cx, Shape *shape)
-{
-    return nativeLookup(cx, shape->propid()) == shape;
-}
-
-inline bool
-js::ObjectImpl::nativeContainsPure(Shape *shape)
-{
-    return nativeLookupPure(shape->propid()) == shape;
-}
-
-inline bool
-js::ObjectImpl::nonProxyIsExtensible() const
-{
-    MOZ_ASSERT(!asObjectPtr()->is<ProxyObject>());
-
-    // [[Extensible]] for ordinary non-proxy objects is an object flag.
-    return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
-}
-
 /* static */ inline bool
 js::ObjectImpl::isExtensible(ExclusiveContext *cx, js::Handle<ObjectImpl*> obj, bool *extensible)
 {
     if (obj->asObjectPtr()->is<ProxyObject>()) {
         if (!cx->shouldBeJSContext())
             return false;
         HandleObject h =
             HandleObject::fromMarkedLocation(reinterpret_cast<JSObject* const*>(obj.address()));
         return Proxy::isExtensible(cx->asJSContext(), h, extensible);
     }
 
     *extensible = obj->nonProxyIsExtensible();
     return true;
 }
 
-inline bool
-js::ObjectImpl::isNative() const
-{
-    return lastProperty()->isNative();
-}
-
-inline uint32_t
-js::ObjectImpl::slotSpan() const
-{
-    if (inDictionaryMode())
-        return lastProperty()->base()->slotSpan();
-    return lastProperty()->slotSpan();
-}
-
-inline uint32_t
-js::ObjectImpl::numDynamicSlots() const
-{
-    return dynamicSlotsCount(numFixedSlots(), slotSpan());
-}
-
-inline bool
-js::ObjectImpl::isDelegate() const
-{
-    return lastProperty()->hasObjectFlag(BaseShape::DELEGATE);
-}
-
-inline bool
-js::ObjectImpl::inDictionaryMode() const
-{
-    return lastProperty()->inDictionary();
-}
-
-JS_ALWAYS_INLINE JS::Zone *
-js::ObjectImpl::zone() const
-{
-    JS_ASSERT(CurrentThreadCanAccessZone(shape_->zone()));
-    return shape_->zone();
-}
-
-/* static */ inline void
-js::ObjectImpl::readBarrier(ObjectImpl *obj)
-{
-#ifdef JSGC_INCREMENTAL
-    Zone *zone = obj->zone();
-    if (zone->needsBarrier()) {
-        MOZ_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting());
-        JSObject *tmp = obj->asObjectPtr();
-        MarkObjectUnbarriered(zone->barrierTracer(), &tmp, "read barrier");
-        MOZ_ASSERT(tmp == obj->asObjectPtr());
-    }
-#endif
-}
-
-inline void
-js::ObjectImpl::privateWriteBarrierPre(void **old)
-{
-#ifdef JSGC_INCREMENTAL
-    Zone *zone = this->zone();
-    if (zone->needsBarrier()) {
-        if (*old && getClass()->trace)
-            getClass()->trace(zone->barrierTracer(), this->asObjectPtr());
-    }
-#endif
-}
-
-/* static */ inline void
-js::ObjectImpl::writeBarrierPre(ObjectImpl *obj)
-{
-#ifdef JSGC_INCREMENTAL
-    /*
-     * This would normally be a null test, but TypeScript::global uses 0x1 as a
-     * special value.
-     */
-    if (IsNullTaggedPointer(obj) || !obj->runtimeFromMainThread()->needsBarrier())
-        return;
-
-    Zone *zone = obj->zone();
-    if (zone->needsBarrier()) {
-        MOZ_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting());
-        JSObject *tmp = obj->asObjectPtr();
-        MarkObjectUnbarriered(zone->barrierTracer(), &tmp, "write barrier");
-        MOZ_ASSERT(tmp == obj->asObjectPtr());
-    }
-#endif
-}
-
-inline void
-js::ObjectImpl::setPrivate(void *data)
-{
-    void **pprivate = &privateRef(numFixedSlots());
-    privateWriteBarrierPre(pprivate);
-    *pprivate = data;
-}
-
-inline void
-js::ObjectImpl::setPrivateGCThing(js::gc::Cell *cell)
-{
-    void **pprivate = &privateRef(numFixedSlots());
-    privateWriteBarrierPre(pprivate);
-    *pprivate = reinterpret_cast<void *>(cell);
-    privateWriteBarrierPost(pprivate);
-}
-
 #endif /* vm_ObjectImpl_inl_h */
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -11,34 +11,16 @@
 #include "vm/Debugger.h"
 
 #include "jsobjinlines.h"
 
 #include "gc/Barrier-inl.h"
 
 using namespace js;
 
-JSCompartment *
-js::ObjectImpl::uninlinedCompartment() const
-{
-    return compartment();
-}
-
-bool
-js::ObjectImpl::uninlinedIsNative() const
-{
-    return isNative();
-}
-
-uint32_t
-js::ObjectImpl::uninlinedSlotSpan() const
-{
-    return slotSpan();
-}
-
 PropDesc::PropDesc()
   : pd_(UndefinedValue()),
     value_(UndefinedValue()),
     get_(UndefinedValue()),
     set_(UndefinedValue()),
     attrs(0),
     hasGet_(false),
     hasSet_(false),
@@ -299,16 +281,22 @@ js::ObjectImpl::copySlotRange(uint32_t s
     for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
         sp->set(zone, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
     for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
         sp->set(zone, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
 }
 
 #ifdef DEBUG
 bool
+js::ObjectImpl::isProxy() const
+{
+    return asObjectPtr()->is<ProxyObject>();
+}
+
+bool
 js::ObjectImpl::slotInRange(uint32_t slot, SentinelAllowed sentinel) const
 {
     uint32_t capacity = numFixedSlots() + numDynamicSlots();
     if (sentinel == SENTINEL_ALLOWED)
         return slot <= capacity;
     return slot < capacity;
 }
 #endif /* DEBUG */
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -975,42 +975,51 @@ class ObjectImpl : public gc::Cell
 
     static inline bool
     isExtensible(ExclusiveContext *cx, Handle<ObjectImpl*> obj, bool *extensible);
 
     // Indicates whether a non-proxy is extensible.  Don't call on proxies!
     // This method really shouldn't exist -- but there are a few internal
     // places that want it (JITs and the like), and it'd be a pain to mark them
     // all as friends.
-    inline bool nonProxyIsExtensible() const;
+    bool nonProxyIsExtensible() const {
+        MOZ_ASSERT(!isProxy());
+
+        // [[Extensible]] for ordinary non-proxy objects is an object flag.
+        return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
+    }
+
+#ifdef DEBUG
+    bool isProxy() const;
+#endif
 
     // Attempt to change the [[Extensible]] bit on |obj| to false.  Callers
     // must ensure that |obj| is currently extensible before calling this!
     static bool
     preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj);
 
     HeapSlotArray getDenseElements() {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         return HeapSlotArray(elements);
     }
     const Value &getDenseElement(uint32_t idx) {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         MOZ_ASSERT(idx < getDenseInitializedLength());
         return elements[idx];
     }
     bool containsDenseElement(uint32_t idx) {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         return idx < getDenseInitializedLength() && !elements[idx].isMagic(JS_ELEMENTS_HOLE);
     }
     uint32_t getDenseInitializedLength() {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         return getElementsHeader()->initializedLength;
     }
     uint32_t getDenseCapacity() {
-        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(isNative());
         return getElementsHeader()->capacity;
     }
 
     bool makeElementsSparse(JSContext *cx) {
         JS_NEW_OBJECT_REPRESENTATION_ONLY();
         MOZ_ASSUME_UNREACHABLE("NYI");
     }
 
@@ -1156,23 +1165,23 @@ class ObjectImpl : public gc::Cell
         MOZ_ASSERT(shape_);
         return shape_;
     }
 
     bool generateOwnShape(ExclusiveContext *cx, js::Shape *newShape = NULL) {
         return replaceWithNewEquivalentShape(cx, lastProperty(), newShape);
     }
 
-    // uninlinedCompartment() is equivalent to compartment(), but isn't inlined.
-    inline JSCompartment *compartment() const;
-    JSCompartment *uninlinedCompartment() const;
+    JSCompartment *compartment() const {
+        return lastProperty()->base()->compartment();
+    }
 
-    // uninlinedIsNative() is equivalent to isNative(), but isn't inlined.
-    inline bool isNative() const;
-    bool uninlinedIsNative() const;
+    bool isNative() const {
+        return lastProperty()->isNative();
+    }
 
     types::TypeObject *type() const {
         MOZ_ASSERT(!hasLazyType());
         return type_;
     }
 
     uint32_t numFixedSlots() const {
         return reinterpret_cast<const shadow::Object *>(this)->numFixedSlots();
@@ -1185,38 +1194,44 @@ class ObjectImpl : public gc::Cell
     bool hasSingletonType() const { return !!type_->singleton; }
 
     /*
      * Whether the object's type has not been constructed yet. If an object
      * might have a lazy type, use getType() below, otherwise type().
      */
     bool hasLazyType() const { return type_->lazy(); }
 
-    // uninlinedSlotSpan() is the same as slotSpan(), but isn't inlined.
-    inline uint32_t slotSpan() const;
-    uint32_t uninlinedSlotSpan() const;
+    uint32_t slotSpan() const {
+        if (inDictionaryMode())
+            return lastProperty()->base()->slotSpan();
+        return lastProperty()->slotSpan();
+    }
 
     /* Compute dynamicSlotsCount() for this object. */
-    inline uint32_t numDynamicSlots() const;
+    uint32_t numDynamicSlots() const {
+        return dynamicSlotsCount(numFixedSlots(), slotSpan());
+    }
 
     Shape *nativeLookup(ExclusiveContext *cx, jsid id);
     Shape *nativeLookup(ExclusiveContext *cx, PropertyId pid) {
         return nativeLookup(cx, pid.asId());
     }
     Shape *nativeLookup(ExclusiveContext *cx, PropertyName *name) {
         return nativeLookup(cx, NameToId(name));
     }
 
     bool nativeContains(ExclusiveContext *cx, jsid id) {
         return nativeLookup(cx, id) != NULL;
     }
     bool nativeContains(ExclusiveContext *cx, PropertyName* name) {
         return nativeLookup(cx, name) != NULL;
     }
-    inline bool nativeContains(ExclusiveContext *cx, Shape* shape);
+    bool nativeContains(ExclusiveContext *cx, Shape* shape) {
+        return nativeLookup(cx, shape->propid()) == shape;
+    }
 
     /*
      * Contextless; can be called from parallel code. Returns false if the
      * operation would have been effectful.
      */
     Shape *nativeLookupPure(jsid id);
     Shape *nativeLookupPure(PropertyId pid) {
         return nativeLookupPure(pid.asId());
@@ -1226,17 +1241,19 @@ class ObjectImpl : public gc::Cell
     }
 
     bool nativeContainsPure(jsid id) {
         return nativeLookupPure(id) != NULL;
     }
     bool nativeContainsPure(PropertyName* name) {
         return nativeContainsPure(NameToId(name));
     }
-    bool nativeContainsPure(Shape* shape);
+    bool nativeContainsPure(Shape* shape) {
+        return nativeLookupPure(shape->propid()) == shape;
+    }
 
     JSClass *getJSClass() const {
         return Jsvalify(getClass());
     }
     bool hasClass(const Class *c) const {
         return getClass() == c;
     }
     const ObjectOps *getOps() const {
@@ -1247,24 +1264,28 @@ class ObjectImpl : public gc::Cell
      * An object is a delegate if it is on another object's prototype or scope
      * chain, and therefore the delegate might be asked implicitly to get or
      * set a property on behalf of another object. Delegates may be accessed
      * directly too, as may any object, but only those objects linked after the
      * head of any prototype or scope chain are flagged as delegates. This
      * definition helps to optimize shape-based property cache invalidation
      * (see Purge{Scope,Proto}Chain in jsobj.cpp).
      */
-    inline bool isDelegate() const;
+    bool isDelegate() const {
+        return lastProperty()->hasObjectFlag(BaseShape::DELEGATE);
+    }
 
     /*
      * Return true if this object is a native one that has been converted from
      * shared-immutable prototype-rooted shape storage to dictionary-shapes in
      * a doubly-linked list.
      */
-    inline bool inDictionaryMode() const;
+    bool inDictionaryMode() const {
+        return lastProperty()->inDictionary();
+    }
 
     const Value &getSlot(uint32_t slot) const {
         MOZ_ASSERT(slotInRange(slot));
         uint32_t fixed = numFixedSlots();
         if (slot < fixed)
             return fixedSlots()[slot];
         return slots[slot - fixed];
     }
@@ -1287,39 +1308,39 @@ class ObjectImpl : public gc::Cell
     }
 
     HeapSlot &getSlotRef(uint32_t slot) {
         MOZ_ASSERT(slotInRange(slot));
         return *getSlotAddress(slot);
     }
 
     HeapSlot &nativeGetSlotRef(uint32_t slot) {
-        JS_ASSERT(uninlinedIsNative() && slot < uninlinedSlotSpan());
+        JS_ASSERT(isNative() && slot < slotSpan());
         return getSlotRef(slot);
     }
     const Value &nativeGetSlot(uint32_t slot) const {
-        JS_ASSERT(uninlinedIsNative() && slot < uninlinedSlotSpan());
+        JS_ASSERT(isNative() && slot < slotSpan());
         return getSlot(slot);
     }
 
     void setSlot(uint32_t slot, const Value &value) {
         MOZ_ASSERT(slotInRange(slot));
-        MOZ_ASSERT(IsObjectValueInCompartment(value, uninlinedCompartment()));
+        MOZ_ASSERT(IsObjectValueInCompartment(value, compartment()));
         getSlotRef(slot).set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
     }
 
     inline void setCrossCompartmentSlot(uint32_t slot, const Value &value) {
         MOZ_ASSERT(slotInRange(slot));
         getSlotRef(slot).set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
     }
 
     void initSlot(uint32_t slot, const Value &value) {
         MOZ_ASSERT(getSlot(slot).isUndefined());
         MOZ_ASSERT(slotInRange(slot));
-        MOZ_ASSERT(IsObjectValueInCompartment(value, uninlinedCompartment()));
+        MOZ_ASSERT(IsObjectValueInCompartment(value, compartment()));
         initSlotUnchecked(slot, value);
     }
 
     void initCrossCompartmentSlot(uint32_t slot, const Value &value) {
         MOZ_ASSERT(getSlot(slot).isUndefined());
         MOZ_ASSERT(slotInRange(slot));
         initSlotUnchecked(slot, value);
     }
@@ -1408,21 +1429,57 @@ class ObjectImpl : public gc::Cell
         return elements == fixedElements();
     }
 
     inline bool hasEmptyElements() const {
         return elements == emptyObjectElements;
     }
 
     /* GC support. */
-    JS_ALWAYS_INLINE Zone *zone() const;
+    JS_ALWAYS_INLINE Zone *zone() const {
+        JS_ASSERT(CurrentThreadCanAccessZone(shape_->zone()));
+        return shape_->zone();
+    }
+
+    JS_ALWAYS_INLINE JS::shadow::Zone *shadowZone() const {
+        return JS::shadow::Zone::asShadowZone(zone());
+    }
+
     static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }
 
-    static inline void readBarrier(ObjectImpl *obj);
-    static inline void writeBarrierPre(ObjectImpl *obj);
+    static void readBarrier(ObjectImpl *obj) {
+#ifdef JSGC_INCREMENTAL
+        JS::shadow::Zone *shadowZone = obj->shadowZone();
+        if (shadowZone->needsBarrier()) {
+            MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));
+            JSObject *tmp = obj->asObjectPtr();
+            js::gc::MarkObjectUnbarriered(shadowZone->barrierTracer(), &tmp, "read barrier");
+            MOZ_ASSERT(tmp == obj->asObjectPtr());
+        }
+#endif
+    }
+
+    static void writeBarrierPre(ObjectImpl *obj) {
+#ifdef JSGC_INCREMENTAL
+        /*
+         * This would normally be a null test, but TypeScript::global uses 0x1 as a
+         * special value.
+         */
+        if (IsNullTaggedPointer(obj) || !obj->shadowRuntimeFromMainThread()->needsBarrier())
+            return;
+
+        JS::shadow::Zone *shadowZone = obj->shadowZone();
+        if (shadowZone->needsBarrier()) {
+            MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone));
+            JSObject *tmp = obj->asObjectPtr();
+            js::gc::MarkObjectUnbarriered(shadowZone->barrierTracer(), &tmp, "write barrier");
+            MOZ_ASSERT(tmp == obj->asObjectPtr());
+        }
+#endif
+    }
 
     static void writeBarrierPost(ObjectImpl *obj, void *addr) {
 #ifdef JSGC_GENERATIONAL
         if (IsNullTaggedPointer(obj))
             return;
         obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->putCell((Cell **)addr);
 #endif
     }
@@ -1434,17 +1491,25 @@ class ObjectImpl : public gc::Cell
     }
 
     static void writeBarrierPostRemove(ObjectImpl *obj, void *addr) {
 #ifdef JSGC_GENERATIONAL
         obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->removeRelocatableCell((Cell **)addr);
 #endif
     }
 
-    inline void privateWriteBarrierPre(void **oldval);
+    void privateWriteBarrierPre(void **oldval) {
+#ifdef JSGC_INCREMENTAL
+        JS::shadow::Zone *shadowZone = this->shadowZone();
+        if (shadowZone->needsBarrier()) {
+            if (*oldval && getClass()->trace)
+                getClass()->trace(shadowZone->barrierTracer(), this->asObjectPtr());
+        }
+#endif
+    }
 
     void privateWriteBarrierPost(void **pprivate) {
 #ifdef JSGC_GENERATIONAL
         shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->putCell(reinterpret_cast<js::gc::Cell **>(pprivate));
 #endif
     }
 
     void markChildren(JSTracer *trc);
@@ -1458,24 +1523,35 @@ class ObjectImpl : public gc::Cell
          * the object.
          */
         MOZ_ASSERT(nfixed == numFixedSlots());
         MOZ_ASSERT(hasPrivate());
         HeapSlot *end = &fixedSlots()[nfixed];
         return *reinterpret_cast<void**>(end);
     }
 
-    inline bool hasPrivate() const {
+    bool hasPrivate() const {
         return getClass()->hasPrivate();
     }
-    inline void *getPrivate() const {
+    void *getPrivate() const {
         return privateRef(numFixedSlots());
     }
-    inline void setPrivate(void *data);
-    inline void setPrivateGCThing(gc::Cell *cell);
+    void setPrivate(void *data) {
+        void **pprivate = &privateRef(numFixedSlots());
+        privateWriteBarrierPre(pprivate);
+        *pprivate = data;
+    }
+
+    void setPrivateGCThing(gc::Cell *cell) {
+        void **pprivate = &privateRef(numFixedSlots());
+        privateWriteBarrierPre(pprivate);
+        *pprivate = reinterpret_cast<void *>(cell);
+        privateWriteBarrierPost(pprivate);
+    }
+
     void setPrivateUnbarriered(void *data) {
         void **pprivate = &privateRef(numFixedSlots());
         *pprivate = data;
     }
     void initPrivate(void *data) {
         privateRef(numFixedSlots()) = data;
     }
 
@@ -1518,17 +1594,17 @@ Downcast(Handle<ObjectImpl*> obj)
 }
 
 #ifdef DEBUG
 static inline bool
 IsObjectValueInCompartment(js::Value v, JSCompartment *comp)
 {
     if (!v.isObject())
         return true;
-    return reinterpret_cast<ObjectImpl*>(&v.toObject())->uninlinedCompartment() == comp;
+    return reinterpret_cast<ObjectImpl*>(&v.toObject())->compartment() == comp;
 }
 #endif
 
 extern JSObject *
 ArrayBufferDelegate(JSContext *cx, Handle<ObjectImpl*> obj);
 
 /* Generic [[GetOwnProperty]] method. */
 bool
deleted file mode 100644
--- a/js/src/vm/RegExpObject-inl.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef vm_RegExpObject_inl_h
-#define vm_RegExpObject_inl_h
-
-#include "vm/RegExpObject.h"
-
-namespace js {
-
-inline void
-RegExpObject::setShared(ExclusiveContext *cx, RegExpShared &shared)
-{
-    shared.prepareForUse(cx);
-    JSObject::setPrivate(&shared);
-}
-
-} /* namespace js */
-
-#endif /* vm_RegExpObject_inl_h */
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "vm/RegExpObject-inl.h"
+#include "vm/RegExpObject.h"
 
 #include "mozilla/MemoryReporting.h"
 
 #include "frontend/TokenStream.h"
 #include "vm/MatchPairs.h"
 #include "vm/RegExpStatics.h"
 #include "vm/StringBuffer.h"
 #include "vm/Xdr.h"
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -423,17 +423,20 @@ class RegExpObject : public JSObject
     bool getShared(ExclusiveContext *cx, RegExpGuard *g) {
         if (RegExpShared *shared = maybeShared()) {
             g->init(*shared);
             return true;
         }
         return createShared(cx, g);
     }
 
-    inline void setShared(ExclusiveContext *cx, RegExpShared &shared);
+    void setShared(ExclusiveContext *cx, RegExpShared &shared) {
+        shared.prepareForUse(cx);
+        JSObject::setPrivate(&shared);
+    }
 
   private:
     friend class RegExpObjectBuilder;
 
     /*
      * Compute the initial shape to associate with fresh RegExp objects,
      * encoding their initial properties. Return the shape after
      * changing this regular expression object's last property to it.