Bug 910771 (part 5) - Move tons of stuff out of inlines.h/-inl.h files into .h files. r=terrence.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 08 Sep 2013 13:31:19 -0700
changeset 146168 3e1dd474a575b5ced0bbf7ac4d7f15a8f51bf6b9
parent 146167 17fcd21b3d3a84bc2982ac386df340a05594264a
child 146169 4f9563af1fa1274bbfde1466a44a9253e1a2a32c
push id25244
push userryanvm@gmail.com
push dateMon, 09 Sep 2013 20:03:14 +0000
treeherdermozilla-central@f320b8c034bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs910771
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 910771 (part 5) - Move tons of stuff out of inlines.h/-inl.h files into .h files. r=terrence.
js/src/jsfun.h
js/src/jsfuninlines.h
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsscript.cpp
js/src/vm/GlobalObject-inl.h
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/Interpreter-inl.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.h
js/src/vm/RegExpStatics.h
js/src/vm/ScopeObject-inl.h
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
js/src/vm/Stack-inl.h
js/src/vm/TypedArrayObject.cpp
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -199,34 +199,48 @@ class JSFunction : public JSObject
 
     // Can be called multiple times by the parser.
     void setIsExprClosure() {
         flags |= EXPR_CLOSURE;
     }
 
     JSAtom *atom() const { return hasGuessedAtom() ? NULL : atom_.get(); }
     js::PropertyName *name() const { return hasGuessedAtom() || !atom_ ? NULL : atom_->asPropertyName(); }
-    inline void initAtom(JSAtom *atom);
+    void initAtom(JSAtom *atom) { atom_.init(atom); }
     JSAtom *displayAtom() const { return atom_; }
 
-    inline void setGuessedAtom(JSAtom *atom);
+    void setGuessedAtom(JSAtom *atom) {
+        JS_ASSERT(atom_ == NULL);
+        JS_ASSERT(atom != NULL);
+        JS_ASSERT(!hasGuessedAtom());
+        atom_ = atom;
+        flags |= HAS_GUESSED_ATOM;
+    }
 
     /* uint16_t representation bounds number of call object dynamic slots. */
     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
 
     /*
      * For an interpreted function, accessors for the initial scope object of
      * activations (stack frames) of the function.
      */
     JSObject *environment() const {
         JS_ASSERT(isInterpreted());
         return u.i.env_;
     }
-    inline void setEnvironment(JSObject *obj);
-    inline void initEnvironment(JSObject *obj);
+
+    void setEnvironment(JSObject *obj) {
+        JS_ASSERT(isInterpreted());
+        *(js::HeapPtrObject *)&u.i.env_ = obj;
+    }
+
+    void initEnvironment(JSObject *obj) {
+        JS_ASSERT(isInterpreted());
+        ((js::HeapPtrObject *)&u.i.env_)->init(obj);
+    }
 
     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
     static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
 
     static bool createScriptForLazilyInterpretedFunction(JSContext *cx, js::HandleFunction fun);
 
     // Function Scripts
     //
@@ -299,16 +313,17 @@ class JSFunction : public JSObject
     bool isGenerator() const { return generatorKind() != js::NotGenerator; }
 
     bool isLegacyGenerator() const { return generatorKind() == js::LegacyGenerator; }
 
     bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
 
     inline void setScript(JSScript *script_);
     inline void initScript(JSScript *script_);
