Bug 909977 - Rename mozilla::Move to mozilla::OldMove, and make mozilla::Move a synonym for std::move(). r=waldo
authorJustin Lebar <justin.lebar@gmail.com>
Thu, 29 Aug 2013 11:54:14 -0700
changeset 145062 bb557a5557c2d70b2d73f2002855e70ed16870f6
parent 145061 dfdb69b6dfd36d996137bc8e92ced7276d90caa6
child 145063 3f307f37b77a321b9deeb4f26e20d78494ea38d0
push id25192
push useremorley@mozilla.com
push dateFri, 30 Aug 2013 16:23:44 +0000
treeherdermozilla-central@cfe8b0ab6d59 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs909977
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 909977 - Rename mozilla::Move to mozilla::OldMove, and make mozilla::Move a synonym for std::move(). r=waldo
chrome/src/nsChromeRegistryChrome.h
gfx/thebes/gfxFont.h
js/public/HashTable.h
js/public/MemoryMetrics.h
js/src/builtin/MapObject.cpp
js/src/jit/AsmJS.cpp
js/src/jit/AsmJSModule.h
js/src/jsmemorymetrics.cpp
js/src/shell/jsheaptools.cpp
mfbt/Move.h
mfbt/TypeTraits.h
mfbt/Vector.h
xpcom/base/nsAutoPtr.h
xpcom/glue/nsBaseHashtable.h
xpcom/glue/nsTHashtable.h
--- a/chrome/src/nsChromeRegistryChrome.h
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -3,16 +3,17 @@
  * 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 nsChromeRegistryChrome_h
 #define nsChromeRegistryChrome_h
 
 #include "nsChromeRegistry.h"
 #include "nsVoidArray.h"
+#include "mozilla/Move.h"
 
 namespace mozilla {
 namespace dom {
 class PContentParent;
 }
 }
 
 class nsIPrefBranch;
@@ -121,18 +122,18 @@ class nsChromeRegistryChrome : public ns
 
   class OverlayListEntry : public nsURIHashKey
   {
    public:
     typedef nsURIHashKey::KeyType        KeyType;
     typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
 
     OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
-    OverlayListEntry(OverlayListEntry& toCopy) : nsURIHashKey(toCopy),
-                                                 mArray(toCopy.mArray) { }
+    OverlayListEntry(OverlayListEntry&& toMove) : nsURIHashKey(mozilla::Move(toMove)),
+                                                  mArray(mozilla::Move(toMove.mArray)) { }
     ~OverlayListEntry() { }
 
     void AddURI(nsIURI* aURI);
 
     nsCOMArray<nsIURI> mArray;
   };
 
   class OverlayListHash
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -600,21 +600,22 @@ private:
         // Declarations for nsTHashtable
 
         typedef nsUint32HashKey KeyClass;
         typedef KeyClass::KeyType KeyType;
         typedef KeyClass::KeyTypePointer KeyTypePointer;
 
         FontTableHashEntry(KeyTypePointer aTag)
             : KeyClass(aTag), mBlob() { }
-        // Copying transfers blob association.
-        FontTableHashEntry(FontTableHashEntry& toCopy)
-            : KeyClass(toCopy), mBlob(toCopy.mBlob)
+
+        FontTableHashEntry(FontTableHashEntry&& toMove)
+            : KeyClass(mozilla::Move(toMove))
+            , mBlob(mozilla::Move(toMove.mBlob))
         {
-            toCopy.mBlob = nullptr;
+            toMove.mBlob = nullptr;
         }
 
         ~FontTableHashEntry() { Clear(); }
 
         // FontTable/Blob API
 
         // Transfer (not copy) elements of aTable to a new hb_blob_t and
         // return ownership to the caller.  A weak reference to the blob is
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -133,28 +133,28 @@ class HashMap
     typedef typename Impl::AddPtr AddPtr;
     AddPtr lookupForAdd(const Lookup &l) const {
         return impl.lookupForAdd(l);
     }
 
     template<typename KeyInput, typename ValueInput>
     bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) {
         Entry e(k, v);
-        return impl.add(p, mozilla::Move(e));
+        return impl.add(p, mozilla::OldMove(e));
     }
 
     bool add(AddPtr &p, const Key &k) {
         Entry e(k, Value());
-        return impl.add(p, mozilla::Move(e));
+        return impl.add(p, mozilla::OldMove(e));
     }
 
     template<typename KeyInput, typename ValueInput>
     bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) {
         Entry e(k, v);
-        return impl.relookupOrAdd(p, k, mozilla::Move(e));
+        return impl.relookupOrAdd(p, k, mozilla::OldMove(e));
     }
 
     // |all()| returns a Range containing |count()| elements. E.g.:
     //
     //   typedef HashMap<int,char> HM;
     //   HM h;
     //   for (HM::Range r = h.all(); !r.empty(); r.popFront())
     //     char c = r.front().value;
@@ -226,17 +226,17 @@ class HashMap
         }
         return add(p, k, v);
     }
 
     // Like put, but assert that the given key is not already present.
     template<typename KeyInput, typename ValueInput>
     bool putNew(const KeyInput &k, const ValueInput &v) {
         Entry e(k, v);
-        return impl.putNew(k, mozilla::Move(e));
+        return impl.putNew(k, mozilla::OldMove(e));
     }
 
     // Add (k,defaultValue) if |k| is not found. Return a false-y Ptr on oom.
     Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
         AddPtr p = lookupForAdd(k);
         if (p)
             return p;
         (void)add(p, k, defaultValue);  // p is left false-y on oom.
@@ -253,18 +253,18 @@ class HashMap
     void rekey(const Lookup &old_key, const Key &new_key) {
         if (old_key != new_key) {
             if (Ptr p = lookup(old_key))
                 impl.rekeyAndMaybeRehash(p, new_key, new_key);
         }
     }
 
     // HashMap is movable
