diff --git a/js/public/GCHashTable.h b/js/public/GCHashTable.h index e55db4d94d6e..c826aeb9b7a8 100644 --- a/js/public/GCHashTable.h +++ b/js/public/GCHashTable.h @@ -149,7 +149,6 @@ class GCHashMapOperations bool empty() const { return map().empty(); } uint32_t count() const { return map().count(); } size_t capacity() const { return map().capacity(); } - uint32_t generation() const { return map().generation(); } bool has(const Lookup& l) const { return map().lookup(l).found(); } }; @@ -288,7 +287,6 @@ class GCHashSetOperations bool empty() const { return set().empty(); } uint32_t count() const { return set().count(); } size_t capacity() const { return set().capacity(); } - uint32_t generation() const { return set().generation(); } bool has(const Lookup& l) const { return set().lookup(l).found(); } }; diff --git a/js/public/HashTable.h b/js/public/HashTable.h index bf137a482f5c..11745d49a6aa 100644 --- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -14,6 +14,7 @@ #include "mozilla/HashFunctions.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Move.h" +#include "mozilla/Opaque.h" #include "mozilla/PodOperations.h" #include "mozilla/ReentrancyGuard.h" #include "mozilla/TemplateLib.h" @@ -34,6 +35,8 @@ namespace detail { /*****************************************************************************/ +using Generation = mozilla::Opaque; + // A JS-friendly, STL-like container providing a hash-based map from keys to // values. In particular, HashMap calls constructors and destructors of all // objects added so non-PODs may be used safely. @@ -208,7 +211,9 @@ class HashMap // If |generation()| is the same before and after a HashMap operation, // pointers into the table remain valid. - uint32_t generation() const { return impl.generation(); } + Generation generation() const { + return impl.generation(); + } /************************************************** Shorthand operations */ @@ -446,7 +451,9 @@ class HashSet // If |generation()| is the same before and after a HashSet operation, // pointers into the table remain valid. - uint32_t generation() const { return impl.generation(); } + Generation generation() const { + return impl.generation(); + } /************************************************** Shorthand operations */ @@ -819,7 +826,7 @@ class HashTable : private AllocPolicy Entry* entry_; #ifdef JS_DEBUG const HashTable* table_; - uint32_t generation; + Generation generation; #endif protected: @@ -927,7 +934,7 @@ class HashTable : private AllocPolicy #ifdef JS_DEBUG const HashTable* table_; uint64_t mutationCount; - uint32_t generation; + Generation generation; bool validEntry; #endif @@ -1076,9 +1083,9 @@ class HashTable : private AllocPolicy static const size_t CAP_BITS = 30; public: - Entry* table; // entry storage - uint32_t gen:24; // entry storage generation number - uint32_t hashShift:8; // multiplicative hash shift + uint64_t gen:56; // entry storage generation number + uint64_t hashShift:8; // multiplicative hash shift + Entry* table; // entry storage uint32_t entryCount; // number of entries in table uint32_t removedCount; // removed entry sentinels in table @@ -1175,9 +1182,9 @@ class HashTable : private AllocPolicy public: explicit HashTable(AllocPolicy ap) : AllocPolicy(ap) - , table(nullptr) , gen(0) , hashShift(sHashBits) + , table(nullptr) , entryCount(0) , removedCount(0) #ifdef JS_DEBUG @@ -1616,10 +1623,10 @@ class HashTable : private AllocPolicy return JS_BIT(sHashBits - hashShift); } - uint32_t generation() const + Generation generation() const { MOZ_ASSERT(table); - return gen; + return Generation(gen); } size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 77e32fdf91f2..5a3a5b505b2d 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -700,10 +700,10 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, JSObject* ExpandoAndGeneration* expandoAndGeneration = (ExpandoAndGeneration*)expandoVal.toPrivate(); masm.movePtr(ImmPtr(expandoAndGeneration), tempVal.scratchReg()); - masm.branch32(Assembler::NotEqual, + masm.branch64(Assembler::NotEqual, Address(tempVal.scratchReg(), ExpandoAndGeneration::offsetOfGeneration()), - Imm32(expandoAndGeneration->generation), + Imm64(expandoAndGeneration->generation), &failDOMProxyCheck); expandoVal = expandoAndGeneration->expando; diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index b023fd65be3f..579d4861c0c2 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -823,6 +823,13 @@ class MacroAssembler : public MacroAssemblerSpecific inline void branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, Label* label) DEFINED_ON(arm, arm64, mips_shared, x86, x64); + inline void branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) PER_ARCH; + + // Compare the value at |lhs| with the value at |rhs|. The scratch + // register *must not* be the base of |lhs| or |rhs|. + inline void branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) PER_ARCH; + inline void branchPtr(Condition cond, Register lhs, Register rhs, Label* label) PER_SHARED_ARCH; inline void branchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label) PER_SHARED_ARCH; inline void branchPtr(Condition cond, Register lhs, ImmPtr rhs, Label* label) PER_SHARED_ARCH; diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 4116430feb58..4f852313c5ac 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -8,6 +8,7 @@ #include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/SizePrintfMacros.h" #include "jslibmath.h" @@ -2177,10 +2178,10 @@ UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback* stub, iter->toGetProp_CallDOMProxyWithGenerationNative(); if (updateStub->expandoAndGeneration() == expandoAndGeneration) { // Update generation - uint32_t generation = expandoAndGeneration->generation; + uint64_t generation = expandoAndGeneration->generation; JitSpew(JitSpew_BaselineIC, " Updating existing stub with generation, old value: %i, " - "new value: %i", updateStub->generation(), + "new value: %" PRIu64 "", updateStub->generation(), generation); updateStub->setGeneration(generation); return true; @@ -3566,9 +3567,9 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register masm.branchPrivatePtr(Assembler::NotEqual, expandoAddr, tempVal.scratchReg(), &failDOMProxyCheck); - masm.load32(*generationAddr, scratch); - masm.branch32(Assembler::NotEqual, - Address(tempVal.scratchReg(), offsetof(ExpandoAndGeneration, generation)), + masm.branch64(Assembler::NotEqual, + Address(tempVal.scratchReg(), ExpandoAndGeneration::offsetOfGeneration()), + *generationAddr, scratch, &failDOMProxyCheck); masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal); @@ -3696,7 +3697,7 @@ ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace* space) Value expandoSlot = GetProxyExtra(proxy_, GetDOMProxyExpandoSlot()); RootedShape expandoShape(cx, nullptr); ExpandoAndGeneration* expandoAndGeneration; - int32_t generation; + uint64_t generation; Value expandoVal; if (kind == ICStub::GetProp_CallDOMProxyNative) { expandoVal = expandoSlot; diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h index e4e2a03024df..b574a831ba55 100644 --- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -3103,13 +3103,13 @@ class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyN { protected: ExpandoAndGeneration* expandoAndGeneration_; - uint32_t generation_; + uint64_t generation_; public: ICGetProp_CallDOMProxyWithGenerationNative(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape, ExpandoAndGeneration* expandoAndGeneration, - uint32_t generation, Shape* expandoShape, + uint64_t generation, Shape* expandoShape, JSObject* holder, Shape* holderShape, JSFunction* getter, uint32_t pcOffset) : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative, @@ -3127,11 +3127,11 @@ class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyN void* expandoAndGeneration() const { return expandoAndGeneration_; } - uint32_t generation() const { + uint64_t generation() const { return generation_; } - void setGeneration(uint32_t value) { + void setGeneration(uint64_t value) { generation_ = value; } diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index 2ab605134fa2..062cccf6de15 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -1136,6 +1136,18 @@ class Operand } }; +inline Imm32 +Imm64::firstHalf() const +{ + return low(); +} + +inline Imm32 +Imm64::secondHalf() const +{ + return hi(); +} + void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect = DontReprotect); diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 21925cf0a3eb..1203c3be62e5 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -515,6 +515,32 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L branch32(cond, scratch, rhs, label); } +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branch32(cond, lhs, val.firstHalf(), label); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + load32(rhs, scratch); + branch32(cond, lhs, scratch, label); + + load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label); +} + void MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, Label* label) { diff --git a/js/src/jit/arm64/Assembler-arm64.h b/js/src/jit/arm64/Assembler-arm64.h index cddc976aa8f5..514807b17042 100644 --- a/js/src/jit/arm64/Assembler-arm64.h +++ b/js/src/jit/arm64/Assembler-arm64.h @@ -502,6 +502,18 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out) return true; } +inline Imm32 +Imm64::firstHalf() const +{ + return low(); +} + +inline Imm32 +Imm64::secondHalf() const +{ + return hi(); +} + void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect = DontReprotect); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index f0314757e553..2ccc1d4fdaca 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -560,6 +560,27 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L branch32(cond, Address(scratch, 0), rhs, label); } +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branchPtr(cond, lhs, ImmWord(val.value), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + loadPtr(rhs, scratch); + branchPtr(cond, lhs, scratch, label); +} void MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, Label* label) { diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index c20847531209..96eb4b5edcf1 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -636,6 +636,18 @@ class Operand } }; +inline Imm32 +Imm64::firstHalf() const +{ + return low(); +} + +inline Imm32 +Imm64::secondHalf() const +{ + return hi(); +} + void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect = DontReprotect); diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 9bb6b828c716..18c4b18bb97d 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -268,6 +268,32 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) // =============================================================== // Branch functions +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branch32(cond, lhs, val.firstHalf(), label); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + load32(rhs, scratch); + branch32(cond, lhs, scratch, label); + + load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label); +} + void MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index b3f26bf30e1a..14ee80f9f9b4 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -207,6 +207,28 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) // =============================================================== // Branch functions +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branchPtr(cond, lhs, ImmWord(val.value), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + loadPtr(rhs, scratch); + branchPtr(cond, lhs, scratch, label); +} + void MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label) { diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index 94f42210fdf1..c3b213f66e59 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -133,6 +133,17 @@ struct Imm64 explicit Imm64(uint64_t value) : value(value) { } + + Imm32 low() const { + return Imm32(int32_t(value)); + } + + Imm32 hi() const { + return Imm32(int32_t(value >> 32)); + } + + inline Imm32 firstHalf() const; + inline Imm32 secondHalf() const; }; #ifdef DEBUG diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index 5dd9ea5148b4..cffef89d41d9 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -307,6 +307,28 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L branch32(cond, Address(scratch, 0), rhs, label); } +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branchPtr(cond, lhs, ImmWord(val.value), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + loadPtr(rhs, scratch); + branchPtr(cond, lhs, scratch, label); +} + void MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label) { diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h index af6835afda29..968d58076ae1 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -173,6 +173,18 @@ class Operand } }; +inline Imm32 +Imm64::firstHalf() const +{ + return low(); +} + +inline Imm32 +Imm64::secondHalf() const +{ + return hi(); +} + class CPUInfo { public: diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index b7b116c5d03f..7cc6c2dd4d94 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -308,6 +308,32 @@ MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, L j(cond, label); } +void +MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + + branch32(cond, lhs, val.firstHalf(), label); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label); +} + +void +MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch, + Label* label) +{ + MOZ_ASSERT(cond == Assembler::NotEqual, + "other condition codes not supported"); + MOZ_ASSERT(lhs.base != scratch); + MOZ_ASSERT(rhs.base != scratch); + + load32(rhs, scratch); + branch32(cond, lhs, scratch, label); + + load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch); + branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label); +} + void MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label) { diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 96a077bf7d1e..3b3975d937ec 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -308,10 +308,6 @@ class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter return map.sizeOfIncludingThis(mallocSizeOf); } - uint32_t generation() const { - return map.generation(); - } - /************************************************** Shorthand operations */ bool has(const Lookup& l) const { @@ -423,10 +419,6 @@ class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter return set.sizeOfIncludingThis(mallocSizeOf); } - uint32_t generation() const { - return set.generation(); - } - /************************************************** Shorthand operations */ bool has(const Lookup& l) const { diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index fd364201859e..a4b6f45aecd7 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -51,11 +51,11 @@ class MOZ_RAII AutoCycleDetector bool foundCycle() { return cyclic; } private: + Generation hashsetGenerationAtInit; JSContext* cx; RootedObject obj; - bool cyclic; - uint32_t hashsetGenerationAtInit; Set::AddPtr hashsetAddPointer; + bool cyclic; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index dfa77a58ba8a..55a795303633 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -1219,7 +1219,7 @@ NukeCrossCompartmentWrappers(JSContext* cx, * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot * should contain a private pointer to a ExpandoAndGeneration, which contains * a JS::Value that should either be undefined or point to an expando object, - * and a uint32 value. If that value changes then the IC for getting a + * and a uint64 value. If that value changes then the IC for getting a * property will be invalidated. * * If Shadows is returned, that means the property is an own property of the * proxy but doesn't live on the expando object. @@ -1248,7 +1248,7 @@ struct ExpandoAndGeneration { } JS::Heap expando; - uint32_t generation; + uint64_t generation; }; typedef enum DOMProxyShadowsResult { diff --git a/js/src/jswatchpoint.cpp b/js/src/jswatchpoint.cpp index 2321fadf84eb..9713ebe59908 100644 --- a/js/src/jswatchpoint.cpp +++ b/js/src/jswatchpoint.cpp @@ -27,15 +27,15 @@ namespace { class AutoEntryHolder { typedef WatchpointMap::Map Map; + Generation gen; 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) + : gen(map.generation()), map(map), p(p), obj(cx, p->key().object), id(cx, p->key().id) { MOZ_ASSERT(!p->value().held); p->value().held = true; diff --git a/js/src/vm/UbiNodeCensus.cpp b/js/src/vm/UbiNodeCensus.cpp index 85dfe80810ff..197db246a01c 100644 --- a/js/src/vm/UbiNodeCensus.cpp +++ b/js/src/vm/UbiNodeCensus.cpp @@ -733,7 +733,7 @@ ByAllocationStack::report(JSContext* cx, CountBase& countBase, MutableHandleValu #ifdef DEBUG // Check that nothing rehashes our table while we hold pointers into it. - uint32_t generation = count.table.generation(); + Generation generation = count.table.generation(); #endif // Build a vector of pointers to entries; sort by total; and then use diff --git a/mfbt/Opaque.h b/mfbt/Opaque.h new file mode 100644 index 000000000000..d7239ee7c23e --- /dev/null +++ b/mfbt/Opaque.h @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* An opaque integral type supporting only comparison operators. */ + +#ifndef mozilla_Opaque_h +#define mozilla_Opaque_h + +#include "mozilla/TypeTraits.h" + +namespace mozilla { + +/** + * Opaque is a replacement for integral T in cases where only comparisons + * must be supported, and it's desirable to prevent accidental dependency on + * exact values. + */ +template +class Opaque final +{ + static_assert(mozilla::IsIntegral::value, + "mozilla::Opaque only supports integral types"); + + T mValue; + +public: + Opaque() {} + explicit Opaque(T aValue) : mValue(aValue) {} + + bool operator==(const Opaque& aOther) const { + return mValue == aOther.mValue; + } + + bool operator!=(const Opaque& aOther) const { + return !(*this == aOther); + } +}; + +} // namespace mozilla + +#endif /* mozilla_Opaque_h */ diff --git a/mfbt/moz.build b/mfbt/moz.build index 38d424dd2edf..710e2c86266d 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -61,6 +61,7 @@ EXPORTS.mozilla = [ 'Move.h', 'NullPtr.h', 'NumericLimits.h', + 'Opaque.h', 'Pair.h', 'PodOperations.h', 'Poison.h',