Bug 940033 - js::HashMapEntry::{key,value} fields should be private, with accessors, and the former should expose a const reference. r=jimb
authorJeff Walden <jwalden@mit.edu>
Mon, 25 Nov 2013 17:35:09 -0800
changeset 158689 b96d513cd89f5aff1841c6a6c926481807864589
parent 158688 5036242b2d531d76027470bd07f0add17659321d
child 158690 4531393b5af60091a724103e26a5d338180b83f1
push id37056
push userjwalden@mit.edu
push dateWed, 04 Dec 2013 00:41:48 +0000
treeherdermozilla-inbound@b96d513cd89f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs940033
milestone28.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 940033 - js::HashMapEntry::{key,value} fields should be private, with accessors, and the former should expose a const reference. r=jimb
dom/plugins/base/nsJSNPRuntime.cpp
js/ipc/JavaScriptShared.cpp
js/public/HashTable.h
js/public/MemoryMetrics.h
js/src/ctypes/CTypes.cpp
js/src/ds/InlineMap.h
js/src/frontend/ParseMaps.cpp
js/src/gc/RootMarking.cpp
js/src/jit/AsmJS.cpp
js/src/jit/BaselineJIT.cpp
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/JitCompartment.h
js/src/jit/ValueNumbering.cpp
js/src/jit/arm/Trampoline-arm.cpp
js/src/jit/x64/MacroAssembler-x64.cpp
js/src/jit/x64/Trampoline-x64.cpp
js/src/jit/x86/MacroAssembler-x86.cpp
js/src/jit/x86/Trampoline-x86.cpp
js/src/jsapi-tests/testHashTable.cpp
js/src/jsapi.cpp
js/src/jscntxt.cpp
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jscompartmentinlines.h
js/src/jsfriendapi.cpp
js/src/jsgc.cpp
js/src/jsinfer.cpp
js/src/jsinferinlines.h
js/src/jsproxy.cpp
js/src/jsscript.cpp
js/src/jswatchpoint.cpp
js/src/jsweakcache.h
js/src/jsweakmap.cpp
js/src/jsweakmap.h
js/src/jswrapper.cpp
js/src/shell/jsheaptools.cpp
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/MemoryMetrics.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/SPSProfiler.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/StructuredClone.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
layout/style/nsNthIndexCache.cpp
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -1009,21 +1009,21 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
       return nullptr;
     }
   }
 
   nsJSObjWrapperKey key(obj, npp);
 
   JSObjWrapperTable::AddPtr p = sJSObjWrappers.lookupForAdd(key);
 