+
     void initLazyScript(js::LazyScript *lazy) {
         JS_ASSERT(isInterpreted());
         flags &= ~INTERPRETED;
         flags |= INTERPRETED_LAZY;
         u.i.s.lazy_ = lazy;
     }
 
     JSNative native() const {
@@ -361,17 +376,23 @@ class JSFunction : public JSObject
 
     inline void trace(JSTracer *trc);
 
     /* Bound function accessors. */
 
     inline bool initBoundFunction(JSContext *cx, js::HandleValue thisArg,
                                   const js::Value *args, unsigned argslen);
 
-    inline JSObject *getBoundFunctionTarget() const;
+    JSObject *getBoundFunctionTarget() const {
+        JS_ASSERT(isBoundFunction());
+
+        /* Bound functions abuse |parent| to store their target function. */
+        return getParent();
+    }
+
     inline const js::Value &getBoundFunctionThis() const;
     inline const js::Value &getBoundFunctionArgument(unsigned which) const;
     inline size_t getBoundFunctionArgumentCount() const;
 
   private:
     inline js::FunctionExtended *toExtended();
     inline const js::FunctionExtended *toExtended() const;
 
@@ -484,16 +505,40 @@ JSFunction::toExtended()
 
 inline const js::FunctionExtended *
 JSFunction::toExtended() const
 {
     JS_ASSERT(isExtended());
     return static_cast<const js::FunctionExtended *>(this);
 }
 
+inline void
+JSFunction::initializeExtended()
+{
+    JS_ASSERT(isExtended());
+
+    JS_ASSERT(mozilla::ArrayLength(toExtended()->extendedSlots) == 2);
+    toExtended()->extendedSlots[0].init(js::UndefinedValue());
+    toExtended()->extendedSlots[1].init(js::UndefinedValue());
+}
+
+inline void
+JSFunction::initExtendedSlot(size_t which, const js::Value &val)
+{
+    JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
+    toExtended()->extendedSlots[which].init(val);
+}
+
+inline void
+JSFunction::setExtendedSlot(size_t which, const js::Value &val)
+{
+    JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
+    toExtended()->extendedSlots[which] = val;
+}
+
 inline const js::Value &
 JSFunction::getExtendedSlot(size_t which) const
 {
     JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
     return toExtended()->extendedSlots[which];
 }
 
 namespace js {
--- a/js/src/jsfuninlines.h
+++ b/js/src/jsfuninlines.h
@@ -6,70 +6,16 @@
 
 #ifndef jsfuninlines_h
 #define jsfuninlines_h
 
 #include "jsfun.h"
 
 #include "vm/ScopeObject.h"
 
-inline void
-JSFunction::initAtom(JSAtom *atom)
-{
-    atom_.init(atom);
-}
-
-inline void
-JSFunction::setGuessedAtom(JSAtom *atom)
-{
-    JS_ASSERT(atom_ == NULL);
-    JS_ASSERT(atom != NULL);
-    JS_ASSERT(!hasGuessedAtom());
-    atom_ = atom;
-    flags |= HAS_GUESSED_ATOM;
-}
-
-inline void
-JSFunction::setEnvironment(JSObject *obj)
-{
-    JS_ASSERT(isInterpreted());
-    *(js::HeapPtrObject *)&u.i.env_ = obj;
-}
-
-inline void
-JSFunction::initEnvironment(JSObject *obj)
-{
-    JS_ASSERT(isInterpreted());
-    ((js::HeapPtrObject *)&u.i.env_)->init(obj);
-}
-
-inline void
-JSFunction::initializeExtended()
-{
-    JS_ASSERT(isExtended());
-
-    JS_ASSERT(mozilla::ArrayLength(toExtended()->extendedSlots) == 2);
-    toExtended()->extendedSlots[0].init(js::UndefinedValue());
-    toExtended()->extendedSlots[1].init(js::UndefinedValue());
-}
-
-inline void
-JSFunction::initExtendedSlot(size_t which, const js::Value &val)
-{
-    JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
-    toExtended()->extendedSlots[which].init(val);
-}
-
-inline void
-JSFunction::setExtendedSlot(size_t which, const js::Value &val)
-{
-    JS_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
-    toExtended()->extendedSlots[which] = val;
-}
-
 namespace js {
 
 inline const char *
 GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
 {
     JSAtom *atom = fun->atom();
     if (atom)
         return bytes->encodeLatin1(cx, atom);
@@ -170,18 +116,9 @@ JSFunction::setScript(JSScript *script_)
 
 inline void
 JSFunction::initScript(JSScript *script_)
 {
     JS_ASSERT(isInterpreted());
     mutableScript().init(script_);
 }
 
-inline JSObject *
-JSFunction::getBoundFunctionTarget() const
-{
-    JS_ASSERT(isBoundFunction());
-
-    /* Bound functions abuse |parent| to store their target function. */
-    return getParent();
-}
-
 #endif /* jsfuninlines_h */
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -346,38 +346,58 @@ class JSObject : public js::ObjectImpl
     static inline bool updateSlotsForSpan(js::ExclusiveContext *cx,
                                           js::HandleObject obj, size_t oldSpan, size_t newSpan);
 
   public:
     /*
      * Trigger the write barrier on a range of slots that will no longer be
      * reachable.
      */
-    inline void prepareSlotRangeForOverwrite(size_t start, size_t end);
-    inline void prepareElementRangeForOverwrite(size_t start, size_t end);
+    void prepareSlotRangeForOverwrite(size_t start, size_t end) {
+        for (size_t i = start; i < end; i++)
+            getSlotAddressUnchecked(i)->js::HeapSlot::~HeapSlot();
+    }
+
+    void prepareElementRangeForOverwrite(size_t start, size_t end) {
+        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);
 
-    inline void nativeSetSlot(uint32_t slot, const js::Value &value);
+    void nativeSetSlot(uint32_t slot, const js::Value &value) {
+        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(slot < uninlinedSlotSpan());
+        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 {
         JS_ASSERT(index < JSSLOT_FREE(getClass()));
         return getSlot(index);
     }
 
     inline js::HeapSlot &getReservedSlotRef(uint32_t index) {
         JS_ASSERT(index < JSSLOT_FREE(getClass()));
         return getSlotRef(index);
     }
 
-    inline void initReservedSlot(uint32_t index, const js::Value &v);
-    inline void setReservedSlot(uint32_t index, const js::Value &v);
+    void initReservedSlot(uint32_t index, const js::Value &v) {
+        JS_ASSERT(index < JSSLOT_FREE(getClass()));
+        initSlot(index, v);
+    }
+
+    void setReservedSlot(uint32_t index, const js::Value &v) {
+        JS_ASSERT(index < JSSLOT_FREE(getClass()));
+        setSlot(index, v);
+    }
 
     /*
      * Marks this object as having a singleton type, and leave the type lazy.
      * Constructs a new, unique shape for the object.
      */
     static inline bool setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj);
 
     // uninlinedGetType() is the same as getType(), but not inlined.
@@ -523,47 +543,79 @@ class JSObject : public js::ObjectImpl
     static inline bool isFrozen(JSContext *cx, js::HandleObject obj, bool *resultp) {
         return isSealedOrFrozen(cx, obj, FREEZE, resultp);
     }
 
     /* toString support. */
     static const char *className(JSContext *cx, js::HandleObject obj);
 
     /* Accessors for elements. */
-    inline bool ensureElements(js::ThreadSafeContext *cx, uint32_t capacity);
+    bool ensureElements(js::ThreadSafeContext *cx, uint32_t capacity) {
+        if (capacity > getDenseCapacity())
+            return growElements(cx, capacity);
+        return true;
+    }
+
     bool growElements(js::ThreadSafeContext *cx, uint32_t newcap);
     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(getElementsHeader()->capacity >= getElementsHeader()->initializedLength);
         return getElementsHeader()->capacity;
     }
 
-    inline void setDenseInitializedLength(uint32_t length);
+    void setDenseInitializedLength(uint32_t length) {
+        JS_ASSERT(uninlinedIsNative());
+        JS_ASSERT(length <= getDenseCapacity());
+        prepareElementRangeForOverwrite(length, getElementsHeader()->initializedLength);
+        getElementsHeader()->initializedLength = length;
+    }
+
     inline void ensureDenseInitializedLength(js::ExclusiveContext *cx,
                                              uint32_t index, uint32_t extra);
-    inline void setDenseElement(uint32_t index, const js::Value &val);
-    inline void initDenseElement(uint32_t index, const js::Value &val);
-    inline void setDenseElementMaybeConvertDouble(uint32_t index, const js::Value &val);
+    void setDenseElement(uint32_t index, const js::Value &val) {
+        JS_ASSERT(uninlinedIsNative() && 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());
+        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);
+    }
+
     static inline void setDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj,
                                                uint32_t index, const js::Value &val);
     static inline void initDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj,
                                                 uint32_t index, const js::Value &val);
     static inline void setDenseElementHole(js::ExclusiveContext *cx,
                                            js::HandleObject obj, uint32_t index);
     static inline void removeDenseElementForSparseIndex(js::ExclusiveContext *cx,
                                                         js::HandleObject obj, uint32_t index);
     inline void copyDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count);
-    inline void initDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count);
+
+    void initDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count) {
+        JS_ASSERT(dstStart + count <= getDenseCapacity());
+        JSRuntime *rt = runtimeFromMainThread();
+        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());
         return getElementsHeader()->shouldConvertDoubleElements();
     }
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -125,91 +125,22 @@ JSObject::canRemoveLastProperty()
     JS_ASSERT(!inDictionaryMode());
     js::Shape *previous = lastProperty()->previous().get();
     return previous->getObjectParent() == lastProperty()->getObjectParent()
         && previous->getObjectMetadata() == lastProperty()->getObjectMetadata()
         && previous->getObjectFlags() == lastProperty()->getObjectFlags();
 }
 
 inline void
-JSObject::setReservedSlot(uint32_t index, const js::Value &v)
-{
-    JS_ASSERT(index < JSSLOT_FREE(getClass()));
-    setSlot(index, v);
-}
-
-inline void
-JSObject::initReservedSlot(uint32_t index, const js::Value &v)
-{
-    JS_ASSERT(index < JSSLOT_FREE(getClass()));
-    initSlot(index, v);
-}
-
-inline void
-JSObject::prepareSlotRangeForOverwrite(size_t start, size_t end)
-{
-    for (size_t i = start; i < end; i++)
-        getSlotAddressUnchecked(i)->js::HeapSlot::~HeapSlot();
-}
-
-inline void
-JSObject::prepareElementRangeForOverwrite(size_t start, size_t end)
-{
-    JS_ASSERT(end <= getDenseInitializedLength());
-    for (size_t i = start; i < end; i++)
-        elements[i].js::HeapSlot::~HeapSlot();
-}
-
-inline void
-JSObject::setDenseInitializedLength(uint32_t length)
-{
-    JS_ASSERT(isNative());
-    JS_ASSERT(length <= getDenseCapacity());
-    prepareElementRangeForOverwrite(length, getElementsHeader()->initializedLength);
-    getElementsHeader()->initializedLength = length;
-}
-
-inline void
 JSObject::setShouldConvertDoubleElements()
 {
     JS_ASSERT(is<js::ArrayObject>() && !hasEmptyElements());
     getElementsHeader()->setShouldConvertDoubleElements();
 }
 
