diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-03-23 17:01:11 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-03-23 17:01:11 -0400 |
commit | f27a5631a6cb48d3e4a2b2888ede44edf66960cd (patch) | |
tree | a7e0501982b15a1d71b2fa1a8d73ce13aba9274f | |
parent | cb4b8b622f30e4ffdaec101c70b2ab4438d3567a (diff) | |
download | mongo-f27a5631a6cb48d3e4a2b2888ede44edf66960cd.tar.gz |
Revert "SERVER-28400 Firefox ESR 45.8.0"
This reverts commit 41d56f108e341c88fe26632084d6140ea75813c0.
89 files changed, 811 insertions, 1588 deletions
diff --git a/src/third_party/mozjs-45/SConscript b/src/third_party/mozjs-45/SConscript index 4e9a8b07f9c..dae5ab61ccb 100644 --- a/src/third_party/mozjs-45/SConscript +++ b/src/third_party/mozjs-45/SConscript @@ -91,7 +91,6 @@ env.Prepend(CPPPATH=[ sources = [ "extract/js/src/builtin/RegExp.cpp", "extract/js/src/frontend/Parser.cpp", - "extract/js/src/jit/ProcessExecutableMemory.cpp", "extract/js/src/jsarray.cpp", "extract/js/src/jsatom.cpp", "extract/js/src/jsmath.cpp", @@ -113,6 +112,13 @@ if env.TargetOSIs('windows'): env.Prepend(CPPDEFINES=[ ("_CRT_RAND_S", "1") ]) + sources.extend([ + "extract/js/src/jit/ExecutableAllocatorWin.cpp", + ]) +else: + sources.extend([ + "extract/js/src/jit/ExecutableAllocatorPosix.cpp", + ]) sources.extend(Glob('platform/' + env["TARGET_ARCH"] + "/" + env["TARGET_OS"] + "/build/*.cpp")), diff --git a/src/third_party/mozjs-45/extract/js/public/GCAPI.h b/src/third_party/mozjs-45/extract/js/public/GCAPI.h index 84b6150c36f..90f8e4eba3f 100644 --- a/src/third_party/mozjs-45/extract/js/public/GCAPI.h +++ b/src/third_party/mozjs-45/extract/js/public/GCAPI.h @@ -566,6 +566,8 @@ namespace gc { static MOZ_ALWAYS_INLINE void ExposeGCThingToActiveJS(JS::GCCellPtr thing) { + MOZ_ASSERT(thing.kind() != JS::TraceKind::Shape); + /* * GC things residing in the nursery cannot be gray: they have no mark bits. * All live objects in the nursery are moved to tenured at the beginning of diff --git a/src/third_party/mozjs-45/extract/js/src/NamespaceImports.h b/src/third_party/mozjs-45/extract/js/src/NamespaceImports.h index 929263e69f4..05a0e5dcf51 100644 --- a/src/third_party/mozjs-45/extract/js/src/NamespaceImports.h +++ b/src/third_party/mozjs-45/extract/js/src/NamespaceImports.h @@ -49,10 +49,6 @@ class MOZ_STACK_CLASS SourceBufferHolder; class HandleValueArray; class ObjectOpResult; - -class Symbol; -enum class SymbolCode: uint32_t; - } // namespace JS // Do the importing. @@ -152,9 +148,6 @@ using JS::ObjectOpResult; using JS::Zone; -using JS::Symbol; -using JS::SymbolCode; - } /* namespace js */ #endif /* NamespaceImports_h */ diff --git a/src/third_party/mozjs-45/extract/js/src/asmjs/AsmJSModule.cpp b/src/third_party/mozjs-45/extract/js/src/asmjs/AsmJSModule.cpp index 9e707d06d0e..350827042ee 100644 --- a/src/third_party/mozjs-45/extract/js/src/asmjs/AsmJSModule.cpp +++ b/src/third_party/mozjs-45/extract/js/src/asmjs/AsmJSModule.cpp @@ -64,11 +64,12 @@ using JS::GenericNaN; static uint8_t* AllocateExecutableMemory(ExclusiveContext* cx, size_t bytes) { - // bytes is a multiple of the system's page size, but not necessarily - // a multiple of ExecutableCodePageSize. - bytes = JS_ROUNDUP(bytes, ExecutableCodePageSize); - - void* p = AllocateExecutableMemory(bytes, ProtectionSetting::Writable); + // On most platforms, this will allocate RWX memory. On iOS, or when + // --non-writable-jitcode is used, this will allocate RW memory. In this + // case, DynamicallyLinkModule will reprotect the code as RX. + unsigned permissions = + ExecutableAllocator::initialProtectionFlags(ExecutableAllocator::Writable); + void* p = AllocateExecutableMemory(nullptr, bytes, permissions, "asm-js-code", AsmJSPageSize); if (!p) ReportOutOfMemory(cx); return (uint8_t*)p; @@ -121,8 +122,7 @@ AsmJSModule::~AsmJSModule() exitDatum.baselineScript->removeDependentAsmJSModule(exit); } - uint32_t size = JS_ROUNDUP(pod.totalBytes_, ExecutableCodePageSize); - DeallocateExecutableMemory(code_, size); + DeallocateExecutableMemory(code_, pod.totalBytes_, AsmJSPageSize); } if (prevLinked_) diff --git a/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.cpp b/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.cpp index 8d474aefb50..94b97f434a5 100644 --- a/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.cpp +++ b/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.cpp @@ -15,7 +15,6 @@ #include "js/Utility.h" #include "vm/GlobalObject.h" #include "vm/Interpreter.h" -#include "vm/Symbol.h" #include "jsobjinlines.h" @@ -64,33 +63,13 @@ HashableValue::setValue(JSContext* cx, HandleValue v) return true; } -static HashNumber -HashValue(const Value& v, const mozilla::HashCodeScrambler& hcs) +HashNumber +HashableValue::hash() const { // HashableValue::setValue normalizes values so that the SameValue relation // on HashableValues is the same as the == relationship on - // value.asRawBits(). So why not just return that? Security. - // - // To avoid revealing GC of atoms, string-based hash codes are computed - // from the string contents rather than any pointer; to avoid revealing - // addresses, pointer-based hash codes are computed using the - // HashCodeScrambler. - - if (v.isString()) - return v.toString()->asAtom().hash(); - if (v.isSymbol()) - return v.toSymbol()->hash(); - if (v.isObject()) - return hcs.scramble(v.asRawBits()); - - MOZ_ASSERT(v.isNull() || !v.isGCThing(), "do not reveal pointers via hash codes"); - return v.asRawBits(); -} - -HashNumber -HashableValue::hash(const mozilla::HashCodeScrambler& hcs) const -{ - return HashValue(value, hcs); + // value.data.asBits. + return value.asRawBits(); } bool @@ -346,15 +325,13 @@ MapObject::mark(JSTracer* trc, JSObject* obj) struct UnbarrieredHashPolicy { typedef Value Lookup; - static HashNumber hash(const Lookup& v, const mozilla::HashCodeScrambler& hcs) { - return HashValue(v, hcs); - } + static HashNumber hash(const Lookup& v) { return v.asRawBits(); } static bool match(const Value& k, const Lookup& l) { return k == l; } static bool isEmpty(const Value& v) { return v.isMagic(JS_HASH_KEY_EMPTY); } static void makeEmpty(Value* vp) { vp->setMagic(JS_HASH_KEY_EMPTY); } }; -template <typename RealTableType, typename TableType> +template <typename TableType> class OrderedHashTableRef : public gc::BufferableRef { TableType* table; @@ -364,9 +341,8 @@ class OrderedHashTableRef : public gc::BufferableRef explicit OrderedHashTableRef(TableType* t, const Value& k) : table(t), key(k) {} void trace(JSTracer* trc) override { - MOZ_ASSERT(reinterpret_cast<RealTableType*>(table) - ->hash(*reinterpret_cast<HashableValue*>(&key)) == - table->hash(key)); + MOZ_ASSERT(UnbarrieredHashPolicy::hash(key) == + HashableValue::Hasher::hash(*reinterpret_cast<HashableValue*>(&key))); Value prior = key; TraceManuallyBarrieredEdge(trc, &key, "ordered hash table key"); table->rekeyOneEntry(prior, key); @@ -378,7 +354,7 @@ WriteBarrierPost(JSRuntime* rt, ValueMap* map, const Value& key) { typedef OrderedHashMap<Value, Value, UnbarrieredHashPolicy, RuntimeAllocPolicy> UnbarrieredMap; if (MOZ_UNLIKELY(key.isObject() && IsInsideNursery(&key.toObject()))) { - rt->gc.storeBuffer.putGeneric(OrderedHashTableRef<ValueMap, UnbarrieredMap>( + rt->gc.storeBuffer.putGeneric(OrderedHashTableRef<UnbarrieredMap>( reinterpret_cast<UnbarrieredMap*>(map), key)); } } @@ -388,7 +364,7 @@ WriteBarrierPost(JSRuntime* rt, ValueSet* set, const Value& key) { typedef OrderedHashSet<Value, UnbarrieredHashPolicy, RuntimeAllocPolicy> UnbarrieredSet; if (MOZ_UNLIKELY(key.isObject() && IsInsideNursery(&key.toObject()))) { - rt->gc.storeBuffer.putGeneric(OrderedHashTableRef<ValueSet, UnbarrieredSet>( + rt->gc.storeBuffer.putGeneric(OrderedHashTableRef<UnbarrieredSet>( reinterpret_cast<UnbarrieredSet*>(set), key)); } } @@ -435,8 +411,7 @@ MapObject::set(JSContext* cx, HandleObject obj, HandleValue k, HandleValue v) MapObject* MapObject::create(JSContext* cx, HandleObject proto /* = nullptr */) { - auto map = cx->make_unique<ValueMap>(cx->runtime(), - cx->compartment()->randomHashCodeScrambler()); + auto map = cx->make_unique<ValueMap>(cx->runtime()); if (!map || !map->init()) { ReportOutOfMemory(cx); return nullptr; @@ -560,7 +535,7 @@ MapObject::is(HandleObject o) } #define ARG0_KEY(cx, args, key) \ - Rooted<HashableValue> key(cx); \ + Rooted<HashableValue> key(cx); \ if (args.length() > 0 && !key.setValue(cx, args[0])) \ return false @@ -1089,8 +1064,7 @@ SetObject::add(JSContext* cx, HandleObject obj, HandleValue k) SetObject* SetObject::create(JSContext* cx, HandleObject proto /* = nullptr */) { - auto set = cx->make_unique<ValueSet>(cx->runtime(), - cx->compartment()->randomHashCodeScrambler()); + auto set = cx->make_unique<ValueSet>(cx->runtime()); if (!set || !set->init()) { ReportOutOfMemory(cx); return nullptr; diff --git a/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.h b/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.h index 9af58fc21cd..1118675f873 100644 --- a/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.h +++ b/src/third_party/mozjs-45/extract/js/src/builtin/MapObject.h @@ -29,9 +29,7 @@ class HashableValue : public JS::Traceable public: struct Hasher { typedef HashableValue Lookup; - static HashNumber hash(const Lookup& v, const mozilla::HashCodeScrambler& hcs) { - return v.hash(hcs); - } + static HashNumber hash(const Lookup& v) { return v.hash(); } static bool match(const HashableValue& k, const Lookup& l) { return k == l; } static bool isEmpty(const HashableValue& v) { return v.value.isMagic(JS_HASH_KEY_EMPTY); } static void makeEmpty(HashableValue* vp) { vp->value = MagicValue(JS_HASH_KEY_EMPTY); } @@ -40,7 +38,7 @@ class HashableValue : public JS::Traceable HashableValue() : value(UndefinedValue()) {} bool setValue(JSContext* cx, HandleValue v); - HashNumber hash(const mozilla::HashCodeScrambler& hcs) const; + HashNumber hash() const; bool operator==(const HashableValue& other) const; HashableValue mark(JSTracer* trc) const; Value get() const { return value.get(); } diff --git a/src/third_party/mozjs-45/extract/js/src/ds/OrderedHashTable.h b/src/third_party/mozjs-45/extract/js/src/ds/OrderedHashTable.h index cb58ac2f735..c9927212976 100644 --- a/src/third_party/mozjs-45/extract/js/src/ds/OrderedHashTable.h +++ b/src/third_party/mozjs-45/extract/js/src/ds/OrderedHashTable.h @@ -29,15 +29,12 @@ * * See the comment about "Hash policy" in HashTable.h for general features that * hash policy classes must provide. Hash policies for OrderedHashMaps and Sets - * differ in that the hash() method takes an extra argument: - * static js::HashNumber hash(Lookup, const HashCodeScrambler&); - * They must additionally provide a distinguished "empty" key value and the + * must additionally provide a distinguished "empty" key value and the * following static member functions: * bool isEmpty(const Key&); * void makeEmpty(Key*); */ -#include "mozilla/HashFunctions.h" #include "mozilla/Move.h" using mozilla::Forward; @@ -81,11 +78,10 @@ class OrderedHashTable uint32_t hashShift; // multiplicative hash shift Range* ranges; // list of all live Ranges on this table AllocPolicy alloc; - mozilla::HashCodeScrambler hcs; // don't reveal pointer hash codes public: - OrderedHashTable(AllocPolicy& ap, mozilla::HashCodeScrambler hcs) - : hashTable(nullptr), data(nullptr), dataLength(0), ranges(nullptr), alloc(ap), hcs(hcs) {} + explicit OrderedHashTable(AllocPolicy& ap) + : hashTable(nullptr), data(nullptr), dataLength(0), ranges(nullptr), alloc(ap) {} bool init() { MOZ_ASSERT(!hashTable, "init must be called at most once"); @@ -434,8 +430,8 @@ class OrderedHashTable void rekeyFront(const Key& k) { MOZ_ASSERT(valid()); Data& entry = ht.data[i]; - HashNumber oldHash = ht.prepareHash(Ops::getKey(entry.element)) >> ht.hashShift; - HashNumber newHash = ht.prepareHash(k) >> ht.hashShift; + HashNumber oldHash = prepareHash(Ops::getKey(entry.element)) >> ht.hashShift; + HashNumber newHash = prepareHash(k) >> ht.hashShift; Ops::setKey(entry.element, k); if (newHash != oldHash) { // Remove this entry from its old hash chain. (If this crashes @@ -531,12 +527,10 @@ class OrderedHashTable */ static double minDataFill() { return 0.25; } - public: - HashNumber prepareHash(const Lookup& l) const { - return ScrambleHashCode(Ops::hash(l, hcs)); + static HashNumber prepareHash(const Lookup& l) { + return ScrambleHashCode(Ops::hash(l)); } - private: /* The size of hashTable, in elements. Always a power of two. */ uint32_t hashBuckets() const { return 1 << (HashNumberSizeBits - hashShift); @@ -707,7 +701,7 @@ class OrderedHashMap public: typedef typename Impl::Range Range; - OrderedHashMap(AllocPolicy ap, mozilla::HashCodeScrambler hcs) : impl(ap, hcs) {} + explicit OrderedHashMap(AllocPolicy ap = AllocPolicy()) : impl(ap) {} bool init() { return impl.init(); } uint32_t count() const { return impl.count(); } bool has(const Key& key) const { return impl.has(key); } @@ -719,8 +713,6 @@ class OrderedHashMap bool remove(const Key& key, bool* foundp) { return impl.remove(key, foundp); } bool clear() { return impl.clear(); } - HashNumber hash(const Key& key) const { return impl.prepareHash(key); } - void rekeyOneEntry(const Key& current, const Key& newKey) { const Entry* e = get(current); if (!e) @@ -746,7 +738,7 @@ class OrderedHashSet public: typedef typename Impl::Range Range; - explicit OrderedHashSet(AllocPolicy ap, mozilla::HashCodeScrambler hcs) : impl(ap, hcs) {} + explicit OrderedHashSet(AllocPolicy ap = AllocPolicy()) : impl(ap) {} bool init() { return impl.init(); } uint32_t count() const { return impl.count(); } bool has(const T& value) const { return impl.has(value); } @@ -755,8 +747,6 @@ class OrderedHashSet bool remove(const T& value, bool* foundp) { return impl.remove(value, foundp); } bool clear() { return impl.clear(); } - HashNumber hash(const T& value) const { return impl.prepareHash(value); } - void rekeyOneEntry(const T& current, const T& newKey) { return impl.rekeyOneEntry(current, newKey, newKey); } diff --git a/src/third_party/mozjs-45/extract/js/src/gc/Allocator.cpp b/src/third_party/mozjs-45/extract/js/src/gc/Allocator.cpp index bdc17bdc8db..b409dfa4a1f 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/Allocator.cpp +++ b/src/third_party/mozjs-45/extract/js/src/gc/Allocator.cpp @@ -57,14 +57,11 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind) } #if defined(JS_GC_ZEAL) || defined(DEBUG) - MOZ_ASSERT_IF(cx->compartment()->isAtomsCompartment(), - kind == AllocKind::ATOM || - kind == AllocKind::FAT_INLINE_ATOM || + MOZ_ASSERT_IF(rt->isAtomsCompartment(cx->compartment()), + kind == AllocKind::STRING || + kind == AllocKind::FAT_INLINE_STRING || kind == AllocKind::SYMBOL || kind == AllocKind::JITCODE); - MOZ_ASSERT_IF(!cx->compartment()->isAtomsCompartment(), - kind != AllocKind::ATOM && - kind != AllocKind::FAT_INLINE_ATOM); MOZ_ASSERT(!rt->isHeapBusy()); MOZ_ASSERT(isAllocAllowed()); #endif @@ -224,8 +221,6 @@ js::Allocate(ExclusiveContext* cx) macro(JSFatInlineString) \ macro(JSScript) \ macro(JSString) \ - macro(js::NormalAtom) \ - macro(js::FatInlineAtom) \ macro(js::AccessorShape) \ macro(js::BaseShape) \ macro(js::LazyScript) \ diff --git a/src/third_party/mozjs-45/extract/js/src/gc/GCRuntime.h b/src/third_party/mozjs-45/extract/js/src/gc/GCRuntime.h index e0ad996150d..d2b45473862 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/GCRuntime.h +++ b/src/third_party/mozjs-45/extract/js/src/gc/GCRuntime.h @@ -923,7 +923,7 @@ class GCRuntime void purgeRuntime(); bool beginMarkPhase(JS::gcreason::Reason reason); bool shouldPreserveJITCode(JSCompartment* comp, int64_t currentTime, - JS::gcreason::Reason reason, bool canAllocateMoreCode); + JS::gcreason::Reason reason); void bufferGrayRoots(); void markCompartments(); IncrementalProgress drainMarkStack(SliceBudget& sliceBudget, gcstats::Phase phase); diff --git a/src/third_party/mozjs-45/extract/js/src/gc/Heap.h b/src/third_party/mozjs-45/extract/js/src/gc/Heap.h index 783da19a388..1ff1d9fa498 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/Heap.h +++ b/src/third_party/mozjs-45/extract/js/src/gc/Heap.h @@ -106,8 +106,6 @@ enum class AllocKind { FAT_INLINE_STRING, STRING, EXTERNAL_STRING, - FAT_INLINE_ATOM, - ATOM, SYMBOL, JITCODE, LIMIT, @@ -199,8 +197,6 @@ MapAllocToTraceKind(AllocKind kind) JS::TraceKind::String, /* AllocKind::FAT_INLINE_STRING */ JS::TraceKind::String, /* AllocKind::STRING */ JS::TraceKind::String, /* AllocKind::EXTERNAL_STRING */ - JS::TraceKind::String, /* AllocKind::FAT_INLINE_ATOM */ - JS::TraceKind::String, /* AllocKind::ATOM */ JS::TraceKind::Symbol, /* AllocKind::SYMBOL */ JS::TraceKind::JitCode, /* AllocKind::JITCODE */ }; diff --git a/src/third_party/mozjs-45/extract/js/src/gc/Marking.cpp b/src/third_party/mozjs-45/extract/js/src/gc/Marking.cpp index 4e10b20b36c..f52ab393f71 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/Marking.cpp +++ b/src/third_party/mozjs-45/extract/js/src/gc/Marking.cpp @@ -171,17 +171,6 @@ template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JS::Symbol>(JS::Symbol* s return sym->isWellKnownSymbol(); } -template <typename T> -static inline bool -IsOwnedByOtherRuntime(JSRuntime* rt, T thing) -{ - bool other = thing->runtimeFromAnyThread() != rt; - MOZ_ASSERT_IF(other, - ThingIsPermanentAtomOrWellKnownSymbol(thing) || - thing->zoneFromAnyThread()->isSelfHostingZone()); - return other; -} - template<typename T> void js::CheckTracedThing(JSTracer* trc, T* thing) @@ -199,10 +188,10 @@ js::CheckTracedThing(JSTracer* trc, T* thing) MOZ_ASSERT_IF(!IsMovingTracer(trc) && !trc->isTenuringTracer(), !IsForwarded(thing)); /* - * Permanent atoms and things in the self-hosting zone are not associated - * with this runtime, but will be ignored during marking. + * Permanent atoms are not associated with this runtime, but will be + * ignored during marking. */ - if (IsOwnedByOtherRuntime(trc->runtime(), thing)) + if (ThingIsPermanentAtomOrWellKnownSymbol(thing)) return; Zone* zone = thing->zoneFromAnyThread(); @@ -686,24 +675,16 @@ GCMarker::markImplicitEdges(T* thing) template <typename T> static inline bool -MustSkipMarking(GCMarker* gcmarker, T thing) +MustSkipMarking(T thing) { - // Don't trace things that are owned by another runtime. - if (IsOwnedByOtherRuntime(gcmarker->runtime(), thing)) - return true; - // Don't mark things outside a zone if we are in a per-zone GC. return !thing->zone()->isGCMarking(); } template <> bool -MustSkipMarking<JSObject*>(GCMarker* gcmarker, JSObject* obj) +MustSkipMarking<JSObject*>(JSObject* obj) { - // Don't trace things that are owned by another runtime. - if (IsOwnedByOtherRuntime(gcmarker->runtime(), obj)) - return true; - // We may mark a Nursery thing outside the context of the // MinorCollectionTracer because of a pre-barrier. The pre-barrier is not // needed in this case because we perform a minor collection before each @@ -717,12 +698,34 @@ MustSkipMarking<JSObject*>(GCMarker* gcmarker, JSObject* obj) return !TenuredCell::fromPointer(obj)->zone()->isGCMarking(); } +template <> +bool +MustSkipMarking<JSString*>(JSString* str) +{ + // Don't mark permanent atoms, as they may be associated with another + // runtime. Note that traverse() also checks this, but we need to not + // run the isGCMarking test from off-main-thread, so have to check it here + // too. + return str->isPermanentAtom() || + !str->zone()->isGCMarking(); +} + +template <> +bool +MustSkipMarking<JS::Symbol*>(JS::Symbol* sym) +{ + // As for JSString, don't touch a globally owned well-known symbol from + // off-main-thread. + return sym->isWellKnownSymbol() || + !sym->zone()->isGCMarking(); +} + template <typename T> void DoMarking(GCMarker* gcmarker, T* thing) { // Do per-type marking precondition checks. - if (MustSkipMarking(gcmarker, thing)) + if (MustSkipMarking(thing)) return; CheckTracedThing(gcmarker, thing); @@ -749,13 +752,13 @@ void NoteWeakEdge(GCMarker* gcmarker, T** thingp) { // Do per-type marking precondition checks. - if (MustSkipMarking(gcmarker, *thingp)) + if (MustSkipMarking(*thingp)) return; CheckTracedThing(gcmarker, *thingp); // If the target is already marked, there's no need to store the edge. - if (IsMarkedUnbarriered(gcmarker->runtime(), thingp)) + if (IsMarkedUnbarriered(thingp)) return; gcmarker->noteWeakEdge(thingp); @@ -2326,22 +2329,17 @@ IsMarkedInternalCommon(T* thingp) template <typename T> static bool -IsMarkedInternal(JSRuntime* rt, T** thingp) +IsMarkedInternal(T** thingp) { - if (IsOwnedByOtherRuntime(rt, *thingp)) - return true; - return IsMarkedInternalCommon(thingp); } template <> /* static */ bool -IsMarkedInternal(JSRuntime* rt, JSObject** thingp) +IsMarkedInternal(JSObject** thingp) { - if (IsOwnedByOtherRuntime(rt, *thingp)) - return true; - if (IsInsideNursery(*thingp)) { + JSRuntime* rt = (*thingp)->runtimeFromAnyThread(); MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); return rt->gc.nursery.getForwardedPointer(thingp); } @@ -2350,18 +2348,18 @@ IsMarkedInternal(JSRuntime* rt, JSObject** thingp) template <typename S> struct IsMarkedFunctor : public IdentityDefaultAdaptor<S> { - template <typename T> S operator()(T* t, JSRuntime* rt, bool* rv) { - *rv = IsMarkedInternal(rt, &t); + template <typename T> S operator()(T* t, bool* rv) { + *rv = IsMarkedInternal(&t); return js::gc::RewrapTaggedPointer<S, T*>::wrap(t); } }; template <typename T> static bool -IsMarkedInternal(JSRuntime* rt, T* thingp) +IsMarkedInternal(T* thingp) { bool rv = true; - *thingp = DispatchTyped(IsMarkedFunctor<T>(), *thingp, rt, &rv); + *thingp = DispatchTyped(IsMarkedFunctor<T>(), *thingp, &rv); return rv; } @@ -2429,16 +2427,16 @@ namespace gc { template <typename T> bool -IsMarkedUnbarriered(JSRuntime* rt, T* thingp) +IsMarkedUnbarriered(T* thingp) { - return IsMarkedInternal(rt, ConvertToBase(thingp)); + return IsMarkedInternal(ConvertToBase(thingp)); } template <typename T> bool -IsMarked(JSRuntime* rt, WriteBarrieredBase<T>* thingp) +IsMarked(WriteBarrieredBase<T>* thingp) { - return IsMarkedInternal(rt, ConvertToBase(thingp->unsafeUnbarrieredForTracing())); + return IsMarkedInternal(ConvertToBase(thingp->unsafeUnbarrieredForTracing())); } template <typename T> @@ -2471,8 +2469,8 @@ EdgeNeedsSweep(JS::Heap<T>* thingp) // Instantiate a copy of the Tracing templates for each derived type. #define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \ - template bool IsMarkedUnbarriered<type>(JSRuntime*, type*); \ - template bool IsMarked<type>(JSRuntime*, WriteBarrieredBase<type>*); \ + template bool IsMarkedUnbarriered<type>(type*); \ + template bool IsMarked<type>(WriteBarrieredBase<type>*); \ template bool IsAboutToBeFinalizedUnbarriered<type>(type*); \ template bool IsAboutToBeFinalized<type>(WriteBarrieredBase<type>*); \ template bool IsAboutToBeFinalized<type>(ReadBarrieredBase<type>*); \ diff --git a/src/third_party/mozjs-45/extract/js/src/gc/Marking.h b/src/third_party/mozjs-45/extract/js/src/gc/Marking.h index 5e237c2154b..5c69cd1fdb6 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/Marking.h +++ b/src/third_party/mozjs-45/extract/js/src/gc/Marking.h @@ -142,9 +142,7 @@ namespace gc { struct WeakKeyTableHashPolicy { typedef JS::GCCellPtr Lookup; - static HashNumber hash(const Lookup& v, const mozilla::HashCodeScrambler&) { - return mozilla::HashGeneric(v.asCell()); - } + static HashNumber hash(const Lookup& v) { return mozilla::HashGeneric(v.asCell()); } static bool match(const JS::GCCellPtr& k, const Lookup& l) { return k == l; } static bool isEmpty(const JS::GCCellPtr& v) { return !v; } static void makeEmpty(JS::GCCellPtr* vp) { *vp = nullptr; } @@ -370,19 +368,13 @@ PushArena(GCMarker* gcmarker, ArenaHeader* aheader); /*** Liveness ***/ -// Report whether a thing has been marked. Things which are in zones that are -// not currently being collected or are owned by another runtime are always -// reported as being marked. template <typename T> bool -IsMarkedUnbarriered(JSRuntime* rt, T* thingp); +IsMarkedUnbarriered(T* thingp); -// Report whether a thing has been marked. Things which are in zones that are -// not currently being collected or are owned by another runtime are always -// reported as being marked. template <typename T> bool -IsMarked(JSRuntime* rt, WriteBarrieredBase<T>* thingp); +IsMarked(WriteBarrieredBase<T>* thingp); template <typename T> bool diff --git a/src/third_party/mozjs-45/extract/js/src/gc/Zone.cpp b/src/third_party/mozjs-45/extract/js/src/gc/Zone.cpp index b001ecff9e6..260f06dbe47 100644 --- a/src/third_party/mozjs-45/extract/js/src/gc/Zone.cpp +++ b/src/third_party/mozjs-45/extract/js/src/gc/Zone.cpp @@ -29,7 +29,6 @@ JS::Zone::Zone(JSRuntime* rt) types(this), compartments(), gcGrayRoots(), - gcWeakKeys(SystemAllocPolicy(), rt->randomHashCodeScrambler()), gcMallocBytes(0), gcMallocGCTriggered(false), usage(&rt->gc.usage), diff --git a/src/third_party/mozjs-45/extract/js/src/irregexp/RegExpEngine.cpp b/src/third_party/mozjs-45/extract/js/src/irregexp/RegExpEngine.cpp index 84dab0c8adf..ba30fc7a72d 100644 --- a/src/third_party/mozjs-45/extract/js/src/irregexp/RegExpEngine.cpp +++ b/src/third_party/mozjs-45/extract/js/src/irregexp/RegExpEngine.cpp @@ -32,7 +32,6 @@ #include "irregexp/NativeRegExpMacroAssembler.h" #include "irregexp/RegExpMacroAssembler.h" -#include "jit/ExecutableAllocator.h" #include "jit/JitCommon.h" using namespace js; @@ -1731,11 +1730,7 @@ irregexp::CompilePattern(JSContext* cx, RegExpShared* shared, RegExpCompileData* Maybe<InterpretedRegExpMacroAssembler> interpreted_assembler; RegExpMacroAssembler* assembler; - if (IsNativeRegExpEnabled(cx) && - !force_bytecode && - jit::CanLikelyAllocateMoreExecutableMemory() && - shared->getSource()->length() < 32 * 1024) - { + if (IsNativeRegExpEnabled(cx) && !force_bytecode) { NativeRegExpMacroAssembler::Mode mode = is_ascii ? NativeRegExpMacroAssembler::ASCII : NativeRegExpMacroAssembler::CHAR16; diff --git a/src/third_party/mozjs-45/extract/js/src/jit/BaselineIC.cpp b/src/third_party/mozjs-45/extract/js/src/jit/BaselineIC.cpp index 69c402bc1a9..03236cff6cc 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/BaselineIC.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/BaselineIC.cpp @@ -1061,14 +1061,6 @@ IsCacheableSetPropCall(JSContext* cx, JSObject* obj, JSObject* holder, Shape* sh JSFunction* func = &shape->setterObject()->as<JSFunction>(); - if (IsWindow(obj)) { - if (!func->isNative()) - return false; - - if (!func->jitInfo() || func->jitInfo()->needsOuterizedThisObject()) - return false; - } - if (func->isNative()) { *isScripted = false; return true; @@ -6406,12 +6398,6 @@ ICCallStubCompiler::guardFunApply(MacroAssembler& masm, AllocatableGeneralRegist Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()), Imm32(BaselineFrame::HAS_ARGS_OBJ), failure); - - // Limit the length to something reasonable. - masm.branch32(Assembler::Above, - Address(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs()), - Imm32(ICCall_ScriptedApplyArray::MAX_ARGS_ARRAY_LENGTH), - failure); } else { MOZ_ASSERT(applyThing == FunApply_Array); diff --git a/src/third_party/mozjs-45/extract/js/src/jit/BaselineJIT.cpp b/src/third_party/mozjs-45/extract/js/src/jit/BaselineJIT.cpp index 293868a741f..f0dc2655e83 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/BaselineJIT.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/BaselineJIT.cpp @@ -314,17 +314,12 @@ CanEnterBaselineJIT(JSContext* cx, HandleScript script, InterpreterFrame* osrFra if (script->nslots() > BaselineScript::MAX_JSSCRIPT_SLOTS) return Method_CantCompile; - if (script->hasBaselineScript()) - return Method_Compiled; - - // Check this before calling ensureJitCompartmentExists, so we're less - // likely to report OOM in JSRuntime::createJitRuntime. - if (!CanLikelyAllocateMoreExecutableMemory()) - return Method_Skipped; - if (!cx->compartment()->ensureJitCompartmentExists(cx)) return Method_Error; + if (script->hasBaselineScript()) + return Method_Compiled; + // Check script warm-up counter. if (script->incWarmUpCounter() <= JitOptions.baselineWarmUpThreshold) return Method_Skipped; diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.cpp b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.cpp index aa24216c3a5..55ad6b6d69c 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.cpp @@ -29,8 +29,15 @@ #include "js/MemoryMetrics.h" +#ifdef __APPLE__ +#include <TargetConditionals.h> +#endif + using namespace js::jit; +size_t ExecutableAllocator::pageSize = 0; +size_t ExecutableAllocator::largeAllocSize = 0; + ExecutablePool::~ExecutablePool() { MOZ_ASSERT(m_ionCodeBytes == 0); @@ -41,6 +48,28 @@ ExecutablePool::~ExecutablePool() m_allocator->releasePoolPages(this); } +/* static */ void +ExecutableAllocator::initStatic() +{ + if (!pageSize) { + pageSize = determinePageSize(); + // On Windows, VirtualAlloc effectively allocates in 64K chunks. + // (Technically, it allocates in page chunks, but the starting + // address is always a multiple of 64K, so each allocation uses up + // 64K of address space.) So a size less than that would be + // pointless. But it turns out that 64KB is a reasonable size for + // all platforms. (This assumes 4KB pages.) On 64-bit windows, + // AllocateExecutableMemory prepends an extra page for structured + // exception handling data (see comments in function) onto whatever + // is passed in, so subtract one page here. +#if defined(JS_CPU_X64) && defined(XP_WIN) + largeAllocSize = pageSize * 15; +#else + largeAllocSize = pageSize * 16; +#endif + } +} + void ExecutableAllocator::addSizeOfCode(JS::CodeSizes* sizes) const { @@ -59,16 +88,8 @@ ExecutableAllocator::addSizeOfCode(JS::CodeSizes* sizes) const } } -ExecutablePool::Allocation -ExecutableAllocator::systemAlloc(size_t n) -{ - void* allocation = AllocateExecutableMemory(n, ProtectionSetting::Executable); - ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; - return alloc; -} - -void -ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) -{ - DeallocateExecutableMemory(alloc.pages, alloc.size); -} +#if TARGET_OS_IPHONE +bool ExecutableAllocator::nonWritableJitCode = true; +#else +bool ExecutableAllocator::nonWritableJitCode = false; +#endif diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.h b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.h index cc0ad2b66ea..874f6b7314f 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.h +++ b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocator.h @@ -39,7 +39,6 @@ #include "jit/arm/Simulator-arm.h" #include "jit/mips32/Simulator-mips32.h" #include "jit/mips64/Simulator-mips64.h" -#include "jit/ProcessExecutableMemory.h" #include "js/GCAPI.h" #include "js/HashTable.h" #include "js/Vector.h" @@ -187,7 +186,13 @@ class ExecutableAllocator typedef void (*DestroyCallback)(void* addr, size_t size); DestroyCallback destroyCallback; +#ifdef XP_WIN + mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomNumberGenerator; +#endif + public: + enum ProtectionSetting { Writable, Executable }; + ExecutableAllocator() : destroyCallback(nullptr) { @@ -258,7 +263,14 @@ class ExecutableAllocator this->destroyCallback = destroyCallback; } + static void initStatic(); + + static bool nonWritableJitCode; + private: + static size_t pageSize; + static size_t largeAllocSize; + static const size_t OVERSIZE_ALLOCATION = size_t(-1); static size_t roundUpAllocationSize(size_t request, size_t granularity) @@ -282,10 +294,11 @@ class ExecutableAllocator // On OOM, this will return an Allocation where pages is nullptr. ExecutablePool::Allocation systemAlloc(size_t n); static void systemRelease(const ExecutablePool::Allocation& alloc); + void* computeRandomAllocationAddress(); ExecutablePool* createPool(size_t n) { - size_t allocSize = roundUpAllocationSize(n, ExecutableCodePageSize); + size_t allocSize = roundUpAllocationSize(n, pageSize); if (allocSize == OVERSIZE_ALLOCATION) return nullptr; @@ -303,8 +316,8 @@ class ExecutableAllocator } if (!m_pools.put(pool)) { - // Note: this will call |systemRelease(a)|. js_delete(pool); + systemRelease(a); return nullptr; } @@ -331,11 +344,11 @@ class ExecutableAllocator } // If the request is large, we just provide a unshared allocator - if (n > ExecutableCodePageSize) + if (n > largeAllocSize) return createPool(n); // Create a new allocator - ExecutablePool* pool = createPool(ExecutableCodePageSize); + ExecutablePool* pool = createPool(largeAllocSize); if (!pool) return nullptr; // At this point, local |pool| is the owner. @@ -372,12 +385,18 @@ class ExecutableAllocator static void makeWritable(void* start, size_t size) { + if (nonWritableJitCode) + reprotectRegion(start, size, Writable); } static void makeExecutable(void* start, size_t size) { + if (nonWritableJitCode) + reprotectRegion(start, size, Executable); } + static unsigned initialProtectionFlags(ProtectionSetting protection); + #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) static void cacheFlush(void*, size_t) { @@ -450,6 +469,8 @@ class ExecutableAllocator ExecutableAllocator(const ExecutableAllocator&) = delete; void operator=(const ExecutableAllocator&) = delete; + static void reprotectRegion(void*, size_t, ProtectionSetting); + // These are strong references; they keep pools alive. static const size_t maxSmallPools = 4; typedef js::Vector<ExecutablePool*, maxSmallPools, js::SystemAllocPolicy> SmallExecPoolVector; @@ -461,8 +482,17 @@ class ExecutableAllocator typedef js::HashSet<ExecutablePool*, js::DefaultHasher<ExecutablePool*>, js::SystemAllocPolicy> ExecPoolHashSet; ExecPoolHashSet m_pools; // All pools, just for stats purposes. + + static size_t determinePageSize(); }; +extern void* +AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions, const char* tag, + size_t pageSize); + +extern void +DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize); + } // namespace jit } // namespace js diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorPosix.cpp b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorPosix.cpp new file mode 100644 index 00000000000..d6d791174d6 --- /dev/null +++ b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorPosix.cpp @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mozilla/DebugOnly.h" +#include "mozilla/TaggedAnonymousMemory.h" + +#include <errno.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "jit/ExecutableAllocator.h" +#include "js/Utility.h" + +using namespace js::jit; + +size_t +ExecutableAllocator::determinePageSize() +{ + return getpagesize(); +} + +void* +js::jit::AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions, const char* tag, + size_t pageSize) +{ + MOZ_ASSERT(bytes % pageSize == 0); + void* p = MozTaggedAnonymousMmap(addr, bytes, permissions, MAP_PRIVATE | MAP_ANON, -1, 0, tag); + return p == MAP_FAILED ? nullptr : p; +} + +void +js::jit::DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize) +{ + MOZ_ASSERT(bytes % pageSize == 0); + mozilla::DebugOnly<int> result = munmap(addr, bytes); + MOZ_ASSERT(!result || errno == ENOMEM); +} + +ExecutablePool::Allocation +ExecutableAllocator::systemAlloc(size_t n) +{ + void* allocation = AllocateExecutableMemory(nullptr, n, initialProtectionFlags(Executable), + "js-jit-code", pageSize); + ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; + return alloc; +} + +void +ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) +{ + DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize); +} + +static const unsigned FLAGS_RW = PROT_READ | PROT_WRITE; +static const unsigned FLAGS_RX = PROT_READ | PROT_EXEC; + +void +ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) +{ + MOZ_ASSERT(nonWritableJitCode); + MOZ_ASSERT(pageSize); + + // Calculate the start of the page containing this region, + // and account for this extra memory within size. + intptr_t startPtr = reinterpret_cast<intptr_t>(start); + intptr_t pageStartPtr = startPtr & ~(pageSize - 1); + void* pageStart = reinterpret_cast<void*>(pageStartPtr); + size += (startPtr - pageStartPtr); + + // Round size up + size += (pageSize - 1); + size &= ~(pageSize - 1); + + mprotect(pageStart, size, (setting == Writable) ? FLAGS_RW : FLAGS_RX); +} + +/* static */ unsigned +ExecutableAllocator::initialProtectionFlags(ProtectionSetting protection) +{ + if (!nonWritableJitCode) + return FLAGS_RW | FLAGS_RX; + + return (protection == Writable) ? FLAGS_RW : FLAGS_RX; +} diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorWin.cpp b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorWin.cpp new file mode 100644 index 00000000000..fe068b90814 --- /dev/null +++ b/src/third_party/mozjs-45/extract/js/src/jit/ExecutableAllocatorWin.cpp @@ -0,0 +1,289 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mozilla/WindowsVersion.h" + +#include "jsfriendapi.h" +#include "jsmath.h" +#include "jswin.h" + +#include "jit/ExecutableAllocator.h" + +using namespace js::jit; + +size_t +ExecutableAllocator::determinePageSize() +{ + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; +} + +void* +ExecutableAllocator::computeRandomAllocationAddress() +{ + /* + * Inspiration is V8's OS::Allocate in platform-win32.cc. + * + * VirtualAlloc takes 64K chunks out of the virtual address space, so we + * keep 16b alignment. + * + * x86: V8 comments say that keeping addresses in the [64MiB, 1GiB) range + * tries to avoid system default DLL mapping space. In the end, we get 13 + * bits of randomness in our selection. + * x64: [2GiB, 4TiB), with 25 bits of randomness. + */ +#ifdef JS_CPU_X64 + static const uintptr_t base = 0x0000000080000000; + static const uintptr_t mask = 0x000003ffffff0000; +#elif defined(JS_CPU_X86) + static const uintptr_t base = 0x04000000; + static const uintptr_t mask = 0x3fff0000; +#else +# error "Unsupported architecture" +#endif + + if (randomNumberGenerator.isNothing()) { + mozilla::Array<uint64_t, 2> seed; + js::GenerateXorShift128PlusSeed(seed); + randomNumberGenerator.emplace(seed[0], seed[1]); + } + + uint64_t rand = randomNumberGenerator.ref().next(); + return (void*) (base | (rand & mask)); +} + +static bool +RandomizeIsBrokenImpl() +{ + // We disable everything before Vista, for now. + return !mozilla::IsVistaOrLater(); +} + +static bool +RandomizeIsBroken() +{ + // Use the compiler's intrinsic guards for |static type value = expr| to avoid some potential + // races if runtimes are created from multiple threads. + static int result = RandomizeIsBrokenImpl(); + return !!result; +} + +#ifdef JS_CPU_X64 +static js::JitExceptionHandler sJitExceptionHandler; + +JS_FRIEND_API(void) +js::SetJitExceptionHandler(JitExceptionHandler handler) +{ + MOZ_ASSERT(!sJitExceptionHandler); + sJitExceptionHandler = handler; +} + +// From documentation for UNWIND_INFO on +// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx +struct UnwindInfo +{ + uint8_t version : 3; + uint8_t flags : 5; + uint8_t sizeOfPrologue; + uint8_t countOfUnwindCodes; + uint8_t frameRegister : 4; + uint8_t frameOffset : 4; + ULONG exceptionHandler; +}; + +static const unsigned ThunkLength = 12; + +struct ExceptionHandlerRecord +{ + RUNTIME_FUNCTION runtimeFunction; + UnwindInfo unwindInfo; + uint8_t thunk[ThunkLength]; +}; + +// This function must match the function pointer type PEXCEPTION_HANDLER +// mentioned in: +// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx. +// This type is rather elusive in documentation; Wine is the best I've found: +// http://source.winehq.org/source/include/winnt.h +static DWORD +ExceptionHandler(PEXCEPTION_RECORD exceptionRecord, _EXCEPTION_REGISTRATION_RECORD*, + PCONTEXT context, _EXCEPTION_REGISTRATION_RECORD**) +{ + return sJitExceptionHandler(exceptionRecord, context); +} + +// For an explanation of the problem being solved here, see +// SetJitExceptionFilter in jsfriendapi.h. +static bool +RegisterExecutableMemory(void* p, size_t bytes, size_t pageSize) +{ + ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p); + + // All these fields are specified to be offsets from the base of the + // executable code (which is 'p'), even if they have 'Address' in their + // names. In particular, exceptionHandler is a ULONG offset which is a + // 32-bit integer. Since 'p' can be farther than INT32_MAX away from + // sJitExceptionHandler, we must generate a little thunk inside the + // record. The record is put on its own page so that we can take away write + // access to protect against accidental clobbering. + + r->runtimeFunction.BeginAddress = pageSize; + r->runtimeFunction.EndAddress = (DWORD)bytes; + r->runtimeFunction.UnwindData = offsetof(ExceptionHandlerRecord, unwindInfo); + + r->unwindInfo.version = 1; + r->unwindInfo.flags = UNW_FLAG_EHANDLER; + r->unwindInfo.sizeOfPrologue = 0; + r->unwindInfo.countOfUnwindCodes = 0; + r->unwindInfo.frameRegister = 0; + r->unwindInfo.frameOffset = 0; + r->unwindInfo.exceptionHandler = offsetof(ExceptionHandlerRecord, thunk); + + // mov imm64, rax + r->thunk[0] = 0x48; + r->thunk[1] = 0xb8; + void* handler = JS_FUNC_TO_DATA_PTR(void*, ExceptionHandler); + memcpy(&r->thunk[2], &handler, 8); + + // jmp rax + r->thunk[10] = 0xff; + r->thunk[11] = 0xe0; + + DWORD oldProtect; + if (!VirtualProtect(p, pageSize, PAGE_EXECUTE_READ, &oldProtect)) + return false; + + return RtlAddFunctionTable(&r->runtimeFunction, 1, reinterpret_cast<DWORD64>(p)); +} + +static void +UnregisterExecutableMemory(void* p, size_t bytes, size_t pageSize) +{ + ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p); + RtlDeleteFunctionTable(&r->runtimeFunction); +} +#endif + +void* +js::jit::AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions, const char* tag, + size_t pageSize) +{ + MOZ_ASSERT(bytes % pageSize == 0); + +#ifdef JS_CPU_X64 + if (sJitExceptionHandler) + bytes += pageSize; +#endif + + void* p = VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE, permissions); + if (!p) + return nullptr; + +#ifdef JS_CPU_X64 + if (sJitExceptionHandler) { + if (!RegisterExecutableMemory(p, bytes, pageSize)) { + VirtualFree(p, 0, MEM_RELEASE); + return nullptr; + } + + p = (uint8_t*)p + pageSize; + } +#endif + + return p; +} + +void +js::jit::DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize) +{ + MOZ_ASSERT(bytes % pageSize == 0); + +#ifdef JS_CPU_X64 + if (sJitExceptionHandler) { + addr = (uint8_t*)addr - pageSize; + UnregisterExecutableMemory(addr, bytes, pageSize); + } +#endif + + VirtualFree(addr, 0, MEM_RELEASE); +} + +ExecutablePool::Allocation +ExecutableAllocator::systemAlloc(size_t n) +{ + void* allocation = nullptr; + if (!RandomizeIsBroken()) { + void* randomAddress = computeRandomAllocationAddress(); + allocation = AllocateExecutableMemory(randomAddress, n, initialProtectionFlags(Executable), + "js-jit-code", pageSize); + } + if (!allocation) { + allocation = AllocateExecutableMemory(nullptr, n, initialProtectionFlags(Executable), + "js-jit-code", pageSize); + } + ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n }; + return alloc; +} + +void +ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) +{ + DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize); +} + +void +ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) +{ + MOZ_ASSERT(nonWritableJitCode); + MOZ_ASSERT(pageSize); + + // Calculate the start of the page containing this region, + // and account for this extra memory within size. + intptr_t startPtr = reinterpret_cast<intptr_t>(start); + intptr_t pageStartPtr = startPtr & ~(pageSize - 1); + void* pageStart = reinterpret_cast<void*>(pageStartPtr); + size += (startPtr - pageStartPtr); + + // Round size up + size += (pageSize - 1); + size &= ~(pageSize - 1); + + DWORD oldProtect; + int flags = (setting == Writable) ? PAGE_READWRITE : PAGE_EXECUTE_READ; + if (!VirtualProtect(pageStart, size, flags, &oldProtect)) + MOZ_CRASH(); +} + +/* static */ unsigned +ExecutableAllocator::initialProtectionFlags(ProtectionSetting protection) +{ + if (!nonWritableJitCode) + return PAGE_EXECUTE_READWRITE; + + return (protection == Writable) ? PAGE_READWRITE : PAGE_EXECUTE_READ; +} diff --git a/src/third_party/mozjs-45/extract/js/src/jit/Ion.cpp b/src/third_party/mozjs-45/extract/js/src/jit/Ion.cpp index f47a413fc68..93d96c257c0 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/Ion.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/Ion.cpp @@ -722,14 +722,13 @@ JitCompartment::sweep(FreeOp* fop, JSCompartment* compartment) if (!stubCodes_->lookup(ICSetProp_Fallback::Compiler::BASELINE_KEY)) baselineSetPropReturnAddr_ = nullptr; - JSRuntime* rt = fop->runtime(); - if (stringConcatStub_ && !IsMarkedUnbarriered(rt, &stringConcatStub_)) + if (stringConcatStub_ && !IsMarkedUnbarriered(&stringConcatStub_)) stringConcatStub_ = nullptr; - if (regExpExecStub_ && !IsMarkedUnbarriered(rt, ®ExpExecStub_)) + if (regExpExecStub_ && !IsMarkedUnbarriered(®ExpExecStub_)) regExpExecStub_ = nullptr; - if (regExpTestStub_ && !IsMarkedUnbarriered(rt, ®ExpTestStub_)) + if (regExpTestStub_ && !IsMarkedUnbarriered(®ExpTestStub_)) regExpTestStub_ = nullptr; for (size_t i = 0; i <= SimdTypeDescr::LAST_TYPE; i++) { @@ -2414,11 +2413,6 @@ Compile(JSContext* cx, HandleScript script, BaselineFrame* osrFrame, jsbytecode* if (optimizationLevel == Optimization_DontCompile) return Method_Skipped; - if (!CanLikelyAllocateMoreExecutableMemory()) { - script->resetWarmUpCounter(); - return Method_Skipped; - } - if (script->hasIonScript()) { IonScript* scriptIon = script->ionScript(); if (!scriptIon->method()) diff --git a/src/third_party/mozjs-45/extract/js/src/jit/IonAnalysis.cpp b/src/third_party/mozjs-45/extract/js/src/jit/IonAnalysis.cpp index 8a41afc51eb..0dd337c2ecb 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/IonAnalysis.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/IonAnalysis.cpp @@ -3673,9 +3673,6 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun, TempAllocator temp(&alloc); JitContext jctx(cx, &temp); - if (!jit::CanLikelyAllocateMoreExecutableMemory()) - return true; - if (!cx->compartment()->ensureJitCompartmentExists(cx)) return false; @@ -3905,9 +3902,6 @@ jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg) TempAllocator temp(&alloc); JitContext jctx(cx, &temp); - if (!jit::CanLikelyAllocateMoreExecutableMemory()) - return true; - if (!cx->compartment()->ensureJitCompartmentExists(cx)) return false; diff --git a/src/third_party/mozjs-45/extract/js/src/jit/IonBuilder.cpp b/src/third_party/mozjs-45/extract/js/src/jit/IonBuilder.cpp index 9e70e244889..3efc6bb0c11 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/IonBuilder.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/IonBuilder.cpp @@ -1235,11 +1235,9 @@ IonBuilder::initScopeChain(MDefinition* callee) current->add(scope); // This reproduce what is done in CallObject::createForFunction. Skip - // this for the arguments analysis, as the script might not have a - // baseline script with template objects yet. - if (fun->needsCallObject() && - info().analysisMode() != Analysis_ArgumentsUsage) - { + // this for analyses, as the script might not have a baseline script + // with template objects yet. + if (fun->needsCallObject() && !info().isAnalysis()) { if (fun->isNamedLambda()) { scope = createDeclEnvObject(callee, scope); if (!scope) @@ -6137,9 +6135,6 @@ IonBuilder::getSingletonPrototype(JSFunction* target) MDefinition* IonBuilder::createThisScriptedSingleton(JSFunction* target, MDefinition* callee) { - if (!target->hasScript()) - return nullptr; - // Get the singleton prototype (if exists) JSObject* proto = getSingletonPrototype(target); if (!proto) diff --git a/src/third_party/mozjs-45/extract/js/src/jit/IonCaches.cpp b/src/third_party/mozjs-45/extract/js/src/jit/IonCaches.cpp index 56437abf613..b5fe6dec072 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/IonCaches.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/IonCaches.cpp @@ -2418,20 +2418,9 @@ IsCacheableSetPropCallNative(HandleObject obj, HandleObject holder, HandleShape if (!shape || !IsCacheableProtoChainForIon(obj, holder)) return false; - if (!shape->hasSetterValue()) - return false; - - if (!shape->setterObject() || !shape->setterObject()->is<JSFunction>()) - return false; - - JSFunction& setter = shape->setterObject()->as<JSFunction>(); - if (!setter.isNative()) - return false; - - if (setter.jitInfo() && !setter.jitInfo()->needsOuterizedThisObject()) - return true; - - return !IsWindow(obj); + return shape->hasSetterValue() && shape->setterObject() && + shape->setterObject()->is<JSFunction>() && + shape->setterObject()->as<JSFunction>().isNative(); } static bool @@ -2440,9 +2429,6 @@ IsCacheableSetPropCallScripted(HandleObject obj, HandleObject holder, HandleShap if (!shape || !IsCacheableProtoChainForIon(obj, holder)) return false; - if (IsWindow(obj)) - return false; - return shape->hasSetterValue() && shape->setterObject() && shape->setterObject()->is<JSFunction>() && shape->setterObject()->as<JSFunction>().hasJITCode(); diff --git a/src/third_party/mozjs-45/extract/js/src/jit/IonCode.h b/src/third_party/mozjs-45/extract/js/src/jit/IonCode.h index 8156b9cb8f6..085a9076c33 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/IonCode.h +++ b/src/third_party/mozjs-45/extract/js/src/jit/IonCode.h @@ -767,7 +767,7 @@ struct AutoFlushICache namespace gc { inline bool -IsMarked(JSRuntime* rt, const jit::VMFunction*) +IsMarked(const jit::VMFunction*) { // VMFunction are only static objects which are used by WeakMaps as keys. // It is considered as a root object which is always marked. diff --git a/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.cpp b/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.cpp index e8cba8e63a4..7f6a06120d2 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.cpp @@ -756,7 +756,7 @@ JitcodeGlobalTable::setAllEntriesAsExpired(JSRuntime* rt) struct Unconditionally { template <typename T> - static bool ShouldMark(JSRuntime* rt, T* thingp) { return true; } + static bool ShouldMark(T* thingp) { return true; } }; void @@ -775,13 +775,13 @@ JitcodeGlobalTable::markUnconditionally(JSTracer* trc) struct IfUnmarked { template <typename T> - static bool ShouldMark(JSRuntime* rt, T* thingp) { return !IsMarkedUnbarriered(rt, thingp); } + static bool ShouldMark(T* thingp) { return !IsMarkedUnbarriered(thingp); } }; template <> -bool IfUnmarked::ShouldMark<TypeSet::Type>(JSRuntime* rt, TypeSet::Type* type) +bool IfUnmarked::ShouldMark<TypeSet::Type>(TypeSet::Type* type) { - return !TypeSet::IsTypeMarked(rt, type); + return !TypeSet::IsTypeMarked(type); } bool @@ -832,7 +832,7 @@ JitcodeGlobalTable::markIteratively(JSTracer* trc) // mapping, alive as well. if (!entry->isSampled(gen, lapCount)) { entry->setAsExpired(); - if (!entry->baseEntry().isJitcodeMarkedFromAnyThread(trc->runtime())) + if (!entry->baseEntry().isJitcodeMarkedFromAnyThread()) continue; } @@ -868,7 +868,7 @@ template <class ShouldMarkProvider> bool JitcodeGlobalEntry::BaseEntry::markJitcode(JSTracer* trc) { - if (ShouldMarkProvider::ShouldMark(trc->runtime(), &jitcode_)) { + if (ShouldMarkProvider::ShouldMark(&jitcode_)) { TraceManuallyBarrieredEdge(trc, &jitcode_, "jitcodglobaltable-baseentry-jitcode"); return true; } @@ -876,9 +876,9 @@ JitcodeGlobalEntry::BaseEntry::markJitcode(JSTracer* trc) } bool -JitcodeGlobalEntry::BaseEntry::isJitcodeMarkedFromAnyThread(JSRuntime* rt) +JitcodeGlobalEntry::BaseEntry::isJitcodeMarkedFromAnyThread() { - return IsMarkedUnbarriered(rt, &jitcode_) || + return IsMarkedUnbarriered(&jitcode_) || jitcode_->arenaHeader()->allocatedDuringIncremental; } @@ -892,7 +892,7 @@ template <class ShouldMarkProvider> bool JitcodeGlobalEntry::BaselineEntry::mark(JSTracer* trc) { - if (ShouldMarkProvider::ShouldMark(trc->runtime(), &script_)) { + if (ShouldMarkProvider::ShouldMark(&script_)) { TraceManuallyBarrieredEdge(trc, &script_, "jitcodeglobaltable-baselineentry-script"); return true; } @@ -906,9 +906,9 @@ JitcodeGlobalEntry::BaselineEntry::sweepChildren() } bool -JitcodeGlobalEntry::BaselineEntry::isMarkedFromAnyThread(JSRuntime* rt) +JitcodeGlobalEntry::BaselineEntry::isMarkedFromAnyThread() { - return IsMarkedUnbarriered(rt, &script_) || + return IsMarkedUnbarriered(&script_) || script_->arenaHeader()->allocatedDuringIncremental; } @@ -918,9 +918,8 @@ JitcodeGlobalEntry::IonEntry::mark(JSTracer* trc) { bool markedAny = false; - JSRuntime* rt = trc->runtime(); for (unsigned i = 0; i < numScripts(); i++) { - if (ShouldMarkProvider::ShouldMark(rt, &sizedScriptList()->pairs[i].script)) { + if (ShouldMarkProvider::ShouldMark(&sizedScriptList()->pairs[i].script)) { TraceManuallyBarrieredEdge(trc, &sizedScriptList()->pairs[i].script, "jitcodeglobaltable-ionentry-script"); markedAny = true; @@ -933,15 +932,15 @@ JitcodeGlobalEntry::IonEntry::mark(JSTracer* trc) for (IonTrackedTypeWithAddendum* iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { - if (ShouldMarkProvider::ShouldMark(rt, &iter->type)) { + if (ShouldMarkProvider::ShouldMark(&iter->type)) { TypeSet::MarkTypeUnbarriered(trc, &iter->type, "jitcodeglobaltable-ionentry-type"); markedAny = true; } - if (iter->hasAllocationSite() && ShouldMarkProvider::ShouldMark(rt, &iter->script)) { + if (iter->hasAllocationSite() && ShouldMarkProvider::ShouldMark(&iter->script)) { TraceManuallyBarrieredEdge(trc, &iter->script, "jitcodeglobaltable-ionentry-type-addendum-script"); markedAny = true; - } else if (iter->hasConstructor() && ShouldMarkProvider::ShouldMark(rt, &iter->constructor)) { + } else if (iter->hasConstructor() && ShouldMarkProvider::ShouldMark(&iter->constructor)) { TraceManuallyBarrieredEdge(trc, &iter->constructor, "jitcodeglobaltable-ionentry-type-addendum-constructor"); markedAny = true; @@ -974,10 +973,10 @@ JitcodeGlobalEntry::IonEntry::sweepChildren() } bool -JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread(JSRuntime* rt) +JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread() { for (unsigned i = 0; i < numScripts(); i++) { - if (!IsMarkedUnbarriered(rt, &sizedScriptList()->pairs[i].script) && + if (!IsMarkedUnbarriered(&sizedScriptList()->pairs[i].script) && !sizedScriptList()->pairs[i].script->arenaHeader()->allocatedDuringIncremental) { return false; @@ -990,7 +989,7 @@ JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread(JSRuntime* rt) for (IonTrackedTypeWithAddendum* iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { - if (!TypeSet::IsTypeMarked(rt, &iter->type) && + if (!TypeSet::IsTypeMarked(&iter->type) && !TypeSet::IsTypeAllocatedDuringIncremental(iter->type)) { return false; diff --git a/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.h b/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.h index e11126321d3..01c475adecb 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.h +++ b/src/third_party/mozjs-45/extract/js/src/jit/JitcodeMap.h @@ -208,7 +208,7 @@ class JitcodeGlobalEntry } template <class ShouldMarkProvider> bool markJitcode(JSTracer* trc); - bool isJitcodeMarkedFromAnyThread(JSRuntime* rt); + bool isJitcodeMarkedFromAnyThread(); bool isJitcodeAboutToBeFinalized(); }; @@ -370,7 +370,7 @@ class JitcodeGlobalEntry template <class ShouldMarkProvider> bool mark(JSTracer* trc); void sweepChildren(); - bool isMarkedFromAnyThread(JSRuntime* rt); + bool isMarkedFromAnyThread(); }; struct BaselineEntry : public BaseEntry @@ -428,7 +428,7 @@ class JitcodeGlobalEntry template <class ShouldMarkProvider> bool mark(JSTracer* trc); void sweepChildren(); - bool isMarkedFromAnyThread(JSRuntime* rt); + bool isMarkedFromAnyThread(); }; struct IonCacheEntry : public BaseEntry @@ -949,13 +949,13 @@ class JitcodeGlobalEntry } bool isMarkedFromAnyThread(JSRuntime* rt) { - if (!baseEntry().isJitcodeMarkedFromAnyThread(rt)) + if (!baseEntry().isJitcodeMarkedFromAnyThread()) return false; switch (kind()) { case Ion: - return ionEntry().isMarkedFromAnyThread(rt); + return ionEntry().isMarkedFromAnyThread(); case Baseline: - return baselineEntry().isMarkedFromAnyThread(rt); + return baselineEntry().isMarkedFromAnyThread(); case IonCache: return ionCacheEntry().isMarkedFromAnyThread(rt); case Dummy: diff --git a/src/third_party/mozjs-45/extract/js/src/jit/Lowering.cpp b/src/third_party/mozjs-45/extract/js/src/jit/Lowering.cpp index f1fc578f207..64f86f38f22 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/Lowering.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/Lowering.cpp @@ -2310,7 +2310,9 @@ LIRGenerator::visitInterruptCheck(MInterruptCheck* ins) // is complicated because there could be another AutoWritableJitCode on the // stack. LInstructionHelper<0, 0, 0>* lir; - if (GetJitContext()->runtime->canUseSignalHandlers()) { + if (GetJitContext()->runtime->canUseSignalHandlers() && + !ExecutableAllocator::nonWritableJitCode) + { lir = new(alloc()) LInterruptCheckImplicit(); } else { lir = new(alloc()) LInterruptCheck(); diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.cpp b/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.cpp deleted file mode 100644 index f34cd458ee5..00000000000 --- a/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.cpp +++ /dev/null @@ -1,607 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "jit/ProcessExecutableMemory.h" - -#include "mozilla/Array.h" -#include "mozilla/Atomics.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/Maybe.h" -#include "mozilla/TaggedAnonymousMemory.h" -#include "mozilla/XorShift128PlusRNG.h" - -#include "jsfriendapi.h" -#include "jslock.h" -#include "jsmath.h" -#include "jsutil.h" -#include "jswin.h" - -#include <errno.h> - -#include "gc/Memory.h" - -#ifdef XP_WIN -# include "mozilla/WindowsVersion.h" -#else -# include <sys/mman.h> -# include <unistd.h> -#endif - -using namespace js; -using namespace js::jit; - -#ifdef XP_WIN -static void* -ComputeRandomAllocationAddress() -{ - /* - * Inspiration is V8's OS::Allocate in platform-win32.cc. - * - * VirtualAlloc takes 64K chunks out of the virtual address space, so we - * keep 16b alignment. - * - * x86: V8 comments say that keeping addresses in the [64MiB, 1GiB) range - * tries to avoid system default DLL mapping space. In the end, we get 13 - * bits of randomness in our selection. - * x64: [2GiB, 4TiB), with 25 bits of randomness. - */ -# ifdef HAVE_64BIT_BUILD - static const uintptr_t base = 0x0000000080000000; - static const uintptr_t mask = 0x000003ffffff0000; -# elif defined(_M_IX86) || defined(__i386__) - static const uintptr_t base = 0x04000000; - static const uintptr_t mask = 0x3fff0000; -# else -# error "Unsupported architecture" -# endif - - uint64_t rand = js::GenerateRandomSeed(); - return (void*) (base | (rand & mask)); -} - -# ifdef HAVE_64BIT_BUILD -static js::JitExceptionHandler sJitExceptionHandler; - -JS_FRIEND_API(void) -js::SetJitExceptionHandler(JitExceptionHandler handler) -{ - MOZ_ASSERT(!sJitExceptionHandler); - sJitExceptionHandler = handler; -} - -// From documentation for UNWIND_INFO on -// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx -struct UnwindInfo -{ - uint8_t version : 3; - uint8_t flags : 5; - uint8_t sizeOfPrologue; - uint8_t countOfUnwindCodes; - uint8_t frameRegister : 4; - uint8_t frameOffset : 4; - ULONG exceptionHandler; -}; - -static const unsigned ThunkLength = 12; - -struct ExceptionHandlerRecord -{ - RUNTIME_FUNCTION runtimeFunction; - UnwindInfo unwindInfo; - uint8_t thunk[ThunkLength]; -}; - -// This function must match the function pointer type PEXCEPTION_HANDLER -// mentioned in: -// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx. -// This type is rather elusive in documentation; Wine is the best I've found: -// http://source.winehq.org/source/include/winnt.h -static DWORD -ExceptionHandler(PEXCEPTION_RECORD exceptionRecord, _EXCEPTION_REGISTRATION_RECORD*, - PCONTEXT context, _EXCEPTION_REGISTRATION_RECORD**) -{ - return sJitExceptionHandler(exceptionRecord, context); -} - -// For an explanation of the problem being solved here, see -// SetJitExceptionFilter in jsfriendapi.h. -static bool -RegisterExecutableMemory(void* p, size_t bytes, size_t pageSize) -{ - if (!VirtualAlloc(p, pageSize, MEM_COMMIT, PAGE_READWRITE)) - MOZ_CRASH(); - - ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p); - - // All these fields are specified to be offsets from the base of the - // executable code (which is 'p'), even if they have 'Address' in their - // names. In particular, exceptionHandler is a ULONG offset which is a - // 32-bit integer. Since 'p' can be farther than INT32_MAX away from - // sJitExceptionHandler, we must generate a little thunk inside the - // record. The record is put on its own page so that we can take away write - // access to protect against accidental clobbering. - - r->runtimeFunction.BeginAddress = pageSize; - r->runtimeFunction.EndAddress = (DWORD)bytes; - r->runtimeFunction.UnwindData = offsetof(ExceptionHandlerRecord, unwindInfo); - - r->unwindInfo.version = 1; - r->unwindInfo.flags = UNW_FLAG_EHANDLER; - r->unwindInfo.sizeOfPrologue = 0; - r->unwindInfo.countOfUnwindCodes = 0; - r->unwindInfo.frameRegister = 0; - r->unwindInfo.frameOffset = 0; - r->unwindInfo.exceptionHandler = offsetof(ExceptionHandlerRecord, thunk); - - // mov imm64, rax - r->thunk[0] = 0x48; - r->thunk[1] = 0xb8; - void* handler = JS_FUNC_TO_DATA_PTR(void*, ExceptionHandler); - memcpy(&r->thunk[2], &handler, 8); - - // jmp rax - r->thunk[10] = 0xff; - r->thunk[11] = 0xe0; - - DWORD oldProtect; - if (!VirtualProtect(p, pageSize, PAGE_EXECUTE_READ, &oldProtect)) - MOZ_CRASH(); - - bool success = RtlAddFunctionTable(&r->runtimeFunction, 1, reinterpret_cast<DWORD64>(p)); - - return success; -} - -static void -UnregisterExecutableMemory(void* p, size_t bytes, size_t pageSize) -{ - ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p); - - RtlDeleteFunctionTable(&r->runtimeFunction); -} -# endif - -static void* -ReserveProcessExecutableMemory(size_t bytes) -{ -# ifdef HAVE_64BIT_BUILD - size_t pageSize = gc::SystemPageSize(); - if (sJitExceptionHandler) - bytes += pageSize; -# endif - - void* p = nullptr; - for (size_t i = 0; i < 10; i++) { - void* randomAddr = ComputeRandomAllocationAddress(); - p = VirtualAlloc(randomAddr, bytes, MEM_RESERVE, PAGE_NOACCESS); - if (p) - break; - } - - if (!p) { - // Try again without randomization. - p = VirtualAlloc(nullptr, bytes, MEM_RESERVE, PAGE_NOACCESS); - if (!p) - return nullptr; - } - -# ifdef HAVE_64BIT_BUILD - if (sJitExceptionHandler) { - if (!RegisterExecutableMemory(p, bytes, pageSize)) { - VirtualFree(p, 0, MEM_RELEASE); - return nullptr; - } - - p = (uint8_t*)p + pageSize; - } -# endif - - return p; -} - -static void -DeallocateProcessExecutableMemory(void* addr, size_t bytes) -{ -# ifdef HAVE_64BIT_BUILD - if (sJitExceptionHandler) { - size_t pageSize = gc::SystemPageSize(); - addr = (uint8_t*)addr - pageSize; - UnregisterExecutableMemory(addr, bytes, pageSize); - } -# endif - - VirtualFree(addr, 0, MEM_RELEASE); -} - -static DWORD -ProtectionSettingToFlags(ProtectionSetting protection) -{ - return PAGE_EXECUTE_READWRITE; -} - -static void -CommitPages(void* addr, size_t bytes, ProtectionSetting protection) -{ - if (!VirtualAlloc(addr, bytes, MEM_COMMIT, ProtectionSettingToFlags(protection))) - MOZ_CRASH("CommitPages failed"); -} - -static void -DecommitPages(void* addr, size_t bytes) -{ - if (!VirtualFree(addr, bytes, MEM_DECOMMIT)) - MOZ_CRASH("DecommitPages failed"); -} -#else // !XP_WIN -static void* -ComputeRandomAllocationAddress() -{ - uint64_t rand = js::GenerateRandomSeed(); - -# ifdef HAVE_64BIT_BUILD - // x64 CPUs have a 48-bit address space and on some platforms the OS will - // give us access to 47 bits, so to be safe we right shift by 18 to leave - // 46 bits. - rand >>= 18; -# else - // On 32-bit, right shift by 34 to leave 30 bits, range [0, 1GiB). Then add - // 512MiB to get range [512MiB, 1.5GiB), or [0x20000000, 0x60000000). This - // is based on V8 comments in platform-posix.cc saying this range is - // relatively unpopulated across a variety of kernels. - rand >>= 34; - rand += 512 * 1024 * 1024; -# endif - - // Ensure page alignment. - uintptr_t mask = ~uintptr_t(gc::SystemPageSize() - 1); - return (void*) uintptr_t(rand & mask); -} - -static void* -ReserveProcessExecutableMemory(size_t bytes) -{ - // Note that randomAddr is just a hint: if the address is not available - // mmap will pick a different address. - void* randomAddr = ComputeRandomAllocationAddress(); - void* p = MozTaggedAnonymousMmap(randomAddr, bytes, PROT_NONE, MAP_PRIVATE | MAP_ANON, - -1, 0, "js-executable-memory"); - if (p == MAP_FAILED) - return nullptr; - return p; -} - -static void -DeallocateProcessExecutableMemory(void* addr, size_t bytes) -{ - mozilla::DebugOnly<int> result = munmap(addr, bytes); - MOZ_ASSERT(!result || errno == ENOMEM); -} - -static unsigned -ProtectionSettingToFlags(ProtectionSetting protection) -{ - return PROT_READ | PROT_WRITE | PROT_EXEC; -} - -static void -CommitPages(void* addr, size_t bytes, ProtectionSetting protection) -{ - void* p = MozTaggedAnonymousMmap(addr, bytes, ProtectionSettingToFlags(protection), - MAP_FIXED | MAP_PRIVATE | MAP_ANON, - -1, 0, "js-executable-memory"); - MOZ_RELEASE_ASSERT(addr == p); -} - -static void -DecommitPages(void* addr, size_t bytes) -{ - // Use mmap with MAP_FIXED and PROT_NONE. Inspired by jemalloc's - // pages_decommit. - void* p = MozTaggedAnonymousMmap(addr, bytes, PROT_NONE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, - -1, 0, "js-executable-memory"); - MOZ_RELEASE_ASSERT(addr == p); -} -#endif - -template <size_t NumBits> -class PageBitSet -{ - using WordType = uint32_t; - static const size_t BitsPerWord = sizeof(WordType) * 8; - - static_assert((NumBits % BitsPerWord) == 0, - "NumBits must be a multiple of BitsPerWord"); - static const size_t NumWords = NumBits / BitsPerWord; - - mozilla::Array<WordType, NumWords> words_; - - uint32_t indexToWord(uint32_t index) const { - MOZ_ASSERT(index < NumBits); - return index / BitsPerWord; - } - WordType indexToBit(uint32_t index) const { - MOZ_ASSERT(index < NumBits); - return WordType(1) << (index % BitsPerWord); - } - - public: - void init() { - mozilla::PodArrayZero(words_); - } - bool contains(size_t index) const { - uint32_t word = indexToWord(index); - return words_[word] & indexToBit(index); - } - void insert(size_t index) { - MOZ_ASSERT(!contains(index)); - uint32_t word = indexToWord(index); - words_[word] |= indexToBit(index); - } - void remove(size_t index) { - MOZ_ASSERT(contains(index)); - uint32_t word = indexToWord(index); - words_[word] &= ~indexToBit(index); - } - -#ifdef DEBUG - bool empty() const { - for (size_t i = 0; i < NumWords; i++) { - if (words_[i] != 0) - return false; - } - return true; - } -#endif -}; - -// Limit on the number of bytes of executable memory to prevent JIT spraying -// attacks. -#if JS_BITS_PER_WORD == 32 -static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024; -#else -static const size_t MaxCodeBytesPerProcess = 640 * 1024 * 1024; -#endif - -// Per-process executable memory allocator. It reserves a block of memory of -// MaxCodeBytesPerProcess bytes, then allocates/deallocates pages from that. -// -// This has a number of benefits compared to raw mmap/VirtualAlloc: -// -// * More resillient against certain attacks. -// -// * Behaves more consistently across platforms: it avoids the 64K granularity -// issues on Windows, for instance. -// -// * On x64, near jumps can be used for jumps to other JIT pages. -// -// * On Win64, we have to register the exception handler only once (at process -// startup). This saves some memory and avoids RtlAddFunctionTable profiler -// deadlocks. -class ProcessExecutableMemory -{ - static_assert((MaxCodeBytesPerProcess % ExecutableCodePageSize) == 0, - "MaxCodeBytesPerProcess must be a multiple of ExecutableCodePageSize"); - static const size_t MaxCodePages = MaxCodeBytesPerProcess / ExecutableCodePageSize; - - // Start of the MaxCodeBytesPerProcess memory block or nullptr if - // uninitialized. Note that this is NOT guaranteed to be aligned to - // ExecutableCodePageSize. - uint8_t* base_; - - // The fields below should only be accessed while we hold the lock. - PRLock* lock_; - - // pagesAllocated_ is an Atomic so that bytesAllocated does not have to - // take the lock. - mozilla::Atomic<size_t, mozilla::ReleaseAcquire> pagesAllocated_; - - // Page where we should try to allocate next. - size_t cursor_; - - mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> rng_; - PageBitSet<MaxCodePages> pages_; - - public: - ProcessExecutableMemory() - : base_(nullptr), - lock_(nullptr), - pagesAllocated_(0), - cursor_(0), - rng_(), - pages_() - {} - - MOZ_MUST_USE bool init() { - pages_.init(); - - MOZ_RELEASE_ASSERT(!initialized()); - MOZ_RELEASE_ASSERT(gc::SystemPageSize() <= ExecutableCodePageSize); - - lock_ = PR_NewLock(); - if (!lock_) - return false; - - void* p = ReserveProcessExecutableMemory(MaxCodeBytesPerProcess); - if (!p) - return false; - - base_ = static_cast<uint8_t*>(p); - - mozilla::Array<uint64_t, 2> seed; - GenerateXorShift128PlusSeed(seed); - rng_.emplace(seed[0], seed[1]); - return true; - } - - bool initialized() const { - return base_ != nullptr; - } - - size_t bytesAllocated() const { - MOZ_ASSERT(pagesAllocated_ <= MaxCodePages); - return pagesAllocated_ * ExecutableCodePageSize; - } - - void release() { - MOZ_ASSERT(initialized()); - MOZ_ASSERT(pages_.empty()); - MOZ_ASSERT(pagesAllocated_ == 0); - DeallocateProcessExecutableMemory(base_, MaxCodeBytesPerProcess); - base_ = nullptr; - rng_.reset(); - MOZ_ASSERT(lock_); - PR_DestroyLock(lock_); - lock_ = nullptr; - MOZ_ASSERT(!initialized()); - } - - void assertValidAddress(void* p, size_t bytes) const { - MOZ_RELEASE_ASSERT(p >= base_ && - uintptr_t(p) + bytes <= uintptr_t(base_) + MaxCodeBytesPerProcess); - } - - void* allocate(size_t bytes, ProtectionSetting protection); - void deallocate(void* addr, size_t bytes); -}; - -void* -ProcessExecutableMemory::allocate(size_t bytes, ProtectionSetting protection) -{ - MOZ_ASSERT(initialized()); - MOZ_ASSERT(bytes > 0); - MOZ_ASSERT((bytes % ExecutableCodePageSize) == 0); - - size_t numPages = bytes / ExecutableCodePageSize; - - // Take the lock and try to allocate. - void* p = nullptr; - { - PR_Lock(lock_); - MOZ_ASSERT(pagesAllocated_ <= MaxCodePages); - - // Check if we have enough pages available. - if (pagesAllocated_ + numPages >= MaxCodePages) { - PR_Unlock(lock_); - return nullptr; - } - - MOZ_ASSERT(bytes <= MaxCodeBytesPerProcess); - - // Maybe skip a page to make allocations less predictable. - size_t page = cursor_ + (rng_.ref().next() % 2); - - for (size_t i = 0; i < MaxCodePages; i++) { - // Make sure page + numPages - 1 is a valid index. - if (page + numPages > MaxCodePages) - page = 0; - - bool available = true; - for (size_t j = 0; j < numPages; j++) { - if (pages_.contains(page + j)) { - available = false; - break; - } - } - if (!available) { - page++; - continue; - } - - // Mark the pages as unavailable. - for (size_t j = 0; j < numPages; j++) - pages_.insert(page + j); - - pagesAllocated_ += numPages; - MOZ_ASSERT(pagesAllocated_ <= MaxCodePages); - - // If we allocated a small number of pages, move cursor_ to the - // next page. We don't do this for larger allocations to avoid - // skipping a large number of small holes. - if (numPages <= 2) - cursor_ = page + numPages; - - p = base_ + page * ExecutableCodePageSize; - break; - } - PR_Unlock(lock_); - if (!p) - return nullptr; - } - - // Commit the pages after releasing the lock. - CommitPages(p, bytes, protection); - return p; -} - -void -ProcessExecutableMemory::deallocate(void* addr, size_t bytes) -{ - MOZ_ASSERT(initialized()); - MOZ_ASSERT(addr); - MOZ_ASSERT((uintptr_t(addr) % gc::SystemPageSize()) == 0); - MOZ_ASSERT(bytes > 0); - MOZ_ASSERT((bytes % ExecutableCodePageSize) == 0); - - assertValidAddress(addr, bytes); - - size_t firstPage = (static_cast<uint8_t*>(addr) - base_) / ExecutableCodePageSize; - size_t numPages = bytes / ExecutableCodePageSize; - - // Decommit before taking the lock. - DecommitPages(addr, bytes); - - PR_Lock(lock_); - MOZ_ASSERT(numPages <= pagesAllocated_); - pagesAllocated_ -= numPages; - - for (size_t i = 0; i < numPages; i++) - pages_.remove(firstPage + i); - - // Move the cursor back so we can reuse pages instead of fragmenting the - // whole region. - if (firstPage < cursor_) - cursor_ = firstPage; - - PR_Unlock(lock_); -} - -static ProcessExecutableMemory execMemory; - -void* -js::jit::AllocateExecutableMemory(size_t bytes, ProtectionSetting protection) -{ - return execMemory.allocate(bytes, protection); -} - -void -js::jit::DeallocateExecutableMemory(void* addr, size_t bytes) -{ - execMemory.deallocate(addr, bytes); -} - -bool -js::jit::InitProcessExecutableMemory() -{ - return execMemory.init(); -} - -void -js::jit::ReleaseProcessExecutableMemory() -{ - execMemory.release(); -} - -bool -js::jit::CanLikelyAllocateMoreExecutableMemory() -{ - // Use a 16 MB buffer. - static const size_t BufferSize = 16 * 1024 * 1024; - - MOZ_ASSERT(execMemory.bytesAllocated() <= MaxCodeBytesPerProcess); - - return execMemory.bytesAllocated() + BufferSize <= MaxCodeBytesPerProcess; -} diff --git a/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.h b/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.h deleted file mode 100644 index 7884706e3bd..00000000000 --- a/src/third_party/mozjs-45/extract/js/src/jit/ProcessExecutableMemory.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- 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/. */ - -#ifndef jit_ProcessExecutableMemory_h -#define jit_ProcessExecutableMemory_h - -#include "mozilla/Attributes.h" - -namespace js { -namespace jit { - -// Executable code is allocated in 64K chunks. ExecutableAllocator uses pools -// that are at least this big. Code we allocate does not necessarily have 64K -// alignment though. -static const size_t ExecutableCodePageSize = 64 * 1024; - -enum class ProtectionSetting { - Protected, // Not readable, writable, or executable. - Writable, - Executable, -}; - -// Functions called at process start-up/shutdown to initialize/release the -// executable memory region. -extern MOZ_MUST_USE bool InitProcessExecutableMemory(); -extern void ReleaseProcessExecutableMemory(); - -// Allocate/deallocate executable pages. -extern void* AllocateExecutableMemory(size_t bytes, ProtectionSetting protection); -extern void DeallocateExecutableMemory(void* addr, size_t bytes); - -// Returns true if we can allocate a few more MB of executable code without -// hitting our code limit. This function can be used to stop compiling things -// that are optional (like Baseline and Ion code) when we're about to reach the -// limit, so we are less likely to OOM or crash. Note that the limit is -// per-process, so other threads can also allocate code after we call this -// function. -extern bool CanLikelyAllocateMoreExecutableMemory(); - -} // namespace jit -} // namespace js - -#endif // jit_ProcessExecutableMemory_h diff --git a/src/third_party/mozjs-45/extract/js/src/jit/SharedIC.cpp b/src/third_party/mozjs-45/extract/js/src/jit/SharedIC.cpp index 3d3a30f4813..2867776f0af 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/SharedIC.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/SharedIC.cpp @@ -2448,14 +2448,6 @@ IsCacheableGetPropCall(JSContext* cx, JSObject* obj, JSObject* holder, Shape* sh return false; JSFunction* func = &shape->getterObject()->as<JSFunction>(); - if (IsWindow(obj)) { - if (!func->isNative()) - return false; - - if (!func->jitInfo() || func->jitInfo()->needsOuterizedThisObject()) - return false; - } - if (func->isNative()) { *isScripted = false; return true; diff --git a/src/third_party/mozjs-45/extract/js/src/jit/VMFunctions.cpp b/src/third_party/mozjs-45/extract/js/src/jit/VMFunctions.cpp index 1296b52fec5..6eda48e0a5f 100644 --- a/src/third_party/mozjs-45/extract/js/src/jit/VMFunctions.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jit/VMFunctions.cpp @@ -1208,18 +1208,14 @@ AssertValidStringPtr(JSContext* cx, JSString* str) MOZ_ASSERT(str->length() <= JSString::MAX_LENGTH); gc::AllocKind kind = str->getAllocKind(); - if (str->isFatInline()) { - MOZ_ASSERT(kind == gc::AllocKind::FAT_INLINE_STRING || - kind == gc::AllocKind::FAT_INLINE_ATOM); - } else if (str->isExternal()) { + if (str->isFatInline()) + MOZ_ASSERT(kind == gc::AllocKind::FAT_INLINE_STRING); + else if (str->isExternal()) MOZ_ASSERT(kind == gc::AllocKind::EXTERNAL_STRING); - } else if (str->isAtom()) { - MOZ_ASSERT(kind == gc::AllocKind::ATOM); - } else if (str->isFlat()) { + else if (str->isAtom() || str->isFlat()) MOZ_ASSERT(kind == gc::AllocKind::STRING || kind == gc::AllocKind::FAT_INLINE_STRING); - } else { + else MOZ_ASSERT(kind == gc::AllocKind::STRING); - } #endif } diff --git a/src/third_party/mozjs-45/extract/js/src/jsarray.cpp b/src/third_party/mozjs-45/extract/js/src/jsarray.cpp index 1131720cb72..59384b3fd4b 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsarray.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsarray.cpp @@ -1882,7 +1882,6 @@ js::array_sort(JSContext* cx, unsigned argc, Value* vp) undefs = 0; bool allStrings = true; bool allInts = true; - bool extraIndexed = ObjectMayHaveExtraIndexedProperties(obj); RootedValue v(cx); for (uint32_t i = 0; i < len; i++) { if (!CheckForInterrupt(cx)) @@ -1915,10 +1914,7 @@ js::array_sort(JSContext* cx, unsigned argc, Value* vp) } /* Here len == n + undefs + number_of_holes. */ - bool defaultOrMatch; if (fval.isNull()) { - defaultOrMatch = true; - /* * Sort using the default comparator converting all elements to * strings. @@ -1942,7 +1938,6 @@ js::array_sort(JSContext* cx, unsigned argc, Value* vp) if (comp == Match_Failure) return false; - defaultOrMatch = comp != Match_None; if (comp != Match_None) { if (allInts) { JS_ALWAYS_TRUE(vec.resize(n * 2)); @@ -1963,10 +1958,7 @@ js::array_sort(JSContext* cx, unsigned argc, Value* vp) } } - ShouldUpdateTypes updateTypes = !extraIndexed && (allStrings || allInts) && defaultOrMatch - ? ShouldUpdateTypes::DontUpdate - : ShouldUpdateTypes::Update; - if (!InitArrayElements(cx, obj, 0, uint32_t(n), vec.begin(), updateTypes)) + if (!InitArrayElements(cx, obj, 0, uint32_t(n), vec.begin(), ShouldUpdateTypes::DontUpdate)) return false; } diff --git a/src/third_party/mozjs-45/extract/js/src/jsatom.cpp b/src/third_party/mozjs-45/extract/js/src/jsatom.cpp index 65f1deffbf9..3d3c0e4d821 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsatom.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsatom.cpp @@ -340,8 +340,7 @@ AtomizeAndCopyChars(ExclusiveContext* cx, const CharT* tbchars, size_t length, P return nullptr; } - JSAtom* atom = flat->morphAtomizedStringIntoAtom(lookup.hash); - MOZ_ASSERT(atom->hash() == lookup.hash); + JSAtom* atom = flat->morphAtomizedStringIntoAtom(); // We have held the lock since looking up p, and the operations we've done // since then can't GC; therefore the atoms table has not been modified and diff --git a/src/third_party/mozjs-45/extract/js/src/jsatom.h b/src/third_party/mozjs-45/extract/js/src/jsatom.h index 48d3c0ef9cf..ed1a6c9adf8 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsatom.h +++ b/src/third_party/mozjs-45/extract/js/src/jsatom.h @@ -23,6 +23,25 @@ class JSAutoByteString; namespace js { +JS_STATIC_ASSERT(sizeof(HashNumber) == 4); + +static MOZ_ALWAYS_INLINE js::HashNumber +HashId(jsid id) +{ + return mozilla::HashGeneric(JSID_BITS(id)); +} + +struct JsidHasher +{ + typedef jsid Lookup; + static HashNumber hash(const Lookup& l) { + return HashNumber(JSID_BITS(l)); + } + static bool match(const jsid& id, const Lookup& l) { + return id == l; + } +}; + /* * Return a printable, lossless char[] representation of a string-type atom. * The lifetime of the result matches the lifetime of bytes. diff --git a/src/third_party/mozjs-45/extract/js/src/jsatominlines.h b/src/third_party/mozjs-45/extract/js/src/jsatominlines.h index 216a91071e2..2fb7d35aa0a 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsatominlines.h +++ b/src/third_party/mozjs-45/extract/js/src/jsatominlines.h @@ -156,13 +156,12 @@ inline AtomHasher::Lookup::Lookup(const JSAtom* atom) : isLatin1(atom->hasLatin1Chars()), length(atom->length()), atom(atom) { - hash = atom->hash(); if (isLatin1) { latin1Chars = atom->latin1Chars(nogc); - MOZ_ASSERT(mozilla::HashString(latin1Chars, length) == hash); + hash = mozilla::HashString(latin1Chars, length); } else { twoByteChars = atom->twoByteChars(nogc); - MOZ_ASSERT(mozilla::HashString(twoByteChars, length) == hash); + hash = mozilla::HashString(twoByteChars, length); } } @@ -172,7 +171,7 @@ AtomHasher::match(const AtomStateEntry& entry, const Lookup& lookup) JSAtom* key = entry.asPtr(); if (lookup.atom) return lookup.atom == key; - if (key->length() != lookup.length || key->hash() != lookup.hash) + if (key->length() != lookup.length) return false; if (key->hasLatin1Chars()) { diff --git a/src/third_party/mozjs-45/extract/js/src/jscntxt.h b/src/third_party/mozjs-45/extract/js/src/jscntxt.h index 89bf2863503..0f70509d67f 100644 --- a/src/third_party/mozjs-45/extract/js/src/jscntxt.h +++ b/src/third_party/mozjs-45/extract/js/src/jscntxt.h @@ -12,7 +12,6 @@ #include "mozilla/MemoryReporting.h" #include "js/TraceableVector.h" -#include "js/Utility.h" #include "js/Vector.h" #include "vm/Runtime.h" diff --git a/src/third_party/mozjs-45/extract/js/src/jscompartment.cpp b/src/third_party/mozjs-45/extract/js/src/jscompartment.cpp index 0d72551ef4b..c0d41ce8037 100644 --- a/src/third_party/mozjs-45/extract/js/src/jscompartment.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jscompartment.cpp @@ -46,7 +46,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), - isAtomsCompartment_(false), isSelfHosting(false), marked(true), warnedAboutFlagsArgument(false), @@ -73,7 +72,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = gcIncomingGrayPointers(nullptr), gcPreserveJitCode(options.preserveJitCode()), debugModeBits(0), - randomKeyGenerator_(runtime_->forkRandomKeyGenerator()), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), @@ -159,12 +157,6 @@ JSRuntime::createJitRuntime(JSContext* cx) MOZ_ASSERT(!jitRuntime_); - if (!CanLikelyAllocateMoreExecutableMemory()) { - // Report OOM instead of potentially hitting the MOZ_CRASH below. - ReportOutOfMemory(cx); - return nullptr; - } - jit::JitRuntime* jrt = cx->new_<jit::JitRuntime>(); if (!jrt) return nullptr; @@ -1176,20 +1168,6 @@ JSCompartment::addTelemetry(const char* filename, DeprecatedLanguageExtension e) sawDeprecatedLanguageExtension[e] = true; } -HashNumber -JSCompartment::randomHashCode() -{ - ensureRandomNumberGenerator(); - return HashNumber(randomNumberGenerator.ref().next()); -} - -mozilla::HashCodeScrambler -JSCompartment::randomHashCodeScrambler() -{ - return mozilla::HashCodeScrambler(randomKeyGenerator_.next(), - randomKeyGenerator_.next()); -} - AutoSetNewObjectMetadata::AutoSetNewObjectMetadata(ExclusiveContext* ecx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) : CustomAutoRooter(ecx) diff --git a/src/third_party/mozjs-45/extract/js/src/jscompartment.h b/src/third_party/mozjs-45/extract/js/src/jscompartment.h index de5592fd65a..96938211507 100644 --- a/src/third_party/mozjs-45/extract/js/src/jscompartment.h +++ b/src/third_party/mozjs-45/extract/js/src/jscompartment.h @@ -270,19 +270,9 @@ struct JSCompartment performanceMonitoring.unlink(); isSystem_ = isSystem; } - - bool isAtomsCompartment() const { - return isAtomsCompartment_; - } - void setIsAtomsCompartment() { - isAtomsCompartment_ = true; - } - private: JSPrincipals* principals_; bool isSystem_; - bool isAtomsCompartment_; - public: bool isSelfHosting; bool marked; @@ -611,14 +601,6 @@ struct JSCompartment void ensureRandomNumberGenerator(); private: - mozilla::non_crypto::XorShift128PlusRNG randomKeyGenerator_; - - public: - js::HashNumber randomHashCode(); - - mozilla::HashCodeScrambler randomHashCodeScrambler(); - - private: JSCompartment* thisForCtor() { return this; } public: diff --git a/src/third_party/mozjs-45/extract/js/src/jsgc.cpp b/src/third_party/mozjs-45/extract/js/src/jsgc.cpp index 776ebef6563..610fd78b0b6 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsgc.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsgc.cpp @@ -238,7 +238,6 @@ using namespace js; using namespace js::gc; using mozilla::ArrayLength; -using mozilla::HashCodeScrambler; using mozilla::Maybe; using mozilla::Swap; @@ -292,8 +291,6 @@ const uint32_t Arena::ThingSizes[] = CHECK_MIN_THING_SIZE( sizeof(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ sizeof(JSString), /* AllocKind::STRING */ sizeof(JSExternalString), /* AllocKind::EXTERNAL_STRING */ - sizeof(js::FatInlineAtom), /* AllocKind::FAT_INLINE_ATOM */ - sizeof(js::NormalAtom), /* AllocKind::ATOM */ sizeof(JS::Symbol), /* AllocKind::SYMBOL */ sizeof(jit::JitCode), /* AllocKind::JITCODE */ ); @@ -327,8 +324,6 @@ const uint32_t Arena::FirstThingOffsets[] = { OFFSET(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ OFFSET(JSString), /* AllocKind::STRING */ OFFSET(JSExternalString), /* AllocKind::EXTERNAL_STRING */ - OFFSET(js::FatInlineAtom), /* AllocKind::FAT_INLINE_ATOM */ - OFFSET(js::NormalAtom), /* AllocKind::ATOM */ OFFSET(JS::Symbol), /* AllocKind::SYMBOL */ OFFSET(jit::JitCode), /* AllocKind::JITCODE */ }; @@ -385,8 +380,6 @@ static const AllocKind BackgroundPhaseObjects[] = { static const AllocKind BackgroundPhaseStringsAndSymbols[] = { AllocKind::FAT_INLINE_STRING, AllocKind::STRING, - AllocKind::FAT_INLINE_ATOM, - AllocKind::ATOM, AllocKind::SYMBOL }; @@ -640,10 +633,6 @@ FinalizeArenas(FreeOp* fop, return FinalizeTypedArenas<JSFatInlineString>(fop, src, dest, thingKind, budget, keepArenas); case AllocKind::EXTERNAL_STRING: return FinalizeTypedArenas<JSExternalString>(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::FAT_INLINE_ATOM: - return FinalizeTypedArenas<js::FatInlineAtom>(fop, src, dest, thingKind, budget, keepArenas); - case AllocKind::ATOM: - return FinalizeTypedArenas<js::NormalAtom>(fop, src, dest, thingKind, budget, keepArenas); case AllocKind::SYMBOL: return FinalizeTypedArenas<JS::Symbol>(fop, src, dest, thingKind, budget, keepArenas); case AllocKind::JITCODE: @@ -2334,9 +2323,8 @@ GCRuntime::relocateArenas(Zone* zone, JS::gcreason::Reason reason, ArenaHeader*& void MovingTracer::onObjectEdge(JSObject** objp) { - JSObject* obj = *objp; - if (obj->runtimeFromAnyThread() == runtime() && IsForwarded(obj)) - *objp = Forwarded(obj); + if (IsForwarded(*objp)) + *objp = Forwarded(*objp); } void @@ -2489,8 +2477,6 @@ bool ArenasToUpdate::shouldProcessKind(AllocKind kind) if (kind == AllocKind::FAT_INLINE_STRING || kind == AllocKind::STRING || kind == AllocKind::EXTERNAL_STRING || - kind == AllocKind::FAT_INLINE_ATOM || - kind == AllocKind::ATOM || kind == AllocKind::SYMBOL) { return false; @@ -3796,12 +3782,10 @@ GCRuntime::purgeRuntime() bool GCRuntime::shouldPreserveJITCode(JSCompartment* comp, int64_t currentTime, - JS::gcreason::Reason reason, bool canAllocateMoreCode) + JS::gcreason::Reason reason) { if (cleanUpEverything) return false; - if (!canAllocateMoreCode) - return false; if (alwaysPreserveCode) return true; @@ -3948,19 +3932,15 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason) zone->setPreservingCode(false); } - // Discard JIT code more aggressively if the process is approaching its - // executable code limit. - bool canAllocateMoreCode = jit::CanLikelyAllocateMoreExecutableMemory(); - for (CompartmentsIter c(rt, WithAtoms); !c.done(); c.next()) { c->marked = false; c->scheduledForDestruction = false; c->maybeAlive = false; - if (shouldPreserveJITCode(c, currentTime, reason, canAllocateMoreCode)) + if (shouldPreserveJITCode(c, currentTime, reason)) c->zone()->setPreservingCode(true); } - if (!rt->gc.cleanUpEverything && canAllocateMoreCode) { + if (!rt->gc.cleanUpEverything) { if (JSCompartment* comp = jit::TopmostIonActivationCompartment(rt)) comp->zone()->setPreservingCode(true); } @@ -4318,7 +4298,7 @@ js::gc::MarkingValidator::nonIncrementalMark() * For saving, smush all of the keys into one big table and split them back * up into per-zone tables when restoring. */ - gc::WeakKeyTable savedWeakKeys(SystemAllocPolicy(), runtime->randomHashCodeScrambler()); + gc::WeakKeyTable savedWeakKeys; if (!savedWeakKeys.init()) return; @@ -4591,6 +4571,7 @@ Zone::findOutgoingEdges(ComponentFinder<JS::Zone>& finder) if (r.front()->isGCMarking()) finder.addEdgeTo(r.front()); } + gcZoneGroupEdges.clear(); Debugger::findZoneEdges(this, finder); } @@ -4619,11 +4600,6 @@ GCRuntime::findZoneEdgesForWeakMaps() void GCRuntime::findZoneGroups() { -#ifdef DEBUG - for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) - MOZ_ASSERT(zone->gcZoneGroupEdges.empty()); -#endif - ComponentFinder<Zone> finder(rt->mainThread.nativeStackLimit[StackForSystemCode]); if (!isIncremental || !findZoneEdgesForWeakMaps()) finder.useOneComponent(); @@ -4636,19 +4612,12 @@ GCRuntime::findZoneGroups() currentZoneGroup = zoneGroups; zoneGroupIndex = 0; - for (GCZonesIter zone(rt); !zone.done(); zone.next()) - zone->gcZoneGroupEdges.clear(); - -#ifdef DEBUG for (Zone* head = currentZoneGroup; head; head = head->nextGroup()) { for (Zone* zone = head; zone; zone = zone->nextNodeInGroup()) MOZ_ASSERT(zone->isGCMarking()); } MOZ_ASSERT_IF(!isIncremental, !currentZoneGroup->nextGroup()); - for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) - MOZ_ASSERT(zone->gcZoneGroupEdges.empty()); -#endif } static void @@ -4818,11 +4787,11 @@ MarkIncomingCrossCompartmentPointers(JSRuntime* rt, const uint32_t color) MOZ_ASSERT(dst->compartment() == c); if (color == GRAY) { - if (IsMarkedUnbarriered(rt, &src) && src->asTenured().isMarked(GRAY)) + if (IsMarkedUnbarriered(&src) && src->asTenured().isMarked(GRAY)) TraceManuallyBarrieredEdge(&rt->gc.marker, &dst, "cross-compartment gray pointer"); } else { - if (IsMarkedUnbarriered(rt, &src) && !src->asTenured().isMarked(GRAY)) + if (IsMarkedUnbarriered(&src) && !src->asTenured().isMarked(GRAY)) TraceManuallyBarrieredEdge(&rt->gc.marker, &dst, "cross-compartment black pointer"); } diff --git a/src/third_party/mozjs-45/extract/js/src/jsgc.h b/src/third_party/mozjs-45/extract/js/src/jsgc.h index d4cfc9960b8..a254a0b3ae9 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsgc.h +++ b/src/third_party/mozjs-45/extract/js/src/jsgc.h @@ -103,8 +103,6 @@ template <> struct MapTypeToFinalizeKind<ObjectGroup> { static const Alloc template <> struct MapTypeToFinalizeKind<JSFatInlineString> { static const AllocKind kind = AllocKind::FAT_INLINE_STRING; }; template <> struct MapTypeToFinalizeKind<JSString> { static const AllocKind kind = AllocKind::STRING; }; template <> struct MapTypeToFinalizeKind<JSExternalString> { static const AllocKind kind = AllocKind::EXTERNAL_STRING; }; -template <> struct MapTypeToFinalizeKind<js::FatInlineAtom> { static const AllocKind kind = AllocKind::FAT_INLINE_ATOM; }; -template <> struct MapTypeToFinalizeKind<js::NormalAtom> { static const AllocKind kind = AllocKind::ATOM; }; template <> struct MapTypeToFinalizeKind<JS::Symbol> { static const AllocKind kind = AllocKind::SYMBOL; }; template <> struct MapTypeToFinalizeKind<jit::JitCode> { static const AllocKind kind = AllocKind::JITCODE; }; @@ -142,8 +140,6 @@ IsNurseryAllocable(AllocKind kind) false, /* AllocKind::FAT_INLINE_STRING */ false, /* AllocKind::STRING */ false, /* AllocKind::EXTERNAL_STRING */ - false, /* AllocKind::FAT_INLINE_ATOM */ - false, /* AllocKind::ATOM */ false, /* AllocKind::SYMBOL */ false, /* AllocKind::JITCODE */ }; @@ -179,8 +175,6 @@ IsBackgroundFinalized(AllocKind kind) true, /* AllocKind::FAT_INLINE_STRING */ true, /* AllocKind::STRING */ false, /* AllocKind::EXTERNAL_STRING */ - true, /* AllocKind::FAT_INLINE_ATOM */ - true, /* AllocKind::ATOM */ true, /* AllocKind::SYMBOL */ false, /* AllocKind::JITCODE */ }; diff --git a/src/third_party/mozjs-45/extract/js/src/jsgcinlines.h b/src/third_party/mozjs-45/extract/js/src/jsgcinlines.h index 0cc2b051cb4..6ca8804cd8f 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsgcinlines.h +++ b/src/third_party/mozjs-45/extract/js/src/jsgcinlines.h @@ -89,19 +89,11 @@ class ArenaIter } }; -enum CellIterNeedsBarrier : uint8_t -{ - CellIterDoesntNeedBarrier = 0, - CellIterMayNeedBarrier = 1 -}; - class ArenaCellIterImpl { - // These are set in initUnsynchronized(). + // These three are set in initUnsynchronized(). size_t firstThingOffset; size_t thingSize; - JS::TraceKind traceKind; - bool needsBarrier; #ifdef DEBUG bool isInited; #endif @@ -130,30 +122,26 @@ class ArenaCellIterImpl ArenaCellIterImpl() : firstThingOffset(0) // Squelch , thingSize(0) // warnings - , traceKind(JS::TraceKind::Null) - , needsBarrier(false) , limit(0) { } - void initUnsynchronized(ArenaHeader* aheader, CellIterNeedsBarrier mayNeedBarrier) { + void initUnsynchronized(ArenaHeader* aheader) { AllocKind kind = aheader->getAllocKind(); #ifdef DEBUG isInited = true; #endif firstThingOffset = Arena::firstThingOffset(kind); thingSize = Arena::thingSize(kind); - traceKind = MapAllocToTraceKind(kind); - needsBarrier = mayNeedBarrier && !aheader->zone->runtimeFromMainThread()->isHeapCollecting(); reset(aheader); } - void init(ArenaHeader* aheader, CellIterNeedsBarrier mayNeedBarrier) { + void init(ArenaHeader* aheader) { #ifdef DEBUG AllocKind kind = aheader->getAllocKind(); MOZ_ASSERT(aheader->zone->arenas.isSynchronizedFreeList(kind)); #endif - initUnsynchronized(aheader, mayNeedBarrier); + initUnsynchronized(aheader); } // Use this to move from an Arena of a particular kind to another Arena of @@ -173,15 +161,7 @@ class ArenaCellIterImpl TenuredCell* getCell() const { MOZ_ASSERT(!done()); - TenuredCell* cell = reinterpret_cast<TenuredCell*>(thing); - - // This can result in a a new reference being created to an object that - // an ongoing incremental GC may find to be unreachable, so we may need - // a barrier here. - if (needsBarrier) - ExposeGCThingToActiveJS(JS::GCCellPtr(cell, traceKind)); - - return cell; + return reinterpret_cast<TenuredCell*>(thing); } template<typename T> T* get() const { @@ -206,7 +186,7 @@ class ArenaCellIterUnderGC : public ArenaCellIterImpl public: explicit ArenaCellIterUnderGC(ArenaHeader* aheader) { MOZ_ASSERT(aheader->zone->runtimeFromAnyThread()->isHeapBusy()); - init(aheader, CellIterDoesntNeedBarrier); + init(aheader); } }; @@ -214,7 +194,7 @@ class ArenaCellIterUnderFinalize : public ArenaCellIterImpl { public: explicit ArenaCellIterUnderFinalize(ArenaHeader* aheader) { - initUnsynchronized(aheader, CellIterDoesntNeedBarrier); + initUnsynchronized(aheader); } }; @@ -230,7 +210,7 @@ class ZoneCellIterImpl MOZ_ASSERT(zone->arenas.isSynchronizedFreeList(kind)); arenaIter.init(zone, kind); if (!arenaIter.done()) - cellIter.init(arenaIter.get(), CellIterMayNeedBarrier); + cellIter.init(arenaIter.get()); } public: diff --git a/src/third_party/mozjs-45/extract/js/src/jsiter.cpp b/src/third_party/mozjs-45/extract/js/src/jsiter.cpp index 9cbff88bfb1..9b27317683b 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsiter.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsiter.cpp @@ -69,7 +69,17 @@ NativeIterator::mark(JSTracer* trc) TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj"); } -typedef HashSet<jsid, JsidHasher> IdSet; +struct IdHashPolicy { + typedef jsid Lookup; + static HashNumber hash(jsid id) { + return JSID_BITS(id); + } + static bool match(jsid id1, jsid id2) { + return id1 == id2; + } +}; + +typedef HashSet<jsid, IdHashPolicy> IdSet; static inline bool NewKeyValuePair(JSContext* cx, jsid id, const Value& val, MutableHandleValue rval) diff --git a/src/third_party/mozjs-45/extract/js/src/jsmath.cpp b/src/third_party/mozjs-45/extract/js/src/jsmath.cpp index e381b42a846..040269f63d9 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsmath.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsmath.cpp @@ -747,8 +747,8 @@ js::math_pow(JSContext* cx, unsigned argc, Value* vp) return math_pow_handle(cx, args.get(0), args.get(1), args.rval()); } -uint64_t -js::GenerateRandomSeed() +static uint64_t +GenerateSeed() { uint64_t seed = 0; @@ -763,7 +763,7 @@ js::GenerateRandomSeed() close(fd); } #else -# error "Platform needs to implement GenerateRandomSeed()" +# error "Platform needs to implement GenerateSeed()" #endif // Also mix in PRMJ_Now() in case we couldn't read random bits from the OS. @@ -775,8 +775,8 @@ js::GenerateXorShift128PlusSeed(mozilla::Array<uint64_t, 2>& seed) { // XorShift128PlusRNG must be initialized with a non-zero seed. do { - seed[0] = GenerateRandomSeed(); - seed[1] = GenerateRandomSeed(); + seed[0] = GenerateSeed(); + seed[1] = GenerateSeed(); } while (seed[0] == 0 && seed[1] == 0); } diff --git a/src/third_party/mozjs-45/extract/js/src/jsmath.h b/src/third_party/mozjs-45/extract/js/src/jsmath.h index a1d1aaedfb3..e703c703c62 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsmath.h +++ b/src/third_party/mozjs-45/extract/js/src/jsmath.h @@ -86,9 +86,6 @@ class MathCache extern JSObject* InitMathClass(JSContext* cx, HandleObject obj); -extern uint64_t -GenerateRandomSeed(); - // Fill |seed[0]| and |seed[1]| with random bits, suitable for // seeding a XorShift128+ random number generator. extern void diff --git a/src/third_party/mozjs-45/extract/js/src/jswatchpoint.cpp b/src/third_party/mozjs-45/extract/js/src/jswatchpoint.cpp index 53418e36fc4..9713ebe5990 100644 --- a/src/third_party/mozjs-45/extract/js/src/jswatchpoint.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jswatchpoint.cpp @@ -11,7 +11,6 @@ #include "jsfriendapi.h" #include "gc/Marking.h" -#include "vm/Shape.h" #include "jsgcinlines.h" @@ -154,7 +153,7 @@ WatchpointMap::markIteratively(JSTracer* trc) JSObject* priorKeyObj = entry.key().object; jsid priorKeyId(entry.key().id.get()); bool objectIsLive = - IsMarked(trc->runtime(), const_cast<PreBarrieredObject*>(&entry.key().object)); + IsMarked(const_cast<PreBarrieredObject*>(&entry.key().object)); if (objectIsLive || entry.value().held) { if (!objectIsLive) { TraceEdge(trc, const_cast<PreBarrieredObject*>(&entry.key().object), @@ -167,7 +166,7 @@ WatchpointMap::markIteratively(JSTracer* trc) JSID_IS_SYMBOL(priorKeyId)); TraceEdge(trc, const_cast<PreBarrieredId*>(&entry.key().id), "WatchKey::id"); - if (entry.value().closure && !IsMarked(trc->runtime(), &entry.value().closure)) { + if (entry.value().closure && !IsMarked(&entry.value().closure)) { TraceEdge(trc, &entry.value().closure, "Watchpoint::closure"); marked = true; } diff --git a/src/third_party/mozjs-45/extract/js/src/jsweakmap.cpp b/src/third_party/mozjs-45/extract/js/src/jsweakmap.cpp index 70a119601c7..2249f46f71c 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsweakmap.cpp +++ b/src/third_party/mozjs-45/extract/js/src/jsweakmap.cpp @@ -150,7 +150,7 @@ ObjectValueMap::findZoneEdges() if (!delegate) continue; Zone* delegateZone = delegate->zone(); - if (delegateZone == zone || !delegateZone->isGCMarking()) + if (delegateZone == zone) continue; if (!delegateZone->gcZoneGroupEdges.put(key->zone())) return false; diff --git a/src/third_party/mozjs-45/extract/js/src/jsweakmap.h b/src/third_party/mozjs-45/extract/js/src/jsweakmap.h index 020f51e9733..3c17c78d415 100644 --- a/src/third_party/mozjs-45/extract/js/src/jsweakmap.h +++ b/src/third_party/mozjs-45/extract/js/src/jsweakmap.h @@ -184,7 +184,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, Key key(p->key()); MOZ_ASSERT((markedCell == extractUnbarriered(key)) || (markedCell == getDelegate(key))); - if (gc::IsMarked(trc->runtime(), &key)) { + if (gc::IsMarked(&key)) { TraceEdge(trc, &p->value(), "ephemeron value"); } else if (keyNeedsMark(key)) { TraceEdge(trc, &p->value(), "WeakMap ephemeron value"); @@ -249,7 +249,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, for (Enum e(*this); !e.empty(); e.popFront()) { // If the entry is live, ensure its key and value are marked. - bool keyIsMarked = gc::IsMarked(trc->runtime(), &e.front().mutableKey()); + bool keyIsMarked = gc::IsMarked(&e.front().mutableKey()); if (!keyIsMarked && keyNeedsMark(e.front().key())) { TraceEdge(trc, &e.front().mutableKey(), "proxy-preserved WeakMap entry key"); keyIsMarked = true; @@ -257,7 +257,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, } if (keyIsMarked) { - if (!gc::IsMarked(trc->runtime(), &e.front().value())) { + if (!gc::IsMarked(&e.front().value())) { TraceEdge(trc, &e.front().value(), "WeakMap entry value"); markedAny = true; } @@ -283,15 +283,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, JSObject* getDelegate(JSObject* key) const { JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp; - if (!op) - return nullptr; - - JSObject* obj = op(key); - if (!obj) - return nullptr; - - MOZ_ASSERT(obj->runtimeFromMainThread() == zone->runtimeFromMainThread()); - return obj; + return op ? op(key) : nullptr; } JSObject* getDelegate(gc::Cell* cell) const { @@ -304,7 +296,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, * 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 gray. */ - return delegate && gc::IsMarkedUnbarriered(zone->runtimeFromMainThread(), &delegate); + return delegate && gc::IsMarkedUnbarriered(&delegate); } bool keyNeedsMark(gc::Cell* cell) const { diff --git a/src/third_party/mozjs-45/extract/js/src/moz.build b/src/third_party/mozjs-45/extract/js/src/moz.build index 123c9f3bcb5..591d7a6a3ee 100644 --- a/src/third_party/mozjs-45/extract/js/src/moz.build +++ b/src/third_party/mozjs-45/extract/js/src/moz.build @@ -236,7 +236,6 @@ UNIFIED_SOURCES += [ 'jit/MoveResolver.cpp', 'jit/OptimizationTracking.cpp', 'jit/PerfSpewer.cpp', - 'jit/ProcessExecutableMemory.cpp', 'jit/RangeAnalysis.cpp', 'jit/Recover.cpp', 'jit/RegisterAllocator.cpp', @@ -531,8 +530,15 @@ elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']: ] if CONFIG['OS_ARCH'] == 'WINNT': + SOURCES += [ + 'jit/ExecutableAllocatorWin.cpp', + ] # _CRT_RAND_S must be #defined before #including stdlib.h to get rand_s() DEFINES['_CRT_RAND_S'] = True +else: + SOURCES += [ + 'jit/ExecutableAllocatorPosix.cpp', + ] if CONFIG['JS_HAS_CTYPES']: SOURCES += [ diff --git a/src/third_party/mozjs-45/extract/js/src/proxy/Wrapper.cpp b/src/third_party/mozjs-45/extract/js/src/proxy/Wrapper.cpp index 6a60746904d..e80113ce362 100644 --- a/src/third_party/mozjs-45/extract/js/src/proxy/Wrapper.cpp +++ b/src/third_party/mozjs-45/extract/js/src/proxy/Wrapper.cpp @@ -42,10 +42,7 @@ JSObject* Wrapper::wrappedObject(JSObject* wrapper) { MOZ_ASSERT(wrapper->is<WrapperObject>()); - JSObject* target = wrapper->as<ProxyObject>().target(); - if (target) - JS::ExposeObjectToActiveJS(target); - return target; + return wrapper->as<ProxyObject>().target(); } bool diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Debugger.cpp b/src/third_party/mozjs-45/extract/js/src/vm/Debugger.cpp index d583c9c52e9..12de1145276 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Debugger.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/Debugger.cpp @@ -517,7 +517,7 @@ Debugger::getHook(Hook hook) const } bool -Debugger::hasAnyLiveHooks(JSRuntime* rt) const +Debugger::hasAnyLiveHooks() const { if (!enabled) return false; @@ -532,7 +532,7 @@ Debugger::hasAnyLiveHooks(JSRuntime* rt) const /* If any breakpoints are in live scripts, return true. */ for (Breakpoint* bp = firstBreakpoint(); bp; bp = bp->nextInDebugger()) { - if (IsMarkedUnbarriered(rt, &bp->site->script)) + if (IsMarkedUnbarriered(&bp->site->script)) return true; } @@ -2520,7 +2520,7 @@ Debugger::markAllIteratively(GCMarker* trc) for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { if (c->isDebuggee()) { GlobalObject* global = c->unsafeUnbarrieredMaybeGlobal(); - if (!IsMarkedUnbarriered(rt, &global)) + if (!IsMarkedUnbarriered(&global)) continue; /* @@ -2542,8 +2542,8 @@ Debugger::markAllIteratively(GCMarker* trc) if (!dbgobj->zone()->isGCMarking()) continue; - bool dbgMarked = IsMarked(rt, &dbgobj); - if (!dbgMarked && dbg->hasAnyLiveHooks(rt)) { + bool dbgMarked = IsMarked(&dbgobj); + if (!dbgMarked && dbg->hasAnyLiveHooks()) { /* * obj could be reachable only via its live, enabled * debugger hooks, which may yet be called. @@ -2556,12 +2556,12 @@ Debugger::markAllIteratively(GCMarker* trc) if (dbgMarked) { /* Search for breakpoints to mark. */ for (Breakpoint* bp = dbg->firstBreakpoint(); bp; bp = bp->nextInDebugger()) { - if (IsMarkedUnbarriered(rt, &bp->site->script)) { + if (IsMarkedUnbarriered(&bp->site->script)) { /* * The debugger and the script are both live. * Therefore the breakpoint handler is live. */ - if (!IsMarked(rt, &bp->getHandlerRef())) { + if (!IsMarked(&bp->getHandlerRef())) { TraceEdge(trc, &bp->getHandlerRef(), "breakpoint handler"); markedAny = true; } diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Debugger.h b/src/third_party/mozjs-45/extract/js/src/vm/Debugger.h index 49744a7d00d..ef7b94bc24f 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Debugger.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/Debugger.h @@ -607,7 +607,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger> void updateObservesAsmJSOnDebuggees(IsObserving observing); JSObject* getHook(Hook hook) const; - bool hasAnyLiveHooks(JSRuntime* rt) const; + bool hasAnyLiveHooks() const; static JSTrapStatus slowPathOnEnterFrame(JSContext* cx, AbstractFramePtr frame); static bool slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, bool ok); diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Initialization.cpp b/src/third_party/mozjs-45/extract/js/src/vm/Initialization.cpp index fcef4b22b44..cf5d21aa230 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Initialization.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/Initialization.cpp @@ -83,9 +83,7 @@ JS_Init(void) js::oom::SetThreadType(js::oom::THREAD_TYPE_MAIN); #endif - js::gc::InitMemorySubsystem(); // Ensure gc::SystemPageSize() works. - if (!js::jit::InitProcessExecutableMemory()) - return false; + js::jit::ExecutableAllocator::initStatic(); if (!js::jit::InitializeIon()) return false; @@ -148,9 +146,6 @@ JS_ShutDown(void) u_cleanup(); #endif // EXPOSE_INTL_API - if (!JSRuntime::hasLiveRuntimes()) - js::jit::ReleaseProcessExecutableMemory(); - libraryInitState = InitState::ShutDown; } diff --git a/src/third_party/mozjs-45/extract/js/src/vm/ObjectGroup.cpp b/src/third_party/mozjs-45/extract/js/src/vm/ObjectGroup.cpp index ad002b4a05e..6ef50de88c3 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/ObjectGroup.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/ObjectGroup.cpp @@ -12,7 +12,6 @@ #include "gc/StoreBuffer.h" #include "gc/Zone.h" #include "vm/ArrayObject.h" -#include "vm/Shape.h" #include "vm/UnboxedObject.h" #include "jsobjinlines.h" @@ -555,38 +554,45 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp, ObjectGroupCompartment::newTablePostBarrier(cx, table, clasp, proto, associated); - if (associated) { - if (associated->is<JSFunction>()) { - if (!TypeNewScript::make(cx->asJSContext(), group, &associated->as<JSFunction>())) - return nullptr; - } else { - group->setTypeDescr(&associated->as<TypeDescr>()); + if (proto.isObject()) { + RootedObject obj(cx, proto.toObject()); + + if (associated) { + if (associated->is<JSFunction>()) { + if (!TypeNewScript::make(cx->asJSContext(), group, &associated->as<JSFunction>())) + return nullptr; + } else { + group->setTypeDescr(&associated->as<TypeDescr>()); + } } - } - /* - * Some builtin objects have slotful native properties baked in at - * creation via the Shape::{insert,get}initialShape mechanism. Since - * these properties are never explicitly defined on new objects, update - * the type information for them here. - */ + /* + * Some builtin objects have slotful native properties baked in at + * creation via the Shape::{insert,get}initialShape mechanism. Since + * these properties are never explicitly defined on new objects, update + * the type information for them here. + */ - const JSAtomState& names = cx->names(); + const JSAtomState& names = cx->names(); - if (clasp == &RegExpObject::class_) { - AddTypePropertyId(cx, group, nullptr, NameToId(names.source), TypeSet::StringType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.global), TypeSet::BooleanType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.ignoreCase), TypeSet::BooleanType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.multiline), TypeSet::BooleanType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.sticky), TypeSet::BooleanType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.lastIndex), TypeSet::Int32Type()); - } else if (clasp == &StringObject::class_) { - AddTypePropertyId(cx, group, nullptr, NameToId(names.length), TypeSet::Int32Type()); - } else if (ErrorObject::isErrorClass(clasp)) { - AddTypePropertyId(cx, group, nullptr, NameToId(names.fileName), TypeSet::StringType()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.lineNumber), TypeSet::Int32Type()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type()); - AddTypePropertyId(cx, group, nullptr, NameToId(names.stack), TypeSet::StringType()); + if (obj->is<RegExpObject>()) { + AddTypePropertyId(cx, group, nullptr, NameToId(names.source), TypeSet::StringType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.global), TypeSet::BooleanType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.ignoreCase), TypeSet::BooleanType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.multiline), TypeSet::BooleanType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.sticky), TypeSet::BooleanType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.lastIndex), TypeSet::Int32Type()); + } + + if (obj->is<StringObject>()) + AddTypePropertyId(cx, group, nullptr, NameToId(names.length), TypeSet::Int32Type()); + + if (obj->is<ErrorObject>()) { + AddTypePropertyId(cx, group, nullptr, NameToId(names.fileName), TypeSet::StringType()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.lineNumber), TypeSet::Int32Type()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type()); + AddTypePropertyId(cx, group, nullptr, NameToId(names.stack), TypeSet::StringType()); + } } return group; @@ -1110,7 +1116,7 @@ struct ObjectGroupCompartment::PlainObjectKey }; static inline HashNumber hash(const Lookup& lookup) { - return (HashNumber) (HashId(lookup.properties[lookup.nproperties - 1].id) ^ + return (HashNumber) (JSID_BITS(lookup.properties[lookup.nproperties - 1].id) ^ lookup.nproperties); } diff --git a/src/third_party/mozjs-45/extract/js/src/vm/RegExpObject.cpp b/src/third_party/mozjs-45/extract/js/src/vm/RegExpObject.cpp index 9d0dd97d037..fec090d3f19 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/RegExpObject.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/RegExpObject.cpp @@ -793,7 +793,7 @@ RegExpCompartment::sweep(JSRuntime* rt) // the RegExpShared if it was accidentally marked earlier but wasn't // marked by the current trace. bool keep = shared->marked() && - IsMarked(rt, &shared->source); + IsMarked(&shared->source); for (size_t i = 0; i < ArrayLength(shared->compilationArray); i++) { RegExpShared::RegExpCompilation& compilation = shared->compilationArray[i]; if (compilation.jitCode && diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Runtime.cpp b/src/third_party/mozjs-45/extract/js/src/vm/Runtime.cpp index a3a3fda4158..94909a2ed47 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Runtime.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/Runtime.cpp @@ -311,7 +311,6 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) return false; atomsCompartment->setIsSystem(true); - atomsCompartment->setIsAtomsCompartment(); atomsZone.forget(); this->atomsCompartment_ = atomsCompartment.forget(); @@ -746,32 +745,6 @@ JSRuntime::triggerActivityCallback(bool active) activityCallback(activityCallbackArg, active); } -mozilla::non_crypto::XorShift128PlusRNG& -JSRuntime::randomKeyGenerator() -{ - MOZ_ASSERT(CurrentThreadCanAccessRuntime(this)); - if (randomKeyGenerator_.isNothing()) { - mozilla::Array<uint64_t, 2> seed; - GenerateXorShift128PlusSeed(seed); - randomKeyGenerator_.emplace(seed[0], seed[1]); - } - return randomKeyGenerator_.ref(); -} - -mozilla::HashCodeScrambler -JSRuntime::randomHashCodeScrambler() -{ - auto& rng = randomKeyGenerator(); - return mozilla::HashCodeScrambler(rng.next(), rng.next()); -} - -mozilla::non_crypto::XorShift128PlusRNG -JSRuntime::forkRandomKeyGenerator() -{ - auto& rng = randomKeyGenerator(); - return mozilla::non_crypto::XorShift128PlusRNG(rng.next(), rng.next()); -} - void JSRuntime::updateMallocCounter(size_t nbytes) { diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Runtime.h b/src/third_party/mozjs-45/extract/js/src/vm/Runtime.h index 9df53087c03..51734df147a 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Runtime.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/Runtime.h @@ -949,15 +949,6 @@ struct JSRuntime : public JS::shadow::Runtime, return interpreterStack_; } - private: - // Used to generate random keys for hash tables. - mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_; - mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator(); - - public: - mozilla::HashCodeScrambler randomHashCodeScrambler(); - mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator(); - //------------------------------------------------------------------------- // Self-hosting support //------------------------------------------------------------------------- diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Shape.h b/src/third_party/mozjs-45/extract/js/src/vm/Shape.h index 1c2c99a1feb..51185898d80 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Shape.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/Shape.h @@ -29,8 +29,6 @@ #include "js/RootingAPI.h" #include "js/UbiNode.h" #include "vm/ObjectGroup.h" -#include "vm/String.h" -#include "vm/Symbol.h" #ifdef _MSC_VER #pragma warning(push) @@ -518,33 +516,11 @@ struct StackBaseShape : public DefaultHasher<ReadBarriered<UnownedBaseShape*>> static inline bool match(ReadBarriered<UnownedBaseShape*> key, const Lookup& lookup); }; -static MOZ_ALWAYS_INLINE js::HashNumber -HashId(jsid id) -{ - // HashGeneric alone would work, but bits of atom and symbol addresses - // could then be recovered from the hash code. See bug 1330769. - if (MOZ_LIKELY(JSID_IS_ATOM(id))) - return JSID_TO_ATOM(id)->hash(); - if (JSID_IS_SYMBOL(id)) - return JSID_TO_SYMBOL(id)->hash(); - return mozilla::HashGeneric(JSID_BITS(id)); -} - -struct JsidHasher -{ - typedef jsid Lookup; - static HashNumber hash(jsid id) { - return HashId(id); - } - static bool match(jsid id1, jsid id2) { - return id1 == id2; - } -}; - typedef HashSet<ReadBarriered<UnownedBaseShape*>, StackBaseShape, SystemAllocPolicy> BaseShapeSet; + class Shape : public gc::TenuredCell { friend class ::JSObject; @@ -1196,7 +1172,7 @@ struct StackShape : public JS::Traceable /* Accumulate from least to most random so the low bits are most random. */ hash = mozilla::RotateLeft(hash, 4) ^ attrs; hash = mozilla::RotateLeft(hash, 4) ^ slot_; - hash = mozilla::RotateLeft(hash, 4) ^ HashId(propid); + hash = mozilla::RotateLeft(hash, 4) ^ JSID_BITS(propid); hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawGetter); hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawSetter); return hash; diff --git a/src/third_party/mozjs-45/extract/js/src/vm/String-inl.h b/src/third_party/mozjs-45/extract/js/src/vm/String-inl.h index 0e95063f21a..b4676d344d0 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/String-inl.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/String-inl.h @@ -13,7 +13,6 @@ #include "mozilla/Range.h" #include "jscntxt.h" -#include "jscompartment.h" #include "gc/Allocator.h" #include "gc/Marking.h" @@ -221,11 +220,7 @@ JSFlatString::new_(js::ExclusiveContext* cx, const CharT* chars, size_t length) if (!validateLength(cx, length)) return nullptr; - JSFlatString* str; - if (cx->compartment()->isAtomsCompartment()) - str = js::Allocate<js::NormalAtom, allowGC>(cx); - else - str = static_cast<JSFlatString*>(js::Allocate<JSString, allowGC>(cx)); + JSFlatString* str = static_cast<JSFlatString*>(js::Allocate<JSString, allowGC>(cx)); if (!str) return nullptr; @@ -252,9 +247,6 @@ template <js::AllowGC allowGC> MOZ_ALWAYS_INLINE JSThinInlineString* JSThinInlineString::new_(js::ExclusiveContext* cx) { - if (cx->compartment()->isAtomsCompartment()) - return (JSThinInlineString*)(js::Allocate<js::NormalAtom, allowGC>(cx)); - return static_cast<JSThinInlineString*>(js::Allocate<JSString, allowGC>(cx)); } @@ -262,9 +254,6 @@ template <js::AllowGC allowGC> MOZ_ALWAYS_INLINE JSFatInlineString* JSFatInlineString::new_(js::ExclusiveContext* cx) { - if (cx->compartment()->isAtomsCompartment()) - return (JSFatInlineString*)(js::Allocate<js::FatInlineAtom, allowGC>(cx)); - return js::Allocate<JSFatInlineString, allowGC>(cx); } @@ -362,7 +351,6 @@ JSString::finalize(js::FreeOp* fop) { /* FatInline strings are in a different arena. */ MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_STRING); - MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_ATOM); if (isFlat()) asFlat().finalize(fop); @@ -374,7 +362,6 @@ inline void JSFlatString::finalize(js::FreeOp* fop) { MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_STRING); - MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_ATOM); if (!isInline()) fop->free_(nonInlineCharsRaw()); @@ -394,8 +381,6 @@ JSAtom::finalize(js::FreeOp* fop) { MOZ_ASSERT(JSString::isAtom()); MOZ_ASSERT(JSString::isFlat()); - MOZ_ASSERT(getAllocKind() == js::gc::AllocKind::ATOM || - getAllocKind() == js::gc::AllocKind::FAT_INLINE_ATOM); if (!isInline()) fop->free_(nonInlineCharsRaw()); diff --git a/src/third_party/mozjs-45/extract/js/src/vm/String.cpp b/src/third_party/mozjs-45/extract/js/src/vm/String.cpp index 1bbe151c015..e5a315fbfc3 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/String.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/String.cpp @@ -71,12 +71,8 @@ JSString::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) JS::ubi::Node::Size JS::ubi::Concrete<JSString>::size(mozilla::MallocSizeOf mallocSizeOf) const { - JSString& str = get(); - size_t size; - if (str.isAtom()) - size = str.isFatInline() ? sizeof(js::FatInlineAtom) : sizeof(js::NormalAtom); - else - size = str.isFatInline() ? sizeof(JSFatInlineString) : sizeof(JSString); + JSString &str = get(); + size_t size = str.isFatInline() ? sizeof(JSFatInlineString) : sizeof(JSString); // We can't use mallocSizeof on things in the nursery. At the moment, // strings are never in the nursery, but that may change. @@ -793,8 +789,7 @@ StaticStrings::init(JSContext* cx) JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 1); if (!s) return false; - HashNumber hash = mozilla::HashString(buffer, 1); - unitStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash); + unitStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(); } for (uint32_t i = 0; i < NUM_SMALL_CHARS * NUM_SMALL_CHARS; i++) { @@ -802,8 +797,7 @@ StaticStrings::init(JSContext* cx) JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 2); if (!s) return false; - HashNumber hash = mozilla::HashString(buffer, 2); - length2StaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash); + length2StaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(); } for (uint32_t i = 0; i < INT_STATIC_LIMIT; i++) { @@ -821,8 +815,7 @@ StaticStrings::init(JSContext* cx) JSFlatString* s = NewStringCopyN<NoGC>(cx, buffer, 3); if (!s) return false; - HashNumber hash = mozilla::HashString(buffer, 3); - intStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash); + intStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(); } } diff --git a/src/third_party/mozjs-45/extract/js/src/vm/String.h b/src/third_party/mozjs-45/extract/js/src/vm/String.h index 80466681507..e788aadbe14 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/String.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/String.h @@ -123,11 +123,7 @@ static const size_t UINT32_CHAR_BUFFER_LENGTH = sizeof("4294967295") - 1; * | | * | +-- JSFatInlineString - / header is fat * | - * JSAtom (abstract) - / string equality === pointer equality - * | | - * | +-- js::NormalAtom - JSFlatString + atom hash code - * | | - * | +-- js::FatInlineAtom - JSFatInlineString + atom hash code + * JSAtom - / string equality === pointer equality * | * js::PropertyName - / chars don't contain an index (uint32_t) * @@ -139,9 +135,10 @@ static const size_t UINT32_CHAR_BUFFER_LENGTH = sizeof("4294967295") - 1; * Atoms can additionally be permanent, i.e. unable to be collected, and can * be combined with other string types to create additional most-derived types * that satisfy the invariants of more than one of the abovementioned - * most-derived types. Furthermore, each atom stores a hash number (based on its - * chars). This hash number is used as key in the atoms table and when the atom - * is used as key in a JS Map/Set. + * most-derived types: + * - InlineAtom = JSInlineString + JSAtom (atom with inline chars, abstract) + * - ThinInlineAtom = JSThinInlineString + JSAtom (atom with inline chars) + * - FatInlineAtom = JSFatInlineString + JSAtom (atom with (more) inline chars) * * Derived string types can be queried from ancestor types via isX() and * retrieved with asX() debug-only-checked casts. @@ -768,8 +765,14 @@ class JSFlatString : public JSLinearString * Once a JSFlatString sub-class has been added to the atom state, this * operation changes the string to the JSAtom type, in place. */ - MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoAtom(js::HashNumber hash); - MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoPermanentAtom(js::HashNumber hash); + MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoAtom() { + d.u1.flags |= ATOM_BIT; + return &asAtom(); + } + MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoPermanentAtom() { + d.u1.flags |= PERMANENT_ATOM_MASK; + return &asAtom(); + } inline void finalize(js::FreeOp* fop); @@ -981,9 +984,6 @@ class JSAtom : public JSFlatString d.u1.flags |= PERMANENT_ATOM_MASK; } - inline js::HashNumber hash() const; - inline void initHash(js::HashNumber hash); - #ifdef DEBUG void dump(); #endif @@ -994,83 +994,6 @@ static_assert(sizeof(JSAtom) == sizeof(JSString), namespace js { -class NormalAtom : public JSAtom -{ - protected: // Silence Clang unused-field warning. - HashNumber hash_; - uint32_t padding_; // Ensure the size is a multiple of gc::CellSize. - - public: - HashNumber hash() const { - return hash_; - } - void initHash(HashNumber hash) { - hash_ = hash; - } -}; - -static_assert(sizeof(NormalAtom) == sizeof(JSString) + sizeof(uint64_t), - "NormalAtom must have size of a string + HashNumber, " - "aligned to gc::CellSize"); - -class FatInlineAtom : public JSAtom -{ - protected: // Silence Clang unused-field warning. - char inlineStorage_[sizeof(JSFatInlineString) - sizeof(JSString)]; - HashNumber hash_; - uint32_t padding_; // Ensure the size is a multiple of gc::CellSize. - - public: - HashNumber hash() const { - return hash_; - } - void initHash(HashNumber hash) { - hash_ = hash; - } -}; - -static_assert(sizeof(FatInlineAtom) == sizeof(JSFatInlineString) + sizeof(uint64_t), - "FatInlineAtom must have size of a fat inline string + HashNumber, " - "aligned to gc::CellSize"); - -} // namespace js - -inline js::HashNumber -JSAtom::hash() const -{ - if (isFatInline()) - return static_cast<const js::FatInlineAtom*>(this)->hash(); - return static_cast<const js::NormalAtom*>(this)->hash(); -} - -inline void -JSAtom::initHash(js::HashNumber hash) -{ - if (isFatInline()) - return static_cast<js::FatInlineAtom*>(this)->initHash(hash); - return static_cast<js::NormalAtom*>(this)->initHash(hash); -} - -MOZ_ALWAYS_INLINE JSAtom* -JSFlatString::morphAtomizedStringIntoAtom(js::HashNumber hash) -{ - d.u1.flags |= ATOM_BIT; - JSAtom* atom = &asAtom(); - atom->initHash(hash); - return atom; -} - -MOZ_ALWAYS_INLINE JSAtom* -JSFlatString::morphAtomizedStringIntoPermanentAtom(js::HashNumber hash) -{ - d.u1.flags |= PERMANENT_ATOM_MASK; - JSAtom* atom = &asAtom(); - atom->initHash(hash); - return atom; -} - -namespace js { - class StaticStrings { private: @@ -1264,8 +1187,6 @@ NewStringCopyZ(js::ExclusiveContext* cx, const char* s) return NewStringCopyN<allowGC>(cx, s, strlen(s)); } -JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - } /* namespace js */ // Addon IDs are interned atoms which are never destroyed. This detail is diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Symbol.cpp b/src/third_party/mozjs-45/extract/js/src/vm/Symbol.cpp index c1ec8892bf0..dfe6278d140 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Symbol.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/Symbol.cpp @@ -20,7 +20,7 @@ using JS::Symbol; using namespace js; Symbol* -Symbol::newInternal(ExclusiveContext* cx, JS::SymbolCode code, uint32_t hash, JSAtom* description) +Symbol::newInternal(ExclusiveContext* cx, JS::SymbolCode code, JSAtom* description) { MOZ_ASSERT(cx->compartment() == cx->atomsCompartment()); MOZ_ASSERT(cx->atomsCompartment()->runtimeFromAnyThread()->currentThreadHasExclusiveAccess()); @@ -31,7 +31,7 @@ Symbol::newInternal(ExclusiveContext* cx, JS::SymbolCode code, uint32_t hash, JS ReportOutOfMemory(cx); return nullptr; } - return new (p) Symbol(code, hash, description); + return new (p) Symbol(code, description); } Symbol* @@ -48,7 +48,7 @@ Symbol::new_(ExclusiveContext* cx, JS::SymbolCode code, JSString* description) // probably be replaced with an assertion that we're on the main thread. AutoLockForExclusiveAccess lock(cx); AutoCompartment ac(cx, cx->atomsCompartment()); - return newInternal(cx, code, cx->compartment()->randomHashCode(), atom); + return newInternal(cx, code, atom); } Symbol* @@ -66,7 +66,7 @@ Symbol::for_(js::ExclusiveContext* cx, HandleString description) return *p; AutoCompartment ac(cx, cx->atomsCompartment()); - Symbol* sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom->hash(), atom); + Symbol* sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom); if (!sym) return nullptr; diff --git a/src/third_party/mozjs-45/extract/js/src/vm/Symbol.h b/src/third_party/mozjs-45/extract/js/src/vm/Symbol.h index e39a490662f..c201ed127c5 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/Symbol.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/Symbol.h @@ -16,11 +16,10 @@ #include "gc/Barrier.h" #include "gc/Marking.h" + #include "js/GCHashTable.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" -#include "js/Utility.h" -#include "vm/String.h" namespace JS { @@ -28,31 +27,25 @@ class Symbol : public js::gc::TenuredCell { private: SymbolCode code_; - - // Each Symbol gets its own hash code so that we don't have to use - // addresses as hash codes (a security hazard). - js::HashNumber hash_; - JSAtom* description_; // The minimum allocation size is sizeof(JSString): 16 bytes on 32-bit - // architectures and 24 bytes on 64-bit. A size_t of padding makes Symbol + // architectures and 24 bytes on 64-bit. 8 bytes of padding makes Symbol // the minimum size on both. - size_t unused_; + uint64_t unused2_; - Symbol(SymbolCode code, js::HashNumber hash, JSAtom* desc) - : code_(code), hash_(hash), description_(desc) + Symbol(SymbolCode code, JSAtom* desc) + : code_(code), description_(desc) { - // Silence warnings about unused_ being... unused. - (void)unused_; + // Silence warnings about unused2 being... unused. + (void)unused2_; } Symbol(const Symbol&) = delete; void operator=(const Symbol&) = delete; static Symbol* - newInternal(js::ExclusiveContext* cx, SymbolCode code, js::HashNumber hash, - JSAtom* description); + newInternal(js::ExclusiveContext* cx, SymbolCode code, JSAtom* description); public: static Symbol* new_(js::ExclusiveContext* cx, SymbolCode code, JSString* description); @@ -60,7 +53,6 @@ class Symbol : public js::gc::TenuredCell JSAtom* description() const { return description_; } SymbolCode code() const { return code_; } - js::HashNumber hash() const { return hash_; } bool isWellKnownSymbol() const { return uint32_t(code_) < WellKnownSymbolLimit; } @@ -96,7 +88,7 @@ struct HashSymbolsByDescription typedef JSAtom* Lookup; static HashNumber hash(Lookup l) { - return HashNumber(l->hash()); + return HashNumber(reinterpret_cast<uintptr_t>(l)); } static bool match(Key sym, Lookup l) { return sym->description() == l; diff --git a/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.cpp b/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.cpp index 2738145960c..b289cfd62a7 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.cpp @@ -749,16 +749,16 @@ TypeSet::readBarrier(const TypeSet* types) } /* static */ bool -TypeSet::IsTypeMarked(JSRuntime* rt, TypeSet::Type* v) +TypeSet::IsTypeMarked(TypeSet::Type* v) { bool rv; if (v->isSingletonUnchecked()) { JSObject* obj = v->singletonNoBarrier(); - rv = IsMarkedUnbarriered(rt, &obj); + rv = IsMarkedUnbarriered(&obj); *v = TypeSet::ObjectType(obj); } else if (v->isGroupUnchecked()) { ObjectGroup* group = v->groupNoBarrier(); - rv = IsMarkedUnbarriered(rt, &group); + rv = IsMarkedUnbarriered(&group); *v = TypeSet::ObjectType(group); } else { rv = true; @@ -4192,10 +4192,6 @@ ObjectGroup::sweep(AutoClearTypeInferenceStateOnOOM* oom) if (unboxedLayout().newScript()) unboxedLayout().newScript()->sweep(); - - // Discard constructor code to avoid holding onto ExecutablePools. - if (zone()->isGCCompacting()) - unboxedLayout().setConstructorCode(nullptr); } if (maybePreliminaryObjects()) diff --git a/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.h b/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.h index 2f85f8620a7..7e647c0fe25 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.h +++ b/src/third_party/mozjs-45/extract/js/src/vm/TypeInference.h @@ -532,7 +532,7 @@ class TypeSet static void MarkTypeRoot(JSTracer* trc, Type* v, const char* name); static void MarkTypeUnbarriered(JSTracer* trc, Type* v, const char* name); - static bool IsTypeMarked(JSRuntime* rt, Type* v); + static bool IsTypeMarked(Type* v); static bool IsTypeAllocatedDuringIncremental(Type v); static bool IsTypeAboutToBeFinalized(Type* v); }; diff --git a/src/third_party/mozjs-45/extract/js/src/vm/TypedArrayObject.cpp b/src/third_party/mozjs-45/extract/js/src/vm/TypedArrayObject.cpp index 7f92aab6da9..a3c8a902581 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/TypedArrayObject.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/TypedArrayObject.cpp @@ -1032,11 +1032,6 @@ DataViewObject* DataViewObject::create(JSContext* cx, uint32_t byteOffset, uint32_t byteLength, Handle<ArrayBufferObject*> arrayBuffer, JSObject* protoArg) { - if (arrayBuffer->isNeutered()) { - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED); - return nullptr; - } - MOZ_ASSERT(byteOffset <= INT32_MAX); MOZ_ASSERT(byteLength <= INT32_MAX); MOZ_ASSERT(byteOffset + byteLength < UINT32_MAX); @@ -2269,50 +2264,36 @@ js::DefineTypedArrayElement(JSContext* cx, HandleObject obj, uint64_t index, { MOZ_ASSERT(IsAnyTypedArray(obj)); - // These are all substeps of 3.b. - - // Steps i-iii are handled by the caller. - - // Steps iv-v. + // These are all substeps of 3.c. + // Steps i-vi. // We (wrongly) ignore out of range defines with a value. - uint32_t length = AnyTypedArrayLength(obj); - if (index >= length) + if (index >= AnyTypedArrayLength(obj)) return result.succeed(); - // Step vi. + // Step vii. if (desc.isAccessorDescriptor()) return result.fail(JSMSG_CANT_REDEFINE_PROP); - // Step vii. + // Step viii. if (desc.hasConfigurable() && desc.configurable()) return result.fail(JSMSG_CANT_REDEFINE_PROP); - // Step viii. + // Step ix. if (desc.hasEnumerable() && !desc.enumerable()) return result.fail(JSMSG_CANT_REDEFINE_PROP); - // Step ix. + // Step x. if (desc.hasWritable() && !desc.writable()) return result.fail(JSMSG_CANT_REDEFINE_PROP); - // Step x. + // Step xi. if (desc.hasValue()) { - // The following step numbers refer to 9.4.5.9 - // IntegerIndexedElementSet. - - // Steps 1-2 are enforced by the caller. - - // Step 3. - double numValue; - if (!ToNumber(cx, desc.value(), &numValue)) + double d; + if (!ToNumber(cx, desc.value(), &d)) return false; - // Steps 4-5, 8-9. - if (AnyTypedArrayIsDetached(obj)) - return result.fail(JSMSG_TYPED_ARRAY_DETACHED); - - // Steps 10-16. - TypedArrayObject::setElement(obj->as<TypedArrayObject>(), index, numValue); + if (obj->is<TypedArrayObject>()) + TypedArrayObject::setElement(obj->as<TypedArrayObject>(), index, d); } // Step xii. diff --git a/src/third_party/mozjs-45/extract/js/src/vm/UnboxedObject.cpp b/src/third_party/mozjs-45/extract/js/src/vm/UnboxedObject.cpp index f1b377d57b4..504a5c418c4 100644 --- a/src/third_party/mozjs-45/extract/js/src/vm/UnboxedObject.cpp +++ b/src/third_party/mozjs-45/extract/js/src/vm/UnboxedObject.cpp @@ -7,7 +7,6 @@ #include "vm/UnboxedObject-inl.h" #include "jit/BaselineIC.h" -#include "jit/ExecutableAllocator.h" #include "jit/JitCommon.h" #include "jit/Linker.h" @@ -699,8 +698,7 @@ UnboxedPlainObject::createWithProperties(ExclusiveContext* cx, HandleObjectGroup #ifndef JS_CODEGEN_NONE if (cx->isJSContext() && !layout.constructorCode() && - cx->asJSContext()->runtime()->jitSupportsFloatingPoint && - jit::CanLikelyAllocateMoreExecutableMemory()) + cx->asJSContext()->runtime()->jitSupportsFloatingPoint) { if (!UnboxedLayout::makeConstructorCode(cx->asJSContext(), group)) return nullptr; diff --git a/src/third_party/mozjs-45/extract/mfbt/HashFunctions.h b/src/third_party/mozjs-45/extract/mfbt/HashFunctions.h index 8eb83a3737c..f490a28fee4 100644 --- a/src/third_party/mozjs-45/extract/mfbt/HashFunctions.h +++ b/src/third_party/mozjs-45/extract/mfbt/HashFunctions.h @@ -50,7 +50,6 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Char16.h" -#include "mozilla/MathAlgorithms.h" #include "mozilla/Types.h" #include <stdint.h> @@ -313,90 +312,6 @@ HashString(const wchar_t* aStr, size_t aLength) MOZ_WARN_UNUSED_RESULT extern MFBT_API uint32_t HashBytes(const void* bytes, size_t aLength); -/** - * A pseudorandom function mapping 32-bit integers to 32-bit integers. - * - * This is for when you're feeding private data (like pointer values or credit - * card numbers) to a non-crypto hash function (like HashBytes) and then using - * the hash code for something that untrusted parties could observe (like a JS - * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the - * private data. - * - * By itself, this does not prevent hash-flooding DoS attacks, because an - * attacker can still generate many values with exactly equal hash codes by - * attacking the non-crypto hash function alone. Equal hash codes will, of - * course, still be equal however much you scramble them. - * - * The algorithm is SipHash-1-3. See <https://131002.net/siphash/>. - */ -class HashCodeScrambler -{ - struct SipHasher; - - uint64_t mK0, mK1; - -public: - /** Creates a new scrambler with the given 128-bit key. */ - HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} - - /** - * Scramble a hash code. Always produces the same result for the same - * combination of key and hash code. - */ - uint32_t scramble(uint32_t aHashCode) const - { - SipHasher hasher(mK0, mK1); - return uint32_t(hasher.sipHash(aHashCode)); - } - -private: - struct SipHasher - { - SipHasher(uint64_t aK0, uint64_t aK1) - { - // 1. Initialization. - mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); - mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); - mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); - mV3 = aK1 ^ UINT64_C(0x7465646279746573); - } - - uint64_t sipHash(uint64_t aM) - { - // 2. Compression. - mV3 ^= aM; - sipRound(); - mV0 ^= aM; - - // 3. Finalization. - mV2 ^= 0xff; - for (int i = 0; i < 3; i++) - sipRound(); - return mV0 ^ mV1 ^ mV2 ^ mV3; - } - - void sipRound() - { - mV0 += mV1; - mV1 = RotateLeft(mV1, 13); - mV1 ^= mV0; - mV0 = RotateLeft(mV0, 32); - mV2 += mV3; - mV3 = RotateLeft(mV3, 16); - mV3 ^= mV2; - mV0 += mV3; - mV3 = RotateLeft(mV3, 21); - mV3 ^= mV0; - mV2 += mV1; - mV1 = RotateLeft(mV1, 17); - mV1 ^= mV2; - mV2 = RotateLeft(mV2, 32); - } - - uint64_t mV0, mV1, mV2, mV3; - }; -}; - } /* namespace mozilla */ #endif /* __cplusplus */ diff --git a/src/third_party/mozjs-45/get-sources.sh b/src/third_party/mozjs-45/get-sources.sh index 089a52d2793..39acace54e5 100644 --- a/src/third_party/mozjs-45/get-sources.sh +++ b/src/third_party/mozjs-45/get-sources.sh @@ -2,7 +2,7 @@ # how we got the last firefox sources -VERSION=45.8.0esr +VERSION=45.5.0esr TARBALL=firefox-$VERSION.source.tar.xz if [ ! -f $TARBALL ]; then wget "https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/$VERSION/source/$TARBALL" diff --git a/src/third_party/mozjs-45/include/js/GCAPI.h b/src/third_party/mozjs-45/include/js/GCAPI.h index 84b6150c36f..90f8e4eba3f 100644 --- a/src/third_party/mozjs-45/include/js/GCAPI.h +++ b/src/third_party/mozjs-45/include/js/GCAPI.h @@ -566,6 +566,8 @@ namespace gc { static MOZ_ALWAYS_INLINE void ExposeGCThingToActiveJS(JS::GCCellPtr thing) { + MOZ_ASSERT(thing.kind() != JS::TraceKind::Shape); + /* * GC things residing in the nursery cannot be gray: they have no mark bits. * All live objects in the nursery are moved to tenured at the beginning of diff --git a/src/third_party/mozjs-45/include/mozilla/HashFunctions.h b/src/third_party/mozjs-45/include/mozilla/HashFunctions.h index 8eb83a3737c..f490a28fee4 100644 --- a/src/third_party/mozjs-45/include/mozilla/HashFunctions.h +++ b/src/third_party/mozjs-45/include/mozilla/HashFunctions.h @@ -50,7 +50,6 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Char16.h" -#include "mozilla/MathAlgorithms.h" #include "mozilla/Types.h" #include <stdint.h> @@ -313,90 +312,6 @@ HashString(const wchar_t* aStr, size_t aLength) MOZ_WARN_UNUSED_RESULT extern MFBT_API uint32_t HashBytes(const void* bytes, size_t aLength); -/** - * A pseudorandom function mapping 32-bit integers to 32-bit integers. - * - * This is for when you're feeding private data (like pointer values or credit - * card numbers) to a non-crypto hash function (like HashBytes) and then using - * the hash code for something that untrusted parties could observe (like a JS - * Map). Plug in a HashCodeScrambler before that last step to avoid leaking the - * private data. - * - * By itself, this does not prevent hash-flooding DoS attacks, because an - * attacker can still generate many values with exactly equal hash codes by - * attacking the non-crypto hash function alone. Equal hash codes will, of - * course, still be equal however much you scramble them. - * - * The algorithm is SipHash-1-3. See <https://131002.net/siphash/>. - */ -class HashCodeScrambler -{ - struct SipHasher; - - uint64_t mK0, mK1; - -public: - /** Creates a new scrambler with the given 128-bit key. */ - HashCodeScrambler(uint64_t aK0, uint64_t aK1) : mK0(aK0), mK1(aK1) {} - - /** - * Scramble a hash code. Always produces the same result for the same - * combination of key and hash code. - */ - uint32_t scramble(uint32_t aHashCode) const - { - SipHasher hasher(mK0, mK1); - return uint32_t(hasher.sipHash(aHashCode)); - } - -private: - struct SipHasher - { - SipHasher(uint64_t aK0, uint64_t aK1) - { - // 1. Initialization. - mV0 = aK0 ^ UINT64_C(0x736f6d6570736575); - mV1 = aK1 ^ UINT64_C(0x646f72616e646f6d); - mV2 = aK0 ^ UINT64_C(0x6c7967656e657261); - mV3 = aK1 ^ UINT64_C(0x7465646279746573); - } - - uint64_t sipHash(uint64_t aM) - { - // 2. Compression. - mV3 ^= aM; - sipRound(); - mV0 ^= aM; - - // 3. Finalization. - mV2 ^= 0xff; - for (int i = 0; i < 3; i++) - sipRound(); - return mV0 ^ mV1 ^ mV2 ^ mV3; - } - - void sipRound() - { - mV0 += mV1; - mV1 = RotateLeft(mV1, 13); - mV1 ^= mV0; - mV0 = RotateLeft(mV0, 32); - mV2 += mV3; - mV3 = RotateLeft(mV3, 16); - mV3 ^= mV2; - mV0 += mV3; - mV3 = RotateLeft(mV3, 21); - mV3 ^= mV0; - mV2 += mV1; - mV1 = RotateLeft(mV1, 17); - mV1 ^= mV2; - mV2 = RotateLeft(mV2, 32); - } - - uint64_t mV0, mV1, mV2, mV3; - }; -}; - } /* namespace mozilla */ #endif /* __cplusplus */ diff --git a/src/third_party/mozjs-45/platform/aarch64/linux/build/js-confdefs.h b/src/third_party/mozjs-45/platform/aarch64/linux/build/js-confdefs.h index 2b1a51d09f7..debbcfb5052 100644 --- a/src/third_party/mozjs-45/platform/aarch64/linux/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/aarch64/linux/build/js-confdefs.h @@ -74,10 +74,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/aarch64/linux/include/js-config.h b/src/third_party/mozjs-45/platform/aarch64/linux/include/js-config.h index e4dcddbe680..49bb6d59d70 100644 --- a/src/third_party/mozjs-45/platform/aarch64/linux/include/js-config.h +++ b/src/third_party/mozjs-45/platform/aarch64/linux/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/ppc64le/linux/build/js-confdefs.h b/src/third_party/mozjs-45/platform/ppc64le/linux/build/js-confdefs.h index 2b1a51d09f7..debbcfb5052 100644 --- a/src/third_party/mozjs-45/platform/ppc64le/linux/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/ppc64le/linux/build/js-confdefs.h @@ -74,10 +74,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/ppc64le/linux/include/js-config.h b/src/third_party/mozjs-45/platform/ppc64le/linux/include/js-config.h index e4dcddbe680..49bb6d59d70 100644 --- a/src/third_party/mozjs-45/platform/ppc64le/linux/include/js-config.h +++ b/src/third_party/mozjs-45/platform/ppc64le/linux/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/s390x/linux/build/js-confdefs.h b/src/third_party/mozjs-45/platform/s390x/linux/build/js-confdefs.h index c94367cff3f..b4a6a864fc0 100644 --- a/src/third_party/mozjs-45/platform/s390x/linux/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/s390x/linux/build/js-confdefs.h @@ -75,10 +75,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/s390x/linux/include/js-config.h b/src/third_party/mozjs-45/platform/s390x/linux/include/js-config.h index e4dcddbe680..49bb6d59d70 100644 --- a/src/third_party/mozjs-45/platform/s390x/linux/include/js-config.h +++ b/src/third_party/mozjs-45/platform/s390x/linux/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/freebsd/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/freebsd/build/js-confdefs.h index c36f3704f05..c99865cff0d 100644 --- a/src/third_party/mozjs-45/platform/x86_64/freebsd/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/freebsd/build/js-confdefs.h @@ -69,10 +69,10 @@ #define MALLOC_H <malloc_np.h> #define MALLOC_USABLE_SIZE_CONST_PTR const #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/freebsd/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/freebsd/include/js-config.h index dcc2617a294..e4175f7d74d 100644 --- a/src/third_party/mozjs-45/platform/x86_64/freebsd/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/freebsd/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/linux/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/linux/build/js-confdefs.h index 9b3d5f6ca7b..d3a0aac8ae9 100644 --- a/src/third_party/mozjs-45/platform/x86_64/linux/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/linux/build/js-confdefs.h @@ -79,10 +79,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/linux/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/linux/include/js-config.h index e4dcddbe680..49bb6d59d70 100644 --- a/src/third_party/mozjs-45/platform/x86_64/linux/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/linux/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/macOS/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/macOS/build/js-confdefs.h index 48623cf2b8b..c4ff9c6d80b 100644 --- a/src/third_party/mozjs-45/platform/x86_64/macOS/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/macOS/build/js-confdefs.h @@ -62,10 +62,10 @@ #define MALLOC_H <malloc/malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR const #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".dylib" #define MOZ_MEMORY 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/macOS/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/macOS/include/js-config.h index dcc2617a294..e4175f7d74d 100644 --- a/src/third_party/mozjs-45/platform/x86_64/macOS/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/macOS/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/openbsd/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/openbsd/build/js-confdefs.h index d4ccca388b9..8b25ee0b17b 100644 --- a/src/third_party/mozjs-45/platform/x86_64/openbsd/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/openbsd/build/js-confdefs.h @@ -67,10 +67,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR const #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so.1.0" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/openbsd/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/openbsd/include/js-config.h index 071a002314c..ac52cef4d93 100644 --- a/src/third_party/mozjs-45/platform/x86_64/openbsd/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/openbsd/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/solaris/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/solaris/build/js-confdefs.h index 24af9ec84b2..bd7f2dc1cba 100644 --- a/src/third_party/mozjs-45/platform/x86_64/solaris/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/solaris/build/js-confdefs.h @@ -69,10 +69,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR const #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".so" #define MOZ_GLUE_IN_PROGRAM 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/solaris/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/solaris/include/js-config.h index 8dd55eebb3f..d916ed709c4 100644 --- a/src/third_party/mozjs-45/platform/x86_64/solaris/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/solaris/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ diff --git a/src/third_party/mozjs-45/platform/x86_64/windows/build/js-confdefs.h b/src/third_party/mozjs-45/platform/x86_64/windows/build/js-confdefs.h index 2be82e81ea4..4bcf6372758 100644 --- a/src/third_party/mozjs-45/platform/x86_64/windows/build/js-confdefs.h +++ b/src/third_party/mozjs-45/platform/x86_64/windows/build/js-confdefs.h @@ -30,10 +30,10 @@ #define MALLOC_H <malloc.h> #define MALLOC_USABLE_SIZE_CONST_PTR const #define MOZILLA_UAVERSION "45.0" -#define MOZILLA_VERSION "45.8.0" -#define MOZILLA_VERSION_U 45.8.0 +#define MOZILLA_VERSION "45.5.0" +#define MOZILLA_VERSION_U 45.5.0 #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #define MOZ_DEBUG_SYMBOLS 1 #define MOZ_DLL_SUFFIX ".dll" #define MOZ_MEMORY 1 diff --git a/src/third_party/mozjs-45/platform/x86_64/windows/include/js-config.h b/src/third_party/mozjs-45/platform/x86_64/windows/include/js-config.h index 1ea25b51001..01fcaf17001 100644 --- a/src/third_party/mozjs-45/platform/x86_64/windows/include/js-config.h +++ b/src/third_party/mozjs-45/platform/x86_64/windows/include/js-config.h @@ -54,6 +54,6 @@ /* MOZILLA JSAPI version number components */ #define MOZJS_MAJOR_VERSION 45 -#define MOZJS_MINOR_VERSION 8 +#define MOZJS_MINOR_VERSION 5 #endif /* js_config_h */ |