summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-09-17 08:51:49 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-09-17 08:51:49 +0200
commit882aaf5b1fda7b216051b55e268de78fd5126f42 (patch)
treeccb3f6f6299a5d1c603e6b73d3892f635bb96a8e /js
parent8ee235ca5df26f39ca3066935bef90c4d28dd61a (diff)
parentd118d486a680ed42030b1bdee263a29831da3e86 (diff)
downloadUXP-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')
-rw-r--r--js/ipc/JavaScriptParent.cpp3
-rw-r--r--js/public/HashTable.h46
-rw-r--r--js/public/MemoryMetrics.h23
-rw-r--r--js/public/Utility.h2
-rw-r--r--js/src/builtin/AtomicsObject.cpp2
-rw-r--r--js/src/ds/LifoAlloc.h16
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp5
-rw-r--r--js/src/frontend/ParseNode.cpp2
-rw-r--r--js/src/frontend/Parser.cpp82
-rw-r--r--js/src/gc/Barrier.h27
-rw-r--r--js/src/gc/GCInternals.h5
-rw-r--r--js/src/gc/Marking.cpp30
-rw-r--r--js/src/gc/Statistics.h18
-rw-r--r--js/src/jit/BacktrackingAllocator.cpp11
-rw-r--r--js/src/jit/BacktrackingAllocator.h15
-rw-r--r--js/src/jit/IonCode.h11
-rw-r--r--js/src/jit/shared/Assembler-shared.h10
-rw-r--r--js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h3
-rw-r--r--js/src/vm/Caches.h16
-rw-r--r--js/src/vm/NativeObject.h11
-rw-r--r--js/src/vm/Runtime.h15
-rw-r--r--js/src/vm/Scope.cpp20
-rw-r--r--js/src/vm/Scope.h120
-rw-r--r--js/src/vm/String.h11
-rw-r--r--js/src/vm/TypeInference.h20
-rw-r--r--js/src/wasm/AsmJS.cpp18
-rw-r--r--js/xpconnect/src/XPCJSContext.cpp99
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 &paramVreg = 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 &reg = 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 &reg = 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