-    HashMap(mozilla::MoveRef<HashMap> rhs) : impl(mozilla::Move(rhs->impl)) {}
-    void operator=(mozilla::MoveRef<HashMap> rhs) { impl = mozilla::Move(rhs->impl); }
+    HashMap(mozilla::MoveRef<HashMap> rhs) : impl(mozilla::OldMove(rhs->impl)) {}
+    void operator=(mozilla::MoveRef<HashMap> rhs) { impl = mozilla::OldMove(rhs->impl); }
 
   private:
     // HashMap is not copyable or assignable
     HashMap(const HashMap &hm) MOZ_DELETE;
     HashMap &operator=(const HashMap &hm) MOZ_DELETE;
 
     friend class Impl::Enum;
 };
@@ -452,18 +452,18 @@ class HashSet
     void rekey(const Lookup &old_key, const T &new_key) {
         if (old_key != new_key) {
             if (Ptr p = lookup(old_key))
                 impl.rekeyAndMaybeRehash(p, new_key, new_key);
         }
     }
 
     // HashSet is movable
-    HashSet(mozilla::MoveRef<HashSet> rhs) : impl(mozilla::Move(rhs->impl)) {}
-    void operator=(mozilla::MoveRef<HashSet> rhs) { impl = mozilla::Move(rhs->impl); }
+    HashSet(mozilla::MoveRef<HashSet> rhs) : impl(mozilla::OldMove(rhs->impl)) {}
+    void operator=(mozilla::MoveRef<HashSet> rhs) { impl = mozilla::OldMove(rhs->impl); }
 
   private:
     // HashSet is not copyable or assignable
     HashSet(const HashSet &hs) MOZ_DELETE;
     HashSet &operator=(const HashSet &hs) MOZ_DELETE;
 
     friend class Impl::Enum;
 };
@@ -580,17 +580,17 @@ class HashMapEntry
     HashMapEntry(const HashMapEntry &) MOZ_DELETE;
     void operator=(const HashMapEntry &) MOZ_DELETE;
 
   public:
     template<typename KeyInput, typename ValueInput>
     HashMapEntry(const KeyInput &k, const ValueInput &v) : key(k), value(v) {}
 
     HashMapEntry(mozilla::MoveRef<HashMapEntry> rhs)
-      : key(mozilla::Move(rhs->key)), value(mozilla::Move(rhs->value)) { }
+      : key(mozilla::OldMove(rhs->key)), value(mozilla::OldMove(rhs->value)) { }
 
     typedef Key KeyType;
     typedef Value ValueType;
 
     const Key key;
     Value value;
 };
 
@@ -1164,17 +1164,17 @@ class HashTable : private AllocPolicy
         removedCount = 0;
         gen++;
         table = newTable;
 
         // Copy only live entries, leaving removed ones behind.
         for (Entry *src = oldTable, *end = src + oldCap; src < end; ++src) {
             if (src->isLive()) {
                 HashNumber hn = src->getKeyHash();
-                findFreeEntry(hn).setLive(hn, mozilla::Move(src->get()));
+                findFreeEntry(hn).setLive(hn, mozilla::OldMove(src->get()));
                 src->destroy();
             }
         }
 
         // All entries have been destroyed, no need to destroyTable.
         this->free_(oldTable);
         return Rehashed;
     }