-inline bool
-JSObject::ensureElements(js::ThreadSafeContext *cx, uint32_t capacity)
-{
-    if (capacity > getDenseCapacity())
-        return growElements(cx, capacity);
-    return true;
-}
-
-inline void
-JSObject::setDenseElement(uint32_t index, const js::Value &val)
-{
-    JS_ASSERT(isNative() && index < getDenseInitializedLength());
-    elements[index].set(this, js::HeapSlot::Element, index, val);
-}
-
-inline void
-JSObject::setDenseElementMaybeConvertDouble(uint32_t index, const js::Value &val)
-{
-    if (val.isInt32() && shouldConvertDoubleElements())
-        setDenseElement(index, js::DoubleValue(val.toInt32()));
-    else
-        setDenseElement(index, val);
-}
-
-inline void
-JSObject::initDenseElement(uint32_t index, const js::Value &val)
-{
-    JS_ASSERT(isNative() && index < getDenseInitializedLength());
-    elements[index].init(this, js::HeapSlot::Element, index, val);
-}
-
 /* static */ inline void
 JSObject::setDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t index,
                                   const js::Value &val)
 {
     js::types::AddTypePropertyId(cx, obj, JSID_VOID, val);
     obj->setDenseElementMaybeConvertDouble(index, val);
 }
 
@@ -245,25 +176,16 @@ JSObject::copyDenseElements(uint32_t dst
 {
     JS_ASSERT(dstStart + count <= getDenseCapacity());
     JS::Zone *zone = this->zone();
     for (uint32_t i = 0; i < count; ++i)
         elements[dstStart + i].set(zone, this, js::HeapSlot::Element, dstStart + i, src[i]);
 }
 
 inline void
-JSObject::initDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count)
-{
-    JS_ASSERT(dstStart + count <= getDenseCapacity());
-    JSRuntime *rt = runtimeFromMainThread();
-    for (uint32_t i = 0; i < count; ++i)
-        elements[dstStart + i].init(rt, this, js::HeapSlot::Element, dstStart + i, src[i]);
-}
-
-inline void
 JSObject::moveDenseElements(uint32_t dstStart, uint32_t srcStart, uint32_t count)
 {
     JS_ASSERT(dstStart + count <= getDenseCapacity());
     JS_ASSERT(srcStart + count <= getDenseInitializedLength());
 
     /*
      * Using memmove here would skip write barriers. Also, we need to consider
      * an array containing [A, B, C], in the following situation:
@@ -642,24 +564,16 @@ JSObject::hasProperty(JSContext *cx, js:
     if (!lookupGeneric(cx, obj, id, &pobj, &prop)) {
         *foundp = false;  /* initialize to shut GCC up */
         return false;
     }
     *foundp = !!prop;
     return true;
 }
 
-inline void
-JSObject::nativeSetSlot(uint32_t slot, const js::Value &value)
-{
-    JS_ASSERT(isNative());
-    JS_ASSERT(slot < slotSpan());
-    return setSlot(slot, value);
-}
-
 /* static */ inline void
 JSObject::nativeSetSlotWithType(js::ExclusiveContext *cx, js::HandleObject obj, js::Shape *shape,
                                 const js::Value &value)
 {
     obj->nativeSetSlot(shape->slot(), value);
     js::types::AddTypePropertyId(cx, obj, shape->propid(), value);
 }
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -34,16 +34,17 @@
 #include "vm/ArgumentsObject.h"
 #include "vm/Debugger.h"
 #include "vm/Interpreter.h"
 #include "vm/Shape.h"
 #include "vm/Xdr.h"
 
 #include "jsfuninlines.h"
 #include "jsinferinlines.h"
+#include "jsobjinlines.h"
 
 #include "vm/Runtime-inl.h"
 #include "vm/ScopeObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::frontend;
deleted file mode 100644
--- a/js/src/vm/GlobalObject-inl.h
+++ /dev/null
@@ -1,158 +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_GlobalObject_inl_h
-#define vm_GlobalObject_inl_h
-
-#include "vm/GlobalObject.h"
-
-#include "vm/ObjectImpl-inl.h"
-
-namespace js {
-
-inline void
-GlobalObject::setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto)
-{
-    JS_ASSERT(getSlotRef(key).isUndefined());
-    JS_ASSERT(getSlotRef(JSProto_LIMIT + key).isUndefined());
-    JS_ASSERT(getSlotRef(2 * JSProto_LIMIT + key).isUndefined());
-    setSlot(key, ObjectValue(*ctor));
-    setSlot(JSProto_LIMIT + key, ObjectValue(*proto));
-    setSlot(2 * JSProto_LIMIT + key, ObjectValue(*ctor));
-}
-
-inline void
-GlobalObject::setObjectClassDetails(JSFunction *ctor, JSObject *proto)
-{
-    setDetailsForKey(JSProto_Object, ctor, proto);
-}
-
-inline void
-GlobalObject::setFunctionClassDetails(JSFunction *ctor, JSObject *proto)
-{
-    setDetailsForKey(JSProto_Function, ctor, proto);
-}
-
-void
-GlobalObject::setThrowTypeError(JSFunction *fun)
-{
-    JS_ASSERT(getSlotRef(THROWTYPEERROR).isUndefined());
-    setSlot(THROWTYPEERROR, ObjectValue(*fun));
-}
-
-void
-GlobalObject::setOriginalEval(JSObject *evalobj)
-{
-    JS_ASSERT(getSlotRef(EVAL).isUndefined());
-    setSlot(EVAL, ObjectValue(*evalobj));
-}
-
-void
-GlobalObject::setCreateArrayFromBufferHelper(uint32_t slot, Handle<JSFunction*> fun)
-{
-    JS_ASSERT(getSlotRef(slot).isUndefined());
-    setSlot(slot, ObjectValue(*fun));
-}
-
-void
-GlobalObject::setCreateDataViewForThis(Handle<JSFunction*> fun)
-{
-    JS_ASSERT(getSlotRef(CREATE_DATAVIEW_FOR_THIS).isUndefined());
-    setSlot(CREATE_DATAVIEW_FOR_THIS, ObjectValue(*fun));
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<uint8_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT8, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<int8_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_INT8, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<uint16_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT16, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<int16_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_INT16, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<uint32_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT32, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<int32_t>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_INT32, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<float>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_FLOAT32, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<double>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_FLOAT64, fun);
-}
-
-template<>
-inline void
-GlobalObject::setCreateArrayFromBuffer<uint8_clamped>(Handle<JSFunction*> fun)
-{
-    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT8CLAMPED, fun);
-}
-
-void
-GlobalObject::setProtoGetter(JSFunction *protoGetter)
-{
-    JS_ASSERT(getSlotRef(PROTO_GETTER).isUndefined());
-    setSlot(PROTO_GETTER, ObjectValue(*protoGetter));
-}
-
-bool
-GlobalObject::setIntrinsicValue(JSContext *cx, PropertyName *name, HandleValue value)
-{
-#ifdef DEBUG
-    RootedObject self(cx, this);
-    JS_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
-#endif
-    RootedObject holder(cx, intrinsicsHolder());
-    RootedValue valCopy(cx, value);
-    return JSObject::setProperty(cx, holder, holder, name, &valCopy, false);
-}
-
-void
-GlobalObject::setIntrinsicsHolder(JSObject *obj)
-{
-    JS_ASSERT(getSlotRef(INTRINSICS).isUndefined());
-    setSlot(INTRINSICS, ObjectValue(*obj));
-}
-
-} // namespace js
-
-#endif /* vm_GlobalObject_inl_h */
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.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/GlobalObject-inl.h"
+#include "vm/GlobalObject.h"
 
 #include "jscntxt.h"
 #include "jsdate.h"
 #include "jsexn.h"
 #include "jsfriendapi.h"
 #include "jsmath.h"
 #include "json.h"
 #include "jsweakmap.h"
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -119,25 +119,52 @@ class GlobalObject : public JSObject
     ::js_InitObjectClass(JSContext *cx, js::HandleObject);
     friend JSObject *
     ::js_InitFunctionClass(JSContext *cx, js::HandleObject);
 
     /* Initialize the Function and Object classes.  Must only be called once! */
     JSObject *
     initFunctionAndObjectClasses(JSContext *cx);
 
