diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/ipc/JavaScriptParent.cpp | 3 | ||||
-rw-r--r-- | js/public/HashTable.h | 46 | ||||
-rw-r--r-- | js/public/MemoryMetrics.h | 18 | ||||
-rw-r--r-- | js/src/builtin/AtomicsObject.cpp | 2 | ||||
-rw-r--r-- | js/src/gc/Barrier.h | 27 | ||||
-rw-r--r-- | js/src/jit/MacroAssembler.cpp | 6 | ||||
-rw-r--r-- | js/src/jit/ProcessExecutableMemory.cpp | 8 | ||||
-rw-r--r-- | js/src/jit/ProcessExecutableMemory.h | 8 | ||||
-rw-r--r-- | js/src/jit/shared/IonAssemblerBuffer.h | 4 | ||||
-rw-r--r-- | js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h | 35 | ||||
-rw-r--r-- | js/src/vm/NativeObject.h | 11 | ||||
-rw-r--r-- | js/xpconnect/src/XPCJSContext.cpp | 99 |
12 files changed, 72 insertions, 195 deletions
diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp index ca0a0bd21..6cf9e0591 100644 --- a/js/ipc/JavaScriptParent.cpp +++ b/js/ipc/JavaScriptParent.cpp @@ -15,7 +15,6 @@ #include "js/HeapAPI.h" #include "xpcprivate.h" #include "mozilla/Casting.h" -#include "mozilla/Telemetry.h" #include "mozilla/Unused.h" #include "nsAutoPtr.h" @@ -110,7 +109,6 @@ JavaScriptParent::allowMessage(JSContext* cx) if (!xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) { if (!addonId && ForbidUnsafeBrowserCPOWs() && !isSafe) { - Telemetry::Accumulate(Telemetry::BROWSER_SHIM_USAGE_BLOCKED, 1); JS_ReportErrorASCII(cx, "unsafe CPOW usage forbidden"); return false; } @@ -120,7 +118,6 @@ JavaScriptParent::allowMessage(JSContext* cx) nsString addonIdString; AssignJSFlatString(addonIdString, flat); NS_ConvertUTF16toUTF8 addonIdCString(addonIdString); - Telemetry::Accumulate(Telemetry::ADDON_FORBIDDEN_CPOW_USAGE, addonIdCString); if (ForbidCPOWsInCompatibleAddon(addonIdCString)) { JS_ReportErrorASCII(cx, "CPOW usage forbidden in this add-on"); diff --git a/js/public/HashTable.h b/js/public/HashTable.h index 5d4c0665d..8a2493b55 100644 --- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -12,6 +12,7 @@ #include "mozilla/Attributes.h" #include "mozilla/Casting.h" #include "mozilla/HashFunctions.h" +#include "mozilla/MemoryChecking.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Move.h" #include "mozilla/Opaque.h" @@ -805,17 +806,22 @@ class HashTableEntry void operator=(const HashTableEntry&) = delete; ~HashTableEntry() = delete; + void destroyStoredT() { + mem.addr()->~T(); + MOZ_MAKE_MEM_UNDEFINED(mem.addr(), sizeof(*mem.addr())); + } + public: // NB: HashTableEntry is treated as a POD: no constructor or destructor calls. void destroyIfLive() { if (isLive()) - mem.addr()->~T(); + destroyStoredT(); } void destroy() { MOZ_ASSERT(isLive()); - mem.addr()->~T(); + destroyStoredT(); } void swap(HashTableEntry* other) { @@ -835,10 +841,28 @@ class HashTableEntry NonConstT& getMutable() { MOZ_ASSERT(isLive()); return *mem.addr(); } bool isFree() const { return keyHash == sFreeKey; } - void clearLive() { MOZ_ASSERT(isLive()); keyHash = sFreeKey; mem.addr()->~T(); } - void clear() { if (isLive()) mem.addr()->~T(); keyHash = sFreeKey; } + void clearLive() { + MOZ_ASSERT(isLive()); + keyHash = sFreeKey; + destroyStoredT(); + } + + void clear() { + if (isLive()) + destroyStoredT(); + + MOZ_MAKE_MEM_UNDEFINED(this, sizeof(*this)); + keyHash = sFreeKey; + } + bool isRemoved() const { return keyHash == sRemovedKey; } - void removeLive() { MOZ_ASSERT(isLive()); keyHash = sRemovedKey; mem.addr()->~T(); } + + void removeLive() { + MOZ_ASSERT(isLive()); + keyHash = sRemovedKey; + destroyStoredT(); + } + bool isLive() const { return isLiveHash(keyHash); } void setCollision() { MOZ_ASSERT(isLive()); keyHash |= sCollisionBit; } void unsetCollision() { keyHash &= ~sCollisionBit; } @@ -1654,14 +1678,10 @@ class HashTable : private AllocPolicy public: void clear() { - if (mozilla::IsPod<Entry>::value) { - memset(table, 0, sizeof(*table) * capacity()); - } else { - uint32_t tableCapacity = capacity(); - Entry* end = table + tableCapacity; - for (Entry* e = table; e < end; ++e) - e->clear(); - } + Entry* end = table + capacity(); + for (Entry* e = table; e < end; ++e) + e->clear(); + removedCount = 0; entryCount = 0; #ifdef JS_DEBUG diff --git a/js/public/MemoryMetrics.h b/js/public/MemoryMetrics.h index 9b5caa24b..b0b26631c 100644 --- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -37,7 +37,13 @@ struct TabSizes Other }; - TabSizes() { mozilla::PodZero(this); } + TabSizes() + : objects(0) + , strings(0) + , private_(0) + , other(0) + { + } void add(Kind kind, size_t n) { switch (kind) { @@ -68,7 +74,15 @@ struct ServoSizes Ignore }; - ServoSizes() { mozilla::PodZero(this); } + ServoSizes() + : gcHeapUsed(0) + , gcHeapUnused(0) + , gcHeapAdmin(0) + , gcHeapDecommitted(0) + , mallocHeap(0) + , nonHeap(0) + { + } void add(Kind kind, size_t n) { switch (kind) { diff --git a/js/src/builtin/AtomicsObject.cpp b/js/src/builtin/AtomicsObject.cpp index 08777fd51..2551f3b7d 100644 --- a/js/src/builtin/AtomicsObject.cpp +++ b/js/src/builtin/AtomicsObject.cpp @@ -789,7 +789,7 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp) // and it provides the necessary memory fence. AutoLockFutexAPI lock; - SharedMem<int32_t*>(addr) = view->viewDataShared().cast<int32_t*>() + offset; + SharedMem<int32_t*> addr = view->viewDataShared().cast<int32_t*>() + offset; if (jit::AtomicOperations::loadSafeWhenRacy(addr) != value) { r.setString(cx->names().futexNotEqual); return true; diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index effc9233e..dce3b2a20 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -667,29 +667,15 @@ class HeapSlot : public WriteBarrieredBase<Value> Element = 1 }; - explicit HeapSlot() = delete; - - explicit HeapSlot(NativeObject* obj, Kind kind, uint32_t slot, const Value& v) - : WriteBarrieredBase<Value>(v) - { - post(obj, kind, slot, v); - } - - explicit HeapSlot(NativeObject* obj, Kind kind, uint32_t slot, const HeapSlot& s) - : WriteBarrieredBase<Value>(s.value) - { - post(obj, kind, slot, s); - } - - ~HeapSlot() { - pre(); - } - void init(NativeObject* owner, Kind kind, uint32_t slot, const Value& v) { value = v; post(owner, kind, slot, v); } + void destroy() { + pre(); + } + #ifdef DEBUG bool preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot) const; bool preconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t slot, @@ -703,11 +689,6 @@ class HeapSlot : public WriteBarrieredBase<Value> post(owner, kind, slot, v); } - /* For users who need to manually barrier the raw types. */ - static void writeBarrierPost(NativeObject* owner, Kind kind, uint32_t slot, const Value& target) { - reinterpret_cast<HeapSlot*>(const_cast<Value*>(&target))->post(owner, kind, slot, target); - } - private: void post(NativeObject* owner, Kind kind, uint32_t slot, const Value& target) { MOZ_ASSERT(preconditionForWriteBarrierPost(owner, kind, slot, target)); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 9dbbe7624..f633b9b7b 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -2214,12 +2214,6 @@ MacroAssembler::finish() } MacroAssemblerSpecific::finish(); - - MOZ_RELEASE_ASSERT(size() <= MaxCodeBytesPerProcess, - "AssemblerBuffer should ensure we don't exceed MaxCodeBytesPerProcess"); - - if (bytesNeeded() > MaxCodeBytesPerProcess) - setOOM(); } void diff --git a/js/src/jit/ProcessExecutableMemory.cpp b/js/src/jit/ProcessExecutableMemory.cpp index 301541541..71c2ab0dc 100644 --- a/js/src/jit/ProcessExecutableMemory.cpp +++ b/js/src/jit/ProcessExecutableMemory.cpp @@ -385,6 +385,14 @@ class PageBitSet #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 = 1 * 1024 * 1024 * 1024; +#endif + // Per-process executable memory allocator. It reserves a block of memory of // MaxCodeBytesPerProcess bytes, then allocates/deallocates pages from that. // diff --git a/js/src/jit/ProcessExecutableMemory.h b/js/src/jit/ProcessExecutableMemory.h index a0e2fab98..078ce7cb7 100644 --- a/js/src/jit/ProcessExecutableMemory.h +++ b/js/src/jit/ProcessExecutableMemory.h @@ -17,14 +17,6 @@ namespace jit { // alignment though. static const size_t ExecutableCodePageSize = 64 * 1024; -// 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 = 1 * 1024 * 1024 * 1024; -#endif - enum class ProtectionSetting { Protected, // Not readable, writable, or executable. Writable, diff --git a/js/src/jit/shared/IonAssemblerBuffer.h b/js/src/jit/shared/IonAssemblerBuffer.h index 3a6552696..cc20e26d2 100644 --- a/js/src/jit/shared/IonAssemblerBuffer.h +++ b/js/src/jit/shared/IonAssemblerBuffer.h @@ -181,10 +181,6 @@ class AssemblerBuffer protected: virtual Slice* newSlice(LifoAlloc& a) { - if (size() > MaxCodeBytesPerProcess - sizeof(Slice)) { - fail_oom(); - return nullptr; - } Slice* tmp = static_cast<Slice*>(a.alloc(sizeof(Slice))); if (!tmp) { fail_oom(); diff --git a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h index fe678fc7d..8343579c8 100644 --- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h @@ -68,33 +68,6 @@ namespace js { namespace jit { - // AllocPolicy for AssemblerBuffer. OOMs when trying to allocate more than - // MaxCodeBytesPerProcess bytes. Use private inheritance to make sure we - // explicitly have to expose SystemAllocPolicy methods. - class AssemblerBufferAllocPolicy : private SystemAllocPolicy - { - public: - using SystemAllocPolicy::checkSimulatedOOM; - using SystemAllocPolicy::reportAllocOverflow; - using SystemAllocPolicy::free_; - - template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - static_assert(sizeof(T) == 1, - "AssemblerBufferAllocPolicy should only be used with byte vectors"); - MOZ_ASSERT(oldSize <= MaxCodeBytesPerProcess); - if (MOZ_UNLIKELY(newSize > MaxCodeBytesPerProcess)) - return nullptr; - return SystemAllocPolicy::pod_realloc<T>(p, oldSize, newSize); - } - template <typename T> T* pod_malloc(size_t numElems) { - static_assert(sizeof(T) == 1, - "AssemblerBufferAllocPolicy should only be used with byte vectors"); - if (MOZ_UNLIKELY(numElems > MaxCodeBytesPerProcess)) - return nullptr; - return SystemAllocPolicy::pod_malloc<T>(numElems); - } - }; - class AssemblerBuffer { template<size_t size, typename T> @@ -120,10 +93,8 @@ namespace jit { void ensureSpace(size_t space) { - // This should only be called with small |space| values to ensure - // we don't overflow below. - MOZ_ASSERT(space <= 16); - if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space))) + if (MOZ_UNLIKELY(m_buffer.length() > (SIZE_MAX - space) || + !m_buffer.reserve(m_buffer.length() + space))) oomDetected(); } @@ -198,7 +169,7 @@ namespace jit { m_buffer.clear(); } - PageProtectingVector<unsigned char, 256, AssemblerBufferAllocPolicy> m_buffer; + PageProtectingVector<unsigned char, 256, SystemAllocPolicy> m_buffer; bool m_oom; }; diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index d2c06eabc..4dbc167ab 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -876,7 +876,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(end <= getDenseInitializedLength()); MOZ_ASSERT(!denseElementsAreCopyOnWrite()); for (size_t i = start; i < end; i++) - elements_[i].HeapSlot::~HeapSlot(); + elements_[i].destroy(); } /* @@ -885,7 +885,7 @@ class NativeObject : public ShapedObject */ void prepareSlotRangeForOverwrite(size_t start, size_t end) { for (size_t i = start; i < end; i++) - getSlotAddressUnchecked(i)->HeapSlot::~HeapSlot(); + getSlotAddressUnchecked(i)->destroy(); } public: @@ -1085,7 +1085,8 @@ class NativeObject : public ShapedObject for (uint32_t i = 0; i < count; ++i) elements_[dstStart + i].set(this, HeapSlot::Element, dstStart + i, src[i]); } else { - memcpy(&elements_[dstStart], src, count * sizeof(HeapSlot)); + memcpy(reinterpret_cast<Value*>(&elements_[dstStart]), src, + count * sizeof(Value)); elementsRangeWriteBarrierPost(dstStart, count); } } @@ -1094,7 +1095,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(dstStart + count <= getDenseCapacity()); MOZ_ASSERT(!denseElementsAreCopyOnWrite()); MOZ_ASSERT(!denseElementsAreFrozen()); - memcpy(&elements_[dstStart], src, count * sizeof(HeapSlot)); + memcpy(reinterpret_cast<Value*>(&elements_[dstStart]), src, count * sizeof(Value)); elementsRangeWriteBarrierPost(dstStart, count); } @@ -1142,7 +1143,7 @@ class NativeObject : public ShapedObject MOZ_ASSERT(!denseElementsAreCopyOnWrite()); MOZ_ASSERT(!denseElementsAreFrozen()); - memmove(elements_ + dstStart, elements_ + srcStart, count * sizeof(Value)); + memmove(elements_ + dstStart, elements_ + srcStart, count * sizeof(HeapSlot)); elementsRangeWriteBarrierPost(dstStart, count); } diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index f352607d4..82af64520 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -28,7 +28,6 @@ #include "nsPIDOMWindow.h" #include "nsPrintfCString.h" #include "mozilla/Preferences.h" -#include "mozilla/Telemetry.h" #include "mozilla/Services.h" #include "mozilla/dom/ScriptSettings.h" @@ -135,8 +134,6 @@ public: { TimeStamp start = TimeStamp::Now(); bool hadSnowWhiteObjects = nsCycleCollector_doDeferredDeletion(); - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING, - uint32_t((TimeStamp::Now() - start).ToMilliseconds())); if (hadSnowWhiteObjects && !mContinuation) { mContinuation = true; if (NS_FAILED(NS_DispatchToCurrentThread(this))) { @@ -1317,7 +1314,6 @@ XPCJSContext::InterruptCallback(JSContext* cx) // Accumulate slow script invokation delay. if (!chrome && !self->mTimeoutAccumulated) { uint32_t delay = uint32_t(self->mSlowScriptActualWait.ToMilliseconds() - (limit * 1000.0)); - Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_NOTIFY_DELAY, delay); self->mTimeoutAccumulated = true; } @@ -2955,100 +2951,7 @@ JSSizeOfTab(JSObject* objArg, size_t* jsObjectsSize, size_t* jsStringsSize, static void AccumulateTelemetryCallback(int id, uint32_t sample, const char* key) { - switch (id) { - case JS_TELEMETRY_GC_REASON: - Telemetry::Accumulate(Telemetry::GC_REASON_2, sample); - break; - case JS_TELEMETRY_GC_IS_ZONE_GC: - Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample); - break; - case JS_TELEMETRY_GC_MS: - Telemetry::Accumulate(Telemetry::GC_MS, sample); - break; - case JS_TELEMETRY_GC_BUDGET_MS: - Telemetry::Accumulate(Telemetry::GC_BUDGET_MS, sample); - break; - case JS_TELEMETRY_GC_ANIMATION_MS: - Telemetry::Accumulate(Telemetry::GC_ANIMATION_MS, sample); - break; - case JS_TELEMETRY_GC_MAX_PAUSE_MS: - Telemetry::Accumulate(Telemetry::GC_MAX_PAUSE_MS, sample); - break; - case JS_TELEMETRY_GC_MARK_MS: - Telemetry::Accumulate(Telemetry::GC_MARK_MS, sample); - break; - case JS_TELEMETRY_GC_SWEEP_MS: - Telemetry::Accumulate(Telemetry::GC_SWEEP_MS, sample); - break; - case JS_TELEMETRY_GC_COMPACT_MS: - Telemetry::Accumulate(Telemetry::GC_COMPACT_MS, sample); - break; - case JS_TELEMETRY_GC_MARK_ROOTS_MS: - Telemetry::Accumulate(Telemetry::GC_MARK_ROOTS_MS, sample); - break; - case JS_TELEMETRY_GC_MARK_GRAY_MS: - Telemetry::Accumulate(Telemetry::GC_MARK_GRAY_MS, sample); - break; - case JS_TELEMETRY_GC_SLICE_MS: - Telemetry::Accumulate(Telemetry::GC_SLICE_MS, sample); - break; - case JS_TELEMETRY_GC_SLOW_PHASE: - Telemetry::Accumulate(Telemetry::GC_SLOW_PHASE, sample); - break; - case JS_TELEMETRY_GC_MMU_50: - Telemetry::Accumulate(Telemetry::GC_MMU_50, sample); - break; - case JS_TELEMETRY_GC_RESET: - Telemetry::Accumulate(Telemetry::GC_RESET, sample); - break; - case JS_TELEMETRY_GC_RESET_REASON: - Telemetry::Accumulate(Telemetry::GC_RESET_REASON, sample); - break; - case JS_TELEMETRY_GC_INCREMENTAL_DISABLED: - Telemetry::Accumulate(Telemetry::GC_INCREMENTAL_DISABLED, sample); - break; - case JS_TELEMETRY_GC_NON_INCREMENTAL: - Telemetry::Accumulate(Telemetry::GC_NON_INCREMENTAL, sample); - break; - case JS_TELEMETRY_GC_NON_INCREMENTAL_REASON: - Telemetry::Accumulate(Telemetry::GC_NON_INCREMENTAL_REASON, sample); - break; - case JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS: - Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_TOTAL_MS, sample); - break; - case JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS: - Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_MAX_PAUSE_MS, sample); - break; - case JS_TELEMETRY_GC_MINOR_REASON: - Telemetry::Accumulate(Telemetry::GC_MINOR_REASON, sample); - break; - case JS_TELEMETRY_GC_MINOR_REASON_LONG: - Telemetry::Accumulate(Telemetry::GC_MINOR_REASON_LONG, sample); - break; - case JS_TELEMETRY_GC_MINOR_US: - Telemetry::Accumulate(Telemetry::GC_MINOR_US, sample); - break; - case JS_TELEMETRY_GC_NURSERY_BYTES: - Telemetry::Accumulate(Telemetry::GC_NURSERY_BYTES, sample); - break; - case JS_TELEMETRY_GC_PRETENURE_COUNT: - Telemetry::Accumulate(Telemetry::GC_PRETENURE_COUNT, sample); - break; - case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT: - Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample); - break; - case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS: - Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS, sample); - break; - case JS_TELEMETRY_ADDON_EXCEPTIONS: - Telemetry::Accumulate(Telemetry::JS_TELEMETRY_ADDON_EXCEPTIONS, nsDependentCString(key), sample); - break; - case JS_TELEMETRY_AOT_USAGE: - Telemetry::Accumulate(Telemetry::JS_AOT_USAGE, sample); - break; - default: - MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id"); - } +/* STUB */ } static void |