diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-09-17 08:51:49 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-09-17 08:51:49 +0200 |
commit | 882aaf5b1fda7b216051b55e268de78fd5126f42 (patch) | |
tree | ccb3f6f6299a5d1c603e6b73d3892f635bb96a8e /js | |
parent | 8ee235ca5df26f39ca3066935bef90c4d28dd61a (diff) | |
parent | d118d486a680ed42030b1bdee263a29831da3e86 (diff) | |
download | UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.gz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.lz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.tar.xz UXP-882aaf5b1fda7b216051b55e268de78fd5126f42.zip |
Merge branch 'master' into Pale_Moon-release
# Conflicts:
# application/palemoon/config/version.txt
# js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
# toolkit/components/search/orginal/nsSearchService.js
Diffstat (limited to 'js')
27 files changed, 311 insertions, 330 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..dcc886217 100644 --- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -11,7 +11,6 @@ // at your own risk. #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "mozilla/TypeTraits.h" #include <string.h> @@ -37,7 +36,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 +73,7 @@ struct ServoSizes Ignore }; - ServoSizes() { mozilla::PodZero(this); } + ServoSizes() = default; void add(Kind kind, size_t n) { switch (kind) { @@ -83,12 +88,12 @@ struct ServoSizes } } - size_t gcHeapUsed; - size_t gcHeapUnused; - size_t gcHeapAdmin; - size_t gcHeapDecommitted; - size_t mallocHeap; - size_t nonHeap; + size_t gcHeapUsed = 0; + size_t gcHeapUnused = 0; + size_t gcHeapAdmin = 0; + size_t gcHeapDecommitted = 0; + size_t mallocHeap = 0; + size_t nonHeap = 0; }; } // namespace JS diff --git a/js/public/Utility.h b/js/public/Utility.h index 68de3004a..99712faa8 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -391,7 +391,7 @@ js_delete_poison(const T* p) { if (p) { p->~T(); - memset(const_cast<T*>(p), 0x3B, sizeof(T)); + memset(static_cast<void*>(const_cast<T*>(p)), 0x3B, sizeof(T)); js_free(const_cast<T*>(p)); } } 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/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index f349cd476..b4e9c3418 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -15,6 +15,8 @@ #include "mozilla/TemplateLib.h" #include "mozilla/TypeTraits.h" +#include <new> + // This data structure supports stacky LIFO allocation (mark/release and // LifoAllocScope). It does not maintain one contiguous segment; instead, it // maintains a bunch of linked memory segments. In order to prevent malloc/free @@ -285,6 +287,20 @@ class LifoAlloc return allocImpl(n); } + template<typename T, typename... Args> + MOZ_ALWAYS_INLINE T* + allocInSize(size_t n, Args&&... args) + { + MOZ_ASSERT(n >= sizeof(T), "must request enough space to store a T"); + static_assert(alignof(T) <= detail::LIFO_ALLOC_ALIGN, + "LifoAlloc must provide enough alignment to store T"); + void* ptr = alloc(n); + if (!ptr) + return nullptr; + + return new (ptr) T(mozilla::Forward<Args>(args)...); + } + MOZ_ALWAYS_INLINE void* allocInfallible(size_t n) { AutoEnterOOMUnsafeRegion oomUnsafe; diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index c7c615ccf..4eb7bf880 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -319,7 +319,7 @@ ScopeKindIsInBody(ScopeKind kind) static inline void MarkAllBindingsClosedOver(LexicalScope::Data& data) { - BindingName* names = data.names; + TrailingNamesArray& names = data.trailingNames; for (uint32_t i = 0; i < data.length; i++) names[i] = BindingName(names[i].name(), true); } @@ -8978,7 +8978,8 @@ BytecodeEmitter::isRestParameter(ParseNode* pn, bool* result) if (bindings->nonPositionalFormalStart > 0) { // |paramName| can be nullptr when the rest destructuring syntax is // used: `function f(...[]) {}`. - JSAtom* paramName = bindings->names[bindings->nonPositionalFormalStart - 1].name(); + JSAtom* paramName = + bindings->trailingNames[bindings->nonPositionalFormalStart - 1].name(); *result = paramName && name == paramName; return true; } diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp index ece3a45df..91f17625c 100644 --- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -838,7 +838,7 @@ LexicalScopeNode::dump(int indent) if (!isEmptyScope()) { LexicalScope::Data* bindings = scopeBindings(); for (uint32_t i = 0; i < bindings->length; i++) { - JSAtom* name = bindings->names[i].name(); + JSAtom* name = bindings->trailingNames[i].name(); JS::AutoCheckCannotGC nogc; if (name->hasLatin1Chars()) DumpName(name->latin1Chars(nogc), name->length()); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 623379f61..7bfab87a3 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -19,6 +19,8 @@ #include "frontend/Parser.h" +#include <new> + #include "jsapi.h" #include "jsatom.h" #include "jscntxt.h" @@ -1451,16 +1453,26 @@ template <typename Scope> static typename Scope::Data* NewEmptyBindingData(ExclusiveContext* cx, LifoAlloc& alloc, uint32_t numBindings) { + using Data = typename Scope::Data; size_t allocSize = Scope::sizeOfData(numBindings); - typename Scope::Data* bindings = static_cast<typename Scope::Data*>(alloc.alloc(allocSize)); - if (!bindings) { + auto* bindings = alloc.allocInSize<Data>(allocSize, numBindings); + if (!bindings) ReportOutOfMemory(cx); - return nullptr; - } - PodZero(bindings); return bindings; } +/** + * Copy-construct |BindingName|s from |bindings| into |cursor|, then return + * the location one past the newly-constructed |BindingName|s. + */ +static MOZ_MUST_USE BindingName* +FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindings) +{ + for (const BindingName& binding : bindings) + new (cursor++) BindingName(binding); + return cursor; +} + template <> Maybe<GlobalScope::Data*> Parser<FullParseHandler>::newGlobalScopeData(ParseContext::Scope& scope) @@ -1505,22 +1517,20 @@ Parser<FullParseHandler>::newGlobalScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in GlobalScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, funs.begin(), funs.length()); - cursor += funs.length(); + cursor = FreshlyInitializeBindings(cursor, funs); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); - cursor += vars.length(); + cursor = FreshlyInitializeBindings(cursor, vars); bindings->letStart = cursor - start; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } @@ -1572,22 +1582,20 @@ Parser<FullParseHandler>::newModuleScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in ModuleScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, imports.begin(), imports.length()); - cursor += imports.length(); + cursor = FreshlyInitializeBindings(cursor, imports); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); - cursor += vars.length(); + cursor = FreshlyInitializeBindings(cursor, vars); bindings->letStart = cursor - start; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } @@ -1623,16 +1631,16 @@ Parser<FullParseHandler>::newEvalScopeData(ParseContext::Scope& scope) if (!bindings) return Nothing(); - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; // Keep track of what vars are functions. This is only used in BCE to omit // superfluous DEFVARs. - PodCopy(cursor, funs.begin(), funs.length()); - cursor += funs.length(); + cursor = FreshlyInitializeBindings(cursor, funs); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1719,18 +1727,17 @@ Parser<FullParseHandler>::newFunctionScopeData(ParseContext::Scope& scope, bool return Nothing(); // The ordering here is important. See comments in FunctionScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, positionalFormals.begin(), positionalFormals.length()); - cursor += positionalFormals.length(); + cursor = FreshlyInitializeBindings(cursor, positionalFormals); bindings->nonPositionalFormalStart = cursor - start; - PodCopy(cursor, formals.begin(), formals.length()); - cursor += formals.length(); + cursor = FreshlyInitializeBindings(cursor, formals); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1760,10 +1767,11 @@ Parser<FullParseHandler>::newVarScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in FunctionScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1808,14 +1816,14 @@ Parser<FullParseHandler>::newLexicalScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in LexicalScope. - BindingName* cursor = bindings->names; + BindingName* cursor = bindings->trailingNames.start(); BindingName* start = cursor; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } 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/gc/GCInternals.h b/js/src/gc/GCInternals.h index 4919b87a5..e8df0bb70 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -9,7 +9,6 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/Maybe.h" -#include "mozilla/PodOperations.h" #include "jscntxt.h" @@ -102,9 +101,9 @@ struct TenureCountCache static const size_t EntryShift = 4; static const size_t EntryCount = 1 << EntryShift; - TenureCount entries[EntryCount]; + TenureCount entries[EntryCount] = {}; // zeroes - TenureCountCache() { mozilla::PodZero(this); } + TenureCountCache() = default; HashNumber hash(ObjectGroup* group) { #if JS_BITS_PER_WORD == 32 diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index b2c105999..3ea4c9d29 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -1231,34 +1231,34 @@ BindingIter::trace(JSTracer* trc) void LexicalScope::Data::trace(JSTracer* trc) { - TraceBindingNames(trc, names, length); + TraceBindingNames(trc, trailingNames.start(), length); } void FunctionScope::Data::trace(JSTracer* trc) { TraceNullableEdge(trc, &canonicalFunction, "scope canonical function"); - TraceNullableBindingNames(trc, names, length); + TraceNullableBindingNames(trc, trailingNames.start(), length); } void VarScope::Data::trace(JSTracer* trc) { - TraceBindingNames(trc, names, length); + TraceBindingNames(trc, trailingNames.start(), length); } void GlobalScope::Data::trace(JSTracer* trc) { - TraceBindingNames(trc, names, length); + TraceBindingNames(trc, trailingNames.start(), length); } void EvalScope::Data::trace(JSTracer* trc) { - TraceBindingNames(trc, names, length); + TraceBindingNames(trc, trailingNames.start(), length); } void ModuleScope::Data::trace(JSTracer* trc) { TraceNullableEdge(trc, &module, "scope module"); - TraceBindingNames(trc, names, length); + TraceBindingNames(trc, trailingNames.start(), length); } void Scope::traceChildren(JSTracer* trc) @@ -1302,13 +1302,13 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) traverseEdge(scope, static_cast<Scope*>(scope->enclosing_)); if (scope->environmentShape_) traverseEdge(scope, static_cast<Shape*>(scope->environmentShape_)); - BindingName* names = nullptr; + TrailingNamesArray* names = nullptr; uint32_t length = 0; switch (scope->kind_) { case ScopeKind::Function: { FunctionScope::Data* data = reinterpret_cast<FunctionScope::Data*>(scope->data_); traverseEdge(scope, static_cast<JSObject*>(data->canonicalFunction)); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1316,7 +1316,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) case ScopeKind::FunctionBodyVar: case ScopeKind::ParameterExpressionVar: { VarScope::Data* data = reinterpret_cast<VarScope::Data*>(scope->data_); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1327,7 +1327,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) case ScopeKind::NamedLambda: case ScopeKind::StrictNamedLambda: { LexicalScope::Data* data = reinterpret_cast<LexicalScope::Data*>(scope->data_); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1335,7 +1335,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) case ScopeKind::Global: case ScopeKind::NonSyntactic: { GlobalScope::Data* data = reinterpret_cast<GlobalScope::Data*>(scope->data_); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1343,7 +1343,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) case ScopeKind::Eval: case ScopeKind::StrictEval: { EvalScope::Data* data = reinterpret_cast<EvalScope::Data*>(scope->data_); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1351,7 +1351,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) case ScopeKind::Module: { ModuleScope::Data* data = reinterpret_cast<ModuleScope::Data*>(scope->data_); traverseEdge(scope, static_cast<JSObject*>(data->module)); - names = data->names; + names = &data->trailingNames; length = data->length; break; } @@ -1361,12 +1361,12 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope) } if (scope->kind_ == ScopeKind::Function) { for (uint32_t i = 0; i < length; i++) { - if (JSAtom* name = names[i].name()) + if (JSAtom* name = names->operator[](i).name()) traverseEdge(scope, static_cast<JSString*>(name)); } } else { for (uint32_t i = 0; i < length; i++) - traverseEdge(scope, static_cast<JSString*>(names[i].name())); + traverseEdge(scope, static_cast<JSString*>(names->operator[](i).name())); } } diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index ca1969b2c..08a2810cf 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -10,7 +10,6 @@ #include "mozilla/EnumeratedArray.h" #include "mozilla/IntegerRange.h" #include "mozilla/Maybe.h" -#include "mozilla/PodOperations.h" #include "jsalloc.h" #include "jsgc.h" @@ -112,29 +111,26 @@ enum Stat { struct ZoneGCStats { /* Number of zones collected in this GC. */ - int collectedZoneCount; + int collectedZoneCount = 0; /* Total number of zones in the Runtime at the start of this GC. */ - int zoneCount; + int zoneCount = 0; /* Number of zones swept in this GC. */ - int sweptZoneCount; + int sweptZoneCount = 0; /* Total number of compartments in all zones collected. */ - int collectedCompartmentCount; + int collectedCompartmentCount = 0; /* Total number of compartments in the Runtime at the start of this GC. */ - int compartmentCount; + int compartmentCount = 0; /* Total number of compartments swept by this GC. */ - int sweptCompartmentCount; + int sweptCompartmentCount = 0; bool isCollectingAllZones() const { return collectedZoneCount == zoneCount; } - ZoneGCStats() - : collectedZoneCount(0), zoneCount(0), sweptZoneCount(0), - collectedCompartmentCount(0), compartmentCount(0), sweptCompartmentCount(0) - {} + ZoneGCStats() = default; }; #define FOR_EACH_GC_PROFILE_TIME(_) \ diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 94ef25785..73aceeccb 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -378,7 +378,6 @@ BacktrackingAllocator::init() size_t numVregs = graph.numVirtualRegisters(); if (!vregs.init(mir->alloc(), numVregs)) return false; - memset(&vregs[0], 0, sizeof(VirtualRegister) * numVregs); for (uint32_t i = 0; i < numVregs; i++) new(&vregs[i]) VirtualRegister(); @@ -1101,9 +1100,9 @@ BacktrackingAllocator::mergeAndQueueRegisters() if (iter->isParameter()) { for (size_t i = 0; i < iter->numDefs(); i++) { DebugOnly<bool> found = false; - VirtualRegister ¶mVreg = vreg(iter->getDef(i)); + VirtualRegister& paramVreg = vreg(iter->getDef(i)); for (; original < paramVreg.vreg(); original++) { - VirtualRegister &originalVreg = vregs[original]; + VirtualRegister& originalVreg = vregs[original]; if (*originalVreg.def()->output() == *iter->getDef(i)->output()) { MOZ_ASSERT(originalVreg.ins()->isParameter()); if (!tryMergeBundles(originalVreg.firstBundle(), paramVreg.firstBundle())) @@ -1136,7 +1135,7 @@ BacktrackingAllocator::mergeAndQueueRegisters() LBlock* block = graph.getBlock(i); for (size_t j = 0; j < block->numPhis(); j++) { LPhi* phi = block->getPhi(j); - VirtualRegister &outputVreg = vreg(phi->getDef(0)); + VirtualRegister& outputVreg = vreg(phi->getDef(0)); for (size_t k = 0, kend = phi->numOperands(); k < kend; k++) { VirtualRegister& inputVreg = vreg(phi->getOperand(k)->toUse()); if (!tryMergeBundles(inputVreg.firstBundle(), outputVreg.firstBundle())) @@ -1334,7 +1333,7 @@ BacktrackingAllocator::computeRequirement(LiveBundle* bundle, for (LiveRange::BundleLinkIterator iter = bundle->rangesBegin(); iter; iter++) { LiveRange* range = LiveRange::get(*iter); - VirtualRegister ® = vregs[range->vreg()]; + VirtualRegister& reg = vregs[range->vreg()]; if (range->hasDefinition()) { // Deal with any definition constraints/hints. @@ -1396,7 +1395,7 @@ BacktrackingAllocator::tryAllocateRegister(PhysicalRegister& r, LiveBundle* bund for (LiveRange::BundleLinkIterator iter = bundle->rangesBegin(); iter; iter++) { LiveRange* range = LiveRange::get(*iter); - VirtualRegister ® = vregs[range->vreg()]; + VirtualRegister& reg = vregs[range->vreg()]; if (!reg.isCompatible(r.reg)) return true; diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index 6d14ffacd..9910498fb 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -478,34 +478,31 @@ class LiveBundle : public TempObject class VirtualRegister { // Instruction which defines this register. - LNode* ins_; + LNode* ins_ = nullptr; // Definition in the instruction for this register. - LDefinition* def_; + LDefinition* def_ = nullptr; // All live ranges for this register. These may overlap each other, and are // ordered by their start position. InlineForwardList<LiveRange::RegisterLink> ranges_; // Whether def_ is a temp or an output. - bool isTemp_; + bool isTemp_ = false; // Whether this vreg is an input for some phi. This use is not reflected in // any range on the vreg. - bool usedByPhi_; + bool usedByPhi_ = false; // If this register's definition is MUST_REUSE_INPUT, whether a copy must // be introduced before the definition that relaxes the policy. - bool mustCopyInput_; + bool mustCopyInput_ = false; void operator=(const VirtualRegister&) = delete; VirtualRegister(const VirtualRegister&) = delete; public: - explicit VirtualRegister() - { - // Note: This class is zeroed before it is constructed. - } + VirtualRegister() = default; void init(LNode* ins, LDefinition* def, bool isTemp) { MOZ_ASSERT(!ins_); diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index c581aa62e..55c3d4dad 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -9,7 +9,6 @@ #include "mozilla/Atomics.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "jstypes.h" @@ -692,17 +691,15 @@ struct IonScriptCounts { private: // Any previous invalidated compilation(s) for the script. - IonScriptCounts* previous_; + IonScriptCounts* previous_ = nullptr; // Information about basic blocks in this script. - size_t numBlocks_; - IonBlockCounts* blocks_; + size_t numBlocks_ = 0; + IonBlockCounts* blocks_ = nullptr; public: - IonScriptCounts() { - mozilla::PodZero(this); - } + IonScriptCounts() = default; ~IonScriptCounts() { for (size_t i = 0; i < numBlocks_; i++) diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index aac9687b8..8044e75cb 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -7,8 +7,6 @@ #ifndef jit_shared_Assembler_shared_h #define jit_shared_Assembler_shared_h -#include "mozilla/PodOperations.h" - #include <limits.h> #include "jit/AtomicOp.h" @@ -491,10 +489,10 @@ class CodeLabel class CodeOffsetJump { - size_t offset_; + size_t offset_ = 0; #ifdef JS_SMALL_BRANCH - size_t jumpTableIndex_; + size_t jumpTableIndex_ = 0; #endif public: @@ -510,9 +508,7 @@ class CodeOffsetJump explicit CodeOffsetJump(size_t offset) : offset_(offset) {} #endif - CodeOffsetJump() { - mozilla::PodZero(this); - } + CodeOffsetJump() = default; size_t offset() const { return offset_; diff --git a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h index 8cb557784..8343579c8 100644 --- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h @@ -93,7 +93,8 @@ namespace jit { void ensureSpace(size_t space) { - 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(); } diff --git a/js/src/vm/Caches.h b/js/src/vm/Caches.h index 91a78bdc8..b11dd9dcb 100644 --- a/js/src/vm/Caches.h +++ b/js/src/vm/Caches.h @@ -7,6 +7,8 @@ #ifndef vm_Caches_h #define vm_Caches_h +#include <new> + #include "jsatom.h" #include "jsbytecode.h" #include "jsobj.h" @@ -191,14 +193,20 @@ class NewObjectCache char templateObject[MAX_OBJ_SIZE]; }; - Entry entries[41]; // TODO: reconsider size + using EntryArray = Entry[41]; // TODO: reconsider size; + EntryArray entries; public: - typedef int EntryIndex; + using EntryIndex = int; + + NewObjectCache() + : entries{} // zeroes out the array + {} - NewObjectCache() { mozilla::PodZero(this); } - void purge() { mozilla::PodZero(this); } + void purge() { + new (&entries) EntryArray{}; // zeroes out the array + } /* Remove any cached items keyed on moved objects. */ void clearNurseryObjects(JSRuntime* rt); 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/src/vm/Runtime.h b/js/src/vm/Runtime.h index 735adadf2..f354d2069 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -11,11 +11,11 @@ #include "mozilla/Attributes.h" #include "mozilla/LinkedList.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "mozilla/Scoped.h" #include "mozilla/ThreadLocal.h" #include "mozilla/Vector.h" +#include <algorithm> #include <setjmp.h> #include "jsatom.h" @@ -1504,20 +1504,21 @@ PerThreadData::exclusiveThreadsPresent() static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) { - mozilla::PodZero(vec, len); + // Don't PodZero here because JS::Value is non-trivial. + for (size_t i = 0; i < len; i++) + vec[i].setDouble(+0.0); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) { - mozilla::PodZero(beg, end - beg); + MakeRangeGCSafe(beg, end - beg); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* beg, jsid* end) { - for (jsid* id = beg; id != end; ++id) - *id = INT_TO_JSID(0); + std::fill(beg, end, INT_TO_JSID(0)); } static MOZ_ALWAYS_INLINE void @@ -1529,13 +1530,13 @@ MakeRangeGCSafe(jsid* vec, size_t len) static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** beg, Shape** end) { - mozilla::PodZero(beg, end - beg); + std::fill(beg, end, nullptr); } static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** vec, size_t len) { - mozilla::PodZero(vec, len); + MakeRangeGCSafe(vec, vec + len); } static MOZ_ALWAYS_INLINE void diff --git a/js/src/vm/Scope.cpp b/js/src/vm/Scope.cpp index 112b34586..a71c03695 100644 --- a/js/src/vm/Scope.cpp +++ b/js/src/vm/Scope.cpp @@ -191,12 +191,12 @@ template <typename ConcreteScope> static UniquePtr<typename ConcreteScope::Data> NewEmptyScopeData(ExclusiveContext* cx, uint32_t length = 0) { - uint8_t* bytes = cx->zone()->pod_calloc<uint8_t>(ConcreteScope::sizeOfData(length)); + uint8_t* bytes = cx->zone()->pod_malloc<uint8_t>(ConcreteScope::sizeOfData(length)); if (!bytes) ReportOutOfMemory(cx); auto data = reinterpret_cast<typename ConcreteScope::Data*>(bytes); if (data) - new (data) typename ConcreteScope::Data(); + new (data) typename ConcreteScope::Data(length); return UniquePtr<typename ConcreteScope::Data>(data); } @@ -273,7 +273,7 @@ Scope::XDRSizedBindingNames(XDRState<mode>* xdr, Handle<ConcreteScope*> scope, } for (uint32_t i = 0; i < length; i++) { - if (!XDRBindingName(xdr, &data->names[i])) { + if (!XDRBindingName(xdr, &data->trailingNames[i])) { if (mode == XDR_DECODE) { DeleteScopeData(data.get()); data.set(nullptr); @@ -1250,7 +1250,7 @@ BindingIter::init(LexicalScope::Data& data, uint32_t firstFrameSlot, uint8_t fla init(0, 0, 0, 0, 0, 0, CanHaveEnvironmentSlots | flags, firstFrameSlot, JSSLOT_FREE(&LexicalEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } else { // imports - [0, 0) // positional formals - [0, 0) @@ -1262,7 +1262,7 @@ BindingIter::init(LexicalScope::Data& data, uint32_t firstFrameSlot, uint8_t fla init(0, 0, 0, 0, 0, data.constStart, CanHaveFrameSlots | CanHaveEnvironmentSlots | flags, firstFrameSlot, JSSLOT_FREE(&LexicalEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } } @@ -1283,7 +1283,7 @@ BindingIter::init(FunctionScope::Data& data, uint8_t flags) init(0, data.nonPositionalFormalStart, data.varStart, data.varStart, data.length, data.length, flags, 0, JSSLOT_FREE(&CallObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1299,7 +1299,7 @@ BindingIter::init(VarScope::Data& data, uint32_t firstFrameSlot) init(0, 0, 0, 0, data.length, data.length, CanHaveFrameSlots | CanHaveEnvironmentSlots, firstFrameSlot, JSSLOT_FREE(&VarEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1315,7 +1315,7 @@ BindingIter::init(GlobalScope::Data& data) init(0, 0, 0, data.varStart, data.letStart, data.constStart, CannotHaveSlots, UINT32_MAX, UINT32_MAX, - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1343,7 +1343,7 @@ BindingIter::init(EvalScope::Data& data, bool strict) // consts - [data.length, data.length) init(0, 0, 0, data.varStart, data.length, data.length, flags, firstFrameSlot, firstEnvironmentSlot, - data.names, data.length); + data.trailingNames.start(), data.length); } void @@ -1359,7 +1359,7 @@ BindingIter::init(ModuleScope::Data& data) init(data.varStart, data.varStart, data.varStart, data.varStart, data.letStart, data.constStart, CanHaveFrameSlots | CanHaveEnvironmentSlots, 0, JSSLOT_FREE(&ModuleEnvironmentObject::class_), - data.names, data.length); + data.trailingNames.start(), data.length); } PositionalFormalParameterIter::PositionalFormalParameterIter(JSScript* script) diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index 5304d6713..1d04fd9f6 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -12,6 +12,7 @@ #include "jsobj.h" #include "jsopcode.h" +#include "jsutil.h" #include "gc/Heap.h" #include "gc/Policy.h" @@ -111,6 +112,47 @@ class BindingName void trace(JSTracer* trc); }; +/** + * The various {Global,Module,...}Scope::Data classes consist of always-present + * bits, then a trailing array of BindingNames. The various Data classes all + * end in a TrailingNamesArray that contains sized/aligned space for *one* + * BindingName. Data instances that contain N BindingNames, are then allocated + * in sizeof(Data) + (space for (N - 1) BindingNames). Because this class's + * |data_| field is properly sized/aligned, the N-BindingName array can start + * at |data_|. + * + * This is concededly a very low-level representation, but we want to only + * allocate once for data+bindings both, and this does so approximately as + * elegantly as C++ allows. + */ +class TrailingNamesArray +{ + private: + alignas(BindingName) unsigned char data_[sizeof(BindingName)]; + + private: + // Some versions of GCC treat it as a -Wstrict-aliasing violation (ergo a + // -Werror compile error) to reinterpret_cast<> |data_| to |T*|, even + // through |void*|. Placing the latter cast in these separate functions + // breaks the chain such that affected GCC versions no longer warn/error. + void* ptr() { + return data_; + } + + public: + // Explicitly ensure no one accidentally allocates scope data without + // poisoning its trailing names. + TrailingNamesArray() = delete; + + explicit TrailingNamesArray(size_t nameCount) { + if (nameCount) + JS_POISON(&data_, 0xCC, sizeof(BindingName) * nameCount); + } + BindingName* start() { return reinterpret_cast<BindingName*>(ptr()); } + + BindingName& operator[](size_t i) { return start()[i]; } +}; + class BindingLocation { public: @@ -337,16 +379,19 @@ class LexicalScope : public Scope // // lets - [0, constStart) // consts - [constStart, length) - uint32_t constStart; - uint32_t length; + uint32_t constStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -433,11 +478,11 @@ class FunctionScope : public Scope // The canonical function of the scope, as during a scope walk we // often query properties of the JSFunction (e.g., is the function an // arrow). - GCPtrFunction canonicalFunction; + GCPtrFunction canonicalFunction = {}; // If parameter expressions are present, parameters act like lexical // bindings. - bool hasParameterExprs; + bool hasParameterExprs = false; // Bindings are sorted by kind in both frames and environments. // @@ -452,17 +497,20 @@ class FunctionScope : public Scope // positional formals - [0, nonPositionalFormalStart) // other formals - [nonPositionalParamStart, varStart) // vars - [varStart, length) - uint16_t nonPositionalFormalStart; - uint16_t varStart; - uint32_t length; + uint16_t nonPositionalFormalStart = 0; + uint16_t varStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -548,15 +596,18 @@ class VarScope : public Scope struct Data { // All bindings are vars. - uint32_t length; + uint32_t length = 0; // Frame slots [firstFrameSlot(), nextFrameSlot) are live when this is // the innermost scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -638,14 +689,17 @@ class GlobalScope : public Scope // vars - [varStart, letStart) // lets - [letStart, constStart) // consts - [constStart, length) - uint32_t varStart; - uint32_t letStart; - uint32_t constStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t letStart = 0; + uint32_t constStart = 0; + uint32_t length = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -736,16 +790,19 @@ class EvalScope : public Scope // // top-level funcs - [0, varStart) // vars - [varStart, length) - uint32_t varStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; @@ -827,7 +884,7 @@ class ModuleScope : public Scope struct Data { // The module of the scope. - GCPtr<ModuleObject*> module; + GCPtr<ModuleObject*> module = {}; // Bindings are sorted by kind. // @@ -835,18 +892,21 @@ class ModuleScope : public Scope // vars - [varStart, letStart) // lets - [letStart, constStart) // consts - [constStart, length) - uint32_t varStart; - uint32_t letStart; - uint32_t constStart; - uint32_t length; + uint32_t varStart = 0; + uint32_t letStart = 0; + uint32_t constStart = 0; + uint32_t length = 0; // Frame slots [0, nextFrameSlot) are live when this is the innermost // scope. - uint32_t nextFrameSlot; + uint32_t nextFrameSlot = 0; // The array of tagged JSAtom* names, allocated beyond the end of the // struct. - BindingName names[1]; + TrailingNamesArray trailingNames; + + explicit Data(size_t nameCount) : trailingNames(nameCount) {} + Data() = delete; void trace(JSTracer* trc); }; diff --git a/js/src/vm/String.h b/js/src/vm/String.h index 1a0c58575..514e2c205 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -8,7 +8,6 @@ #define vm_String_h #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "mozilla/Range.h" #include "jsapi.h" @@ -1087,19 +1086,17 @@ class StaticStrings static const size_t SMALL_CHAR_LIMIT = 128U; static const size_t NUM_SMALL_CHARS = 64U; - JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS]; + JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS] = {}; // zeroes public: /* We keep these public for the JITs. */ static const size_t UNIT_STATIC_LIMIT = 256U; - JSAtom* unitStaticTable[UNIT_STATIC_LIMIT]; + JSAtom* unitStaticTable[UNIT_STATIC_LIMIT] = {}; // zeroes static const size_t INT_STATIC_LIMIT = 256U; - JSAtom* intStaticTable[INT_STATIC_LIMIT]; + JSAtom* intStaticTable[INT_STATIC_LIMIT] = {}; // zeroes - StaticStrings() { - mozilla::PodZero(this); - } + StaticStrings() = default; bool init(JSContext* cx); void trace(JSTracer* trc); diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h index 9ba1c3cc8..0e737bad7 100644 --- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -807,12 +807,10 @@ class PreliminaryObjectArray private: // All objects with the type which have been allocated. The pointers in // this array are weak. - JSObject* objects[COUNT]; + JSObject* objects[COUNT] = {}; // zeroes public: - PreliminaryObjectArray() { - mozilla::PodZero(this); - } + PreliminaryObjectArray() = default; void registerNewObject(JSObject* res); void unregisterObject(JSObject* obj); @@ -906,11 +904,11 @@ class TypeNewScript private: // Scripted function which this information was computed for. - HeapPtr<JSFunction*> function_; + HeapPtr<JSFunction*> function_ = {}; // Any preliminary objects with the type. The analyses are not performed // until this array is cleared. - PreliminaryObjectArray* preliminaryObjects; + PreliminaryObjectArray* preliminaryObjects = nullptr; // After the new script properties analyses have been performed, a template // object to use for newly constructed objects. The shape of this object @@ -918,7 +916,7 @@ class TypeNewScript // allocation kind to use. This is null if the new objects have an unboxed // layout, in which case the UnboxedLayout provides the initial structure // of the object. - HeapPtr<PlainObject*> templateObject_; + HeapPtr<PlainObject*> templateObject_ = {}; // Order in which definite properties become initialized. We need this in // case the definite properties are invalidated (such as by adding a setter @@ -928,21 +926,21 @@ class TypeNewScript // shape. Property assignments in inner frames are preceded by a series of // SETPROP_FRAME entries specifying the stack down to the frame containing // the write. - Initializer* initializerList; + Initializer* initializerList = nullptr; // If there are additional properties found by the acquired properties // analysis which were not found by the definite properties analysis, this // shape contains all such additional properties (plus the definite // properties). When an object of this group acquires this shape, it is // fully initialized and its group can be changed to initializedGroup. - HeapPtr<Shape*> initializedShape_; + HeapPtr<Shape*> initializedShape_ = {}; // Group with definite properties set for all properties found by // both the definite and acquired properties analyses. - HeapPtr<ObjectGroup*> initializedGroup_; + HeapPtr<ObjectGroup*> initializedGroup_ = {}; public: - TypeNewScript() { mozilla::PodZero(this); } + TypeNewScript() = default; ~TypeNewScript() { js_delete(preliminaryObjects); js_free(initializerList); diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index 7fade24fb..2237d1d7f 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -249,14 +249,14 @@ typedef Vector<AsmJSImport, 0, SystemAllocPolicy> AsmJSImportVector; // case the function is toString()ed. class AsmJSExport { - uint32_t funcIndex_; + uint32_t funcIndex_ = 0; // All fields are treated as cacheable POD: - uint32_t startOffsetInModule_; // Store module-start-relative offsets - uint32_t endOffsetInModule_; // so preserved by serialization. + uint32_t startOffsetInModule_ = 0; // Store module-start-relative offsets + uint32_t endOffsetInModule_ = 0; // so preserved by serialization. public: - AsmJSExport() { PodZero(this); } + AsmJSExport() = default; AsmJSExport(uint32_t funcIndex, uint32_t startOffsetInModule, uint32_t endOffsetInModule) : funcIndex_(funcIndex), startOffsetInModule_(startOffsetInModule), @@ -288,12 +288,12 @@ enum class CacheResult struct AsmJSMetadataCacheablePod { - uint32_t numFFIs; - uint32_t srcLength; - uint32_t srcLengthWithRightBrace; - bool usesSimd; + uint32_t numFFIs = 0; + uint32_t srcLength = 0; + uint32_t srcLengthWithRightBrace = 0; + bool usesSimd = false; - AsmJSMetadataCacheablePod() { PodZero(this); } + AsmJSMetadataCacheablePod() = default; }; struct js::AsmJSMetadata : Metadata, AsmJSMetadataCacheablePod 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 |