-    inline void setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto);
-    inline void setObjectClassDetails(JSFunction *ctor, JSObject *proto);
-    inline void setFunctionClassDetails(JSFunction *ctor, JSObject *proto);
+    void setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto) {
+        JS_ASSERT(getSlotRef(key).isUndefined());
+        JS_ASSERT(getSlotRef(JSProto_LIMIT + key).isUndefined());
+        JS_ASSERT(getSlotRef(2 * JSProto_LIMIT + key).isUndefined());
+        setSlot(key, ObjectValue(*ctor));
+        setSlot(JSProto_LIMIT + key, ObjectValue(*proto));
+        setSlot(2 * JSProto_LIMIT + key, ObjectValue(*ctor));
+    }
+
+    void setObjectClassDetails(JSFunction *ctor, JSObject *proto) {
+        setDetailsForKey(JSProto_Object, ctor, proto);
+    }
+
+    void setFunctionClassDetails(JSFunction *ctor, JSObject *proto) {
+        setDetailsForKey(JSProto_Function, ctor, proto);
+    }
 
-    inline void setThrowTypeError(JSFunction *fun);
-    inline void setOriginalEval(JSObject *evalobj);
-    inline void setProtoGetter(JSFunction *protoGetter);
+    void setThrowTypeError(JSFunction *fun) {
+        JS_ASSERT(getSlotRef(THROWTYPEERROR).isUndefined());
+        setSlot(THROWTYPEERROR, ObjectValue(*fun));
+    }
+
+    void setOriginalEval(JSObject *evalobj) {
+        JS_ASSERT(getSlotRef(EVAL).isUndefined());
+        setSlot(EVAL, ObjectValue(*evalobj));
+    }
 
-    inline void setIntrinsicsHolder(JSObject *obj);
+    void setProtoGetter(JSFunction *protoGetter) {
+        JS_ASSERT(getSlotRef(PROTO_GETTER).isUndefined());
+        setSlot(PROTO_GETTER, ObjectValue(*protoGetter));
+    }
+
+    void setIntrinsicsHolder(JSObject *obj) {
+        JS_ASSERT(getSlotRef(INTRINSICS).isUndefined());
+        setSlot(INTRINSICS, ObjectValue(*obj));
+    }
 
     Value getConstructor(JSProtoKey key) const {
         JS_ASSERT(key <= JSProto_LIMIT);
         return getSlot(key);
     }
 
     Value getPrototype(JSProtoKey key) const {
         JS_ASSERT(key <= JSProto_LIMIT);
@@ -188,21 +215,27 @@ class GlobalObject : public JSObject
     }
 
     Value createArrayFromBufferHelper(uint32_t slot) const {
         JS_ASSERT(typedArrayClassesInitialized());
         JS_ASSERT(FROM_BUFFER_UINT8 <= slot && slot <= FROM_BUFFER_UINT8CLAMPED);
         return getSlot(slot);
     }
 
-    inline void setCreateArrayFromBufferHelper(uint32_t slot, Handle<JSFunction*> fun);
+    void setCreateArrayFromBufferHelper(uint32_t slot, Handle<JSFunction*> fun) {
+        JS_ASSERT(getSlotRef(slot).isUndefined());
+        setSlot(slot, ObjectValue(*fun));
+    }
 
   public:
     /* XXX Privatize me! */
-    inline void setCreateDataViewForThis(Handle<JSFunction*> fun);
+    void setCreateDataViewForThis(Handle<JSFunction*> fun) {
+        JS_ASSERT(getSlotRef(CREATE_DATAVIEW_FOR_THIS).isUndefined());
+        setSlot(CREATE_DATAVIEW_FOR_THIS, ObjectValue(*fun));
+    }
 
     template<typename T>
     inline void setCreateArrayFromBuffer(Handle<JSFunction*> fun);
 
   public:
     static GlobalObject *create(JSContext *cx, Class *clasp);
 
     /*
@@ -411,19 +444,30 @@ class GlobalObject : public JSObject
             return true;
         if (!cx->runtime()->cloneSelfHostedValue(cx, name, value))
             return false;
         mozilla::DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, id, value, NULL, NULL, 0);
         JS_ASSERT(ok);
         return true;
     }
 
-    inline bool setIntrinsicValue(JSContext *cx, PropertyName *name, HandleValue value);
+    bool setIntrinsicValue(JSContext *cx, PropertyName *name, HandleValue value) {
+#ifdef DEBUG
+        RootedObject self(cx, this);
+        JS_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
+#endif
+        RootedObject holder(cx, intrinsicsHolder());
+        RootedValue valCopy(cx, value);
+        return JSObject::setProperty(cx, holder, holder, name, &valCopy, false);
+    }
 
-    inline RegExpStatics *getRegExpStatics() const;
+    RegExpStatics *getRegExpStatics() const {
+        JSObject &resObj = getSlot(REGEXP_STATICS).toObject();
+        return static_cast<RegExpStatics *>(resObj.getPrivate());
+    }
 
     JSObject *getThrowTypeError() const {
         JS_ASSERT(functionObjectClassesInitialized());
         return &getSlot(THROWTYPEERROR).toObject();
     }
 
     Value createDataViewForThis() const {
         JS_ASSERT(dataViewClassInitialized());
@@ -478,16 +522,79 @@ class GlobalObject : public JSObject
      * exist. Returns NULL only on OOM.
      */
     static DebuggerVector *getOrCreateDebuggers(JSContext *cx, Handle<GlobalObject*> global);
 
     static bool addDebugger(JSContext *cx, Handle<GlobalObject*> global, Debugger *dbg);
 };
 
 template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<uint8_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT8, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<int8_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_INT8, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<uint16_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT16, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<int16_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_INT16, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<uint32_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT32, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<int32_t>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_INT32, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<float>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_FLOAT32, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<double>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_FLOAT64, fun);
+}
+
+template<>
+inline void
+GlobalObject::setCreateArrayFromBuffer<uint8_clamped>(Handle<JSFunction*> fun)
+{
+    setCreateArrayFromBufferHelper(FROM_BUFFER_UINT8CLAMPED, fun);
+}
+
+template<>
 inline Value
 GlobalObject::createArrayFromBuffer<uint8_t>() const
 {
     return createArrayFromBufferHelper(FROM_BUFFER_UINT8);
 }
 
 template<>
 inline Value
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -18,17 +18,16 @@
 #include "jit/IonCompartment.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/ForkJoin.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
