diff --git a/xpcom/ds/PLDHashTable.cpp b/xpcom/ds/PLDHashTable.cpp
--- a/xpcom/ds/PLDHashTable.cpp
+++ b/xpcom/ds/PLDHashTable.cpp
@@ -13,16 +13,23 @@
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/OperatorNewExtensions.h"
 #include "nsAlgorithm.h"
 #include "nsPointerHashKeys.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ChaosMode.h"
 
+#if _MSC_VER >= 1400
+#include <intrin.h>
+#endif
+#if (_M_IX86_FP >= 1) || defined(__SSE__) || defined(_M_AMD64) || defined(__amd64__)
+#include <xmmintrin.h>
+#endif
+
 using namespace mozilla;
 
 #ifdef DEBUG
 
 class AutoReadOp
 {
   Checker& mChk;
 public:
@@ -95,23 +102,39 @@ PLDHashTable::MatchStringKey(const PLDHa
           strcmp((const char*)stub->key, (const char*)aKey) == 0);
 }
 
 /* static */ void
 PLDHashTable::MoveEntryStub(PLDHashTable* aTable,
                             const PLDHashEntryHdr* aFrom,
                             PLDHashEntryHdr* aTo)
 {
+#if _MSC_VER >= 1400
+  if ((aTable->mEntrySize & 3) == 0) {
+    __movsd((unsigned long*)aTo, (unsigned long*)aFrom, aTable->mEntrySize >> 2);
+  } else {
+    memcpy(aTo, aFrom, aTable->mEntrySize);
+  }
+#else
   memcpy(aTo, aFrom, aTable->mEntrySize);
+#endif
 }
 
 /* static */ void
 PLDHashTable::ClearEntryStub(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
 {
+#if _MSC_VER >= 1400
+  if ((aTable->mEntrySize & 3) == 0) {
+    __stosd((unsigned long*)aEntry, 0, aTable->mEntrySize >> 2);
+  } else {
+    memset(aEntry, 0, aTable->mEntrySize);
+  }
+#else
   memset(aEntry, 0, aTable->mEntrySize);
+#endif
 }
 
 static const PLDHashTableOps gStubOps = {
   PLDHashTable::HashVoidPtrKeyStub,
   PLDHashTable::MatchEntryStub,
   PLDHashTable::MoveEntryStub,
   PLDHashTable::ClearEntryStub,
   nullptr
@@ -481,28 +504,50 @@ PLDHashTable::ChangeTable(int32_t aDelta
     return false;
   }
 
   // We can't fail from here on, so update table parameters.
   mHashShift = kHashBits - newLog2;
   mRemovedCount = 0;
 
   // Assign the new entry store to table.
+#ifdef TT_MEMUTIL
+  {
+    static bool initialized = false;
+    static uint32_t dwNonTemporalDataSizeMin = NON_TEMPORAL_STORES_NOT_SUPPORTED;
+
+    if (!initialized) {
+      dwNonTemporalDataSizeMin = GetNonTemporalDataSizeMin_tt();
+      initialized = true;
+    }
+
+    if (nbytes < dwNonTemporalDataSizeMin ||
+        NON_TEMPORAL_STORES_NOT_SUPPORTED == dwNonTemporalDataSizeMin) {
+      memset(newEntryStore, 0, nbytes);
+    } else {
+      memset_nontemporal_tt(newEntryStore, 0, nbytes);
+    }
+  }
+#else
   memset(newEntryStore, 0, nbytes);
+#endif
   char* oldEntryStore;
   char* oldEntryAddr;
   oldEntryAddr = oldEntryStore = mEntryStore.Get();
   mEntryStore.Set(newEntryStore, &mGeneration);
   PLDHashMoveEntry moveEntry = mOps->moveEntry;
 
   // Copy only live entries, leaving removed ones behind.
   uint32_t oldCapacity = 1u << oldLog2;
   for (uint32_t i = 0; i < oldCapacity; ++i) {
     PLDHashEntryHdr* oldEntry = (PLDHashEntryHdr*)oldEntryAddr;
     if (EntryIsLive(oldEntry)) {
+#if (_M_IX86_FP >= 1) || defined(__SSE__) || defined(_M_AMD64) || defined(__amd64__)
+      _mm_prefetch((char *)(oldEntryAddr + mEntrySize), _MM_HINT_NTA);
+#endif
       oldEntry->mKeyHash &= ~kCollisionFlag;
       PLDHashEntryHdr* newEntry = FindFreeEntry(oldEntry->mKeyHash);
       NS_ASSERTION(EntryIsFree(newEntry), "EntryIsFree(newEntry)");
       moveEntry(this, oldEntry, newEntry);
       newEntry->mKeyHash = oldEntry->mKeyHash;
     }
     oldEntryAddr += mEntrySize;
   }