-  if (p/* && p->value*/) {
-    MOZ_ASSERT(p->value);
+  if (p/* && p->value()*/) {
+    MOZ_ASSERT(p->value());
     // Found a live nsJSObjWrapper, return it.
 
-    return _retainobject(p->value);
+    return _retainobject(p->value());
   }
 
   // No existing nsJSObjWrapper, create one.
 
   nsJSObjWrapper *wrapper =
     (nsJSObjWrapper *)_createobject(npp, &sJSObjWrapperNPClass);
 
   if (!wrapper) {
@@ -1868,17 +1868,17 @@ NPObjWrapperPluginDestroyedCallback(PLDH
 }
 
 // static
 void
 nsJSNPRuntime::OnPluginDestroy(NPP npp)
 {
   if (sJSObjWrappers.initialized()) {
     for (JSObjWrapperTable::Enum e(sJSObjWrappers); !e.empty(); e.popFront()) {
-      nsJSObjWrapper *npobj = e.front().value;
+      nsJSObjWrapper *npobj = e.front().value();
       MOZ_ASSERT(npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass);
       if (npobj->mNpp == npp) {
         npobj->ClearJSObject();
         _releaseobject(npobj);
         e.removeFront();
       }
     }
   }
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -25,29 +25,29 @@ ObjectStore::init()
 {
     return table_.init(32);
 }
 
 void
 ObjectStore::trace(JSTracer *trc)
 {
     for (ObjectTable::Range r(table_.all()); !r.empty(); r.popFront()) {
-        DebugOnly<JSObject *> prior = r.front().value.get();
-        JS_CallHeapObjectTracer(trc, &r.front().value, "ipc-object");
-        MOZ_ASSERT(r.front().value == prior);
+        DebugOnly<JSObject *> prior = r.front().value().get();
+        JS_CallHeapObjectTracer(trc, &r.front().value(), "ipc-object");
+        MOZ_ASSERT(r.front().value() == prior);
     }
 }
 
 JSObject *
 ObjectStore::find(ObjectId id)
 {
     ObjectTable::Ptr p = table_.lookup(id);
     if (!p)
         return nullptr;
-    return p->value;
+    return p->value();
 }
 
 bool
 ObjectStore::add(ObjectId id, JSObject *obj)
 {
     return table_.put(id, obj);
 }
 
@@ -77,29 +77,29 @@ ObjectIdCache::init()
     table_ = new ObjectIdTable(SystemAllocPolicy());
     return table_ && table_->init(32);
 }
 
 void
 ObjectIdCache::trace(JSTracer *trc)
 {
     for (ObjectIdTable::Range r(table_->all()); !r.empty(); r.popFront()) {
-        JSObject *obj = r.front().key;
+        JSObject *obj = r.front().key();
         JS_CallObjectTracer(trc, &obj, "ipc-id");
-        MOZ_ASSERT(obj == r.front().key);
+        MOZ_ASSERT(obj == r.front().key());
     }
 }
 
 ObjectId
 ObjectIdCache::find(JSObject *obj)
 {
     ObjectIdTable::Ptr p = table_->lookup(obj);
     if (!p)
         return 0;
-    return p->value;
+    return p->value();
 }
 
 bool
 ObjectIdCache::add(JSContext *cx, JSObject *obj, ObjectId id)
 {
     if (!table_->put(obj, id))
         return false;
     JS_StoreObjectPostBarrierCallback(cx, keyMarkCallback, obj, table_);
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -55,18 +55,18 @@ template <class Key,
           class AllocPolicy = TempAllocPolicy>
 class HashMap
 {
     typedef HashMapEntry<Key, Value> TableEntry;
 
     struct MapHashPolicy : HashPolicy
     {
         typedef Key KeyType;
-        static const Key &getKey(TableEntry &e) { return e.key; }
-        static void setKey(TableEntry &e, Key &k) { HashPolicy::rekey(const_cast<Key &>(e.key), k); }
+        static const Key &getKey(TableEntry &e) { return e.key(); }
+        static void setKey(TableEntry &e, Key &k) { HashPolicy::rekey(e.mutableKey(), k); }
     };
 
     typedef detail::HashTable<TableEntry, MapHashPolicy, AllocPolicy> Impl;
     Impl impl;
 
   public:
     typedef typename HashPolicy::Lookup Lookup;
     typedef TableEntry Entry;
@@ -146,17 +146,17 @@ class HashMap
     bool add(AddPtr &p, KeyInput &&k) {
         Entry e(mozilla::Forward<KeyInput>(k), Value());
         return impl.add(p, mozilla::Move(e));
     }
 
     template<typename KeyInput, typename ValueInput>
     bool relookupOrAdd(AddPtr &p, KeyInput &&k, ValueInput &&v) {
         Entry e(mozilla::Forward<KeyInput>(k), mozilla::Forward<ValueInput>(v));
-        return impl.relookupOrAdd(p, e.key, mozilla::Move(e));
+        return impl.relookupOrAdd(p, e.key(), mozilla::Move(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;
@@ -218,27 +218,27 @@ class HashMap
         return impl.lookup(l) != nullptr;
     }
 
     // Overwrite existing value with v. Return false on oom.
     template<typename KeyInput, typename ValueInput>
     bool put(KeyInput &&k, ValueInput &&v) {
         AddPtr p = lookupForAdd(k);
         if (p) {
-            p->value = mozilla::Forward<ValueInput>(v);
+            p->value() = mozilla::Forward<ValueInput>(v);
             return true;
         }
         return add(p, mozilla::Forward<KeyInput>(k), mozilla::Forward<ValueInput>(v));
     }
 
     // Like put, but assert that the given key is not already present.
     template<typename KeyInput, typename ValueInput>
     bool putNew(KeyInput &&k, ValueInput &&v) {
         Entry e(mozilla::Forward<KeyInput>(k), mozilla::Forward<ValueInput>(v));
-        return impl.putNew(e.key, mozilla::Move(e));
+        return impl.putNew(e.key(), mozilla::Move(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.
@@ -611,35 +611,47 @@ struct DefaultHasher<float>
 // Both HashMap and HashSet are implemented by a single HashTable that is even
 // more heavily parameterized than the other two. This leaves HashTable gnarly
 // and extremely coupled to HashMap and HashSet; thus code should not use
 // HashTable directly.
 
 template <class Key, class Value>
 class HashMapEntry
 {
+    Key key_;
+    Value value_;
+
     template <class, class, class> friend class detail::HashTable;
     template <class> friend class detail::HashTableEntry;
+    template <class, class, class, class> friend class HashMap;
 
-    HashMapEntry(const HashMapEntry &) MOZ_DELETE;
-    void operator=(const HashMapEntry &) MOZ_DELETE;
+    Key & mutableKey() { return key_; }
 
   public:
     template<typename KeyInput, typename ValueInput>
     HashMapEntry(KeyInput &&k, ValueInput &&v)
-      : key(mozilla::Forward<KeyInput>(k)), value(mozilla::Forward<ValueInput>(v)) { }
+      : key_(mozilla::Forward<KeyInput>(k)),
+        value_(mozilla::Forward<ValueInput>(v))
+    {}
 
     HashMapEntry(HashMapEntry &&rhs)
-      : key(mozilla::Move(const_cast<Key &>(rhs.key))), value(mozilla::Move(rhs.value)) { }
+      : key_(mozilla::Move(rhs.key_)),
+        value_(mozilla::Move(rhs.value_))
+    {}
 
     typedef Key KeyType;
     typedef Value ValueType;
 
-    const Key key;
-    Value value;
+    const Key & key() const { return key_; }
+    const Value & value() const { return value_; }
+    Value & value() { return value_; }
+
+  private:
+    HashMapEntry(const HashMapEntry &) MOZ_DELETE;
+    void operator=(const HashMapEntry &) MOZ_DELETE;
 };
 
 } // namespace js
 
 namespace mozilla {
 
 template <typename T>
 struct IsPod<js::detail::HashTableEntry<T> > : IsPod<T> {};
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -338,23 +338,23 @@ struct ZoneStats : js::ZoneStatsPod
     // same string.)
     void add(const ZoneStats &other) {
         ZoneStatsPod::add(other);
 
         MOZ_ASSERT(notableStrings.empty());
         MOZ_ASSERT(other.notableStrings.empty());
 
         for (StringsHashMap::Range r = other.strings.all(); !r.empty(); r.popFront()) {
-            StringsHashMap::AddPtr p = strings.lookupForAdd(r.front().key);
+            StringsHashMap::AddPtr p = strings.lookupForAdd(r.front().key());
             if (p) {
                 // We've seen this string before; add its size to our tally.
-                p->value.add(r.front().value);
+                p->value().add(r.front().value());
             } else {
                 // We haven't seen this string before; add it to the hashtable.
-                strings.add(p, r.front().key, r.front().value);
+                strings.add(p, r.front().key(), r.front().value());
             }
         }
     }
 
     size_t sizeOfLiveGCThings() const {
         size_t n = ZoneStatsPod::sizeOfLiveGCThings();
         for (size_t i = 0; i < notableStrings.length(); i++) {
             const JS::NotableStringInfo& info = notableStrings[i];
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -2918,24 +2918,24 @@ BuildTypeSource(JSContext* cx,
 
     const FieldInfoHash* fields = StructType::GetFieldInfo(typeObj);
     size_t length = fields->count();
     Array<const FieldInfoHash::Entry*, 64> fieldsArray;
     if (!fieldsArray.resize(length))
       break;
 
     for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront())
-      fieldsArray[r.front().value.mIndex] = &r.front();
+      fieldsArray[r.front().value().mIndex] = &r.front();
 
     for (size_t i = 0; i < length; ++i) {
       const FieldInfoHash::Entry* entry = fieldsArray[i];
       AppendString(result, "{ \"");
-      AppendString(result, entry->key);
+      AppendString(result, entry->key());
       AppendString(result, "\": ");
-      BuildTypeSource(cx, entry->value.mType, true, result);
+      BuildTypeSource(cx, entry->value().mType, true, result);
       AppendString(result, " }");
       if (i != length - 1)
         AppendString(result, ", ");
     }
 
     AppendString(result, "])");
     break;
   }
@@ -3068,29 +3068,29 @@ BuildDataSource(JSContext* cx,
     // be able to ImplicitConvert successfully.
     const FieldInfoHash* fields = StructType::GetFieldInfo(typeObj);
     size_t length = fields->count();
     Array<const FieldInfoHash::Entry*, 64> fieldsArray;
     if (!fieldsArray.resize(length))
       return false;
 
     for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront())
-      fieldsArray[r.front().value.mIndex] = &r.front();
+      fieldsArray[r.front().value().mIndex] = &r.front();
 
     for (size_t i = 0; i < length; ++i) {
       const FieldInfoHash::Entry* entry = fieldsArray[i];
 
       if (isImplicit) {
         AppendString(result, "\"");
-        AppendString(result, entry->key);
+        AppendString(result, entry->key());
         AppendString(result, "\": ");
       }
 
-      char* fieldData = static_cast<char*>(data) + entry->value.mOffset;
-      RootedObject entryType(cx, entry->value.mType);
+      char* fieldData = static_cast<char*>(data) + entry->value().mOffset;
+      RootedObject entryType(cx, entry->value().mType);
       if (!BuildDataSource(cx, entryType, fieldData, true, result))
         return false;
 
       if (i + 1 != length)
         AppendString(result, ", ");
     }
 
     if (isImplicit)
@@ -3347,21 +3347,21 @@ CType::Trace(JSTracer* trc, JSObject* ob
   case TYPE_struct: {
     slot = obj->getReservedSlot(SLOT_FIELDINFO);
     if (JSVAL_IS_VOID(slot))
       return;
 
     FieldInfoHash* fields =
       static_cast<FieldInfoHash*>(JSVAL_TO_PRIVATE(slot));
     for (FieldInfoHash::Enum e(*fields); !e.empty(); e.popFront()) {
-      JSString *key = e.front().key;
+      JSString *key = e.front().key();
       JS_CallStringTracer(trc, &key, "fieldName");
-      if (key != e.front().key)
+      if (key != e.front().key())
           e.rekeyFront(JS_ASSERT_STRING_IS_FLAT(key));
-      JS_CallHeapObjectTracer(trc, &e.front().value.mType, "fieldType");
+      JS_CallHeapObjectTracer(trc, &e.front().value().mType, "fieldType");
     }
 
     break;
   }
   case TYPE_function: {
     // Check if we have a FunctionInfo.
     slot = obj->getReservedSlot(SLOT_FNINFO);
     if (JSVAL_IS_VOID(slot))
@@ -4926,20 +4926,20 @@ StructType::BuildFFIType(JSContext* cx, 
     if (!elements) {
       JS_ReportOutOfMemory(cx);
       return nullptr;
     }
     elements[len] = nullptr;
 
     for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
       const FieldInfoHash::Entry& entry = r.front();
-      ffi_type* fieldType = CType::GetFFIType(cx, entry.value.mType);
+      ffi_type* fieldType = CType::GetFFIType(cx, entry.value().mType);
       if (!fieldType)
         return nullptr;
-      elements[entry.value.mIndex] = fieldType;
+      elements[entry.value().mIndex] = fieldType;
     }
 
   } else {
     // Represent an empty struct as having a size of 1 byte, just like C++.
     JS_ASSERT(structSize == 1);
     JS_ASSERT(structAlign == 1);
     elements = cx->pod_malloc<ffi_type*>(2);
     if (!elements) {
@@ -5067,17 +5067,17 @@ StructType::ConstructData(JSContext* cx,
 
     // Fall through to try option 2).
   }
 
   // We have a type constructor of the form 'ctypes.StructType(a, b, c, ...)'.
   // ImplicitConvert each field.
   if (args.length() == fields->count()) {
     for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
-      const FieldInfo& field = r.front().value;
+      const FieldInfo& field = r.front().value();
       STATIC_ASSUME(field.mIndex < fields->count());  /* Quantified invariant */
       if (!ImplicitConvert(cx, args[field.mIndex], field.mType,
              buffer + field.mOffset,
              false, nullptr))
         return false;
     }
 
     return true;
@@ -5103,17 +5103,17 @@ StructType::GetFieldInfo(JSObject* obj)
 const FieldInfo*
 StructType::LookupField(JSContext* cx, JSObject* obj, JSFlatString *name)
 {
   JS_ASSERT(CType::IsCType(obj));
   JS_ASSERT(CType::GetTypeCode(obj) == TYPE_struct);
 
   FieldInfoHash::Ptr ptr = GetFieldInfo(obj)->lookup(name);
   if (ptr)
-    return &ptr->value;
+    return &ptr->value();
 
   JSAutoByteString bytes(cx, name);
   if (!bytes)
     return nullptr;
 
   JS_ReportError(cx, "%s does not name a field", bytes.ptr());
   return nullptr;
 }
@@ -5131,18 +5131,18 @@ StructType::BuildFieldsArray(JSContext* 
   // Prepare a new array for the 'fields' property of the StructType.
   JS::AutoValueVector fieldsVec(cx);
   if (!fieldsVec.resize(len))
     return nullptr;
 
   for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
     const FieldInfoHash::Entry& entry = r.front();
     // Add the field descriptor to the array.
-    if (!AddFieldToArray(cx, &fieldsVec[entry.value.mIndex],
-                         entry.key, entry.value.mType))
+    if (!AddFieldToArray(cx, &fieldsVec[entry.value().mIndex],
+                         entry.key(), entry.value().mType))
       return nullptr;
   }
 
   RootedObject fieldsProp(cx, JS_NewArrayObject(cx, len, fieldsVec.begin()));
   if (!fieldsProp)
     return nullptr;
 
   // Seal the fields array.
--- a/js/src/ds/InlineMap.h
+++ b/js/src/ds/InlineMap.h
@@ -129,22 +129,22 @@ class InlineMap
         }
 
         operator ConvertibleToBool() const {
             return ConvertibleToBool(found());
         }
 
         K &key() {
             JS_ASSERT(found());
-            return isInlinePtr ? inlPtr->key : mapPtr->key;
+            return isInlinePtr ? inlPtr->key : mapPtr->key();
         }
 
         V &value() {
             JS_ASSERT(found());
-            return isInlinePtr ? inlPtr->value : mapPtr->value;
+            return isInlinePtr ? inlPtr->value : mapPtr->value();
         }
     }; /* class Ptr */
 
     class AddPtr
     {
         friend class InlineMap;
 
         WordMapAddPtr   mapAddPtr;
@@ -173,17 +173,17 @@ class InlineMap
         operator ConvertibleToBool() const {
             return found() ? ConvertibleToBool(1) : ConvertibleToBool(0);
         }
 
         V &value() {
             JS_ASSERT(found());
             if (isInlinePtr)
                 return inlAddPtr->value;
-            return mapAddPtr->value;
+            return mapAddPtr->value();
         }
     }; /* class AddPtr */
 
     size_t count() {
         return usingMap() ? map.count() : inlCount;
     }
 
     bool empty() const {
@@ -351,17 +351,17 @@ class InlineMap
         bool empty() const {
             return isInlineRange() ? cur == end : mapRange.empty();
         }
 
         Entry front() {
             JS_ASSERT(!empty());
             if (isInlineRange())
                 return Entry(cur->key, cur->value);
-            return Entry(mapRange.front().key, mapRange.front().value);
+            return Entry(mapRange.front().key(), mapRange.front().value());
         }
 
         void popFront() {
             JS_ASSERT(!empty());
             if (isInlineRange())
                 bumpCurPtr();
             else
                 mapRange.popFront();
--- a/js/src/frontend/ParseMaps.cpp
+++ b/js/src/frontend/ParseMaps.cpp
@@ -110,18 +110,18 @@ AtomDecls<ParseHandler>::addShadow(JSAto
 
 void
 frontend::InitAtomMap(frontend::AtomIndexMap *indices, HeapPtrAtom *atoms)
 {
     if (indices->isMap()) {
         typedef AtomIndexMap::WordMap WordMap;
         const WordMap &wm = indices->asMap();
         for (WordMap::Range r = wm.all(); !r.empty(); r.popFront()) {
-            JSAtom *atom = r.front().key;
-            jsatomid index = r.front().value;
+            JSAtom *atom = r.front().key();
+            jsatomid index = r.front().value();
             JS_ASSERT(index < indices->count());
             atoms[index].init(atom);
         }
     } else {
         for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd();
              it != end; ++it) {
             JSAtom *atom = it->key;
             if (!atom)
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -469,33 +469,33 @@ AutoGCRooter::trace(JSTracer *trc)
         AutoScriptVector::VectorImpl &vector = static_cast<AutoScriptVector *>(this)->vector;
         MarkScriptRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector");
         return;
       }
 
       case OBJOBJHASHMAP: {
         AutoObjectObjectHashMap::HashMapImpl &map = static_cast<AutoObjectObjectHashMap *>(this)->map;
         for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) {
-            MarkObjectRoot(trc, &e.front().value, "AutoObjectObjectHashMap value");
-            JS_SET_TRACING_LOCATION(trc, (void *)&e.front().key);
-            JSObject *key = e.front().key;
+            MarkObjectRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value");
+            JS_SET_TRACING_LOCATION(trc, (void *)&e.front().key());
+            JSObject *key = e.front().key();
             MarkObjectRoot(trc, &key, "AutoObjectObjectHashMap key");
-            if (key != e.front().key)
+            if (key != e.front().key())
                 e.rekeyFront(key);
         }
         return;
       }
 
       case OBJU32HASHMAP: {
         AutoObjectUnsigned32HashMap *self = static_cast<AutoObjectUnsigned32HashMap *>(this);
         AutoObjectUnsigned32HashMap::HashMapImpl &map = self->map;
         for (AutoObjectUnsigned32HashMap::Enum e(map); !e.empty(); e.popFront()) {
-            JSObject *key = e.front().key;
+            JSObject *key = e.front().key();
             MarkObjectRoot(trc, &key, "AutoObjectUnsignedHashMap key");
-            if (key != e.front().key)
+            if (key != e.front().key())
                 e.rekeyFront(key);
         }
         return;
       }
 
       case OBJHASHSET: {
         AutoObjectHashSet *self = static_cast<AutoObjectHashSet *>(this);
         AutoObjectHashSet::HashSetImpl &set = self->set;
@@ -679,26 +679,28 @@ js::gc::MarkRuntime(JSTracer *trc, bool 
 #else
         MarkConservativeStackRoots(trc, useSavedRoots);
 #endif
         rt->markSelfHostingGlobal(trc);
     }
 
     for (RootRange r = rt->gcRootsHash.all(); !r.empty(); r.popFront()) {
         const RootEntry &entry = r.front();
-        const char *name = entry.value.name ? entry.value.name : "root";
-        if (entry.value.type == JS_GC_ROOT_VALUE_PTR) {
-            MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
-        } else if (*reinterpret_cast<void **>(entry.key)){
-            if (entry.value.type == JS_GC_ROOT_STRING_PTR)
-                MarkStringRoot(trc, reinterpret_cast<JSString **>(entry.key), name);
-            else if (entry.value.type == JS_GC_ROOT_OBJECT_PTR)
-                MarkObjectRoot(trc, reinterpret_cast<JSObject **>(entry.key), name);
-            else if (entry.value.type == JS_GC_ROOT_SCRIPT_PTR)
-                MarkScriptRoot(trc, reinterpret_cast<JSScript **>(entry.key), name);
+        const char *name = entry.value().name ? entry.value().name : "root";
+        JSGCRootType type = entry.value().type;
+        void *key = entry.key();
+        if (type == JS_GC_ROOT_VALUE_PTR) {
+            MarkValueRoot(trc, reinterpret_cast<Value *>(key), name);
+        } else if (*reinterpret_cast<void **>(key)){
+            if (type == JS_GC_ROOT_STRING_PTR)
+                MarkStringRoot(trc, reinterpret_cast<JSString **>(key), name);
+            else if (type == JS_GC_ROOT_OBJECT_PTR)
+                MarkObjectRoot(trc, reinterpret_cast<JSObject **>(key), name);
+            else if (type == JS_GC_ROOT_SCRIPT_PTR)
+                MarkScriptRoot(trc, reinterpret_cast<JSScript **>(key), name);
             else
                 MOZ_ASSUME_UNREACHABLE("unexpected js::RootInfo::type value");
         }
     }
 
     MarkPersistentRootedChains(trc);
 
     if (rt->scriptAndCountsVector) {
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -1391,23 +1391,24 @@ class MOZ_STACK_CLASS ModuleCompiler
     bool hasError() const { return errorString_ != nullptr; }
     const AsmJSModule &module() const { return *module_.get(); }
 
     ParseNode *moduleFunctionNode() const { return moduleFunctionNode_; }
     PropertyName *moduleFunctionName() const { return moduleFunctionName_; }
 
     const Global *lookupGlobal(PropertyName *name) const {
         if (GlobalMap::Ptr p = globals_.lookup(name))
-            return p->value;
+            return p->value();
         return nullptr;
     }
     Func *lookupFunction(PropertyName *name) {
         if (GlobalMap::Ptr p = globals_.lookup(name)) {
-            if (p->value->which() == Global::Function)
-                return functions_[p->value->funcIndex()];
+            Global *value = p->value();
+            if (value->which() == Global::Function)
+                return functions_[value->funcIndex()];
         }
         return nullptr;
     }
     unsigned numFunctions() const {
         return functions_.length();
     }
     Func &function(unsigned i) {
         return *functions_[i];
@@ -1415,17 +1416,17 @@ class MOZ_STACK_CLASS ModuleCompiler
     unsigned numFuncPtrTables() const {
         return funcPtrTables_.length();
     }
     FuncPtrTable &funcPtrTable(unsigned i) {
         return funcPtrTables_[i];
     }
     bool lookupStandardLibraryMathName(PropertyName *name, AsmJSMathBuiltin *mathBuiltin) const {
         if (MathNameMap::Ptr p = standardLibraryMathNames_.lookup(name)) {
-            *mathBuiltin = p->value;
+            *mathBuiltin = p->value();
             return true;
         }
         return false;
     }
     ExitMap::Range allExits() const {
         return exits_.all();
     }
 
@@ -1546,17 +1547,17 @@ class MOZ_STACK_CLASS ModuleCompiler
         AsmJSModule::ReturnType retType = func->sig().retType().toModuleReturnType();
         return module_->addExportedFunction(func->name(), maybeFieldName,
                                             Move(argCoercions), retType);
     }
     bool addExit(unsigned ffiIndex, PropertyName *name, Signature &&sig, unsigned *exitIndex) {
         ExitDescriptor exitDescriptor(name, Move(sig));
         ExitMap::AddPtr p = exits_.lookupForAdd(exitDescriptor);
         if (p) {
-            *exitIndex = p->value;
+            *exitIndex = p->value();
             return true;
         }
         if (!module_->addExit(ffiIndex, exitIndex))
             return false;
         return exits_.add(p, Move(exitDescriptor), *exitIndex);
     }
     bool addGlobalAccess(AsmJSGlobalAccess access) {
         return globalAccesses_.append(access);
@@ -1974,17 +1975,17 @@ class FunctionCompiler
 
     MIRGenerator & mirGen() const     { JS_ASSERT(mirGen_); return *mirGen_; }
     MIRGraph &     mirGraph() const   { JS_ASSERT(graph_); return *graph_; }
     CompileInfo &  info() const       { JS_ASSERT(info_); return *info_; }
 
     const Local *lookupLocal(PropertyName *name) const
     {
         if (LocalMap::Ptr p = locals_.lookup(name))
-            return &p->value;
+            return &p->value();
         return nullptr;
     }
 
     MDefinition *getLocalDef(const Local &local)
     {
         if (!curBlock_)
             return nullptr;
         return curBlock_->getSlot(info().localSlot(local.slot));
@@ -2531,17 +2532,17 @@ class FunctionCompiler
         }
         return bindUnlabeledBreaks(pn);
     }
 
     bool bindContinues(ParseNode *pn, const LabelVector *maybeLabels)
     {
         bool createdJoinBlock = false;
         if (UnlabeledBlockMap::Ptr p = unlabeledContinues_.lookup(pn)) {
-            if (!bindBreaksOrContinues(&p->value, &createdJoinBlock, pn))
+            if (!bindBreaksOrContinues(&p->value(), &createdJoinBlock, pn))
                 return false;
             unlabeledContinues_.remove(p);
         }
         return bindLabeledBreaksOrContinues(maybeLabels, &labeledContinues_, &createdJoinBlock, pn);
     }
 
     bool bindLabeledBreaks(const LabelVector *maybeLabels, ParseNode *pn)
     {
@@ -2693,17 +2694,17 @@ class FunctionCompiler
     bool bindLabeledBreaksOrContinues(const LabelVector *maybeLabels, LabeledBlockMap *map,
                                       bool *createdJoinBlock, ParseNode *pn)
     {
         if (!maybeLabels)
             return true;
         const LabelVector &labels = *maybeLabels;
         for (unsigned i = 0; i < labels.length(); i++) {
             if (LabeledBlockMap::Ptr p = map->lookup(labels[i])) {
-                if (!bindBreaksOrContinues(&p->value, createdJoinBlock, pn))
+                if (!bindBreaksOrContinues(&p->value(), createdJoinBlock, pn))
                     return false;
                 map->remove(p);
             }
         }
         return true;
     }
 
     template <class Key, class Map>
@@ -2712,27 +2713,27 @@ class FunctionCompiler
         if (!curBlock_)
             return true;
         typename Map::AddPtr p = map->lookupForAdd(key);
         if (!p) {
             BlockVector empty(m().cx());
             if (!map->add(p, key, Move(empty)))
                 return false;
         }
-        if (!p->value.append(curBlock_))
+        if (!p->value().append(curBlock_))
             return false;
         curBlock_ = nullptr;
         return true;
     }
 
     bool bindUnlabeledBreaks(ParseNode *pn)
     {
         bool createdJoinBlock = false;
         if (UnlabeledBlockMap::Ptr p = unlabeledBreaks_.lookup(pn)) {
-            if (!bindBreaksOrContinues(&p->value, &createdJoinBlock, pn))
+            if (!bindBreaksOrContinues(&p->value(), &createdJoinBlock, pn))
                 return false;
             unlabeledBreaks_.remove(p);
         }
         return true;
     }
 };
 
 } /* anonymous namespace */
@@ -6368,17 +6369,17 @@ GenerateStubs(ModuleCompiler &m)
             return false;
     }
 
     Label throwLabel;
 
     // The order of the iterations here is non-deterministic, since
     // m.allExits() is a hash keyed by pointer values!
     for (ModuleCompiler::ExitMap::Range r = m.allExits(); !r.empty(); r.popFront()) {
-        GenerateFFIExit(m, r.front().key, r.front().value, &throwLabel);
+        GenerateFFIExit(m, r.front().key(), r.front().value(), &throwLabel);
         if (m.masm().oom())
             return false;
     }
 
     if (m.stackOverflowLabel().used()) {
         if (!GenerateStackOverflowExit(m, &throwLabel))
             return false;
     }
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -886,17 +886,17 @@ jit::FinishDiscardBaselineScript(FreeOp 
     script->setBaselineScript(nullptr);
     BaselineScript::Destroy(fop, baseline);
 }
 
 void
 jit::JitCompartment::toggleBaselineStubBarriers(bool enabled)
 {
     for (ICStubCodeMap::Enum e(*stubCodes_); !e.empty(); e.popFront()) {
-        IonCode *code = *e.front().value.unsafeGet();
+        IonCode *code = *e.front().value().unsafeGet();
         code->togglePreBarriers(enabled);
     }
 }
 
 void
 jit::AddSizeOfBaselineData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf, size_t *data,
                            size_t *fallbackStubs)
 {
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -598,17 +598,17 @@ JitRuntime::getBailoutTable(const FrameS
 IonCode *
 JitRuntime::getVMWrapper(const VMFunction &f) const
 {
     JS_ASSERT(functionWrappers_);
     JS_ASSERT(functionWrappers_->initialized());
     JitRuntime::VMWrapperMap::Ptr p = functionWrappers_->readonlyThreadsafeLookup(&f);
     JS_ASSERT(p);
 
-    return p->value;
+    return p->value();
 }
 
 template <AllowGC allowGC>
 IonCode *
 IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool)
 {
     IonCode *codeObj = gc::NewGCThing<IonCode, allowGC>(cx, gc::FINALIZE_IONCODE, sizeof(IonCode), gc::DefaultHeap);
     if (!codeObj) {
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -1372,29 +1372,29 @@ BoundsCheckHashIgnoreOffset(MBoundsCheck
 }
 
 static MBoundsCheck *
 FindDominatingBoundsCheck(BoundsCheckMap &checks, MBoundsCheck *check, size_t index)
 {
     // See the comment in ValueNumberer::findDominatingDef.
     HashNumber hash = BoundsCheckHashIgnoreOffset(check);
     BoundsCheckMap::Ptr p = checks.lookup(hash);
-    if (!p || index > p->value.validUntil) {
+    if (!p || index > p->value().validUntil) {
         // We didn't find a dominating bounds check.
         BoundsCheckInfo info;
         info.check = check;
         info.validUntil = index + check->block()->numDominated();
 
         if(!checks.put(hash, info))
             return nullptr;
 
         return check;
     }
 
-    return p->value.check;
+    return p->value().check;
 }
 
 // Extract a linear sum from ins, if possible (otherwise giving the sum 'ins + 0').
 SimpleLinearSum
 jit::ExtractLinearSum(MDefinition *ins)
 {
     if (ins->isBeta())
         ins = ins->getOperand(0);
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -363,17 +363,17 @@ class JitCompartment
   public:
     OffThreadCompilationVector &finishedOffThreadCompilations() {
         return finishedOffThreadCompilations_;
     }
 
     IonCode *getStubCode(uint32_t key) {
         ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
         if (p)
-            return p->value;
+            return p->value();
         return nullptr;
     }
     bool putStubCode(uint32_t key, Handle<IonCode *> stubCode) {
         // Make sure to do a lookupForAdd(key) and then insert into that slot, because
         // that way if stubCode gets moved due to a GC caused by lookupForAdd, then
         // we still write the correct pointer.
         JS_ASSERT(!stubCodes_->has(key));
         ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
--- a/js/src/jit/ValueNumbering.cpp
+++ b/js/src/jit/ValueNumbering.cpp
@@ -30,24 +30,24 @@ ValueNumberer::alloc() const
 uint32_t
 ValueNumberer::lookupValue(MDefinition *ins)
 {
 
     ValueMap::AddPtr p = values.lookupForAdd(ins);
 
     if (p) {
         // make sure this is in the correct group
-        setClass(ins, p->key);
+        setClass(ins, p->key());
     } else {
         if (!values.add(p, ins, ins->id()))
             return 0;
         breakClass(ins);
     }
 
-    return p->value;
+    return p->value();
 }
 
 MDefinition *
 ValueNumberer::simplify(MDefinition *def, bool useValueNumbers)
 {
     if (def->isEffectful())
         return def;
 
@@ -304,34 +304,34 @@ ValueNumberer::computeValueNumbers()
 }
 
 MDefinition *
 ValueNumberer::findDominatingDef(InstructionMap &defs, MDefinition *ins, size_t index)
 {
     JS_ASSERT(ins->valueNumber() != 0);
     InstructionMap::Ptr p = defs.lookup(ins->valueNumber());
     MDefinition *dom;
-    if (!p || index > p->value.validUntil) {
+    if (!p || index > p->value().validUntil) {
         DominatingValue value;
         value.def = ins;
         // Since we are traversing the dominator tree in pre-order, when we
         // are looking at the |index|-th block, the next numDominated() blocks
         // we traverse are precisely the set of blocks that are dominated.
         //
         // So, this value is visible in all blocks if:
         // index <= index + ins->block->numDominated()
         // and becomes invalid after that.
         value.validUntil = index + ins->block()->numDominated();
 
         if(!defs.put(ins->valueNumber(), value))
             return nullptr;
 
         dom = ins;
     } else {
-        dom = p->value.def;
+        dom = p->value().def;
     }
 
     return dom;
 }
 
 bool
 ValueNumberer::eliminateRedundancies()
 {
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -655,17 +655,17 @@ IonCode *
 JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
 {
     typedef MoveResolver::MoveOperand MoveOperand;
 
     JS_ASSERT(functionWrappers_);
     JS_ASSERT(functionWrappers_->initialized());
     VMWrapperMap::AddPtr p = functionWrappers_->lookupForAdd(&f);
     if (p)
-        return p->value;
+        return p->value();
 
     // Generate a separated code for the wrapper.
     MacroAssembler masm(cx);
     GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
 
     // Wrapper register set is a superset of Volatile register set.
     JS_STATIC_ASSERT((Register::Codes::VolatileMask & ~Register::Codes::WrapperMask) == 0);
 
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -23,17 +23,17 @@ MacroAssemblerX64::loadConstantDouble(do
 
     if (!doubleMap_.initialized()) {
         enoughMemory_ &= doubleMap_.init();
         if (!enoughMemory_)
             return;
     }
     size_t doubleIndex;
     if (DoubleMap::AddPtr p = doubleMap_.lookupForAdd(d)) {
-        doubleIndex = p->value;
+        doubleIndex = p->value();
     } else {
         doubleIndex = doubles_.length();
         enoughMemory_ &= doubles_.append(Double(d));
         enoughMemory_ &= doubleMap_.add(p, d, doubleIndex);
         if (!enoughMemory_)
             return;
     }
     Double &dbl = doubles_[doubleIndex];
@@ -57,17 +57,17 @@ MacroAssemblerX64::loadConstantFloat32(f
 
     if (!floatMap_.initialized()) {
         enoughMemory_ &= floatMap_.init();
         if (!enoughMemory_)
             return;
     }
     size_t floatIndex;
     if (FloatMap::AddPtr p = floatMap_.lookupForAdd(f)) {
-        floatIndex = p->value;
+        floatIndex = p->value();
     } else {
         floatIndex = floats_.length();
         enoughMemory_ &= floats_.append(Float(f));
         enoughMemory_ &= floatMap_.add(p, f, floatIndex);
         if (!enoughMemory_)
             return;
     }
     Float &flt = floats_[floatIndex];
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -505,17 +505,17 @@ JitRuntime::generateVMWrapper(JSContext 
 {
     typedef MoveResolver::MoveOperand MoveOperand;
 
     JS_ASSERT(!StackKeptAligned);
     JS_ASSERT(functionWrappers_);
     JS_ASSERT(functionWrappers_->initialized());
     VMWrapperMap::AddPtr p = functionWrappers_->lookupForAdd(&f);
     if (p)
-        return p->value;
+        return p->value();
 
     // Generate a separated code for the wrapper.
     MacroAssembler masm;
 
     // Avoid conflicts with argument registers while discarding the result after
     // the function call.
     GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
 
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -24,17 +24,17 @@ MacroAssemblerX86::getDouble(double d)
     if (!doubleMap_.initialized()) {
         enoughMemory_ &= doubleMap_.init();
         if (!enoughMemory_)
             return nullptr;
     }
     size_t doubleIndex;
     DoubleMap::AddPtr p = doubleMap_.lookupForAdd(d);
     if (p) {
-        doubleIndex = p->value;
+        doubleIndex = p->value();
     } else {
         doubleIndex = doubles_.length();
         enoughMemory_ &= doubles_.append(Double(d));
         enoughMemory_ &= doubleMap_.add(p, d, doubleIndex);
         if (!enoughMemory_)
             return nullptr;
     }
     Double &dbl = doubles_[doubleIndex];
@@ -70,17 +70,17 @@ MacroAssemblerX86::getFloat(float f)
     if (!floatMap_.initialized()) {
         enoughMemory_ &= floatMap_.init();
         if (!enoughMemory_)
             return nullptr;
     }
     size_t floatIndex;
     FloatMap::AddPtr p = floatMap_.lookupForAdd(f);
     if (p) {
-        floatIndex = p->value;
+        floatIndex = p->value();
     } else {
         floatIndex = floats_.length();
         enoughMemory_ &= floats_.append(Float(f));
         enoughMemory_ &= floatMap_.add(p, f, floatIndex);
         if (!enoughMemory_)
             return nullptr;
     }
     Float &flt = floats_[floatIndex];
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -540,17 +540,17 @@ JitRuntime::generateVMWrapper(JSContext 
 {
     typedef MoveResolver::MoveOperand MoveOperand;
 
     JS_ASSERT(!StackKeptAligned);
     JS_ASSERT(functionWrappers_);
     JS_ASSERT(functionWrappers_->initialized());
     VMWrapperMap::AddPtr p = functionWrappers_->lookupForAdd(&f);
     if (p)
-        return p->value;
+        return p->value();
 
     // Generate a separated code for the wrapper.
     MacroAssembler masm;
 
     // Avoid conflicts with argument registers while discarding the result after
     // the function call.
     GeneralRegisterSet regs = GeneralRegisterSet(Register::Codes::WrapperMask);
 
--- a/js/src/jsapi-tests/testHashTable.cpp
+++ b/js/src/jsapi-tests/testHashTable.cpp
@@ -56,25 +56,25 @@ static bool
 MapsAreEqual(IntMap &am, IntMap &bm)
 {
     bool equal = true;
     if (am.count() != bm.count()) {
         equal = false;
         fprintf(stderr, "A.count() == %u and B.count() == %u\n", am.count(), bm.count());
     }
     for (IntMap::Range r = am.all(); !r.empty(); r.popFront()) {
-        if (!bm.has(r.front().key)) {
+        if (!bm.has(r.front().key())) {
             equal = false;
-            fprintf(stderr, "B does not have %x which is in A\n", r.front().key);
+            fprintf(stderr, "B does not have %x which is in A\n", r.front().key());
         }
     }
     for (IntMap::Range r = bm.all(); !r.empty(); r.popFront()) {
-        if (!am.has(r.front().key)) {
+        if (!am.has(r.front().key())) {
             equal = false;
-            fprintf(stderr, "A does not have %x which is in B\n", r.front().key);
+            fprintf(stderr, "A does not have %x which is in B\n", r.front().key());
         }
     }
     return equal;
 }
 
 static bool
 SetsAreEqual(IntSet &am, IntSet &bm)
 {
@@ -136,27 +136,27 @@ AddLowKeys(IntSet *as, IntSet *bs, int s
 
 template <class NewKeyFunction>
 static bool
 SlowRekey(IntMap *m) {
     IntMap tmp;
     tmp.init();
 
     for (IntMap::Range r = m->all(); !r.empty(); r.popFront()) {
-        if (NewKeyFunction::shouldBeRemoved(r.front().key))
+        if (NewKeyFunction::shouldBeRemoved(r.front().key()))
             continue;
-        uint32_t hi = NewKeyFunction::rekey(r.front().key);
+        uint32_t hi = NewKeyFunction::rekey(r.front().key());
         if (tmp.has(hi))
             return false;
-        tmp.putNew(hi, r.front().value);
+        tmp.putNew(hi, r.front().value());
     }
 
     m->clear();
     for (IntMap::Range r = tmp.all(); !r.empty(); r.popFront()) {
-        m->putNew(r.front().key, r.front().value);
+        m->putNew(r.front().key(), r.front().value());
     }
 
     return true;
 }
 
 template <class NewKeyFunction>
 static bool
 SlowRekey(IntSet *s) {
@@ -188,18 +188,18 @@ BEGIN_TEST(testHashRekeyManual)
     for (size_t i = 0; i < TestIterations; ++i) {
 #ifdef FUZZ
         fprintf(stderr, "map1: %lu\n", i);
 #endif
         CHECK(AddLowKeys(&am, &bm, i));
         CHECK(MapsAreEqual(am, bm));
 
         for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
-            uint32_t tmp = LowToHigh::rekey(e.front().key);
-            if (tmp != e.front().key)
+            uint32_t tmp = LowToHigh::rekey(e.front().key());
+            if (tmp != e.front().key())
                 e.rekeyFront(tmp);
         }
         CHECK(SlowRekey<LowToHigh>(&bm));
 
         CHECK(MapsAreEqual(am, bm));
         am.clear();
         bm.clear();
     }
@@ -238,21 +238,21 @@ BEGIN_TEST(testHashRekeyManualRemoval)
     for (size_t i = 0; i < TestIterations; ++i) {
 #ifdef FUZZ
         fprintf(stderr, "map2: %lu\n", i);
 #endif
         CHECK(AddLowKeys(&am, &bm, i));
         CHECK(MapsAreEqual(am, bm));
 
         for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
-            if (LowToHighWithRemoval::shouldBeRemoved(e.front().key)) {
+            if (LowToHighWithRemoval::shouldBeRemoved(e.front().key())) {
                 e.removeFront();
             } else {
-                uint32_t tmp = LowToHighWithRemoval::rekey(e.front().key);
-                if (tmp != e.front().key)
+                uint32_t tmp = LowToHighWithRemoval::rekey(e.front().key());
+                if (tmp != e.front().key())
                     e.rekeyFront(tmp);
             }
         }
         CHECK(SlowRekey<LowToHighWithRemoval>(&bm));
 
         CHECK(MapsAreEqual(am, bm));
         am.clear();
         bm.clear();
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1090,17 +1090,17 @@ JS_TransplantObject(JSContext *cx, Handl
         // object will continue to work.
         if (!JSObject::swap(cx, origobj, target))
             MOZ_CRASH();
         newIdentity = origobj;
     } else if (WrapperMap::Ptr p = destination->lookupWrapper(origv)) {
         // There might already be a wrapper for the original object in
         // the new compartment. If there is, we use its identity and swap
         // in the contents of |target|.
-        newIdentity = &p->value.toObject();
+        newIdentity = &p->value().toObject();
 
         // When we remove origv from the wrapper map, its wrapper, newIdentity,
         // must immediately cease to be a cross-compartment wrapper. Neuter it.
         destination->removeWrapper(p);
         NukeCrossCompartmentWrapper(cx, newIdentity);
 
         if (!JSObject::swap(cx, newIdentity, target))
             MOZ_CRASH();
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -96,18 +96,18 @@ js::TraceCycleDetectionSet(JSTracer *trc
     }
 }
 
 void
 JSCompartment::sweepCallsiteClones()
 {
     if (callsiteClones.initialized()) {
         for (CallsiteCloneTable::Enum e(callsiteClones); !e.empty(); e.popFront()) {
-            CallsiteCloneKey key = e.front().key;
-            JSFunction *fun = e.front().value;
+            CallsiteCloneKey key = e.front().key();
+            JSFunction *fun = e.front().value();
             if (!IsScriptMarked(&key.script) || !IsObjectMarked(&fun))
                 e.removeFront();
         }
     }
 }
 
 JSFunction *
 js::ExistingCloneFunctionAtCallsite(const CallsiteCloneTable &table, JSFunction *fun,
@@ -123,17 +123,17 @@ js::ExistingCloneFunctionAtCallsite(cons
      */
     JS_ASSERT(fun->isTenured());
 
     if (!table.initialized())
         return nullptr;
 
     CallsiteCloneTable::Ptr p = table.lookup(CallsiteCloneKey(fun, script, script->pcToOffset(pc)));
     if (p)
-        return p->value;
+        return p->value();
 
     return nullptr;
 }
 
 JSFunction *
 js::CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun, HandleScript script, jsbytecode *pc)
 {
     if (JSFunction *clone = ExistingCloneFunctionAtCallsite(cx->compartment()->callsiteClones, fun, script, pc))
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -224,17 +224,17 @@ JSCompartment::wrap(JSContext *cx, JSStr
     if (str->isAtom()) {
         JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
         return true;
     }
 
     /* Check the cache. */
     RootedValue key(cx, StringValue(str));
     if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
-        *strp = p->value.get().toString();
+        *strp = p->value().get().toString();
         return true;
     }
 
     /* No dice. Make a copy, and cache it. */
     Rooted<JSLinearString *> linear(cx, str->ensureLinear(cx));
     if (!linear)
         return false;
     JSString *copy = js_NewStringCopyN<CanGC>(cx, linear->chars(),
@@ -328,17 +328,17 @@ JSCompartment::wrap(JSContext *cx, Mutab
         JSObject *outer = GetOuterObject(cx, obj);
         JS_ASSERT(outer && outer == obj);
     }
 #endif
 
     /* If we already have a wrapper for this value, use it. */
     RootedValue key(cx, ObjectValue(*obj));
     if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
-        obj.set(&p->value.get().toObject());
+        obj.set(&p->value().get().toObject());
         JS_ASSERT(obj->is<CrossCompartmentWrapperObject>());
         JS_ASSERT(obj->getParent() == global);
         return true;
     }
 
     RootedObject proto(cx, Proxy::LazyProto);
     RootedObject existing(cx, existingArg);
     if (existing) {
@@ -444,18 +444,18 @@ JSCompartment::wrap(JSContext *cx, AutoI
  * across compartments.
  */
 void
 JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
 {
     JS_ASSERT(!zone()->isCollecting());
 
     for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
-        Value v = e.front().value;
-        if (e.front().key.kind == CrossCompartmentKey::ObjectWrapper) {
+        Value v = e.front().value();
+        if (e.front().key().kind == CrossCompartmentKey::ObjectWrapper) {
             ProxyObject *wrapper = &v.toObject().as<ProxyObject>();
 
             /*
              * We have a cross-compartment wrapper. Its private pointer may
              * point into the compartment being collected, so we should mark it.
              */
             Value referent = wrapper->private_();
             MarkValueRoot(trc, &referent, "cross-compartment wrapper");
@@ -469,22 +469,22 @@ JSCompartment::markCrossCompartmentWrapp
  * wrapper map. It should be called only for minor GCs, since minor GCs cannot,
  * by their nature, apply the weak constraint to safely remove items from the
  * wrapper map.
  */
 void
 JSCompartment::markAllCrossCompartmentWrappers(JSTracer *trc)
 {
     for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
-        CrossCompartmentKey key = e.front().key;
+        CrossCompartmentKey key = e.front().key();
         MarkGCThingRoot(trc, (void **)&key.wrapped, "CrossCompartmentKey::wrapped");
         if (key.debugger)
             MarkObjectRoot(trc, &key.debugger, "CrossCompartmentKey::debugger");
-        MarkValueRoot(trc, e.front().value.unsafeGet(), "CrossCompartmentWrapper");
-        if (key.wrapped != e.front().key.wrapped || key.debugger != e.front().key.debugger)
+        MarkValueRoot(trc, e.front().value().unsafeGet(), "CrossCompartmentWrapper");
+        if (key.wrapped != e.front().key().wrapped || key.debugger != e.front().key().debugger)
             e.rekeyFront(key);
     }
 }
 
 void
 JSCompartment::mark(JSTracer *trc)
 {
     JS_ASSERT(!trc->runtime->isHeapMinorCollecting());
@@ -572,24 +572,26 @@ JSCompartment::sweepCrossCompartmentWrap
 {
     JSRuntime *rt = runtimeFromMainThread();
 
     gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_SWEEP_TABLES);
     gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_WRAPPER);
 
     /* Remove dead wrappers from the table. */
     for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
-        CrossCompartmentKey key = e.front().key;
+        CrossCompartmentKey key = e.front().key();
         bool keyDying = IsCellAboutToBeFinalized(&key.wrapped);
-        bool valDying = IsValueAboutToBeFinalized(e.front().value.unsafeGet());
+        bool valDying = IsValueAboutToBeFinalized(e.front().value().unsafeGet());
         bool dbgDying = key.debugger && IsObjectAboutToBeFinalized(&key.debugger);
         if (keyDying || valDying || dbgDying) {
             JS_ASSERT(key.kind != CrossCompartmentKey::StringWrapper);
             e.removeFront();
-        } else if (key.wrapped != e.front().key.wrapped || key.debugger != e.front().key.debugger) {
+        } else if (key.wrapped != e.front().key().wrapped ||
+                   key.debugger != e.front().key().debugger)
+        {
             e.rekeyFront(key);
         }
     }
 }
 
 void
 JSCompartment::purge()
 {
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -605,21 +605,21 @@ struct WrapperValue
 {
     /*
      * We use unsafeGet() in the constructors to avoid invoking a read barrier
      * on the wrapper, which may be dead (see the comment about bug 803376 in
      * jsgc.cpp regarding this). If there is an incremental GC while the wrapper
      * is in use, the AutoWrapper rooter will ensure the wrapper gets marked.
      */
     explicit WrapperValue(const WrapperMap::Ptr &ptr)
-      : value(*ptr->value.unsafeGet())
+      : value(*ptr->value().unsafeGet())
     {}
 
     explicit WrapperValue(const WrapperMap::Enum &e)
-      : value(*e.front().value.unsafeGet())
+      : value(*e.front().value().unsafeGet())
     {}
 
     Value &get() { return value; }
     Value get() const { return value; }
     operator const Value &() const { return value; }
     JSObject &toObject() const { return value.toObject(); }
 
   private:
--- a/js/src/jscompartmentinlines.h
+++ b/js/src/jscompartmentinlines.h
@@ -86,19 +86,19 @@ JSCompartment::wrap(JSContext *cx, JS::M
      * that we get the same answer.
      */
 #ifdef DEBUG
     JS::RootedObject cacheResult(cx);
 #endif
     JS::RootedValue v(cx, vp);
     if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(v)) {
 #ifdef DEBUG
-        cacheResult = &p->value.get().toObject();
+        cacheResult = &p->value().get().toObject();
 #else
-        vp.set(p->value);
+        vp.set(p->value());
         return true;
 #endif
     }
 
     JS::RootedObject obj(cx, &vp.toObject());
     if (!wrap(cx, &obj, existing))
         return false;
     vp.setObject(*obj);
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -655,17 +655,17 @@ js::GCThingTraceKind(void *thing)
 }
 
 JS_FRIEND_API(void)
 js::VisitGrayWrapperTargets(Zone *zone, GCThingCallback callback, void *closure)
 {
     JSRuntime *rt = zone->runtimeFromMainThread();
     for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
         for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
-            gc::Cell *thing = e.front().key.wrapped;
+            gc::Cell *thing = e.front().key().wrapped;
             if (!IsInsideNursery(rt, thing) && thing->isMarked(gc::GRAY))
                 callback(closure, thing);
         }
     }
 }
 
 JS_FRIEND_API(JSObject *)
 js::GetWeakmapKeyDelegate(JSObject *key)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2876,27 +2876,27 @@ struct CompartmentCheckTracer : public J
 static bool
 InCrossCompartmentMap(JSObject *src, Cell *dst, JSGCTraceKind dstKind)
 {
     JSCompartment *srccomp = src->compartment();
 
     if (dstKind == JSTRACE_OBJECT) {
         Value key = ObjectValue(*static_cast<JSObject *>(dst));
         if (WrapperMap::Ptr p = srccomp->lookupWrapper(key)) {
-            if (*p->value.unsafeGet() == ObjectValue(*src))
+            if (*p->value().unsafeGet() == ObjectValue(*src))
                 return true;
         }
     }
 
     /*
      * If the cross-compartment edge is caused by the debugger, then we don't
      * know the right hashtable key, so we have to iterate.
      */
     for (JSCompartment::WrapperEnum e(srccomp); !e.empty(); e.popFront()) {
-        if (e.front().key.wrapped == dst && ToMarkable(e.front().value) == src)
+        if (e.front().key().wrapped == dst && ToMarkable(e.front().value()) == src)
             return true;
     }
 
     return false;
 }
 
 static void
 CheckCompartment(CompartmentCheckTracer *trc, JSCompartment *thingCompartment,
@@ -3119,17 +3119,17 @@ BeginMarkPhase(JSRuntime *rt)
      * the JS_TransplantObject function has finished. This ensures that the dead
      * zones will be cleaned up. See AutoMarkInDeadZone and
      * AutoMaybeTouchDeadZones for details.
      */
 
     /* Set the maybeAlive flag based on cross-compartment edges. */
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
-            Cell *dst = e.front().key.wrapped;
+            Cell *dst = e.front().key().wrapped;
             dst->tenuredZone()->maybeAlive = true;
         }
     }
 
     /*
      * For black roots, code in gc/Marking.cpp will already have set maybeAlive
      * during MarkRuntime.
      */
@@ -3247,17 +3247,17 @@ js::gc::MarkingValidator::MarkingValidat
 {}
 
 js::gc::MarkingValidator::~MarkingValidator()
 {
     if (!map.initialized())
         return;
 
     for (BitmapMap::Range r(map.all()); !r.empty(); r.popFront())
-        js_delete(r.front().value);
+        js_delete(r.front().value());
 }
 
 void
 js::gc::MarkingValidator::nonIncrementalMark()
 {
     /*
      * Perform a non-incremental mark for all collecting zones and record
      * the results for later comparison.
@@ -3353,17 +3353,17 @@ js::gc::MarkingValidator::nonIncremental
             zone->setGCState(Zone::Mark);
         }
     }
 
     /* Take a copy of the non-incremental mark state and restore the original. */
     for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
         Chunk *chunk = r.front();
         ChunkBitmap *bitmap = &chunk->bitmap;
-        ChunkBitmap *entry = map.lookup(chunk)->value;
+        ChunkBitmap *entry = map.lookup(chunk)->value();
         Swap(*entry, *bitmap);
     }
 
     /* Restore the weak map and array buffer lists. */
     for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
         WeakMapBase::resetCompartmentWeakMapList(c);
         ArrayBufferObject::resetArrayBufferList(c);
     }
@@ -3385,17 +3385,17 @@ js::gc::MarkingValidator::validate()
         return;
 
     for (GCChunkSet::Range r(runtime->gcChunkSet.all()); !r.empty(); r.popFront()) {
         Chunk *chunk = r.front();
         BitmapMap::Ptr ptr = map.lookup(chunk);
         if (!ptr)
             continue;  /* Allocated after we did the non-incremental mark. */
 
-        ChunkBitmap *bitmap = ptr->value;
+        ChunkBitmap *bitmap = ptr->value();
         ChunkBitmap *incBitmap = &chunk->bitmap;
 
         for (size_t i = 0; i < ArenasPerChunk; i++) {
             if (chunk->decommittedArenas.get(i))
                 continue;
             Arena *arena = &chunk->arenas[i];
             if (!arena->aheader.allocated())
                 continue;
@@ -3477,17 +3477,17 @@ DropStringWrappers(JSRuntime *rt)
 {
     /*
      * String "wrappers" are dropped on GC because their presence would require
      * us to sweep the wrappers in all compartments every time we sweep a
      * compartment group.
      */
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
-            if (e.front().key.kind == CrossCompartmentKey::StringWrapper)
+            if (e.front().key().kind == CrossCompartmentKey::StringWrapper)
                 e.removeFront();
         }
     }
 }
 
 /*
  * Group zones that must be swept at the same time.
  *
@@ -3502,19 +3502,19 @@ DropStringWrappers(JSRuntime *rt)
  *
  * Tarjan's algorithm is used to calculate the components.
  */
 
 void
 JSCompartment::findOutgoingEdges(ComponentFinder<JS::Zone> &finder)
 {
     for (js::WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
-        CrossCompartmentKey::Kind kind = e.front().key.kind;
+        CrossCompartmentKey::Kind kind = e.front().key().kind;
         JS_ASSERT(kind != CrossCompartmentKey::StringWrapper);
-        Cell *other = e.front().key.wrapped;
+        Cell *other = e.front().key().wrapped;
         if (kind == CrossCompartmentKey::ObjectWrapper) {
             /*
              * Add edge to wrapped object compartment if wrapped object is not
              * marked black to indicate that wrapper compartment not be swept
              * after wrapped compartment.
              */
             if (!other->isMarked(BLACK) || other->isMarked(GRAY)) {
                 JS::Zone *w = other->tenuredZone();
@@ -4028,18 +4028,18 @@ BeginSweepPhase(JSRuntime *rt, bool last
 #ifdef JS_THREADSAFE
     rt->gcSweepOnBackgroundThread = !lastGC && rt->useHelperThreads();
 #endif
 
 #ifdef DEBUG
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         JS_ASSERT(!c->gcIncomingGrayPointers);
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
-            if (e.front().key.kind != CrossCompartmentKey::StringWrapper)
-                AssertNotOnGrayList(&e.front().value.get().toObject());
+            if (e.front().key().kind != CrossCompartmentKey::StringWrapper)
+                AssertNotOnGrayList(&e.front().value().get().toObject());
         }
     }
 #endif
 
     DropStringWrappers(rt);
     FindZoneGroups(rt);
     EndMarkingZoneGroup(rt);
     BeginSweepingZoneGroup(rt);
@@ -4251,18 +4251,18 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocat
     }
 
 #ifdef DEBUG
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         JS_ASSERT(!c->gcIncomingGrayPointers);
         JS_ASSERT(!c->gcLiveArrayBuffers);
 
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
-            if (e.front().key.kind != CrossCompartmentKey::StringWrapper)
-                AssertNotOnGrayList(&e.front().value.get().toObject());
+            if (e.front().key().kind != CrossCompartmentKey::StringWrapper)
+                AssertNotOnGrayList(&e.front().value().get().toObject());
         }
     }
 #endif
 
     FinishMarkingValidation(rt);
 
     rt->gcLastGCTime = PRMJ_Now();
 }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1817,17 +1817,17 @@ TypeCompartment::addAllocationSiteTypeOb
     if (prev) {
         AllocationSiteKey nkey;
         nkey.script = key.script;
         nkey.offset = key.script->pcToOffset(prev);
         nkey.kind = JSProto_Array;
 
         AllocationSiteTable::Ptr p = cx->compartment()->types.allocationSiteTable->lookup(nkey);
         if (p)
-            res = p->value;
+            res = p->value();
     }
 
     if (!res) {
         RootedObject proto(cx);
         if (!js_GetClassPrototype(cx, key.kind, &proto, nullptr))
             return nullptr;
 
         Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
@@ -2298,17 +2298,17 @@ TypeCompartment::setTypeToHomogenousArra
             cx->compartment()->types.setPendingNukeTypes(cx);
             return;
         }
     }
 
     ArrayTableKey key(elementType, obj->getProto());
     DependentAddPtr<ArrayTypeTable> p(cx, *arrayTypeTable, key);
     if (p) {
-        obj->setType(p->value);
+        obj->setType(p->value());
     } else {
         /* Make a new type to use for future arrays with the same elements. */
         RootedObject objProto(cx, obj->getProto());
         TypeObject *objType = newTypeObject(cx, &ArrayObject::class_, objProto);
         if (!objType) {
             cx->compartment()->types.setPendingNukeTypes(cx);
             return;
         }
@@ -2487,21 +2487,21 @@ TypeCompartment::fixObjectType(Exclusive
         entry.value = obj->getSlot(shape->slot());
         shape = shape->previous();
     }
 
     ObjectTableKey::Lookup lookup(properties.begin(), properties.length(), obj->numFixedSlots());
     ObjectTypeTable::AddPtr p = objectTypeTable->lookupForAdd(lookup);
 
     if (p) {
-        JS_ASSERT(obj->getProto() == p->value.object->proto);
-        JS_ASSERT(obj->lastProperty() == p->value.shape);
-
-        UpdateObjectTableEntryTypes(cx, p->value, properties.begin(), properties.length());
-        obj->setType(p->value.object);
+        JS_ASSERT(obj->getProto() == p->value().object->proto);
+        JS_ASSERT(obj->lastProperty() == p->value().shape);
+
+        UpdateObjectTableEntryTypes(cx, p->value(), properties.begin(), properties.length());
+        obj->setType(p->value().object);
         return;
     }
 
     /* Make a new type to use for the object and similar future ones. */
     Rooted<TaggedProto> objProto(cx, obj->getTaggedProto());
     TypeObject *objType = newTypeObject(cx, &JSObject::class_, objProto);
     if (!objType || !objType->addDefiniteProperties(cx, obj)) {
         cx->compartment()->types.setPendingNukeTypes(cx);
@@ -2590,30 +2590,30 @@ TypeCompartment::newTypedObject(JSContex
     if (!p)
         return nullptr;
 
     RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_, allocKind));
     if (!obj) {
         cx->clearPendingException();
         return nullptr;
     }
-    JS_ASSERT(obj->getProto() == p->value.object->proto);
-
-    RootedShape shape(cx, p->value.shape);
+    JS_ASSERT(obj->getProto() == p->value().object->proto);
+
+    RootedShape shape(cx, p->value().shape);
     if (!JSObject::setLastProperty(cx, obj, shape)) {
         cx->clearPendingException();
         return nullptr;
     }
 
-    UpdateObjectTableEntryTypes(cx, p->value, properties, nproperties);
+    UpdateObjectTableEntryTypes(cx, p->value(), properties, nproperties);
 
     for (size_t i = 0; i < nproperties; i++)
         obj->setSlot(i, properties[i].value);
 
-    obj->setType(p->value.object);
+    obj->setType(p->value().object);
     return obj;
 }
 
 /////////////////////////////////////////////////////////////////////
 // TypeObject
 /////////////////////////////////////////////////////////////////////
 
 static inline void
@@ -4021,44 +4021,44 @@ TypeCompartment::sweep(FreeOp *fop)
 {
     /*
      * Iterate through the array/object type tables and remove all entries
      * referencing collected data. These tables only hold weak references.
      */
 
     if (arrayTypeTable) {
         for (ArrayTypeTable::Enum e(*arrayTypeTable); !e.empty(); e.popFront()) {
-            const ArrayTableKey &key = e.front().key;
+            const ArrayTableKey &key = e.front().key();
             JS_ASSERT(key.type.isUnknown() || !key.type.isSingleObject());
 
             bool remove = false;
             TypeObject *typeObject = nullptr;
             if (!key.type.isUnknown() && key.type.isTypeObject()) {
                 typeObject = key.type.typeObject();
                 if (IsTypeObjectAboutToBeFinalized(&typeObject))
                     remove = true;
             }
-            if (IsTypeObjectAboutToBeFinalized(e.front().value.unsafeGet()))
+            if (IsTypeObjectAboutToBeFinalized(e.front().value().unsafeGet()))
                 remove = true;
 
             if (remove) {
                 e.removeFront();
             } else if (typeObject && typeObject != key.type.typeObject()) {
                 ArrayTableKey newKey;
                 newKey.type = Type::ObjectType(typeObject);
                 newKey.proto = key.proto;
                 e.rekeyFront(newKey);
             }
         }
     }
 
     if (objectTypeTable) {
         for (ObjectTypeTable::Enum e(*objectTypeTable); !e.empty(); e.popFront()) {
-            const ObjectTableKey &key = e.front().key;
-            ObjectTableEntry &entry = e.front().value;
+            const ObjectTableKey &key = e.front().key();
+            ObjectTableEntry &entry = e.front().value();
 
             bool remove = false;
             if (IsTypeObjectAboutToBeFinalized(entry.object.unsafeGet()))
                 remove = true;
             if (IsShapeAboutToBeFinalized(entry.shape.unsafeGet()))
                 remove = true;
             for (unsigned i = 0; !remove && i < key.nproperties; i++) {
                 if (JSID_IS_STRING(key.properties[i])) {
@@ -4083,22 +4083,22 @@ TypeCompartment::sweep(FreeOp *fop)
                 js_free(entry.types);
                 e.removeFront();
             }
         }
     }
 
     if (allocationSiteTable) {
         for (AllocationSiteTable::Enum e(*allocationSiteTable); !e.empty(); e.popFront()) {
-            AllocationSiteKey key = e.front().key;
+            AllocationSiteKey key = e.front().key();
             bool keyDying = IsScriptAboutToBeFinalized(&key.script);
-            bool valDying = IsTypeObjectAboutToBeFinalized(e.front().value.unsafeGet());
+            bool valDying = IsTypeObjectAboutToBeFinalized(e.front().value().unsafeGet());
             if (keyDying || valDying)
                 e.removeFront();
-            else if (key.script != e.front().key.script)
+            else if (key.script != e.front().key().script)
                 e.rekeyFront(key);
         }
     }
 
     /*
      * The pending array is reset on GC, it can grow large (75+ KB) and is easy
      * to reallocate if the compartment becomes active again.
      */
@@ -4113,18 +4113,18 @@ void
 TypeCompartment::sweepShapes(FreeOp *fop)
 {
     /*
      * Sweep any weak shape references that may be finalized even if a GC is
      * preserving type information.
      */
     if (objectTypeTable) {
         for (ObjectTypeTable::Enum e(*objectTypeTable); !e.empty(); e.popFront()) {
-            const ObjectTableKey &key = e.front().key;
-            ObjectTableEntry &entry = e.front().value;
+            const ObjectTableKey &key = e.front().key();
+            ObjectTableEntry &entry = e.front().value();
 
             if (IsShapeAboutToBeFinalized(entry.shape.unsafeGet())) {
                 fop->free_(key.properties);
                 fop->free_(entry.types);
                 e.removeFront();
             }
         }
     }
@@ -4228,18 +4228,18 @@ TypeCompartment::addSizeOfExcludingThis(
 
     if (objectTypeTable) {
         *objectTypeTables += objectTypeTable->sizeOfIncludingThis(mallocSizeOf);
 
         for (ObjectTypeTable::Enum e(*objectTypeTable);
              !e.empty();
              e.popFront())
         {
-            const ObjectTableKey &key = e.front().key;
-            const ObjectTableEntry &value = e.front().value;
+            const ObjectTableKey &key = e.front().key();
+            const ObjectTableEntry &value = e.front().value();
 
             /* key.ids and values.types have the same length. */
             *objectTypeTables += mallocSizeOf(key.properties) + mallocSizeOf(value.types);
         }
     }
 }
 
 size_t
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -716,17 +716,17 @@ TypeScript::InitObject(JSContext *cx, JS
     key.kind = kind;
 
     if (!cx->compartment()->types.allocationSiteTable)
         return cx->compartment()->types.addAllocationSiteTypeObject(cx, key);
 
     AllocationSiteTable::Ptr p = cx->compartment()->types.allocationSiteTable->lookup(key);
 
     if (p)
-        return p->value;
+        return p->value();
     return cx->compartment()->types.addAllocationSiteTypeObject(cx, key);
 }
 
 /* Set the type to use for obj according to the site it was allocated at. */
 static inline bool
 SetInitializerObjectType(JSContext *cx, HandleScript script, jsbytecode *pc, HandleObject obj, NewObjectKind kind)
 {
     if (!cx->typeInferenceEnabled())
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -3003,17 +3003,17 @@ ProxyObject::trace(JSTracer *trc, JSObje
         JSObject *referent = &proxy->private_().toObject();
         if (referent->compartment() != proxy->compartment()) {
             /*
              * Assert that this proxy is tracked in the wrapper map. We maintain
              * the invariant that the wrapped object is the key in the wrapper map.
              */
             Value key = ObjectValue(*referent);
             WrapperMap::Ptr p = proxy->compartment()->lookupWrapper(key);
-            JS_ASSERT(*p->value.unsafeGet() == ObjectValue(*proxy));
+            JS_ASSERT(*p->value().unsafeGet() == ObjectValue(*proxy));
         }
     }
 #endif
 
     // Note: If you add new slots here, make sure to change
     // nuke() to cope.
     MarkCrossCompartmentSlot(trc, obj, proxy->slotOfPrivate(), "private");
     MarkSlot(trc, proxy->slotOfExtra(0), "extra0");
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -907,40 +907,40 @@ static inline ScriptCountsMap::Ptr GetSc
     JS_ASSERT(p);
     return p;
 }
 
 js::PCCounts
 JSScript::getPCCounts(jsbytecode *pc) {
     JS_ASSERT(containsPC(pc));
     ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);
-    return p->value.pcCountsVector[pcToOffset(pc)];
+    return p->value().pcCountsVector[pcToOffset(pc)];
 }
 
 void
 JSScript::addIonCounts(jit::IonScriptCounts *ionCounts)
 {
     ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);
-    if (p->value.ionCounts)
-        ionCounts->setPrevious(p->value.ionCounts);
-    p->value.ionCounts = ionCounts;
+    if (p->value().ionCounts)
+        ionCounts->setPrevious(p->value().ionCounts);
+    p->value().ionCounts = ionCounts;
 }
 
 jit::IonScriptCounts *
 JSScript::getIonCounts()
 {
     ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);
-    return p->value.ionCounts;
+    return p->value().ionCounts;
 }
 
 ScriptCounts
 JSScript::releaseScriptCounts()
 {
     ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);
-    ScriptCounts counts = p->value;
+    ScriptCounts counts = p->value();
     compartment()->scriptCountsMap->remove(p);
     hasScriptCounts = false;
     return counts;
 }
 
 void
 JSScript::destroyScriptCounts(FreeOp *fop)
 {
@@ -1077,17 +1077,17 @@ SourceDataCache::AutoSuppressPurge::~Aut
 
 const jschar *
 SourceDataCache::lookup(ScriptSource *ss, const AutoSuppressPurge &asp)
 {
     JS_ASSERT(this == &asp.cache());
     if (!map_)
         return nullptr;
     if (Map::Ptr p = map_->lookup(ss))
-        return p->value;
+        return p->value();
     return nullptr;
 }
 
 bool
 SourceDataCache::put(ScriptSource *ss, const jschar *str, const AutoSuppressPurge &asp)
 {
     JS_ASSERT(this == &asp.cache());
 
@@ -1108,17 +1108,17 @@ SourceDataCache::put(ScriptSource *ss, c
 
 void
 SourceDataCache::purge()
 {
     if (!map_ || numSuppressPurges_ > 0)
         return;
 
     for (Map::Range r = map_->all(); !r.empty(); r.popFront())
-        js_delete(const_cast<jschar*>(r.front().value));
+        js_delete(const_cast<jschar*>(r.front().value()));
 
     js_delete(map_);
     map_ = nullptr;
 }
 
 const jschar *
 ScriptSource::chars(JSContext *cx, const SourceDataCache::AutoSuppressPurge &asp)
 {
@@ -2159,17 +2159,17 @@ js::GetSrcNote(GSNCache &cache, JSScript
 {
     size_t target = pc - script->code();
     if (target >= script->length())
         return nullptr;
 
     if (cache.code == script->code()) {
         JS_ASSERT(cache.map.initialized());
         GSNCache::Map::Ptr p = cache.map.lookup(pc);
-        return p ? p->value : nullptr;
+        return p ? p->value() : nullptr;
     }
 
     size_t offset = 0;
     jssrcnote *result;
     for (jssrcnote *sn = script->notes(); ; sn = SN_NEXT(sn)) {
         if (SN_IS_TERMINATOR(sn)) {
             result = nullptr;
             break;
@@ -2586,28 +2586,28 @@ js::CloneFunctionScript(JSContext *cx, H
 DebugScript *
 JSScript::debugScript()
 {
     JS_ASSERT(hasDebugScript);
     DebugScriptMap *map = compartment()->debugScriptMap;
     JS_ASSERT(map);
     DebugScriptMap::Ptr p = map->lookup(this);
     JS_ASSERT(p);
-    return p->value;
+    return p->value();
 }
 
 DebugScript *
 JSScript::releaseDebugScript()
 {
     JS_ASSERT(hasDebugScript);
     DebugScriptMap *map = compartment()->debugScriptMap;
     JS_ASSERT(map);
     DebugScriptMap::Ptr p = map->lookup(this);
     JS_ASSERT(p);
-    DebugScript *debug = p->value;
+    DebugScript *debug = p->value();
     map->remove(p);
     hasDebugScript = false;
     return debug;
 }
 
 void
 JSScript::destroyDebugScript(FreeOp *fop)
 {
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -30,26 +30,27 @@ class AutoEntryHolder {
     Map &map;
     Map::Ptr p;
     uint32_t gen;
     RootedObject obj;
     RootedId id;
 
   public:
     AutoEntryHolder(JSContext *cx, Map &map, Map::Ptr p)
-        : map(map), p(p), gen(map.generation()), obj(cx, p->key.object), id(cx, p->key.id) {
-        JS_ASSERT(!p->value.held);
-        p->value.held = true;
+      : map(map), p(p), gen(map.generation()), obj(cx, p->key().object), id(cx, p->key().id)
+    {
+        JS_ASSERT(!p->value().held);
+        p->value().held = true;
     }
 
     ~AutoEntryHolder() {
         if (gen != map.generation())
             p = map.lookup(WatchKey(obj, id));
         if (p)
-            p->value.held = false;
+            p->value().held = false;
     }
 };
 
 } /* anonymous namespace */
 
 bool
 WatchpointMap::init()
 {
@@ -79,55 +80,55 @@ WatchpointMap::watch(JSContext *cx, Hand
 }
 
 void
 WatchpointMap::unwatch(JSObject *obj, jsid id,
                        JSWatchPointHandler *handlerp, JSObject **closurep)
 {
     if (Map::Ptr p = map.lookup(WatchKey(obj, id))) {
         if (handlerp)
-            *handlerp = p->value.handler;
+            *handlerp = p->value().handler;
         if (closurep) {
             // Read barrier to prevent an incorrectly gray closure from escaping the
             // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp
-            JS::ExposeGCThingToActiveJS(p->value.closure, JSTRACE_OBJECT);
-            *closurep = p->value.closure;
+            JS::ExposeGCThingToActiveJS(p->value().closure, JSTRACE_OBJECT);
+            *closurep = p->value().closure;
         }
         map.remove(p);
     }
 }
 
 void
 WatchpointMap::unwatchObject(JSObject *obj)
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry &entry = e.front();
-        if (entry.key.object == obj)
+        if (entry.key().object == obj)
             e.removeFront();
     }
 }
 
 void
 WatchpointMap::clear()
 {
     map.clear();
 }
 
 bool
 WatchpointMap::triggerWatchpoint(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp)
 {
     Map::Ptr p = map.lookup(WatchKey(obj, id));
-    if (!p || p->value.held)
+    if (!p || p->value().held)
         return true;
 
     AutoEntryHolder holder(cx, map, p);
 
     /* Copy the entry, since GC would invalidate p. */
-    JSWatchPointHandler handler = p->value.handler;
-    RootedObject closure(cx, p->value.closure);
+    JSWatchPointHandler handler = p->value().handler;
+    RootedObject closure(cx, p->value().closure);
 
     /* Determine the property's old value. */
     Value old;
     old.setUndefined();
     if (obj->isNative()) {
         if (Shape *shape = obj->nativeLookup(cx, id)) {
             if (shape->hasSlot())
                 old = obj->nativeGetSlot(shape->slot());
@@ -151,55 +152,56 @@ WatchpointMap::markCompartmentIterativel
 }
 
 bool
 WatchpointMap::markIteratively(JSTracer *trc)
 {
     bool marked = false;
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry &entry = e.front();
-        JSObject *priorKeyObj = entry.key.object;
-        jsid priorKeyId(entry.key.id.get());
-        bool objectIsLive = IsObjectMarked(const_cast<EncapsulatedPtrObject *>(&entry.key.object));
-        if (objectIsLive || entry.value.held) {
+        JSObject *priorKeyObj = entry.key().object;
+        jsid priorKeyId(entry.key().id.get());
+        bool objectIsLive =
+            IsObjectMarked(const_cast<EncapsulatedPtrObject *>(&entry.key().object));
+        if (objectIsLive || entry.value().held) {
             if (!objectIsLive) {
-                MarkObject(trc, const_cast<EncapsulatedPtrObject *>(&entry.key.object),
+                MarkObject(trc, const_cast<EncapsulatedPtrObject *>(&entry.key().object),
                            "held Watchpoint object");
                 marked = true;
             }
 
             JS_ASSERT(JSID_IS_STRING(priorKeyId) || JSID_IS_INT(priorKeyId));
-            MarkId(trc, const_cast<EncapsulatedId *>(&entry.key.id), "WatchKey::id");
+            MarkId(trc, const_cast<EncapsulatedId *>(&entry.key().id), "WatchKey::id");
 
-            if (entry.value.closure && !IsObjectMarked(&entry.value.closure)) {
-                MarkObject(trc, &entry.value.closure, "Watchpoint::closure");
+            if (entry.value().closure && !IsObjectMarked(&entry.value().closure)) {
+                MarkObject(trc, &entry.value().closure, "Watchpoint::closure");
                 marked = true;
             }
 
             /* We will sweep this entry in sweepAll if !objectIsLive. */
-            if (priorKeyObj != entry.key.object || priorKeyId != entry.key.id)
-                e.rekeyFront(WatchKey(entry.key.object, entry.key.id));
+            if (priorKeyObj != entry.key().object || priorKeyId != entry.key().id)
+                e.rekeyFront(WatchKey(entry.key().object, entry.key().id));
         }
     }
     return marked;
 }
 
 void
 WatchpointMap::markAll(JSTracer *trc)
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry &entry = e.front();
-        WatchKey key = entry.key;
+        WatchKey key = entry.key();
         WatchKey prior = key;
         JS_ASSERT(JSID_IS_STRING(prior.id) || JSID_IS_INT(prior.id));
 
         MarkObject(trc, const_cast<EncapsulatedPtrObject *>(&key.object),
                    "held Watchpoint object");
         MarkId(trc, const_cast<EncapsulatedId *>(&key.id), "WatchKey::id");
-        MarkObject(trc, &entry.value.closure, "Watchpoint::closure");
+        MarkObject(trc, &entry.value().closure, "Watchpoint::closure");
 
         if (prior.object != key.object || prior.id != key.id)
             e.rekeyFront(key);
     }
 }
 
 void
 WatchpointMap::sweepAll(JSRuntime *rt)
@@ -210,22 +212,22 @@ WatchpointMap::sweepAll(JSRuntime *rt)
     }
 }
 
 void
 WatchpointMap::sweep()
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry &entry = e.front();
-        JSObject *obj(entry.key.object);
+        JSObject *obj(entry.key().object);
         if (IsObjectAboutToBeFinalized(&obj)) {
-            JS_ASSERT(!entry.value.held);
+            JS_ASSERT(!entry.value().held);
             e.removeFront();
-        } else if (obj != entry.key.object) {
-            e.rekeyFront(WatchKey(obj, entry.key.id));
+        } else if (obj != entry.key().object) {
+            e.rekeyFront(WatchKey(obj, entry.key().id));
         }
     }
 }
 
 void
 WatchpointMap::traceAll(WeakMapTracer *trc)
 {
     JSRuntime *rt = trc->runtime;
@@ -236,12 +238,12 @@ WatchpointMap::traceAll(WeakMapTracer *t
 }
 
 void
 WatchpointMap::trace(WeakMapTracer *trc)
 {
     for (Map::Range r = map.all(); !r.empty(); r.popFront()) {
         Map::Entry &entry = r.front();
         trc->callback(trc, nullptr,
-                      entry.key.object.get(), JSTRACE_OBJECT,
-                      entry.value.closure.get(), JSTRACE_OBJECT);
+                      entry.key().object.get(), JSTRACE_OBJECT,
+                      entry.value().closure.get(), JSTRACE_OBJECT);
     }
 }
--- a/js/src/jsweakcache.h
+++ b/js/src/jsweakcache.h
@@ -84,24 +84,24 @@ class WeakValueCache : public HashMap<Ke
     explicit WeakValueCache(JSRuntime *rt) : Base(rt) { }
     explicit WeakValueCache(JSContext *cx) : Base(cx->runtime()) { }
 
   public:
     // Sweep all entries which have unmarked key or value.
     void sweep(FreeOp *fop) {
         // Remove all entries whose values remain unmarked.
         for (Enum e(*this); !e.empty(); e.popFront()) {
-            if (gc::IsAboutToBeFinalized(e.front().value))
+            if (gc::IsAboutToBeFinalized(e.front().value()))
                 e.removeFront();
         }
 
 #if DEBUG
         // Once we've swept, all remaining edges should stay within the
         // known-live part of the graph.
         for (Range r = Base::all(); !r.empty(); r.popFront())
-            JS_ASSERT(!gc::IsAboutToBeFinalized(r.front().value));
+            JS_ASSERT(!gc::IsAboutToBeFinalized(r.front().value()));
 #endif
     }
 };
 
 } // namespace js
 
 #endif /* jsweakcache_h */
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -195,19 +195,19 @@ WeakMap_get_impl(JSContext *cx, CallArgs
     JSObject *key = GetKeyArg(cx, args);
     if (!key)
         return false;
 
     if (ObjectValueMap *map = args.thisv().toObject().as<WeakMapObject>().getMap()) {
         if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
             // Read barrier to prevent an incorrectly gray value from escaping the
             // weak map. See the comment before UnmarkGrayChildren in gc/Marking.cpp
-            ExposeValueToActiveJS(ptr->value.get());
+            ExposeValueToActiveJS(ptr->value().get());
 
-            args.rval().set(ptr->value);
+            args.rval().set(ptr->value());
             return true;
         }
     }
 
     args.rval().set((args.length() > 1) ? args[1] : UndefinedValue());
     return true;
 }
 
@@ -352,17 +352,17 @@ JS_NondeterministicGetWeakMapKeys(JSCont
     RootedObject arr(cx, NewDenseEmptyArray(cx));
     if (!arr)
         return false;
     ObjectValueMap *map = obj->as<WeakMapObject>().getMap();
     if (map) {
         // Prevent GC from mutating the weakmap while iterating.
         gc::AutoSuppressGC suppress(cx);
         for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
-            RootedObject key(cx, r.front().key);
+            RootedObject key(cx, r.front().key());
             if (!cx->compartment()->wrap(cx, &key))
                 return false;
             if (!js_NewbornArrayPush(cx, arr, ObjectValue(*key)))
                 return false;
         }
     }
     *ret = arr;
     return true;
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -143,26 +143,26 @@ class WeakMap : public HashMap<Key, Valu
             return false;
         gc::Mark(trc, x, "WeakMap entry value");
         JS_ASSERT(gc::IsMarked(x));
         return true;
     }
 
     void nonMarkingTraceKeys(JSTracer *trc) {
         for (Enum e(*this); !e.empty(); e.popFront()) {
-            Key key(e.front().key);
+            Key key(e.front().key());
             gc::Mark(trc, &key, "WeakMap entry key");
-            if (key != e.front().key)
+            if (key != e.front().key())
                 entryMoved(e, key);
         }
     }
 
     void nonMarkingTraceValues(JSTracer *trc) {
         for (Range r = Base::all(); !r.empty(); r.popFront())
-            gc::Mark(trc, &r.front().value, "WeakMap entry value");
+            gc::Mark(trc, &r.front().value(), "WeakMap entry value");
     }
 
     bool keyNeedsMark(JSObject *key) {
         if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
             JSObject *delegate = op(key);
             /*
              * Check if the delegate is marked with any color to properly handle
              * gray marking when the key's delegate is black and the map is
@@ -176,59 +176,59 @@ class WeakMap : public HashMap<Key, Valu
     bool keyNeedsMark(gc::Cell *cell) {
         return false;
     }
 
     bool markIteratively(JSTracer *trc) {
         bool markedAny = false;
         for (Enum e(*this); !e.empty(); e.popFront()) {
             /* If the entry is live, ensure its key and value are marked. */
-            Key key(e.front().key);
+            Key key(e.front().key());
             if (gc::IsMarked(const_cast<Key *>(&key))) {
-                if (markValue(trc, &e.front().value))
+                if (markValue(trc, &e.front().value()))
                     markedAny = true;
-                if (e.front().key != key)
+                if (e.front().key() != key)
                     entryMoved(e, key);
             } else if (keyNeedsMark(key)) {
-                gc::Mark(trc, const_cast<Key *>(&key), "proxy-preserved WeakMap entry key");
-                if (e.front().key != key)
+                gc::Mark(trc, &key, "proxy-preserved WeakMap entry key");
+                if (e.front().key() != key)
                     entryMoved(e, key);
-                gc::Mark(trc, &e.front().value, "WeakMap entry value");
+                gc::Mark(trc, &e.front().value(), "WeakMap entry value");
                 markedAny = true;
             }
             key.unsafeSet(nullptr);
         }
         return markedAny;
     }
 
     void sweep() {
         /* Remove all entries whose keys remain unmarked. */
         for (Enum e(*this); !e.empty(); e.popFront()) {
-            Key k(e.front().key);
+            Key k(e.front().key());
             if (gc::IsAboutToBeFinalized(&k))
                 e.removeFront();
-            else if (k != e.front().key)
+            else if (k != e.front().key())
                 entryMoved(e, k);
         }
         /*
          * Once we've swept, all remaining edges should stay within the
          * known-live part of the graph.
          */
         assertEntriesNotAboutToBeFinalized();
     }
 
     /* memberOf can be nullptr, which means that the map is not part of a JSObject. */
     void traceMappings(WeakMapTracer *tracer) {
         for (Range r = Base::all(); !r.empty(); r.popFront()) {
-            gc::Cell *key = gc::ToMarkable(r.front().key);
-            gc::Cell *value = gc::ToMarkable(r.front().value);
+            gc::Cell *key = gc::ToMarkable(r.front().key());
+            gc::Cell *value = gc::ToMarkable(r.front().value());
             if (key && value) {
                 tracer->callback(tracer, memberOf,
-                                 key, gc::TraceKind(r.front().key),
-                                 value, gc::TraceKind(r.front().value));
+                                 key, gc::TraceKind(r.front().key()),
+                                 value, gc::TraceKind(r.front().value()));
             }
         }
     }
 
     /* Rekey an entry when moved, ensuring we do not trigger barriers. */
     void entryMoved(Enum &eArg, const Key &k) {
         typedef typename HashMap<typename Unbarriered<Key>::type,
                                  typename Unbarriered<Value>::type,
@@ -237,20 +237,20 @@ class WeakMap : public HashMap<Key, Valu
         UnbarrieredEnum &e = reinterpret_cast<UnbarrieredEnum &>(eArg);
         e.rekeyFront(reinterpret_cast<const typename Unbarriered<Key>::type &>(k));
     }
 
 protected:
     void assertEntriesNotAboutToBeFinalized() {
 #if DEBUG
         for (Range r = Base::all(); !r.empty(); r.popFront()) {
-            Key k(r.front().key);
+            Key k(r.front().key());
             JS_ASSERT(!gc::IsAboutToBeFinalized(&k));
-            JS_ASSERT(!gc::IsAboutToBeFinalized(&r.front().value));
-            JS_ASSERT(k == r.front().key);
+            JS_ASSERT(!gc::IsAboutToBeFinalized(&r.front().value()));
+            JS_ASSERT(k == r.front().key());
         }
 #endif
     }
 };
 
 } /* namespace js */
 
 extern JSObject *
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -888,17 +888,17 @@ js::NukeCrossCompartmentWrappers(JSConte
     for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
         if (!sourceFilter.match(c))
             continue;
 
         // Iterate the wrappers looking for anything interesting.
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
             // Some cross-compartment wrappers are for strings.  We're not
             // interested in those.
-            const CrossCompartmentKey &k = e.front().key;
+            const CrossCompartmentKey &k = e.front().key();
             if (k.kind != CrossCompartmentKey::ObjectWrapper)
                 continue;
 
             AutoWrapperRooter wobj(cx, WrapperValue(e));
             JSObject *wrapped = UncheckedUnwrap(wobj);
 
             if (nukeReferencesToWindow == DontNukeWindowReferences &&
                 wrapped->getClass()->ext.innerObject)
@@ -936,17 +936,17 @@ js::RemapWrapper(JSContext *cx, JSObject
     // for the same target), we must not have an existing wrapper for the new
     // target, otherwise this will break.
     JS_ASSERT_IF(origTarget != newTarget,
                  !wcompartment->lookupWrapper(ObjectValue(*newTarget)));
 
     // The old value should still be in the cross-compartment wrapper map, and
     // the lookup should return wobj.
     WrapperMap::Ptr p = wcompartment->lookupWrapper(origv);
-    JS_ASSERT(&p->value.unsafeGet()->toObject() == wobj);
+    JS_ASSERT(&p->value().unsafeGet()->toObject() == wobj);
     wcompartment->removeWrapper(p);
 
     // When we remove origv from the wrapper map, its wrapper, wobj, must
     // immediately cease to be a cross-compartment wrapper. Neuter it.
     NukeCrossCompartmentWrapper(cx, wobj);
 
     // First, we wrap it in the new compartment. We try to use the existing
     // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
@@ -1020,17 +1020,17 @@ js::RecomputeWrappers(JSContext *cx, con
     for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
         // Filter by source compartment.
         if (!sourceFilter.match(c))
             continue;
 
         // Iterate over the wrappers, filtering appropriately.
         for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
             // Filter out non-objects.
-            const CrossCompartmentKey &k = e.front().key;
+            const CrossCompartmentKey &k = e.front().key();
             if (k.kind != CrossCompartmentKey::ObjectWrapper)
                 continue;
 
             // Filter by target compartment.
             if (!targetFilter.match(static_cast<JSObject *>(k.wrapped)->compartment()))
                 continue;
 
             // Add it to the list.
--- a/js/src/shell/jsheaptools.cpp
+++ b/js/src/shell/jsheaptools.cpp
@@ -241,18 +241,18 @@ class HeapReverser : public JSTracer, pu
         return OBJECT_TO_JSVAL(object);
     }
 
     /* Keep all tracked objects live across GC. */
     virtual void trace(JSTracer *trc) MOZ_OVERRIDE {
         if (!map.initialized())
             return;
         for (Map::Enum e(map); !e.empty(); e.popFront()) {
-            gc::MarkGCThingRoot(trc, const_cast<void **>(&e.front().key), "HeapReverser::map::key");
-            e.front().value.trace(trc);
+            gc::MarkGCThingRoot(trc, const_cast<void **>(&e.front().key()), "HeapReverser::map::key");
+            e.front().value().trace(trc);
         }
         for (Child *c = work.begin(); c != work.end(); ++c)
             gc::MarkGCThingRoot(trc, &c->cell, "HeapReverser::Child");
     }
 };
 
 bool
 HeapReverser::traverseEdge(void *cell, JSGCTraceKind kind)
@@ -276,17 +276,17 @@ HeapReverser::traverseEdge(void *cell, J
             !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(Move(e));
 }
 
 bool
 HeapReverser::reverseHeap()
 {
     traversalStatus = true;
 
     /* Prime the work stack with the roots of collection. */
@@ -422,17 +422,17 @@ ReferenceFinder::visit(void *cell, Path 
     JS_CHECK_RECURSION(context, return false);
 
     /* Have we reached a root? Always report that. */
     if (!cell)
         return addReferrer(JSVAL_NULL, path);
 
     HeapReverser::Map::Ptr p = reverser.map.lookup(cell);
     JS_ASSERT(p);
-    HeapReverser::Node *node = &p->value;
+    HeapReverser::Node *node = &p->value();
 
     /* Is |cell| a representable cell, reached via a non-empty path? */
     if (path != nullptr) {
         jsval representation = representable(cell, node->kind);
         if (!JSVAL_IS_VOID(representation))
             return addReferrer(representation, path);
     }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -206,17 +206,17 @@ class Debugger::FrameRange
     }
 
     bool empty() const {
         return nextDebugger >= debuggerCount;
     }
 
     JSObject *frontFrame() const {
         JS_ASSERT(!empty());
-        return entry->value;
+        return entry->value();
     }
 
     Debugger *frontDebugger() const {
         JS_ASSERT(!empty());
         return (*debuggers)[nextDebugger];
     }
 
     /*
@@ -463,17 +463,17 @@ Debugger::getScriptFrame(JSContext *cx, 
         frameobj->setPrivate(frame.raw());
         frameobj->setReservedSlot(JSSLOT_DEBUGFRAME_OWNER, ObjectValue(*object));
 
         if (!frames.add(p, frame, frameobj)) {
             js_ReportOutOfMemory(cx);
             return false;
         }
     }
-    vp.setObject(*p->value);
+    vp.setObject(*p->value());
     return true;
 }
 
 JSObject *
 Debugger::getHook(Hook hook) const
 {
     JS_ASSERT(hook >= 0 && hook < HookCount);
     const Value &v = object->getReservedSlot(JSSLOT_DEBUG_HOOK_START + hook);
@@ -496,17 +496,17 @@ Debugger::hasAnyLiveHooks() const
 
     /* If any breakpoints are in live scripts, return true. */
     for (Breakpoint *bp = firstBreakpoint(); bp; bp = bp->nextInDebugger()) {
         if (IsScriptMarked(&bp->site->script))
             return true;
     }
 
     for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) {
-        JSObject *frameObj = r.front().value;
+        JSObject *frameObj = r.front().value();
         if (!frameObj->getReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER).isUndefined() ||
             !frameObj->getReservedSlot(JSSLOT_DEBUGFRAME_ONPOP_HANDLER).isUndefined())
             return true;
     }
 
     return false;
 }
 
@@ -669,17 +669,17 @@ Debugger::wrapEnvironment(JSContext *cx,
      * DebuggerEnv should only wrap a debug scope chain obtained (transitively)
      * from GetDebugScopeFor(Frame|Function).
      */
     JS_ASSERT(!env->is<ScopeObject>());
 
     JSObject *envobj;
     DependentAddPtr<ObjectWeakMap> p(cx, environments, env);
     if (p) {
-        envobj = p->value;
+        envobj = p->value();
     } else {
         /* Create a new Debugger.Environment for env. */
         JSObject *proto = &object->getReservedSlot(JSSLOT_DEBUG_ENV_PROTO).toObject();
         envobj = NewObjectWithGivenProto(cx, &DebuggerEnv_class, proto, nullptr, TenuredObject);
         if (!envobj)
             return false;
         envobj->setPrivateGCThing(env);
         envobj->setReservedSlot(JSSLOT_DEBUGENV_OWNER, ObjectValue(*object));
@@ -710,17 +710,17 @@ Debugger::wrapDebuggeeValue(JSContext *c
         if (obj->is<JSFunction>()) {
             RootedFunction fun(cx, &obj->as<JSFunction>());
             if (!EnsureFunctionHasScript(cx, fun))
                 return false;
         }
 
         DependentAddPtr<ObjectWeakMap> p(cx, objects, obj);
         if (p) {
-            vp.setObject(*p->value);
+            vp.setObject(*p->value());
         } else {
             /* Create a new Debugger.Object for obj. */
             JSObject *proto = &object->getReservedSlot(JSSLOT_DEBUG_OBJECT_PROTO).toObject();
             JSObject *dobj =
                 NewObjectWithGivenProto(cx, &DebuggerObject_class, proto, nullptr, TenuredObject);
             if (!dobj)
                 return false;
             dobj->setPrivateGCThing(obj);
@@ -1262,18 +1262,18 @@ Debugger::onSingleStep(JSContext *cx, Mu
     {
         uint32_t stepperCount = 0;
         JSScript *trappingScript = iter.script();
         GlobalObject *global = cx->global();
         if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
             for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
                 Debugger *dbg = *p;
                 for (FrameMap::Range r = dbg->frames.all(); !r.empty(); r.popFront()) {
-                    AbstractFramePtr frame = r.front().key;
-                    JSObject *frameobj = r.front().value;
+                    AbstractFramePtr frame = r.front().key();
+                    JSObject *frameobj = r.front().value();
                     if (frame.script() == trappingScript &&
                         !frameobj->getReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER).isUndefined())
                     {
                         stepperCount++;
                     }
                 }
             }
         }
@@ -1589,17 +1589,17 @@ Debugger::trace(JSTracer *trc)
      * Mark Debugger.Frame objects. These are all reachable from JS, because the
      * corresponding StackFrames are still on the stack.
      *
      * (Once we support generator frames properly, we will need
      * weakly-referenced Debugger.Frame objects as well, for suspended generator
      * frames.)
      */
     for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) {
-        RelocatablePtrObject &frameobj = r.front().value;
+        RelocatablePtrObject &frameobj = r.front().value();
         JS_ASSERT(frameobj->getPrivate());
         MarkObject(trc, &frameobj, "live Debugger.Frame");
     }
 
     /* Trace the weak map from JSScript instances to Debugger.Script objects. */
     scripts.trace(trc);
 
     /* Trace the referent ->Debugger.Source weak map */
@@ -2267,19 +2267,19 @@ Debugger::removeDebuggeeGlobal(FreeOp *f
      * objects referring to a particular js::StackFrame. This is hard if
      * Debugger objects that are no longer debugging the relevant global might
      * have live Frame objects. So we take the easy way out and kill them here.
      * This is a bug, since it's observable and contrary to the spec. One
      * possible fix would be to put such objects into a compartment-wide bag
      * which slowPathOnLeaveFrame would have to examine.
      */
     for (FrameMap::Enum e(frames); !e.empty(); e.popFront()) {
-        AbstractFramePtr frame = e.front().key;
+        AbstractFramePtr frame = e.front().key();
         if (&frame.script()->global() == global) {
-            DebuggerFrame_freeScriptFrameIterData(fop, e.front().value);
+            DebuggerFrame_freeScriptFrameIterData(fop, e.front().value());
             e.removeFront();
         }
     }
 
     GlobalObject::DebuggerVector *v = global->getDebuggers();
     Debugger **p;
     for (p = v->begin(); p != v->end(); p++) {
         if (*p == this)
@@ -2449,17 +2449,17 @@ class Debugger::ScriptQuery {
          * them. But if this is an 'innermost' query, then we've accumulated the
          * results in the 'innermostForCompartment' map. In that case, we now need to
          * walk that map and populate 'vector'.
          */
         if (innermost) {
             for (CompartmentToScriptMap::Range r = innermostForCompartment.all();
                  !r.empty();
                  r.popFront()) {
-                if (!v->append(r.front().value)) {
+                if (!v->append(r.front().value())) {
                     js_ReportOutOfMemory(cx);
                     return false;
                 }
             }
         }
 
         return true;
     }
@@ -2594,19 +2594,19 @@ class Debugger::ScriptQuery {
              *
              * So: check this script against the innermost one we've found so
              * far (if any), as recorded in innermostForCompartment, and replace
              * that if it's better.
              */
             CompartmentToScriptMap::AddPtr p = innermostForCompartment.lookupForAdd(compartment);
             if (p) {
                 /* Is our newly found script deeper than the last one we found? */
-                JSScript *incumbent = p->value;
+                JSScript *incumbent = p->value();
                 if (script->staticLevel > incumbent->staticLevel)
-                    p->value = script;
+                    p->value() = script;
             } else {
                 /*
                  * This is the first matching script we've encountered for this
                  * compartment, so it is thus the innermost such script.
                  */
                 if (!innermostForCompartment.add(p, compartment, script)) {
                     oom = true;
                     return;
@@ -2813,18 +2813,18 @@ Debugger::wrapScript(JSContext *cx, Hand
         CrossCompartmentKey key(CrossCompartmentKey::DebuggerScript, object, script);
         if (!object->compartment()->putWrapper(key, ObjectValue(*scriptobj))) {
             scripts.remove(script);
             js_ReportOutOfMemory(cx);
             return nullptr;
         }
     }
 
-    JS_ASSERT(GetScriptReferent(p->value) == script);
-    return p->value;
+    JS_ASSERT(GetScriptReferent(p->value()) == script);
+    return p->value();
 }
 
 static JSObject *
 DebuggerScript_check(JSContext *cx, const Value &v, const char *clsname, const char *fnname)
 {
     if (!v.isObject()) {
         ReportObjectRequired(cx);
         return nullptr;
@@ -3706,18 +3706,18 @@ Debugger::wrapSource(JSContext *cx, Hand
         CrossCompartmentKey key(CrossCompartmentKey::DebuggerSource, object, source);
         if (!object->compartment()->putWrapper(key, ObjectValue(*sourceobj))) {
             sources.remove(source);
             js_ReportOutOfMemory(cx);
             return nullptr;
         }
     }
 
-    JS_ASSERT(GetSourceReferent(p->value) == source);
-    return p->value;
+    JS_ASSERT(GetSourceReferent(p->value()) == source);
+    return p->value();
 }
 
 static bool
 DebuggerSource_construct(JSContext *cx, unsigned argc, Value *vp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
                          "Debugger.Source");
     return false;
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -102,57 +102,57 @@ class DebuggerWeakMap : private WeakMap<
         JS_ASSERT(Base::has(l));
         Base::remove(l);
         decZoneCount(l->zone());
     }
 
   public:
     void markKeys(JSTracer *tracer) {
         for (Enum e(*static_cast<Base *>(this)); !e.empty(); e.popFront()) {
-            Key key = e.front().key;
+            Key key = e.front().key();
             gc::Mark(tracer, &key, "Debugger WeakMap key");
-            if (key != e.front().key)
+            if (key != e.front().key())
                 e.rekeyFront(key);
             key.unsafeSet(nullptr);
         }
     }
 
     bool hasKeyInZone(JS::Zone *zone) {
         CountMap::Ptr p = zoneCounts.lookup(zone);
-        JS_ASSERT_IF(p, p->value > 0);
+        JS_ASSERT_IF(p, p->value() > 0);
         return p;
     }
 
   private:
     /* Override sweep method to also update our edge cache. */
     void sweep() {
         for (Enum e(*static_cast<Base *>(this)); !e.empty(); e.popFront()) {
-            Key k(e.front().key);
+            Key k(e.front().key());
             if (gc::IsAboutToBeFinalized(&k)) {
                 e.removeFront();
                 decZoneCount(k->zone());
             }
         }
         Base::assertEntriesNotAboutToBeFinalized();
     }
 
     bool incZoneCount(JS::Zone *zone) {
         CountMap::Ptr p = zoneCounts.lookupWithDefault(zone, 0);
         if (!p)
             return false;
-        ++p->value;
+        ++p->value();
         return true;
     }
 
     void decZoneCount(JS::Zone *zone) {
         CountMap::Ptr p = zoneCounts.lookup(zone);
         JS_ASSERT(p);
-        JS_ASSERT(p->value > 0);
-        --p->value;
-        if (p->value == 0)
+        JS_ASSERT(p->value() > 0);
+        --p->value();
+        if (p->value() == 0)
             zoneCounts.remove(zone);
     }
 };
 
 /*
  * Env is the type of what ES5 calls "lexical environments" (runtime
  * activations of lexical scopes). This is currently just JSObject, and is
  * implemented by Call, Block, With, and DeclEnv objects, among others--but
--- a/js/src/vm/MemoryMetrics.cpp
+++ b/js/src/vm/MemoryMetrics.cpp
@@ -284,17 +284,17 @@ StatsCellCallback(JSRuntime *rt, void *d
         // profile speed for complex pages such as gmail.com.
         if (granularity == FineGrained) {
             ZoneStats::StringsHashMap::AddPtr p = zStats->strings.lookupForAdd(str);
             if (!p) {
                 JS::StringInfo info(str->length(), shortStringThingSize,
                                     normalStringThingSize, strCharsSize);
                 zStats->strings.add(p, str, info);
             } else {
-                p->value.add(shortStringThingSize, normalStringThingSize, strCharsSize);
+                p->value().add(shortStringThingSize, normalStringThingSize, strCharsSize);
             }
         }
 
         zStats->stringsShortGCHeap += shortStringThingSize;
         zStats->stringsNormalGCHeap += normalStringThingSize;
         zStats->stringsNormalMallocHeap += strCharsSize;
 
         break;
@@ -388,18 +388,18 @@ FindNotableStrings(ZoneStats &zStats)
 
     // You should only run FindNotableStrings once per ZoneStats object
     // (although it's not going to break anything if you run it more than once,
     // unless you add to |strings| in the meantime).
     MOZ_ASSERT(zStats.notableStrings.empty());
 
     for (ZoneStats::StringsHashMap::Range r = zStats.strings.all(); !r.empty(); r.popFront()) {
 
-        JSString *str = r.front().key;
-        StringInfo &info = r.front().value;
+        JSString *str = r.front().key();
+        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() = NotableStringInfo(str, info);
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -664,17 +664,17 @@ RegExpCompartment::init(JSContext *cx)
 }
 
 /* See the comment on RegExpShared lifetime in RegExpObject.h. */
 void
 RegExpCompartment::sweep(JSRuntime *rt)
 {
 #ifdef DEBUG
     for (Map::Range r = map_.all(); !r.empty(); r.popFront())
-        JS_ASSERT(inUse_.has(r.front().value));
+        JS_ASSERT(inUse_.has(r.front().value()));
 #endif
 
     map_.clear();
 
     for (PendingSet::Enum e(inUse_); !e.empty(); e.popFront()) {
         RegExpShared *shared = e.front();
         if (shared->activeUseCount == 0 && shared->gcNumberWhenUsed < rt->gcStartNumber) {
             js_delete(shared);
@@ -691,17 +691,17 @@ RegExpCompartment::clearTables()
 }
 
 bool
 RegExpCompartment::get(ExclusiveContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g)
 {
     Key key(source, flags);
     Map::AddPtr p = map_.lookupForAdd(key);
     if (p) {
-        g->init(*p->value);
+        g->init(*p->value());
         return true;
     }
 
     uint64_t gcNumber = cx->zone()->gcNumber();
     ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags, gcNumber));
     if (!shared)
         return false;
 
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -28,17 +28,17 @@ SPSProfiler::SPSProfiler(JSRuntime *rt)
 {
     JS_ASSERT(rt != nullptr);
 }
 
 SPSProfiler::~SPSProfiler()
 {
     if (strings.initialized()) {
         for (ProfileStringMap::Enum e(strings); !e.empty(); e.popFront())
-            js_free(const_cast<char *>(e.front().value));
+            js_free(const_cast<char *>(e.front().value()));
     }
 }
 
 void
 SPSProfiler::setProfilingStack(ProfileEntry *stack, uint32_t *size, uint32_t max)
 {
     JS_ASSERT_IF(size_ && *size_ != 0, !enabled());
     if (!strings.initialized())
@@ -75,17 +75,17 @@ SPSProfiler::enable(bool enabled)
 
 /* Lookup the string for the function/script, creating one if necessary */
 const char*
 SPSProfiler::profileString(JSContext *cx, JSScript *script, JSFunction *maybeFun)
 {
     JS_ASSERT(strings.initialized());
     ProfileStringMap::AddPtr s = strings.lookupForAdd(script);
     if (s)
-        return s->value;
+        return s->value();
     const char *str = allocProfileString(cx, script, maybeFun);
     if (str == nullptr)
         return nullptr;
     if (!strings.add(s, script, str)) {
         js_free(const_cast<char *>(str));
         return nullptr;
     }
     return str;
@@ -99,17 +99,17 @@ SPSProfiler::onScriptFinalized(JSScript 
      * whether profiling has been turned on, so don't invoke a function on an
      * invalid hash set. Also, even if profiling was enabled but then turned
      * off, we still want to remove the string, so no check of enabled() is
      * done.
      */
     if (!strings.initialized())
         return;
     if (ProfileStringMap::Ptr entry = strings.lookup(script)) {
-        const char *tofree = entry->value;
+        const char *tofree = entry->value();
         strings.remove(entry);
         js_free(const_cast<char *>(tofree));
     }
 }
 
 bool
 SPSProfiler::enter(JSContext *cx, JSScript *script, JSFunction *maybeFun)
 {
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -89,17 +89,17 @@ js::ScopeCoordinateName(ScopeCoordinateN
             }
         }
     }
 
     jsid id;
     ScopeCoordinate sc(pc);
     if (shape == cache.shape) {
         ScopeCoordinateNameCache::Map::Ptr p = cache.map.lookup(sc.slot);
-        id = p->value;
+        id = p->value();
     } else {
         Shape::Range<NoGC> r(shape);
         while (r.front().slot() != sc.slot)
             r.popFront();
         id = r.front().propid();
     }
 
     /* Beware nameless destructuring formal. */
@@ -1587,23 +1587,23 @@ void
 DebugScopes::sweep(JSRuntime *rt)
 {
     /*
      * Note: missingScopes points to debug scopes weakly not just so that debug
      * scopes can be released more eagerly, but, more importantly, to avoid
      * creating an uncollectable cycle with suspended generator frames.
      */
     for (MissingScopeMap::Enum e(missingScopes); !e.empty(); e.popFront()) {
-        if (IsObjectAboutToBeFinalized(e.front().value.unsafeGet()))
+        if (IsObjectAboutToBeFinalized(e.front().value().unsafeGet()))
             e.removeFront();
     }
 
     for (LiveScopeMap::Enum e(liveScopes); !e.empty(); e.popFront()) {
-        ScopeObject *scope = e.front().key;
-        AbstractFramePtr frame = e.front().value;
+        ScopeObject *scope = e.front().key();
+        AbstractFramePtr frame = e.front().value();
 
         /*
          * Scopes can be finalized when a debugger-synthesized ScopeObject is
          * no longer reachable via its DebugScopeObject.
          */
         if (IsObjectAboutToBeFinalized(&scope)) {
             e.removeFront();
             continue;
@@ -1656,17 +1656,17 @@ DebugScopeObject *
 DebugScopes::hasDebugScope(JSContext *cx, ScopeObject &scope)
 {
     DebugScopes *scopes = scope.compartment()->debugScopes;
     if (!scopes)
         return nullptr;
 
     if (ObjectWeakMap::Ptr p = scopes->proxiedScopes.lookup(&scope)) {
         JS_ASSERT(CanUseDebugScopeMaps(cx));
-        return &p->value->as<DebugScopeObject>();
+        return &p->value()->as<DebugScopeObject>();
     }
 
     return nullptr;
 }
 
 bool
 DebugScopes::addDebugScope(JSContext *cx, ScopeObject &scope, DebugScopeObject &debugScope)
 {
@@ -1696,17 +1696,17 @@ DebugScopes::hasDebugScope(JSContext *cx
     JS_ASSERT(!si.hasScopeObject());
 
     DebugScopes *scopes = cx->compartment()->debugScopes;
     if (!scopes)
         return nullptr;
 
     if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
         JS_ASSERT(CanUseDebugScopeMaps(cx));
-        return p->value;
+        return p->value();
     }
     return nullptr;
 }
 
 bool
 DebugScopes::addDebugScope(JSContext *cx, const ScopeIter &si, DebugScopeObject &debugScope)
 {
     JS_ASSERT(!si.hasScopeObject());
@@ -1753,21 +1753,21 @@ DebugScopes::onPopCall(AbstractFramePtr 
          * CallObject. See ScopeIter::settle.
          */
         if (!frame.hasCallObj())
             return;
 
         CallObject &callobj = frame.scopeChain()->as<CallObject>();
         scopes->liveScopes.remove(&callobj);
         if (ObjectWeakMap::Ptr p = scopes->proxiedScopes.lookup(&callobj))
-            debugScope = &p->value->as<DebugScopeObject>();
+            debugScope = &p->value()->as<DebugScopeObject>();
     } else {
         ScopeIter si(frame, cx);
         if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
-            debugScope = p->value;
+            debugScope = p->value();
             scopes->liveScopes.remove(&debugScope->scope().as<CallObject>());
             scopes->missingScopes.remove(p);
         }
     }
 
     /*
      * When the StackFrame is popped, the values of unaliased variables
      * are lost. If there is any debug scope referring to this scope, save a
@@ -1826,17 +1826,17 @@ DebugScopes::onPopBlock(JSContext *cx, A
     StaticBlockObject &staticBlock = *frame.maybeBlockChain();
     if (staticBlock.needsClone()) {
         ClonedBlockObject &clone = frame.scopeChain()->as<ClonedBlockObject>();
         clone.copyUnaliasedValues(frame);
         scopes->liveScopes.remove(&clone);
     } else {
         ScopeIter si(frame, cx);
         if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
-            ClonedBlockObject &clone = p->value->scope().as<ClonedBlockObject>();
+            ClonedBlockObject &clone = p->value()->scope().as<ClonedBlockObject>();
             clone.copyUnaliasedValues(frame);
             scopes->liveScopes.remove(&clone);
             scopes->missingScopes.remove(p);
         }
     }
 }
 
 void
@@ -1876,27 +1876,27 @@ DebugScopes::onGeneratorFrameChange(Abst
              * mappings [scope -> to], but we must add [scope -> to] if it
              * doesn't already exist so that if we need to proxy a generator's
              * scope while it is suspended, we can find its frame (which would
              * otherwise not be found by AllFramesIter).
              */
             JS_ASSERT(toIter.scope().compartment() == cx->compartment());
             LiveScopeMap::AddPtr livePtr = scopes->liveScopes.lookupForAdd(&toIter.scope());
             if (livePtr) {
-                livePtr->value = to;
+                livePtr->value() = to;
             } else {
                 scopes->liveScopes.add(livePtr, &toIter.scope(), to);  // OOM here?
                 liveScopesPostWriteBarrier(cx->runtime(), &scopes->liveScopes, &toIter.scope());
             }
         } else {
             ScopeIter si(toIter, from, cx);
             JS_ASSERT(si.frame().scopeChain()->compartment() == cx->compartment());
             if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
-                DebugScopeObject &debugScope = *p->value;
-                scopes->liveScopes.lookup(&debugScope.scope())->value = to;
+                DebugScopeObject &debugScope = *p->value();
+                scopes->liveScopes.lookup(&debugScope.scope())->value() = to;
                 scopes->missingScopes.remove(p);
                 scopes->missingScopes.put(toIter, &debugScope);  // OOM here?
             }
         }
     }
 }
 
 void
@@ -1962,17 +1962,17 @@ DebugScopes::updateLiveScopes(JSContext 
 AbstractFramePtr
 DebugScopes::hasLiveFrame(ScopeObject &scope)
 {
     DebugScopes *scopes = scope.compartment()->debugScopes;
     if (!scopes)
         return NullFramePtr();
 
     if (LiveScopeMap::Ptr p = scopes->liveScopes.lookup(&scope)) {
-        AbstractFramePtr frame = p->value;
+        AbstractFramePtr frame = p->value();
 
         /*
          * Since liveScopes is effectively a weak pointer, we need a read
          * barrier. The scenario where this is necessary is:
          *  1. GC starts, a suspended generator is not live
          *  2. hasLiveFrame returns a StackFrame* to the (soon to be dead)
          *     suspended generator
          *  3. stack frame values (which will neve be marked) are read from the
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -886,17 +886,17 @@ GetObjectAllocKindForClone(JSRuntime *rt
     return kind;
 }
 
 static JSObject *
 CloneObject(JSContext *cx, HandleObject srcObj, CloneMemory &clonedObjects)
 {
     DependentAddPtr<CloneMemory> p(cx, clonedObjects, srcObj.get());
     if (p)
-        return p->value;
+        return p->value();
     RootedObject clone(cx);
     if (srcObj->is<JSFunction>()) {
         if (srcObj->as<JSFunction>().isWrappable()) {
             clone = srcObj;
             if (!cx->compartment()->wrap(cx, &clone))
                 return nullptr;
         } else {
             RootedFunction fun(cx, &srcObj->as<JSFunction>());
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -824,17 +824,17 @@ JSStructuredCloneWriter::writeArrayBuffe
 }
 
 bool
 JSStructuredCloneWriter::startObject(HandleObject obj, bool *backref)
 {
     /* Handle cycles in the object graph. */
     CloneMemory::AddPtr p = memory.lookupForAdd(obj);
     if ((*backref = p))
-        return out.writePair(SCTAG_BACK_REFERENCE_OBJECT, p->value);
+        return out.writePair(SCTAG_BACK_REFERENCE_OBJECT, p->value());
     if (!memory.add(p, obj, memory.count()))
         return false;
 
     if (memory.count() == UINT32_MAX) {
         JS_ReportErrorNumber(context(), js_GetErrorMessage, nullptr,
                              JSMSG_NEED_DIET, "object graph to serialize");
         return false;
     }
--- a/js/xpconnect/src/XPCMaps.cpp
+++ b/js/xpconnect/src/XPCMaps.cpp
@@ -80,33 +80,33 @@ HashNativeKey(PLDHashTable *table, const
 
 /***************************************************************************/
 // implement JSObject2WrappedJSMap...
 
 void
 JSObject2WrappedJSMap::FindDyingJSObjects(nsTArray<nsXPCWrappedJS*>* dying)
 {
     for (Map::Range r = mTable.all(); !r.empty(); r.popFront()) {
-        nsXPCWrappedJS* wrapper = r.front().value;
+        nsXPCWrappedJS* wrapper = r.front().value();
         MOZ_ASSERT(wrapper, "found a null JS wrapper!");
 
         // walk the wrapper chain and find any whose JSObject is to be finalized
         while (wrapper) {
             if (wrapper->IsSubjectToFinalization() && wrapper->IsObjectAboutToBeFinalized())
                 dying->AppendElement(wrapper);
             wrapper = wrapper->GetNextWrapper();
         }
     }
 }
 
 void
 JSObject2WrappedJSMap::ShutdownMarker()
 {
     for (Map::Range r = mTable.all(); !r.empty(); r.popFront()) {
-        nsXPCWrappedJS* wrapper = r.front().value;
+        nsXPCWrappedJS* wrapper = r.front().value();
         MOZ_ASSERT(wrapper, "found a null JS wrapper!");
         MOZ_ASSERT(wrapper->IsValid(), "found an invalid JS wrapper!");
         wrapper->SystemIsBeingShutDown();
     }
 }
 
 /***************************************************************************/
 // implement Native2WrappedNativeMap...
--- a/js/xpconnect/src/XPCMaps.h
+++ b/js/xpconnect/src/XPCMaps.h
@@ -36,41 +36,41 @@ public:
             return map;
         delete map;
         return nullptr;
     }
 
     inline nsXPCWrappedJS* Find(JSObject* Obj) {
         NS_PRECONDITION(Obj,"bad param");
         Map::Ptr p = mTable.lookup(Obj);
-        return p ? p->value : nullptr;
+        return p ? p->value() : nullptr;
     }
 
     inline nsXPCWrappedJS* Add(JSContext* cx, nsXPCWrappedJS* wrapper) {
         NS_PRECONDITION(wrapper,"bad param");
         JSObject* obj = wrapper->GetJSObjectPreserveColor();
         Map::AddPtr p = mTable.lookupForAdd(obj);
         if (p)
-            return p->value;
+            return p->value();
         if (!mTable.add(p, obj, wrapper))
             return nullptr;
         JS_StoreObjectPostBarrierCallback(cx, KeyMarkCallback, obj, this);
         return wrapper;
     }
 
     inline void Remove(nsXPCWrappedJS* wrapper) {
         NS_PRECONDITION(wrapper,"bad param");
         mTable.remove(wrapper->GetJSObjectPreserveColor());
     }
 
     inline uint32_t Count() {return mTable.count();}
 
     inline void Dump(int16_t depth) {
         for (Map::Range r = mTable.all(); !r.empty(); r.popFront())
-            r.front().value->DebugDump(depth);
+            r.front().value()->DebugDump(depth);
     }
 
     void FindDyingJSObjects(nsTArray<nsXPCWrappedJS*>* dying);
 
     void ShutdownMarker();
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) {
         size_t n = mallocSizeOf(this);
@@ -629,63 +629,63 @@ public:
             return map;
         delete map;
         return nullptr;
     }
 
     inline JSObject* Find(JSObject* key) {
         NS_PRECONDITION(key, "bad param");
         if (Map::Ptr p = mTable.lookup(key))
-            return p->value;
+            return p->value();
         return nullptr;
     }
 
     /* Note: If the entry already exists, return the old value. */
     inline JSObject* Add(JSContext *cx, JSObject *key, JSObject *value) {
         NS_PRECONDITION(key,"bad param");
         Map::AddPtr p = mTable.lookupForAdd(key);
         if (p)
-            return p->value;
+            return p->value();
         if (!mTable.add(p, key, value))
             return nullptr;
         MOZ_ASSERT(xpc::GetCompartmentPrivate(key)->scope->mWaiverWrapperMap == this);
         JS_StoreObjectPostBarrierCallback(cx, KeyMarkCallback, key, this);
         return value;
     }
 
     inline void Remove(JSObject* key) {
         NS_PRECONDITION(key,"bad param");
         mTable.remove(key);
     }
 
     inline uint32_t Count() { return mTable.count(); }
 
     void Sweep() {
         for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
-            JSObject *updated = e.front().key;
-            if (JS_IsAboutToBeFinalizedUnbarriered(&updated) || JS_IsAboutToBeFinalized(&e.front().value))
+            JSObject *updated = e.front().key();
+            if (JS_IsAboutToBeFinalizedUnbarriered(&updated) || JS_IsAboutToBeFinalized(&e.front().value()))
                 e.removeFront();
-            else if (updated != e.front().key)
+            else if (updated != e.front().key())
                 e.rekeyFront(updated);
         }
     }
 
     void Reparent(JSContext *aCx, JSObject *aNewInnerArg) {
         JS::RootedObject aNewInner(aCx, aNewInnerArg);
         for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
             /*
              * We reparent wrappers that have as their parent an inner window
              * whose outer has the new inner window as its current inner.
              */
-            JS::RootedObject parent(aCx, JS_GetParent(e.front().value));
+            JS::RootedObject parent(aCx, JS_GetParent(e.front().value()));
             JS::RootedObject outer(aCx, JS_ObjectToOuterObject(aCx, parent));
             if (outer) {
                 JSObject *inner = JS_ObjectToInnerObject(aCx, outer);
                 if (inner == aNewInner && inner != parent)
-                    JS_SetParent(aCx, e.front().value, aNewInner);
+                    JS_SetParent(aCx, e.front().value(), aNewInner);
             } else {
                 JS_ClearPendingException(aCx);
             }
         }
     }
 
 private:
     JSObject2JSObjectMap() {}
--- a/layout/style/nsNthIndexCache.cpp
+++ b/layout/style/nsNthIndexCache.cpp
@@ -43,17 +43,17 @@ nsNthIndexCache::IndexDeterminedFromPrev
                                                     bool aIsOfType,
                                                     bool aIsFromEnd,
                                                     const Cache& aCache,
                                                     int32_t& aResult)
 {
   if (SiblingMatchesElement(aSibling, aChild, aIsOfType)) {
     Cache::Ptr siblingEntry = aCache.lookup(aSibling);
     if (siblingEntry) {
-      int32_t siblingIndex = siblingEntry->value;
+      int32_t siblingIndex = siblingEntry->value();
       NS_ASSERTION(siblingIndex != 0,
                    "How can a non-anonymous node have an anonymous sibling?");
       if (siblingIndex > 0) {
         // At this point, aResult is a count of how many elements matching
         // aChild we have seen after aSibling, including aChild itself.
         // |siblingIndex| is the index of aSibling.
         // So if aIsFromEnd, we want |aResult = siblingIndex - aResult| and
         // otherwise we want |aResult = siblingIndex + aResult|.
@@ -88,17 +88,17 @@ nsNthIndexCache::GetNthIndex(Element* aC
   Cache::AddPtr entry = cache.lookupForAdd(aChild);
 
   // Default the value to -2 when adding
   if (!entry && !cache.add(entry, aChild, -2)) {
     // No good; don't match.
     return 0;
   }
 
-  int32_t &slot = entry->value;
+  int32_t &slot = entry->value();
   if (slot != -2 && (slot != -1 || aCheckEdgeOnly)) {
     return slot;
   }
   
   int32_t result = 1;
   if (aCheckEdgeOnly) {
     // The caller only cares whether or not the result is 1, so we can
     // stop as soon as we see any other elements that match us.