-#include "vm/GlobalObject-inl.h"
 #include "vm/Stack-inl.h"
 
 namespace js {
 
 inline bool
 ComputeThis(JSContext *cx, AbstractFramePtr frame)
 {
     JS_ASSERT_IF(frame.isStackFrame(), !frame.asStackFrame()->runningInJit());
--- a/js/src/vm/ObjectImpl-inl.h
+++ b/js/src/vm/ObjectImpl-inl.h
@@ -62,78 +62,16 @@ js::ObjectImpl::isExtensible(ExclusiveCo
 }
 
 inline bool
 js::ObjectImpl::isNative() const
 {
     return lastProperty()->isNative();
 }
 
-#ifdef DEBUG
-inline bool
-IsObjectValueInCompartment(js::Value v, JSCompartment *comp)
-{
-    if (!v.isObject())
-        return true;
-    return v.toObject().compartment() == comp;
-}
-#endif
-
-inline void
-js::ObjectImpl::setSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(slotInRange(slot));
-    MOZ_ASSERT(IsObjectValueInCompartment(value, asObjectPtr()->compartment()));
-    getSlotRef(slot).set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
-}
-
-inline void
-js::ObjectImpl::setCrossCompartmentSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(slotInRange(slot));
-    getSlotRef(slot).set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
-}
-
-inline void
-js::ObjectImpl::initSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(getSlot(slot).isUndefined());
-    MOZ_ASSERT(slotInRange(slot));
-    MOZ_ASSERT(IsObjectValueInCompartment(value, asObjectPtr()->compartment()));
-    initSlotUnchecked(slot, value);
-}
-
-inline void
-js::ObjectImpl::initCrossCompartmentSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(getSlot(slot).isUndefined());
-    MOZ_ASSERT(slotInRange(slot));
-    initSlotUnchecked(slot, value);
-}
-
-inline void
-js::ObjectImpl::initSlotUnchecked(uint32_t slot, const js::Value &value)
-{
-    getSlotAddressUnchecked(slot)->init(this->asObjectPtr(), HeapSlot::Slot, slot, value);
-}
-
-inline void
-js::ObjectImpl::setFixedSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(slot < numFixedSlots());
-    fixedSlots()[slot].set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
-}
-
-inline void
-js::ObjectImpl::initFixedSlot(uint32_t slot, const js::Value &value)
-{
-    MOZ_ASSERT(slot < numFixedSlots());
-    fixedSlots()[slot].init(this->asObjectPtr(), HeapSlot::Slot, slot, value);
-}
-
 inline uint32_t
 js::ObjectImpl::slotSpan() const
 {
     if (inDictionaryMode())
         return lastProperty()->base()->slotSpan();
     return lastProperty()->slotSpan();
 }
 
@@ -183,24 +121,16 @@ js::ObjectImpl::privateWriteBarrierPre(v
     Zone *zone = this->zone();
     if (zone->needsBarrier()) {
         if (*old && getClass()->trace)
             getClass()->trace(zone->barrierTracer(), this->asObjectPtr());
     }
 #endif
 }
 
-inline void
-js::ObjectImpl::privateWriteBarrierPost(void **pprivate)
-{
-#ifdef JSGC_GENERATIONAL
-    runtimeFromAnyThread()->gcStoreBuffer.putCell(reinterpret_cast<js::gc::Cell **>(pprivate));
-#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.
      */
@@ -212,42 +142,16 @@ js::ObjectImpl::writeBarrierPre(ObjectIm
         MOZ_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting());
         JSObject *tmp = obj->asObjectPtr();
         MarkObjectUnbarriered(zone->barrierTracer(), &tmp, "write barrier");
         MOZ_ASSERT(tmp == obj->asObjectPtr());
     }
 #endif
 }
 
-/* static */ inline void
-js::ObjectImpl::writeBarrierPost(ObjectImpl *obj, void *addr)
-{
-#ifdef JSGC_GENERATIONAL
-    if (IsNullTaggedPointer(obj))
-        return;
-    obj->runtimeFromAnyThread()->gcStoreBuffer.putCell((Cell **)addr);
-#endif
-}
-
-/* static */ inline void
-js::ObjectImpl::writeBarrierPostRelocate(ObjectImpl *obj, void *addr)
-{
-#ifdef JSGC_GENERATIONAL
-    obj->runtimeFromAnyThread()->gcStoreBuffer.putRelocatableCell((Cell **)addr);
-#endif
-}
-
-/* static */ inline void
-js::ObjectImpl::writeBarrierPostRemove(ObjectImpl *obj, void *addr)
-{
-#ifdef JSGC_GENERATIONAL
-    obj->runtimeFromAnyThread()->gcStoreBuffer.removeRelocatableCell((Cell **)addr);
-#endif
-}
-
 inline void
 js::ObjectImpl::setPrivate(void *data)
 {
     void **pprivate = &privateRef(numFixedSlots());
     privateWriteBarrierPre(pprivate);
     *pprivate = data;
 }
 
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -11,16 +11,22 @@
 #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
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -13,16 +13,17 @@
 #include <stdint.h>
 
 #include "jsfriendapi.h"
 #include "jsinfer.h"
 #include "NamespaceImports.h"
 
 #include "gc/Barrier.h"
 #include "gc/Heap.h"
+#include "gc/Marking.h"
 #include "js/Value.h"
 #include "vm/NumericConversions.h"
 #include "vm/String.h"
 
 #define JSSLOT_FREE(clasp)  JSCLASS_RESERVED_SLOTS(clasp)
 
 namespace js {
 
@@ -1140,16 +1141,21 @@ struct ObjectOps;
 class Shape;
 
 class NewObjectCache;
 class TaggedProto;
 
 inline Value
 ObjectValue(ObjectImpl &obj);
 
+#ifdef DEBUG
+static inline bool
+IsObjectValueInCompartment(js::Value v, JSCompartment *comp);
+#endif
+
 /*
  * ObjectImpl specifies the internal implementation of an object.  (In contrast
  * JSObject specifies an "external" interface, at the conceptual level of that
  * exposed in ECMAScript.)
  *
  * The |shape_| member stores the shape of the object, which includes the
  * object's class and the layout of all its properties.
  *
@@ -1192,17 +1198,17 @@ ObjectValue(ObjectImpl &obj);
  * will change so that some members are private, and only certain methods that
  * act upon them will be protected.
  */
 class ObjectImpl : public gc::Cell
 {
   protected:
     /*
      * Shape of the object, encodes the layout of the object's properties and
-     * all other information about its structure. See jsscope.h.
+     * all other information about its structure. See vm/Shape.h.
      */
     HeapPtrShape shape_;
 
     /*
      * The object's type and prototype. For objects with the LAZY_TYPE flag
      * set, this is the prototype's default 'new' type and can only be used
      * to get that prototype.
      */
@@ -1431,17 +1437,19 @@ 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;
 
     // uninlinedIsNative() is equivalent to isNative(), but isn't inlined.
     inline bool isNative() const;
     bool uninlinedIsNative() const;
 
     types::TypeObject *type() const {
         MOZ_ASSERT(!hasLazyType());
         return type_;
@@ -1568,36 +1576,65 @@ class ObjectImpl : public gc::Cell
         JS_ASSERT(uninlinedIsNative() && slot < uninlinedSlotSpan());
         return getSlotRef(slot);
     }
     const Value &nativeGetSlot(uint32_t slot) const {
         JS_ASSERT(uninlinedIsNative() && slot < uninlinedSlotSpan());
         return getSlot(slot);
     }
 
-    inline void setSlot(uint32_t slot, const Value &value);
-    inline void setCrossCompartmentSlot(uint32_t slot, const Value &value);
-    inline void initSlot(uint32_t slot, const Value &value);
-    inline void initCrossCompartmentSlot(uint32_t slot, const Value &value);
-    inline void initSlotUnchecked(uint32_t slot, const Value &value);
+    void setSlot(uint32_t slot, const Value &value) {
+        MOZ_ASSERT(slotInRange(slot));
+        MOZ_ASSERT(IsObjectValueInCompartment(value, uninlinedCompartment()));
+        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()));
+        initSlotUnchecked(slot, value);
+    }
+
+    void initCrossCompartmentSlot(uint32_t slot, const Value &value) {
+        MOZ_ASSERT(getSlot(slot).isUndefined());
+        MOZ_ASSERT(slotInRange(slot));
+        initSlotUnchecked(slot, value);
+    }
+
+    void initSlotUnchecked(uint32_t slot, const Value &value) {
+        getSlotAddressUnchecked(slot)->init(this->asObjectPtr(), HeapSlot::Slot, slot, value);
+    }
 
     /* For slots which are known to always be fixed, due to the way they are allocated. */
 
     HeapSlot &getFixedSlotRef(uint32_t slot) {
         MOZ_ASSERT(slot < numFixedSlots());
         return fixedSlots()[slot];
     }
 
     const Value &getFixedSlot(uint32_t slot) const {
         MOZ_ASSERT(slot < numFixedSlots());
         return fixedSlots()[slot];
     }
 