@@ -1462,20 +1462,20 @@ class HashTable : private AllocPolicy
         checkUnderloaded();
     }
 
     void rekeyWithoutRehash(Ptr p, const Lookup &l, const Key &k)
     {
         JS_ASSERT(table);
         mozilla::ReentrancyGuard g(*this);
         JS_ASSERT(p.found());
-        typename HashTableEntry<T>::NonConstT t(mozilla::Move(*p));
+        typename HashTableEntry<T>::NonConstT t(mozilla::OldMove(*p));
         HashPolicy::setKey(t, const_cast<Key &>(k));
         remove(*p.entry_);
-        putNewInfallible(l, mozilla::Move(t));
+        putNewInfallible(l, mozilla::OldMove(t));
     }
 
     void rekeyAndMaybeRehash(Ptr p, const Lookup &l, const Key &k)
     {
         rekeyWithoutRehash(p, l, k);
         checkOverRemoved();
     }
 
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -272,18 +272,18 @@ struct RuntimeSizes
 struct ZoneStats : js::ZoneStatsPod
 {
     ZoneStats() {
         strings.init();
     }
 
     ZoneStats(mozilla::MoveRef<ZoneStats> other)
         : ZoneStatsPod(other),
-          strings(mozilla::Move(other->strings)),
-          notableStrings(mozilla::Move(other->notableStrings))
+          strings(mozilla::OldMove(other->strings)),
+          notableStrings(mozilla::OldMove(other->notableStrings))
     {}
 
     // Add other's numbers to this object's numbers.  Both objects'
     // notableStrings vectors must be empty at this point, because we can't
     // merge them.  (A NotableStringInfo contains only a prefix of the string,
     // so we can't tell whether two NotableStringInfo objects correspond to the
     // same string.)
     void add(const ZoneStats &other) {
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -20,17 +20,17 @@
 #include "jsobjinlines.h"
 
 #include "gc/Barrier-inl.h"
 
 using namespace js;
 
 using mozilla::DoubleIsInt32;
 using mozilla::IsNaN;
-using mozilla::Move;
+using mozilla::OldMove;
 using mozilla::MoveRef;
 
 
 /*** OrderedHashTable ****************************************************************************/
 
 /*
  * Define two collection templates, js::OrderedHashMap and js::OrderedHashSet.
  * They are like js::HashMap and js::HashSet except that:
@@ -605,17 +605,17 @@ class OrderedHashTable
     void rehashInPlace() {
         for (uint32_t i = 0, N = hashBuckets(); i < N; i++)
             hashTable[i] = NULL;
         Data *wp = data, *end = data + dataLength;
         for (Data *rp = data; rp != end; rp++) {
             if (!Ops::isEmpty(Ops::getKey(rp->element))) {
                 HashNumber h = prepareHash(Ops::getKey(rp->element)) >> hashShift;
                 if (rp != wp)
-                    wp->element = Move(rp->element);
+                    wp->element = OldMove(rp->element);
                 wp->chain = hashTable[h];
                 hashTable[h] = wp;
                 wp++;
             }
         }
         MOZ_ASSERT(wp == data + liveCount);
 
         while (wp != end)
@@ -652,17 +652,17 @@ class OrderedHashTable
             alloc.free_(newHashTable);
             return false;
         }
 
         Data *wp = newData;
         for (Data *p = data, *end = data + dataLength; p != end; p++) {
             if (!Ops::isEmpty(Ops::getKey(p->element))) {
                 HashNumber h = prepareHash(Ops::getKey(p->element)) >> newHashShift;
-                new (wp) Data(Move(p->element), newHashTable[h]);
+                new (wp) Data(OldMove(p->element), newHashTable[h]);
                 newHashTable[h] = wp;
                 wp++;
             }
         }
         MOZ_ASSERT(wp == newData + liveCount);
 
         alloc.free_(hashTable);
         freeData(data, dataLength);
@@ -693,24 +693,24 @@ class OrderedHashMap
     {
         template <class, class, class> friend class detail::OrderedHashTable;
         void operator=(const Entry &rhs) {
             const_cast<Key &>(key) = rhs.key;
             value = rhs.value;
         }
 
         void operator=(MoveRef<Entry> rhs) {
-            const_cast<Key &>(key) = Move(rhs->key);
-            value = Move(rhs->value);
+            const_cast<Key &>(key) = OldMove(rhs->key);
+            value = OldMove(rhs->value);
         }
 
       public:
         Entry() : key(), value() {}
         Entry(const Key &k, const Value &v) : key(k), value(v) {}
-        Entry(MoveRef<Entry> rhs) : key(Move(rhs->key)), value(Move(rhs->value)) {}
+        Entry(MoveRef<Entry> rhs) : key(OldMove(rhs->key)), value(OldMove(rhs->value)) {}
 
         const Key key;
         Value value;
     };
 
   private:
     struct MapOps : OrderedHashPolicy
     {
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -39,17 +39,17 @@ using namespace js::jit;
 
 using mozilla::AddToHash;
 using mozilla::ArrayLength;
 using mozilla::DebugOnly;
 using mozilla::HashGeneric;
 using mozilla::IsNaN;
 using mozilla::IsNegativeZero;
 using mozilla::Maybe;
-using mozilla::Move;
+using mozilla::OldMove;
 using mozilla::MoveRef;
 
 static const size_t LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
 
 /*****************************************************************************/
 // ParseNode utilities
 
 static inline ParseNode *
@@ -659,31 +659,31 @@ class Signature
   public:
     Signature(ExclusiveContext *cx)
       : argTypes_(cx) {}
     Signature(ExclusiveContext *cx, RetType retType)
       : argTypes_(cx), retType_(retType) {}
     Signature(MoveRef<VarTypeVector> argTypes, RetType retType)
       : argTypes_(argTypes), retType_(retType) {}
     Signature(MoveRef<Signature> rhs)
-      : argTypes_(Move(rhs->argTypes_)), retType_(rhs->retType_) {}
+      : argTypes_(OldMove(rhs->argTypes_)), retType_(rhs->retType_) {}
 
     bool copy(const Signature &rhs) {
         if (!argTypes_.resize(rhs.argTypes_.length()))
             return false;
         for (unsigned i = 0; i < argTypes_.length(); i++)
             argTypes_[i] = rhs.argTypes_[i];
         retType_ = rhs.retType_;
         return true;
     }
 
     bool appendArg(VarType type) { return argTypes_.append(type); }
     VarType arg(unsigned i) const { return argTypes_[i]; }
     const VarTypeVector &args() const { return argTypes_; }
-    MoveRef<VarTypeVector> extractArgs() { return Move(argTypes_); }
+    MoveRef<VarTypeVector> extractArgs() { return OldMove(argTypes_); }
 
     RetType retType() const { return retType_; }
 };
 
 static
 bool operator==(const Signature &lhs, const Signature &rhs)
 {
     if (lhs.retType() != rhs.retType())
@@ -1072,18 +1072,18 @@ class MOZ_STACK_CLASS ModuleCompiler
         FuncPtrVector elems_;
 
       public:
         FuncPtrTable(ExclusiveContext *cx, MoveRef<Signature> sig, uint32_t mask, uint32_t gdo)
           : sig_(sig), mask_(mask), globalDataOffset_(gdo), elems_(cx)
         {}
 
         FuncPtrTable(MoveRef<FuncPtrTable> rhs)
-          : sig_(Move(rhs->sig_)), mask_(rhs->mask_), globalDataOffset_(rhs->globalDataOffset_),
-            elems_(Move(rhs->elems_))
+          : sig_(OldMove(rhs->sig_)), mask_(rhs->mask_), globalDataOffset_(rhs->globalDataOffset_),
+            elems_(OldMove(rhs->elems_))
         {}
 
         Signature &sig() { return sig_; }
         const Signature &sig() const { return sig_; }
         unsigned mask() const { return mask_; }
         unsigned globalDataOffset() const { return globalDataOffset_; }
 
         void initElems(MoveRef<FuncPtrVector> elems) { elems_ = elems; JS_ASSERT(!elems_.empty()); }
@@ -1097,17 +1097,17 @@ class MOZ_STACK_CLASS ModuleCompiler
     {
         PropertyName *name_;
         Signature sig_;
 
       public:
         ExitDescriptor(PropertyName *name, MoveRef<Signature> sig)
           : name_(name), sig_(sig) {}
         ExitDescriptor(MoveRef<ExitDescriptor> rhs)
-          : name_(rhs->name_), sig_(Move(rhs->sig_))
+          : name_(rhs->name_), sig_(OldMove(rhs->sig_))
         {}
         const Signature &sig() const {
             return sig_;
         }
 
         // ExitDescriptor is a HashPolicy:
         typedef ExitDescriptor Lookup;
         static HashNumber hash(const ExitDescriptor &d) {
@@ -1396,17 +1396,17 @@ class MOZ_STACK_CLASS ModuleCompiler
             return false;
         global->u.funcPtrTableIndex_ = funcPtrTables_.length();
         if (!globals_.putNew(name, global))
             return false;
         uint32_t globalDataOffset;
         if (!module_->addFuncPtrTable(/* numElems = */ mask + 1, &globalDataOffset))
             return false;
         FuncPtrTable tmpTable(cx_, sig, mask, globalDataOffset);
-        if (!funcPtrTables_.append(Move(tmpTable)))
+        if (!funcPtrTables_.append(OldMove(tmpTable)))
             return false;
         *table = &funcPtrTables_.back();
         return true;
     }
     bool addFFI(PropertyName *varName, PropertyName *field) {
         Global *global = moduleLifo_.new_<Global>(Global::FFI);
         if (!global)
             return false;
@@ -1447,28 +1447,28 @@ class MOZ_STACK_CLASS ModuleCompiler
         AsmJSModule::ArgCoercionVector argCoercions;
         const VarTypeVector &args = func->sig().args();
         if (!argCoercions.resize(args.length()))
             return false;
         for (unsigned i = 0; i < args.length(); i++)
             argCoercions[i] = args[i].toCoercion();
         AsmJSModule::ReturnType retType = func->sig().retType().toModuleReturnType();
         return module_->addExportedFunction(func->name(), maybeFieldName,
-                                            Move(argCoercions), retType);
+                                            OldMove(argCoercions), retType);
     }
     bool addExit(unsigned ffiIndex, PropertyName *name, MoveRef<Signature> sig, unsigned *exitIndex) {
         ExitDescriptor exitDescriptor(name, sig);
         ExitMap::AddPtr p = exits_.lookupForAdd(exitDescriptor);
         if (p) {
             *exitIndex = p->value;
             return true;
         }
         if (!module_->addExit(ffiIndex, exitIndex))
             return false;
-        return exits_.add(p, Move(exitDescriptor), *exitIndex);
+        return exits_.add(p, OldMove(exitDescriptor), *exitIndex);
     }
     bool addGlobalAccess(AsmJSGlobalAccess access) {
         return globalAccesses_.append(access);
     }
 
     bool collectAccesses(MIRGenerator &gen) {
         if (!module_->addHeapAccesses(gen.heapAccesses()))
             return false;
@@ -2503,17 +2503,17 @@ class FunctionCompiler
     template <class Key, class Map>
     bool addBreakOrContinue(Key key, Map *map)
     {
         if (!curBlock_)
             return true;
         typename Map::AddPtr p = map->lookupForAdd(key);
         if (!p) {
             BlockVector empty(m().cx());
-            if (!map->add(p, key, Move(empty)))
+            if (!map->add(p, key, OldMove(empty)))
                 return false;
         }
         if (!p->value.append(curBlock_))
             return false;
         curBlock_ = NULL;
         return true;
     }
 
@@ -3380,17 +3380,17 @@ CheckInternalCall(FunctionCompiler &f, P
                   RetType retType, MDefinition **def, Type *type)
 {
     FunctionCompiler::Call call(f, retType);
 
     if (!CheckCallArgs(f, callNode, CheckIsVarType, &call))
         return false;
 
     ModuleCompiler::Func *callee;
-    if (!CheckFunctionSignature(f.m(), callNode, Move(call.sig()), calleeName, &callee))
+    if (!CheckFunctionSignature(f.m(), callNode, OldMove(call.sig()), calleeName, &callee))
         return false;
 
     if (!f.internalCall(*callee, call, def))
         return false;
 
     *type = retType.toType();
     return true;
 }
@@ -3456,17 +3456,17 @@ CheckFuncPtrCall(FunctionCompiler &f, Pa
         return f.failf(indexNode, "%s is not a subtype of intish", indexType.toChars());
 
     FunctionCompiler::Call call(f, retType);
 
     if (!CheckCallArgs(f, callNode, CheckIsVarType, &call))
         return false;
 
     ModuleCompiler::FuncPtrTable *table;
-    if (!CheckFuncPtrTableAgainstExisting(f.m(), tableNode, name, Move(call.sig()), mask, &table))
+    if (!CheckFuncPtrTableAgainstExisting(f.m(), tableNode, name, OldMove(call.sig()), mask, &table))
         return false;
 
     if (!f.funcPtrCall(*table, indexDef, call, def))
         return false;
 
     *type = retType.toType();
     return true;
 }
@@ -3485,17 +3485,17 @@ CheckFFICall(FunctionCompiler &f, ParseN
 {
     PropertyName *calleeName = CallCallee(callNode)->name();
 
     FunctionCompiler::Call call(f, retType);
     if (!CheckCallArgs(f, callNode, CheckIsExternType, &call))
         return false;
 
     unsigned exitIndex;
-    if (!f.m().addExit(ffiIndex, calleeName, Move(call.sig()), &exitIndex))
+    if (!f.m().addExit(ffiIndex, calleeName, OldMove(call.sig()), &exitIndex))
         return false;
 
     if (!f.ffiCall(exitIndex, call, retType.toMIRType(), def))
         return false;
 
     *type = retType.toType();
     return true;
 }
@@ -4669,19 +4669,19 @@ CheckFunction(ModuleCompiler &m, LifoAll
 
     RetType retType;
     if (!CheckFinalReturn(f, lastNonEmptyStmt, &retType))
         return false;
 
     if (!CheckReturnType(f, lastNonEmptyStmt, retType))
         return false;
 
-    Signature sig(Move(argTypes), retType);
+    Signature sig(OldMove(argTypes), retType);
     ModuleCompiler::Func *func;
-    if (!CheckFunctionSignature(m, fn, Move(sig), FunctionName(fn), &func))
+    if (!CheckFunctionSignature(m, fn, OldMove(sig), FunctionName(fn), &func))
         return false;
 
     if (func->defined())
         return m.failName(fn, "function '%s' already defined", FunctionName(fn));
 
     func->define(fn->pn_pos.begin);
     func->accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
 
@@ -5052,20 +5052,20 @@ CheckFuncPtrTable(ModuleCompiler &m, Par
             return false;
     }
 
     Signature sig(m.cx());
     if (!sig.copy(*firstSig))
         return false;
 
     ModuleCompiler::FuncPtrTable *table;
-    if (!CheckFuncPtrTableAgainstExisting(m, var, var->name(), Move(sig), mask, &table))
+    if (!CheckFuncPtrTableAgainstExisting(m, var, var->name(), OldMove(sig), mask, &table))
         return false;
 
-    table->initElems(Move(elems));
+    table->initElems(OldMove(elems));
     return true;
 }
 
 static bool
 CheckFuncPtrTables(ModuleCompiler &m)
 {
     while (true) {
         ParseNode *varStmt;
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -223,17 +223,17 @@ class AsmJSModule
             if (maybeFieldName_)
                 MarkStringUnbarriered(trc, &maybeFieldName_, "asm.js export field");
         }
 
       public:
         ExportedFunction(mozilla::MoveRef<ExportedFunction> rhs) {
             name_ = rhs->name_;
             maybeFieldName_ = rhs->maybeFieldName_;
-            argCoercions_ = mozilla::Move(rhs->argCoercions_);
+            argCoercions_ = mozilla::OldMove(rhs->argCoercions_);
             pod = rhs->pod;
         }
 
         void initCodeOffset(unsigned off) {
             JS_ASSERT(pod.codeOffset_ == UINT32_MAX);
             pod.codeOffset_ = off;
         }
 
@@ -283,22 +283,22 @@ class AsmJSModule
 
 #if defined(JS_ION_PERF)
     struct ProfiledBlocksFunction : public ProfiledFunction
     {
         jit::PerfSpewer::BasicBlocksVector blocks;
 
         ProfiledBlocksFunction(JSAtom *name, unsigned start, unsigned end,
                                jit::PerfSpewer::BasicBlocksVector &blocksVector)
-          : ProfiledFunction(name, start, end), blocks(mozilla::Move(blocksVector))
+          : ProfiledFunction(name, start, end), blocks(mozilla::OldMove(blocksVector))
         { }
 
         ProfiledBlocksFunction(const ProfiledBlocksFunction &copy)
           : ProfiledFunction(copy.name, copy.startCodeOffset, copy.endCodeOffset),
-            blocks(mozilla::Move(copy.blocks))
+            blocks(mozilla::OldMove(copy.blocks))
         { }
     };
 #endif
 
   private:
     typedef Vector<ExportedFunction, 0, SystemAllocPolicy> ExportedFunctionVector;
     typedef Vector<Global, 0, SystemAllocPolicy> GlobalVector;
     typedef Vector<Exit, 0, SystemAllocPolicy> ExitVector;
@@ -452,17 +452,17 @@ class AsmJSModule
         return functionCounts_.append(counts);
     }
 
     bool addExportedFunction(PropertyName *name, PropertyName *maybeFieldName,
                              mozilla::MoveRef<ArgCoercionVector> argCoercions,
                              ReturnType returnType)
     {
         ExportedFunction func(name, maybeFieldName, argCoercions, returnType);
-        return exports_.append(mozilla::Move(func));
+        return exports_.append(mozilla::OldMove(func));
     }
     unsigned numExportedFunctions() const {
         return exports_.length();
     }
     const ExportedFunction &exportedFunction(unsigned i) const {
         return exports_[i];
     }
     ExportedFunction &exportedFunction(unsigned i) {
--- a/js/src/jsmemorymetrics.cpp
+++ b/js/src/jsmemorymetrics.cpp
@@ -20,17 +20,17 @@
 #include "vm/Runtime.h"
 #include "vm/Shape.h"
 #include "vm/String.h"
 #include "vm/WrapperObject.h"
 
 #include "vm/ObjectImpl-inl.h"
 
 using mozilla::DebugOnly;
-using mozilla::Move;
+using mozilla::OldMove;
 using mozilla::MoveRef;
 using mozilla::PodEqual;
 
 using namespace js;
 
 using JS::RuntimeStats;
 using JS::ObjectPrivateVisitor;
 using JS::ZoneStats;
@@ -434,17 +434,17 @@ FindNotableStrings(ZoneStats &zStats)
         StringInfo &info = r.front().value;
 
         // If this string is too small, or if we can't grow the notableStrings
         // vector, skip this string.
         if (info.totalSizeOf() < NotableStringInfo::notableSize() ||
             !zStats.notableStrings.growBy(1))
             continue;
 
-        zStats.notableStrings.back() = Move(NotableStringInfo(str, info));
+        zStats.notableStrings.back() = OldMove(NotableStringInfo(str, info));
 
         // We're moving this string from a non-notable to a notable bucket, so
         // subtract it out of the non-notable tallies.
         MOZ_ASSERT(zStats.gcHeapStringsShort >= info.sizeOfShortStringGCThings);
         MOZ_ASSERT(zStats.gcHeapStringsNormal >= info.sizeOfNormalStringGCThings);
         MOZ_ASSERT(zStats.stringCharsNonNotable >= info.sizeOfAllStringChars);
         zStats.gcHeapStringsShort -= info.sizeOfShortStringGCThings;
         zStats.gcHeapStringsNormal -= info.sizeOfNormalStringGCThings;
--- a/js/src/shell/jsheaptools.cpp
+++ b/js/src/shell/jsheaptools.cpp
@@ -18,17 +18,17 @@
 #include "jsobj.h"
 #include "jsprf.h"
 #include "jsutil.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 
-using mozilla::Move;
+using mozilla::OldMove;
 using mozilla::MoveRef;
 
 #ifdef DEBUG
 
 
 /*** class HeapReverser **************************************************************************/
 
 /*
@@ -72,17 +72,17 @@ class HeapReverser : public JSTracer, pu
           : kind(kind), incoming(), marked(false) { }
 
         /*
          * Move constructor and move assignment. These allow us to store our
          * incoming edge Vector in the hash table: Vectors support moves, but
          * not assignments or copy construction.
          */
         Node(MoveRef<Node> rhs)
-          : kind(rhs->kind), incoming(Move(rhs->incoming)), marked(rhs->marked) { }
+          : kind(rhs->kind), incoming(OldMove(rhs->incoming)), marked(rhs->marked) { }
         Node &operator=(MoveRef<Node> rhs) {
             this->~Node();
             new(this) Node(rhs);
             return *this;
         }
 
         void trace(JSTracer *trc) {
             for (Edge *e = incoming.begin(); e != incoming.end(); e++)
@@ -268,26 +268,26 @@ HeapReverser::traverseEdge(void *cell, J
     if (!a) {
         /*
          * We've never visited this cell before. Add it to the map (thus
          * marking it as visited), and put it on the work stack, to be
          * visited from the main loop.
          */
         Node n(kind);
         uint32_t generation = map.generation();
-        if (!map.add(a, cell, Move(n)) ||
+        if (!map.add(a, cell, OldMove(n)) ||
             !work.append(Child(cell, kind)))
             return false;
         /* If the map has been resized, re-check the pointer. */
         if (map.generation() != generation)
             a = map.lookupForAdd(cell);
     }
 
     /* Add this edge to the reversed map. */
-    return a->value.incoming.append(Move(e));
+    return a->value.incoming.append(OldMove(e));
 }
 
 bool
 HeapReverser::reverseHeap()
 {
     traversalStatus = true;
 
     /* Prime the work stack with the roots of collection. */
--- a/mfbt/Move.h
+++ b/mfbt/Move.h
@@ -4,21 +4,31 @@
  * 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/. */
 
 /* C++11-style, but C++98-usable, "move references" implementation. */
 
 #ifndef mozilla_Move_h
 #define mozilla_Move_h
 
+#include "mozilla/TypeTraits.h"
+
 namespace mozilla {
 
 /*
  * "Move" References
  *
+ * [Once upon a time, C++11 rvalue references were not implemented by all the
+ * compilers we cared about, so we invented mozilla::Move() (now called
+ * OldMove()), which does something similar.  We're in the process of
+ * transitioning away from this to pure stl (bug 896100).  Until that bug is
+ * completed, this header will provide both mozilla::OldMove() and
+ * mozilla::Move().]
+ *
+ *
  * Some types can be copied much more efficiently if we know the original's
  * value need not be preserved --- that is, if we are doing a "move", not a
  * "copy". For example, if we have:
  *
  *   Vector<T> u;
  *   Vector<T> v(u);
  *
  * the constructor for v must apply a copy constructor to each element of u ---
@@ -43,66 +53,80 @@ namespace mozilla {
  * 1) a way for a particular invocation of a copy constructor to say that it's
  *    really a move, and that the value of the original isn't important
  *    afterwards (although it must still be safe to destroy); and
  *
  * 2) a way for a type (like Vector) to announce that it can be moved more
  *    efficiently than it can be copied, and provide an implementation of that
  *    move operation.
  *
- * The Move(T&) function takes a reference to a T, and returns a MoveRef<T>
- * referring to the same value; that's 1). A MoveRef<T> is simply a reference
+ * The OldMove(T&) function takes a reference to a T, and returns a MoveRef<T>
+ * referring to the same value; that's (1). A MoveRef<T> is simply a reference
  * to a T, annotated to say that a copy constructor applied to it may move that
  * T, instead of copying it. Finally, a constructor that accepts an MoveRef<T>
- * should perform a more efficient move, instead of a copy, providing 2).
+ * should perform a more efficient move, instead of a copy, providing (2).
+ *
+ * The Move(T&) function takes a reference to a T and returns a T&&.  It acts
+ * just like std::move(), which is not available on all our platforms.
  *
- * So, where we might define a copy constructor for a class C like this:
+ * In new code, you should use Move(T&) and T&& instead of OldMove(T&) and
+ * MoveRef<T>, where possible.
+ *
+ * Where we might define a copy constructor for a class C like this:
  *
  *   C(const C& rhs) { ... copy rhs to this ... }
  *
  * we would declare a move constructor like this:
  *
+ *   C(C&& rhs) { .. move rhs to this ... }
+ *
+ * or, in the deprecated OldMove style:
+ *
  *   C(MoveRef<C> rhs) { ... move rhs to this ... }
  *
  * And where we might perform a copy like this:
  *
  *   C c2(c1);
  *
  * we would perform a move like this:
  *
- *   C c2(Move(c1))
+ *   C c2(Move(c1));
+ *
+ * or, in the deprecated OldMove style:
+ *
+ *   C c2(OldMove(c1));
  *
  * Note that MoveRef<T> implicitly converts to T&, so you can pass a MoveRef<T>
  * to an ordinary copy constructor for a type that doesn't support a special
  * move constructor, and you'll just get a copy.  This means that templates can
  * use Move whenever they know they won't use the original value any more, even
  * if they're not sure whether the type at hand has a specialized move
  * constructor.  If it doesn't, the MoveRef<T> will just convert to a T&, and
  * the ordinary copy constructor will apply.
  *
  * A class with a move constructor can also provide a move assignment operator,
  * which runs this's destructor, and then applies the move constructor to
  * *this's memory. A typical definition:
  *
- *   C& operator=(MoveRef<C> rhs) {
+ *   C& operator=(C&& rhs) {  // or |MoveRef<C> rhs|
  *     this->~C();
  *     new(this) C(rhs);
  *     return *this;
  *   }
  *
  * With that in place, one can write move assignments like this:
  *
- *   c2 = Move(c1);
+ *   c2 = Move(c1); // or OldMove()
  *
  * This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but
  * destructible state.
  *
- * This header file defines MoveRef and Move in the mozilla namespace.  It's up
- * to individual containers to annotate moves as such, by calling Move; and it's
- * up to individual types to define move constructors.
+ * This header file defines MoveRef, Move, and OldMove in the mozilla namespace.
+ * It's up to individual containers to annotate moves as such, by calling Move
+ * or OldMove; and it's up to individual types to define move constructors.
  *
  * One hint: if you're writing a move constructor where the type has members
  * that should be moved themselves, it's much nicer to write this:
  *
  *   C(MoveRef<C> c) : x(Move(c->x)), y(Move(c->y)) { }
  *
  * than the equivalent:
  *
@@ -120,24 +144,24 @@ class MoveRef
     explicit MoveRef(T& t) : pointer(&t) { }
     T& operator*() const { return *pointer; }
     T* operator->() const { return pointer; }
     operator T& () const { return *pointer; }
 };
 
 template<typename T>
 inline MoveRef<T>
-Move(T& t)
+OldMove(T& t)
 {
   return MoveRef<T>(t);
 }
 
 template<typename T>
 inline MoveRef<T>
-Move(const T& t)
+OldMove(const T& t)
 {
   // With some versions of gcc, for a class C, there's an (incorrect) ambiguity
   // between the C(const C&) constructor and the default C(C&&) C++11 move
   // constructor, when the constructor is called with a const C& argument.
   //
   // This ambiguity manifests with the Move implementation above when Move is
   // passed const U& for some class U.  Calling Move(const U&) returns a
   // MoveRef<const U&>, which is then commonly passed to the U constructor,
@@ -146,21 +170,52 @@ Move(const T& t)
   //
   // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so
   // this is no longer an issue for up-to-date compilers.  But there's no harm
   // in keeping it around for older compilers, so we might as well.  See also
   // bug 686280.
   return MoveRef<T>(const_cast<T&>(t));
 }
 
+/**
+ * Identical to std::Move(); this is necessary until our stlport supports
+ * std::move().
+ */
+template<typename T>
+inline typename RemoveReference<T>::Type&&
+Move(T&& a)
+{
+  return static_cast<typename RemoveReference<T>::Type&&>(a);
+}
+
+/**
+ * These two overloads are identidal to std::Forward(); they are necessary until
+ * our stlport supports std::forward().
+ */
+template<typename T>
+inline T&&
+Forward(typename RemoveReference<T>::Type& a)
+{
+  return static_cast<T&&>(a);
+}
+
+template<typename T>
+inline T&&
+Forward(typename RemoveReference<T>::Type&& t)
+{
+  static_assert(!IsLvalueReference<T>::value,
+                "misuse of Forward detected!  try the other overload");
+  return static_cast<T&&>(t);
+}
+
 /** Swap |t| and |u| using move-construction if possible. */
 template<typename T>
 inline void
 Swap(T& t, T& u)
 {
-  T tmp(Move(t));
-  t = Move(u);
-  u = Move(tmp);
+  T tmp(OldMove(t));
+  t = OldMove(u);
+  u = OldMove(tmp);
 }
 
 } // namespace mozilla
 
 #endif /* mozilla_Move_h */
--- a/mfbt/TypeTraits.h
+++ b/mfbt/TypeTraits.h
@@ -413,16 +413,26 @@ struct ConvertibleTester
  * are related through private inheritance, and you'll get a compile error if
  * you try.  Just don't do it!
  */
 template<typename From, typename To>
 struct IsConvertible
   : IntegralConstant<bool, detail::ConvertibleTester<From, To>::value>
 {};
 
+/**
+ * Is IsLvalueReference<T> is true if its template param is T& and is false if
+ * its type is T or T&&.
+ */
+template<typename T>
+struct IsLvalueReference : FalseType {};
+
+template<typename T>
+struct IsLvalueReference<T&> : TrueType {};
+
 /* 20.9.7 Transformations between types [meta.trans] */
 
 /* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */
 
 /**
  * RemoveConst removes top-level const qualifications on a type.
  *
  * mozilla::RemoveConst<int>::Type is int;
@@ -473,16 +483,42 @@ struct RemoveVolatile<volatile T>
 template<typename T>
 struct RemoveCV
 {
     typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type;
 };
 
 /* 20.9.7.2 Reference modifications [meta.trans.ref] */
 
+/**
+ * Converts reference types to the underlying types.
+ *
+ * mozilla::RemoveReference<T>::Type is T;
+ * mozilla::RemoveReference<T&>::Type is T;
+ * mozilla::RemoveReference<T&&>::Type is T;
+ */
+
+template<typename T>
+struct RemoveReference
+{
+    typedef T Type;
+};
+
+template<typename T>
+struct RemoveReference<T&>
+{
+    typedef T Type;
+};
+
+template<typename T>
+struct RemoveReference<T&&>
+{
+    typedef T Type;
+};
+
 /* 20.9.7.3 Sign modifications [meta.trans.sign] */
 
 template<bool B, typename T = void>
 struct EnableIf;
 
 template<bool Condition, typename A, typename B>
 struct Conditional;
 
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -81,17 +81,17 @@ struct VectorImpl
 
     /*
      * Move-constructs objects in the uninitialized range
      * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend).
      */
     template<typename U>
     static inline void moveConstruct(T* dst, const U* srcbeg, const U* srcend) {
       for (const U* p = srcbeg; p < srcend; ++p, ++dst)
-        new(dst) T(Move(*p));
+        new(dst) T(OldMove(*p));
     }
 
     /*
      * Copy-constructs objects in the uninitialized range [dst, dst+n) from the
      * same object u.
      */
     template<typename U>
     static inline void copyConstructN(T* dst, size_t n, const U& u) {
@@ -110,17 +110,17 @@ struct VectorImpl
       MOZ_ASSERT(!v.usingInlineStorage());
       MOZ_ASSERT(!CapacityHasExcessSpace<T>(newCap));
       T* newbuf = reinterpret_cast<T*>(v.malloc_(newCap * sizeof(T)));
       if (!newbuf)
         return false;
       T* dst = newbuf;
       T* src = v.beginNoCheck();
       for (; src < v.endNoCheck(); ++dst, ++src)
-        new(dst) T(Move(*src));
+        new(dst) T(OldMove(*src));
       VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck());
       v.free_(v.mBegin);
       v.mBegin = newbuf;
       /* v.mLength is unchanged. */
       v.mCapacity = newCap;
       return true;
     }
 };
--- a/xpcom/base/nsAutoPtr.h
+++ b/xpcom/base/nsAutoPtr.h
@@ -86,22 +86,29 @@ class nsAutoPtr
         }
 
       nsAutoPtr( Ptr aRawPtr )
             : mRawPtr(aRawPtr)
           // construct from a raw pointer (of the right type)
         {
         }
 
+      // This constructor shouldn't exist; we should just use the &&
+      // constructor.
       nsAutoPtr( nsAutoPtr<T>& aSmartPtr )
             : mRawPtr( aSmartPtr.forget() )
           // Construct by transferring ownership from another smart pointer.
         {
         }
 
+      nsAutoPtr( nsAutoPtr<T>&& aSmartPtr )
+            : mRawPtr( aSmartPtr.forget() )
+          // Construct by transferring ownership from another smart pointer.
+        {
+        }
 
         // Assignment operators
 
       nsAutoPtr<T>&
       operator=( T* rhs )
           // assign from a raw pointer (of the right type)
         {
           assign(rhs);
--- a/xpcom/glue/nsBaseHashtable.h
+++ b/xpcom/glue/nsBaseHashtable.h
@@ -2,16 +2,17 @@
 /* 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 nsBaseHashtable_h__
 #define nsBaseHashtable_h__
 
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/Move.h"
 #include "nsTHashtable.h"
 #include "prlock.h"
 #include "nsDebug.h"
 
 template<class KeyClass,class DataType,class UserDataType>
 class nsBaseHashtable; // forward declaration
 
 /**
@@ -26,17 +27,17 @@ public:
   DataType mData;
   friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
 
 private:
   typedef typename KeyClass::KeyType KeyType;
   typedef typename KeyClass::KeyTypePointer KeyTypePointer;
   
   nsBaseHashtableET(KeyTypePointer aKey);
-  nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>& toCopy);
+  nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>&& toMove);
   ~nsBaseHashtableET();
 };
 
 /**
  * templated hashtable for simple data types
  * This class manages simple data types that do not need construction or
  * destruction.
  *
@@ -406,19 +407,19 @@ protected:
 
 template<class KeyClass,class DataType>
 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
   KeyClass(aKey)
 { }
 
 template<class KeyClass,class DataType>
 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
-  (nsBaseHashtableET<KeyClass,DataType>& toCopy) :
-  KeyClass(toCopy),
-  mData(toCopy.mData)
+  (nsBaseHashtableET<KeyClass,DataType>&& toMove) :
+  KeyClass(mozilla::Move(toMove)),
+  mData(mozilla::Move(toMove.mData))
 { }
 
 template<class KeyClass,class DataType>
 nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
 { }
 
 
 //
--- a/xpcom/glue/nsTHashtable.h
+++ b/xpcom/glue/nsTHashtable.h
@@ -4,21 +4,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsTHashtable_h__
 #define nsTHashtable_h__
 
 #include "nscore.h"
 #include "pldhash.h"
 #include "nsDebug.h"
-#include <new>
+#include "mozilla/MemoryChecking.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Move.h"
 #include "mozilla/fallible.h"
 
+#include <new>
+
 // helper function for nsTHashtable::Clear()
 NS_COM_GLUE PLDHashOperator
 PL_DHashStubEnumRemove(PLDHashTable    *table,
                        PLDHashEntryHdr *entry,
                        uint32_t         ordinal,
                        void            *userArg);
 
 
@@ -41,20 +43,20 @@ PL_DHashStubEnumRemove(PLDHashTable    *
  *     // a const reference (const nsAString&)
  *     typedef something KeyType;
  *     // KeyTypePointer is the pointer-version of KeyType, because pldhash.h
  *     // requires keys to cast to <code>const void*</code>
  *     typedef const something* KeyTypePointer;
  *
  *     EntryType(KeyTypePointer aKey);
  *
- *     // A copy or move constructor must be defined, even if AllowMemMove() ==
- *     // true, otherwise you will cause link errors.
- *     EntryType(const EntryType& aEnt);   // Either this...
- *     EntryType(MoveRef<EntryType> aEnt); // ...or this
+ *     // A copy or C++11 Move constructor must be defined, even if
+ *     // AllowMemMove() == true, otherwise you will cause link errors.
+ *     EntryType(const EntryType& aEnt);  // Either this...
+ *     EntryType(EntryType&& aEnt);       // ...or this
  *
  *     // the destructor must be defined... or you will cause link errors!
  *     ~EntryType();
  *
  *     // KeyEquals(): does this entry match this key?
  *     bool KeyEquals(KeyTypePointer aKey) const;
  *
  *     // KeyToPointer(): Convert KeyType to KeyTypePointer
@@ -85,17 +87,17 @@ public:
    */
   nsTHashtable();
 
   /**
    * destructor, cleans up and deallocates
    */
   ~nsTHashtable();
 
-  nsTHashtable(mozilla::MoveRef<nsTHashtable<EntryType> > aOther);
+  nsTHashtable(nsTHashtable<EntryType>&& aOther);
 
   /**
    * Initialize the table.  This function must be called before any other
    * class operations.  This can fail due to OOM conditions.
    * @param initSize the initial number of buckets in the hashtable, default 16
    * @return true if the class was initialized properly.
    */
   void Init(uint32_t initSize = PL_DHASH_MIN_SIZE)
@@ -373,27 +375,33 @@ private:
 
 //
 // template definitions
 //
 
 template<class EntryType>
 nsTHashtable<EntryType>::nsTHashtable()
 {
-  // entrySize is our "I'm initialized" indicator
+  // mTable.entrySize == 0 means we're not yet initialized.  In Init(), we set
+  // mTable.entrySize == sizeof(EntryType).
   mTable.entrySize = 0;
 }
 
 template<class EntryType>
 nsTHashtable<EntryType>::nsTHashtable(
-  mozilla::MoveRef<nsTHashtable<EntryType> > aOther)
-  : mTable(aOther->mTable)
+  nsTHashtable<EntryType>&& aOther)
+  : mTable(mozilla::Move(aOther.mTable))
 {
-  aOther->mTable = PLDHashTable();
-  aOther->mTable.entrySize = 0;
+  // aOther shouldn't touch mTable after this, because we've stolen the table's
+  // pointers but not overwitten them.
+  MOZ_MAKE_MEM_UNDEFINED(aOther.mTable, sizeof(aOther.mTable));
+
+  // Indicate that aOther is not initialized.  This will make its destructor a
+  // nop, which is what we want.
+  aOther.mTable.entrySize = 0;
 }
 
 template<class EntryType>
 nsTHashtable<EntryType>::~nsTHashtable()
 {
   if (mTable.entrySize)
     PL_DHashTableFinish(&mTable);
 }
@@ -456,22 +464,20 @@ nsTHashtable<EntryType>::s_MatchEntry(PL
 }
 
 template<class EntryType>
 void
 nsTHashtable<EntryType>::s_CopyEntry(PLDHashTable          *table,
                                      const PLDHashEntryHdr *from,
                                      PLDHashEntryHdr       *to)
 {
-  using mozilla::Move;
-
   EntryType* fromEntry =
     const_cast<EntryType*>(reinterpret_cast<const EntryType*>(from));
 
-  new(to) EntryType(Move(*fromEntry));
+  new(to) EntryType(mozilla::Move(*fromEntry));
 
   fromEntry->~EntryType();
 }
 
 template<class EntryType>
 void
 nsTHashtable<EntryType>::s_ClearEntry(PLDHashTable    *table,
                                       PLDHashEntryHdr *entry)