-    inline void setFixedSlot(uint32_t slot, const Value &value);
-    inline void initFixedSlot(uint32_t slot, const Value &value);
+    void setFixedSlot(uint32_t slot, const Value &value) {
+        MOZ_ASSERT(slot < numFixedSlots());
+        fixedSlots()[slot].set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
+    }
+
+    void initFixedSlot(uint32_t slot, const Value &value) {
+        MOZ_ASSERT(slot < numFixedSlots());
+        fixedSlots()[slot].init(this->asObjectPtr(), HeapSlot::Slot, slot, value);
+    }
 
     /*
      * Get the number of dynamic slots to allocate to cover the properties in
      * an object with the given number of fixed slots and slot span. The slot
      * capacity is not stored explicitly, and the allocated size of the slot
      * array is kept in sync with this count.
      */
     static uint32_t dynamicSlotsCount(uint32_t nfixed, uint32_t span) {
@@ -1653,24 +1690,49 @@ class ObjectImpl : public gc::Cell
     }
 
     inline bool hasEmptyElements() const {
         return elements == emptyObjectElements;
     }
 
     /* GC support. */
     JS_ALWAYS_INLINE Zone *zone() const;
-    static inline ThingRootKind rootKind() { return THING_ROOT_OBJECT; }
+    static ThingRootKind rootKind() { return THING_ROOT_OBJECT; }
+
     static inline void readBarrier(ObjectImpl *obj);
     static inline void writeBarrierPre(ObjectImpl *obj);
-    static inline void writeBarrierPost(ObjectImpl *obj, void *addr);
-    static inline void writeBarrierPostRelocate(ObjectImpl *obj, void *addr);
-    static inline void writeBarrierPostRemove(ObjectImpl *obj, void *addr);
+
+    static void writeBarrierPost(ObjectImpl *obj, void *addr) {
+#ifdef JSGC_GENERATIONAL
+        if (IsNullTaggedPointer(obj))
+            return;
+        obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->putCell((Cell **)addr);
+#endif
+    }
+
+    static void writeBarrierPostRelocate(ObjectImpl *obj, void *addr) {
+#ifdef JSGC_GENERATIONAL
+        obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->putRelocatableCell((Cell **)addr);
+#endif
+    }
+
+    static void writeBarrierPostRemove(ObjectImpl *obj, void *addr) {
+#ifdef JSGC_GENERATIONAL
+        obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->removeRelocatableCell((Cell **)addr);
+#endif
+    }
+
     inline void privateWriteBarrierPre(void **oldval);
-    inline void privateWriteBarrierPost(void **pprivate);
+
+    void privateWriteBarrierPost(void **pprivate) {
+#ifdef JSGC_GENERATIONAL
+        shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->putCell(reinterpret_cast<js::gc::Cell **>(pprivate));
+#endif
+    }
+
     void markChildren(JSTracer *trc);
 
     /* Private data accessors. */
 
     inline void *&privateRef(uint32_t nfixed) const { /* XXX should be private, not protected! */
         /*
          * The private pointer of an object can hold any word sized value.
          * Private pointers are stored immediately after the last fixed slot of
@@ -1731,16 +1793,26 @@ ObjectValue(ObjectImpl &obj)
 }
 
 inline Handle<JSObject*>
 Downcast(Handle<ObjectImpl*> obj)
 {
     return Handle<JSObject*>::fromMarkedLocation(reinterpret_cast<JSObject* const*>(obj.address()));
 }
 
+#ifdef DEBUG
+static inline bool
+IsObjectValueInCompartment(js::Value v, JSCompartment *comp)
+{
+    if (!v.isObject())
+        return true;
+    return reinterpret_cast<ObjectImpl*>(&v.toObject())->uninlinedCompartment() == comp;
+}
+#endif
+
 extern JSObject *
 ArrayBufferDelegate(JSContext *cx, Handle<ObjectImpl*> obj);
 
 /* Generic [[GetOwnProperty]] method. */
 bool
 GetOwnElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
               PropDesc *desc);
 extern bool
--- a/js/src/vm/RegExpObject-inl.h
+++ b/js/src/vm/RegExpObject-inl.h
@@ -13,53 +13,11 @@ namespace js {
 
 inline void
 RegExpObject::setShared(ExclusiveContext *cx, RegExpShared &shared)
 {
     shared.prepareForUse(cx);
     JSObject::setPrivate(&shared);
 }
 
-inline void
-RegExpObject::setLastIndex(double d)
-{
-    setSlot(LAST_INDEX_SLOT, NumberValue(d));
-}
-
-inline void
-RegExpObject::zeroLastIndex()
-{
-    setSlot(LAST_INDEX_SLOT, Int32Value(0));
-}
-
-inline void
-RegExpObject::setSource(JSAtom *source)
-{
-    setSlot(SOURCE_SLOT, StringValue(source));
-}
-
-inline void
-RegExpObject::setIgnoreCase(bool enabled)
-{
-    setSlot(IGNORE_CASE_FLAG_SLOT, BooleanValue(enabled));
-}
-
-inline void
-RegExpObject::setGlobal(bool enabled)
-{
-    setSlot(GLOBAL_FLAG_SLOT, BooleanValue(enabled));
-}
-
-inline void
-RegExpObject::setMultiline(bool enabled)
-{
-    setSlot(MULTILINE_FLAG_SLOT, BooleanValue(enabled));
-}
-
-inline void
-RegExpObject::setSticky(bool enabled)
-{
-    setSlot(STICKY_FLAG_SLOT, BooleanValue(enabled));
-}
-
 } /* namespace js */
 
 #endif /* vm_RegExpObject_inl_h */
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -361,39 +361,60 @@ class RegExpObject : public JSObject
     static RegExpObject *
     createNoStatics(ExclusiveContext *cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStream *ts);
 
     /* Accessors. */
 
     static unsigned lastIndexSlot() { return LAST_INDEX_SLOT; }
 
     const Value &getLastIndex() const { return getSlot(LAST_INDEX_SLOT); }
-    inline void setLastIndex(double d);
-    inline void zeroLastIndex();
+
+    void setLastIndex(double d) {
+        setSlot(LAST_INDEX_SLOT, NumberValue(d));
+    }
+
+    void zeroLastIndex() {
+        setSlot(LAST_INDEX_SLOT, Int32Value(0));
+    }
 
     JSFlatString *toString(JSContext *cx) const;
 
     JSAtom *getSource() const { return &getSlot(SOURCE_SLOT).toString()->asAtom(); }
-    inline void setSource(JSAtom *source);
+
+    void setSource(JSAtom *source) {
+        setSlot(SOURCE_SLOT, StringValue(source));
+    }
 
     RegExpFlag getFlags() const {
         unsigned flags = 0;
         flags |= global() ? GlobalFlag : 0;
         flags |= ignoreCase() ? IgnoreCaseFlag : 0;
         flags |= multiline() ? MultilineFlag : 0;
         flags |= sticky() ? StickyFlag : 0;
         return RegExpFlag(flags);
     }
 
     /* Flags. */
 
-    inline void setIgnoreCase(bool enabled);
-    inline void setGlobal(bool enabled);
-    inline void setMultiline(bool enabled);
-    inline void setSticky(bool enabled);
+    void setIgnoreCase(bool enabled) {
+        setSlot(IGNORE_CASE_FLAG_SLOT, BooleanValue(enabled));
+    }
+
+    void setGlobal(bool enabled) {
+        setSlot(GLOBAL_FLAG_SLOT, BooleanValue(enabled));
+    }
+
+    void setMultiline(bool enabled) {
+        setSlot(MULTILINE_FLAG_SLOT, BooleanValue(enabled));
+    }
+
+    void setSticky(bool enabled) {
+        setSlot(STICKY_FLAG_SLOT, BooleanValue(enabled));
+    }
+
     bool ignoreCase() const { return getSlot(IGNORE_CASE_FLAG_SLOT).toBoolean(); }
     bool global() const     { return getSlot(GLOBAL_FLAG_SLOT).toBoolean(); }
     bool multiline() const  { return getSlot(MULTILINE_FLAG_SLOT).toBoolean(); }
     bool sticky() const     { return getSlot(STICKY_FLAG_SLOT).toBoolean(); }
 
     void shared(RegExpGuard *g) const {
         JS_ASSERT(maybeShared() != NULL);
         g->init(*maybeShared());
@@ -401,16 +422,17 @@ 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);
 
   private:
     friend class RegExpObjectBuilder;
 
     /*
      * Compute the initial shape to associate with fresh RegExp objects,
      * encoding their initial properties. Return the shape after
--- a/js/src/vm/RegExpStatics.h
+++ b/js/src/vm/RegExpStatics.h
@@ -195,23 +195,16 @@ class PreserveRegExpStatics
 
     bool init(JSContext *cx) {
         return original->save(cx, &buffer.getStatics());
     }
 
     ~PreserveRegExpStatics() { original->restore(); }
 };
 
-inline js::RegExpStatics *
-js::GlobalObject::getRegExpStatics() const
-{
-    JSObject &resObj = getSlot(REGEXP_STATICS).toObject();
-    return static_cast<RegExpStatics *>(resObj.getPrivate());
-}
-
 inline bool
 RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, MutableHandleValue out)
 {
     /* Private function: caller must perform lazy evaluation. */
     JS_ASSERT(!pendingLazyEvaluation);
 
     JS_ASSERT(start <= end);
     JS_ASSERT(end <= matchesInput->length());
--- a/js/src/vm/ScopeObject-inl.h
+++ b/js/src/vm/ScopeObject-inl.h
@@ -5,29 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ScopeObject_inl_h
 #define vm_ScopeObject_inl_h
 
 #include "vm/ScopeObject.h"
 
 #include "jsinferinlines.h"
-#include "jsobjinlines.h"
 
 namespace js {
 
 inline void
-ScopeObject::setEnclosingScope(HandleObject obj)
-{
-    JS_ASSERT_IF(obj->is<CallObject>() || obj->is<DeclEnvObject>() || obj->is<BlockObject>(),
-                 obj->isDelegate());
-    setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj));
-}
-
-inline void
 ScopeObject::setAliasedVar(JSContext *cx, ScopeCoordinate sc, PropertyName *name, const Value &v)
 {
     JS_ASSERT(is<CallObject>() || is<ClonedBlockObject>());
     JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == BlockObject::RESERVED_SLOTS);
 
     // name may be null for non-singletons, whose types do not need to be tracked.
     JS_ASSERT_IF(hasSingletonType(), name);
 
@@ -40,68 +31,11 @@ inline void
 CallObject::setAliasedVar(JSContext *cx, AliasedFormalIter fi, PropertyName *name, const Value &v)
 {
     JS_ASSERT(name == fi->name());
     setSlot(fi.scopeSlot(), v);
     if (hasSingletonType())
         types::AddTypePropertyId(cx, this, NameToId(name), v);
 }
 
-inline void
-BlockObject::setSlotValue(unsigned i, const Value &v)
-{
-    setSlot(RESERVED_SLOTS + i, v);
-}
-
-inline void
-StaticBlockObject::initPrevBlockChainFromParser(StaticBlockObject *prev)
-{
-    setReservedSlot(SCOPE_CHAIN_SLOT, ObjectOrNullValue(prev));
-}
-
-inline void
-StaticBlockObject::resetPrevBlockChainFromParser()
-{
-    setReservedSlot(SCOPE_CHAIN_SLOT, UndefinedValue());
-}
-
-inline void
-StaticBlockObject::initEnclosingStaticScope(JSObject *obj)
-{
-    JS_ASSERT(getReservedSlot(SCOPE_CHAIN_SLOT).isUndefined());
-    setReservedSlot(SCOPE_CHAIN_SLOT, ObjectOrNullValue(obj));
-}
-
-inline void
-StaticBlockObject::setStackDepth(uint32_t depth)
-{
-    JS_ASSERT(getReservedSlot(DEPTH_SLOT).isUndefined());
-    initReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
-}
-
-inline void
-StaticBlockObject::setDefinitionParseNode(unsigned i, frontend::Definition *def)
-{
-    JS_ASSERT(slotValue(i).isUndefined());
-    setSlotValue(i, PrivateValue(def));
-}
-
-inline void
-StaticBlockObject::setAliased(unsigned i, bool aliased)
-{
-    JS_ASSERT_IF(i > 0, slotValue(i-1).isBoolean());
-    setSlotValue(i, BooleanValue(aliased));
-    if (aliased && !needsClone()) {
-        setSlotValue(0, MagicValue(JS_BLOCK_NEEDS_CLONE));
-        JS_ASSERT(needsClone());
-    }
-}
-
-inline void
-ClonedBlockObject::setVar(unsigned i, const Value &v, MaybeCheckAliasing checkAliasing)
-{
-    JS_ASSERT_IF(checkAliasing, staticBlock().isAliased(i));
-    setSlotValue(i, v);
-}
-
 }  /* namespace js */
 
 #endif /* vm_ScopeObject_inl_h */
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -161,16 +161,24 @@ js::ScopeCoordinateFunctionScript(JSCont
     }
     if (ssi.type() != StaticScopeIter::FUNCTION)
         return NULL;
     return ssi.funScript();
 }
 
 /*****************************************************************************/
 
+inline void
+ScopeObject::setEnclosingScope(HandleObject obj)
+{
+    JS_ASSERT_IF(obj->is<CallObject>() || obj->is<DeclEnvObject>() || obj->is<BlockObject>(),
+                 obj->isDelegate());
+    setFixedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*obj));
+}
+
 /*
  * Construct a bare-bones call object given a shape, type, and slots pointer.
  * The call object must be further initialized to be usable.
  */
 CallObject *
 CallObject::create(JSContext *cx, HandleScript script, HandleShape shape, HandleTypeObject type, HeapSlot *slots)
 {
     gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -165,17 +165,18 @@ class ScopeObject : public JSObject
     /*
      * Since every scope chain terminates with a global object and GlobalObject
      * does not derive ScopeObject (it has a completely different layout), the
      * enclosing scope of a ScopeObject is necessarily non-null.
      */
     inline JSObject &enclosingScope() const {
         return getReservedSlot(SCOPE_CHAIN_SLOT).toObject();
     }
-    void setEnclosingScope(HandleObject obj);
+
+    inline void setEnclosingScope(HandleObject obj);
 
     /*
      * Get or set an aliased variable contained in this scope. Unaliased
      * variables should instead access the StackFrame. Aliased variable access
      * is primarily made through JOF_SCOPECOORD ops which is why these members
      * take a ScopeCoordinate instead of just the slot index.
      */
     inline const Value &aliasedVar(ScopeCoordinate sc);
@@ -337,17 +338,19 @@ class BlockObject : public NestedScopeOb
     }
 
   protected:
     /* Blocks contain an object slot for each slot i: 0 <= i < slotCount. */
     const Value &slotValue(unsigned i) {
         return getSlotRef(RESERVED_SLOTS + i);
     }
 
-    inline void setSlotValue(unsigned i, const Value &v);
+    void setSlotValue(unsigned i, const Value &v) {
+        setSlot(RESERVED_SLOTS + i, v);
+    }
 };
 
 class StaticBlockObject : public BlockObject
 {
   public:
     static StaticBlockObject *create(ExclusiveContext *cx);
 
     /* See StaticScopeIter comment. */
@@ -383,38 +386,62 @@ class StaticBlockObject : public BlockOb
      */
     bool needsClone() {
         return !slotValue(0).isFalse();
     }
 
     /* Frontend-only functions ***********************************************/
 
     /* Initialization functions for above fields. */
-    void setAliased(unsigned i, bool aliased);
-    void setStackDepth(uint32_t depth);
-    void initEnclosingStaticScope(JSObject *obj);
+    void setAliased(unsigned i, bool aliased) {
+        JS_ASSERT_IF(i > 0, slotValue(i-1).isBoolean());
+        setSlotValue(i, BooleanValue(aliased));
+        if (aliased && !needsClone()) {
+            setSlotValue(0, MagicValue(JS_BLOCK_NEEDS_CLONE));
+            JS_ASSERT(needsClone());
+        }
+    }
+
+    void setStackDepth(uint32_t depth) {
+        JS_ASSERT(getReservedSlot(DEPTH_SLOT).isUndefined());
+        initReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
+    }
+
+    void initEnclosingStaticScope(JSObject *obj) {
+        JS_ASSERT(getReservedSlot(SCOPE_CHAIN_SLOT).isUndefined());
+        setReservedSlot(SCOPE_CHAIN_SLOT, ObjectOrNullValue(obj));
+    }
 
     /*
      * Frontend compilation temporarily uses the object's slots to link
      * a let var to its associated Definition parse node.
      */
-    void setDefinitionParseNode(unsigned i, frontend::Definition *def);
+    void setDefinitionParseNode(unsigned i, frontend::Definition *def) {
+        JS_ASSERT(slotValue(i).isUndefined());
+        setSlotValue(i, PrivateValue(def));
+    }
+
     frontend::Definition *maybeDefinitionParseNode(unsigned i) {
         Value v = slotValue(i);
         return v.isUndefined() ? NULL : reinterpret_cast<frontend::Definition *>(v.toPrivate());
     }
 
     /*
      * The parser uses 'enclosingBlock' as the prev-link in the pc->blockChain
      * stack. Note: in the case of hoisting, this prev-link will not ultimately
      * be the same as enclosingBlock, initEnclosingStaticScope must be called
      * separately in the emitter. 'reset' is just for asserting stackiness.
      */
-    void initPrevBlockChainFromParser(StaticBlockObject *prev);
-    void resetPrevBlockChainFromParser();
+    void initPrevBlockChainFromParser(StaticBlockObject *prev) {
+        setReservedSlot(SCOPE_CHAIN_SLOT, ObjectOrNullValue(prev));
+    }
+
+    void resetPrevBlockChainFromParser() {
+        setReservedSlot(SCOPE_CHAIN_SLOT, UndefinedValue());
+    }
 
     static Shape *addVar(ExclusiveContext *cx, Handle<StaticBlockObject*> block, HandleId id,
                          int index, bool *redeclared);
 };
 
 class ClonedBlockObject : public BlockObject
 {
   public:
@@ -427,17 +454,20 @@ class ClonedBlockObject : public BlockOb
     }
 
     /* Assuming 'put' has been called, return the value of the ith let var. */
     const Value &var(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
         JS_ASSERT_IF(checkAliasing, staticBlock().isAliased(i));
         return slotValue(i);
     }
 
-    void setVar(unsigned i, const Value &v, MaybeCheckAliasing checkAliasing = CHECK_ALIASING);
+    void setVar(unsigned i, const Value &v, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
+        JS_ASSERT_IF(checkAliasing, staticBlock().isAliased(i));
+        setSlotValue(i, v);
+    }
 
     /* Copy in all the unaliased formals and locals. */
     void copyUnaliasedValues(AbstractFramePtr frame);
 };
 
 template<XDRMode mode>
 bool
 XDRStaticBlockObject(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript script,
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -11,16 +11,18 @@
 
 #include "mozilla/PodOperations.h"
 
 #include "jscntxt.h"
 
 #include "jit/BaselineFrame.h"
 #include "vm/ScopeObject.h"
 
+#include "jsobjinlines.h"
+
 #include "jit/BaselineFrame-inl.h"
 #include "jit/IonFrameIterator-inl.h"
 
 namespace js {
 
 /*
  * We cache name lookup results only for the global object or for native
  * non-global objects without prototype or with prototype that never mutates,
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -35,18 +35,16 @@
 #include "vm/Interpreter.h"
 #include "vm/NumericConversions.h"
 #include "vm/WrapperObject.h"
 
 #include "jsatominlines.h"
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
-#include "vm/GlobalObject-inl.h"
-
 #if JS_USE_NEW_OBJECT_REPRESENTATION
 // See the comment above OldObjectRepresentationHack.
 #  error "TypedArray support for new object representation unimplemented."
 #endif
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;