Bug 1280407 - Use SystemAllocPolicy rather that the default with mozilla::Vector in the JS engine r=sfink r=fitzgen r=jandem

This commit is contained in:
Jon Coppeard 2016-06-18 10:46:13 +01:00
Родитель f1e52c331d
Коммит a54a6f9345
15 изменённых файлов: 120 добавлений и 60 удалений

Просмотреть файл

@ -183,6 +183,9 @@ using mozilla::Move;
using mozilla::RangedPtr;
using mozilla::Variant;
template <typename T>
using Vector = mozilla::Vector<T, 0, js::SystemAllocPolicy>;
/*** ubi::StackFrame ******************************************************************************/
// Concrete JS::ubi::StackFrame instances backed by a live SavedFrame object

Просмотреть файл

@ -94,10 +94,10 @@ class JS_PUBLIC_API(DominatorTree)
{
friend class DominatedSetRange;
const mozilla::Vector<Node>& postOrder;
const JS::ubi::Vector<Node>& postOrder;
const uint32_t* ptr;
DominatedNodePtr(const mozilla::Vector<Node>& postOrder, const uint32_t* ptr)
DominatedNodePtr(const JS::ubi::Vector<Node>& postOrder, const uint32_t* ptr)
: postOrder(postOrder)
, ptr(ptr)
{ }
@ -118,11 +118,11 @@ class JS_PUBLIC_API(DominatorTree)
{
friend class DominatedSets;
const mozilla::Vector<Node>& postOrder;
const JS::ubi::Vector<Node>& postOrder;
const uint32_t* beginPtr;
const uint32_t* endPtr;
DominatedSetRange(mozilla::Vector<Node>& postOrder, const uint32_t* begin, const uint32_t* end)
DominatedSetRange(JS::ubi::Vector<Node>& postOrder, const uint32_t* begin, const uint32_t* end)
: postOrder(postOrder)
, beginPtr(begin)
, endPtr(end)
@ -179,10 +179,10 @@ class JS_PUBLIC_API(DominatorTree)
*/
class DominatedSets
{
mozilla::Vector<uint32_t> dominated;
mozilla::Vector<uint32_t> indices;
JS::ubi::Vector<uint32_t> dominated;
JS::ubi::Vector<uint32_t> indices;
DominatedSets(mozilla::Vector<uint32_t>&& dominated, mozilla::Vector<uint32_t>&& indices)
DominatedSets(JS::ubi::Vector<uint32_t>&& dominated, JS::ubi::Vector<uint32_t>&& indices)
: dominated(mozilla::Move(dominated))
, indices(mozilla::Move(indices))
{ }
@ -210,7 +210,7 @@ class JS_PUBLIC_API(DominatorTree)
* immediate dominator. Returns `Some` on success, `Nothing` on OOM
* failure.
*/
static mozilla::Maybe<DominatedSets> Create(const mozilla::Vector<uint32_t>& doms) {
static mozilla::Maybe<DominatedSets> Create(const JS::ubi::Vector<uint32_t>& doms) {
auto length = doms.length();
MOZ_ASSERT(length < UINT32_MAX);
@ -235,8 +235,8 @@ class JS_PUBLIC_API(DominatorTree)
// filled in. After having filled in all of a bucket's entries,
// the index points to the start of the bucket.
mozilla::Vector<uint32_t> dominated;
mozilla::Vector<uint32_t> indices;
JS::ubi::Vector<uint32_t> dominated;
JS::ubi::Vector<uint32_t> indices;
if (!dominated.growBy(length) || !indices.growBy(length))
return mozilla::Nothing();
@ -278,7 +278,7 @@ class JS_PUBLIC_API(DominatorTree)
* Get the set of nodes immediately dominated by the node at
* `postOrder[nodeIndex]`.
*/
DominatedSetRange dominatedSet(mozilla::Vector<Node>& postOrder, uint32_t nodeIndex) const {
DominatedSetRange dominatedSet(JS::ubi::Vector<Node>& postOrder, uint32_t nodeIndex) const {
MOZ_ASSERT(postOrder.length() == indices.length());
MOZ_ASSERT(nodeIndex < indices.length());
auto end = nodeIndex == indices.length() - 1
@ -290,11 +290,11 @@ class JS_PUBLIC_API(DominatorTree)
private:
// Data members.
mozilla::Vector<Node> postOrder;
JS::ubi::Vector<Node> postOrder;
NodeToIndexMap nodeToPostOrderIndex;
mozilla::Vector<uint32_t> doms;
JS::ubi::Vector<uint32_t> doms;
DominatedSets dominatedSets;
mozilla::Maybe<mozilla::Vector<JS::ubi::Node::Size>> retainedSizes;
mozilla::Maybe<JS::ubi::Vector<JS::ubi::Node::Size>> retainedSizes;
private:
// We use `UNDEFINED` as a sentinel value in the `doms` vector to signal
@ -302,8 +302,8 @@ class JS_PUBLIC_API(DominatorTree)
// index in `postOrder` yet.
static const uint32_t UNDEFINED = UINT32_MAX;
DominatorTree(mozilla::Vector<Node>&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex,
mozilla::Vector<uint32_t>&& doms, DominatedSets&& dominatedSets)
DominatorTree(JS::ubi::Vector<Node>&& postOrder, NodeToIndexMap&& nodeToPostOrderIndex,
JS::ubi::Vector<uint32_t>&& doms, DominatedSets&& dominatedSets)
: postOrder(mozilla::Move(postOrder))
, nodeToPostOrderIndex(mozilla::Move(nodeToPostOrderIndex))
, doms(mozilla::Move(doms))
@ -311,7 +311,7 @@ class JS_PUBLIC_API(DominatorTree)
, retainedSizes(mozilla::Nothing())
{ }
static uint32_t intersect(mozilla::Vector<uint32_t>& doms, uint32_t finger1, uint32_t finger2) {
static uint32_t intersect(JS::ubi::Vector<uint32_t>& doms, uint32_t finger1, uint32_t finger2) {
while (finger1 != finger2) {
if (finger1 < finger2)
finger1 = doms[finger1];
@ -324,7 +324,7 @@ class JS_PUBLIC_API(DominatorTree)
// Do the post order traversal of the heap graph and populate our
// predecessor sets.
static MOZ_MUST_USE bool doTraversal(JSRuntime* rt, AutoCheckCannotGC& noGC, const Node& root,
mozilla::Vector<Node>& postOrder,
JS::ubi::Vector<Node>& postOrder,
PredecessorSets& predecessorSets) {
uint32_t nodeCount = 0;
auto onNode = [&](const Node& node) {
@ -357,7 +357,7 @@ class JS_PUBLIC_API(DominatorTree)
// Populates the given `map` with an entry for each node to its index in
// `postOrder`.
static MOZ_MUST_USE bool mapNodesToTheirIndices(mozilla::Vector<Node>& postOrder,
static MOZ_MUST_USE bool mapNodesToTheirIndices(JS::ubi::Vector<Node>& postOrder,
NodeToIndexMap& map) {
MOZ_ASSERT(!map.initialized());
MOZ_ASSERT(postOrder.length() < UINT32_MAX);
@ -373,10 +373,10 @@ class JS_PUBLIC_API(DominatorTree)
// form.
static MOZ_MUST_USE bool convertPredecessorSetsToVectors(
const Node& root,
mozilla::Vector<Node>& postOrder,
JS::ubi::Vector<Node>& postOrder,
PredecessorSets& predecessorSets,
NodeToIndexMap& nodeToPostOrderIndex,
mozilla::Vector<mozilla::Vector<uint32_t>>& predecessorVectors)
JS::ubi::Vector<JS::ubi::Vector<uint32_t>>& predecessorVectors)
{
MOZ_ASSERT(postOrder.length() < UINT32_MAX);
uint32_t length = postOrder.length();
@ -410,7 +410,7 @@ class JS_PUBLIC_API(DominatorTree)
// Initialize `doms` such that the immediate dominator of the `root` is the
// `root` itself and all others are `UNDEFINED`.
static MOZ_MUST_USE bool initializeDominators(mozilla::Vector<uint32_t>& doms,
static MOZ_MUST_USE bool initializeDominators(JS::ubi::Vector<uint32_t>& doms,
uint32_t length) {
MOZ_ASSERT(doms.length() == 0);
if (!doms.growByUninitialized(length))
@ -514,7 +514,7 @@ class JS_PUBLIC_API(DominatorTree)
*/
static mozilla::Maybe<DominatorTree>
Create(JSRuntime* rt, AutoCheckCannotGC& noGC, const Node& root) {
mozilla::Vector<Node> postOrder;
JS::ubi::Vector<Node> postOrder;
PredecessorSets predecessorSets;
if (!predecessorSets.init() || !doTraversal(rt, noGC, root, postOrder, predecessorSets))
return mozilla::Nothing();
@ -533,12 +533,12 @@ class JS_PUBLIC_API(DominatorTree)
if (!mapNodesToTheirIndices(postOrder, nodeToPostOrderIndex))
return mozilla::Nothing();
mozilla::Vector<mozilla::Vector<uint32_t>> predecessorVectors;
JS::ubi::Vector<JS::ubi::Vector<uint32_t>> predecessorVectors;
if (!convertPredecessorSetsToVectors(root, postOrder, predecessorSets, nodeToPostOrderIndex,
predecessorVectors))
return mozilla::Nothing();
mozilla::Vector<uint32_t> doms;
JS::ubi::Vector<uint32_t> doms;
if (!initializeDominators(doms, length))
return mozilla::Nothing();

Просмотреть файл

@ -69,7 +69,7 @@ struct JS_PUBLIC_API(BackEdge)
/**
* A path is a series of back edges from which we discovered a target node.
*/
using Path = mozilla::Vector<BackEdge*>;
using Path = JS::ubi::Vector<BackEdge*>;
/**
* The `JS::ubi::ShortestPaths` type represents a collection of up to N shortest
@ -81,7 +81,7 @@ struct JS_PUBLIC_API(ShortestPaths)
private:
// Types, type aliases, and data members.
using BackEdgeVector = mozilla::Vector<BackEdge::Ptr>;
using BackEdgeVector = JS::ubi::Vector<BackEdge::Ptr>;
using NodeToBackEdgeVectorMap = js::HashMap<Node, BackEdgeVector, js::DefaultHasher<Node>,
js::SystemAllocPolicy>;

Просмотреть файл

@ -2662,11 +2662,16 @@ FindPath(JSContext* cx, unsigned argc, Value* vp)
heaptools::FindPathHandler handler(cx, start, target, &nodes, edges);
heaptools::FindPathHandler::Traversal traversal(cx->runtime(), handler, autoCannotGC);
if (!traversal.init() || !traversal.addStart(start))
if (!traversal.init() || !traversal.addStart(start)) {
ReportOutOfMemory(cx);
return false;
}
if (!traversal.traverse())
if (!traversal.traverse()) {
if (!cx->isExceptionPending())
ReportOutOfMemory(cx);
return false;
}
if (!handler.foundPath) {
// We didn't find any paths from the start to the target.

Просмотреть файл

@ -194,13 +194,13 @@ static ExtraPhaseInfo phaseExtra[PHASE_LIMIT] = { { 0, 0 } };
// Mapping from all nodes with a multi-parented child to a Vector of all
// multi-parented children and their descendants. (Single-parented children will
// not show up in this list.)
static mozilla::Vector<Phase> dagDescendants[Statistics::NumTimingArrays];
static mozilla::Vector<Phase, 0, SystemAllocPolicy> dagDescendants[Statistics::NumTimingArrays];
struct AllPhaseIterator {
int current;
int baseLevel;
size_t activeSlot;
mozilla::Vector<Phase>::Range descendants;
mozilla::Vector<Phase, 0, SystemAllocPolicy>::Range descendants;
explicit AllPhaseIterator(const Statistics::PhaseTimeTable table)
: current(0)
@ -829,7 +829,7 @@ Statistics::initialize()
// Fill in the depth of each node in the tree. Multi-parented nodes
// have depth 0.
mozilla::Vector<Phase> stack;
mozilla::Vector<Phase, 0, SystemAllocPolicy> stack;
if (!stack.append(PHASE_LIMIT)) // Dummy entry to avoid special-casing the first node
return false;
for (int i = 0; i < PHASE_LIMIT; i++) {

Просмотреть файл

@ -0,0 +1,19 @@
if (!('oomTest' in this))
quit();
oomTest(() => byteSize({}));
oomTest(() => byteSize({ w: 1, x: 2, y: 3 }));
oomTest(() => byteSize({ w:1, x:2, y:3, z:4, a:6, 0:0, 1:1, 2:2 }));
oomTest(() => byteSize([1, 2, 3]));
oomTest(() => byteSize(function () {}));
function f1() {
return 42;
}
oomTest(() => byteSizeOfScript(f1));
oomTest(() => byteSize("1234567"));
oomTest(() => byteSize("千早ぶる神代"));
let s = Symbol();
oomTest(() => byteSize(s));

Просмотреть файл

@ -0,0 +1,19 @@
if (!('oomTest' in this))
quit();
var o = { w: { x: { y: { z: {} } } } };
oomTest(() => findPath(o, o.w.x.y.z));
var a = [ , o ];
oomTest(() => findPath(a, o));
function C() {}
C.prototype.obj = {};
var c = new C;
oomTest(() => findPath(c, c.obj));
function f(x) { return function g(y) { return x+y; }; }
var o = {}
var gc = f(o);
oomTest(() => findPath(gc, o));

Просмотреть файл

@ -9,6 +9,9 @@
#include "mozilla/IntegerRange.h"
#include "mozilla/Move.h"
#include "mozilla/Vector.h"
#include "jsalloc.h"
#include "jsapi-tests/tests.h"
#include "threading/Thread.h"
@ -62,7 +65,7 @@ BEGIN_TEST(testThreadingThreadVectorMoveConstruct)
{
const static size_t N = 10;
mozilla::Atomic<int> count(0);
mozilla::Vector<js::Thread> v;
mozilla::Vector<js::Thread, 0, js::SystemAllocPolicy> v;
for (auto i : mozilla::MakeRange(N)) {
CHECK(v.emplaceBack([](mozilla::Atomic<int>* countp){(*countp)++;}, &count));
CHECK(v.length() == i + 1);

Просмотреть файл

@ -6150,6 +6150,8 @@ struct PerformanceGroup {
uint64_t refCount_;
};
using PerformanceGroupVector = mozilla::Vector<RefPtr<js::PerformanceGroup>, 0, SystemAllocPolicy>;
/**
* Commit any Performance Monitoring data.
*
@ -6208,12 +6210,12 @@ extern JS_PUBLIC_API(bool)
SetStopwatchStartCallback(JSRuntime*, StopwatchStartCallback, void*);
typedef bool
(*StopwatchCommitCallback)(uint64_t, mozilla::Vector<RefPtr<PerformanceGroup>>&, void*);
(*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*);
extern JS_PUBLIC_API(bool)
SetStopwatchCommitCallback(JSRuntime*, StopwatchCommitCallback, void*);
typedef bool
(*GetGroupsCallback)(JSContext*, mozilla::Vector<RefPtr<PerformanceGroup>>&, void*);
(*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*);
extern JS_PUBLIC_API(bool)
SetGetPerformanceGroupsCallback(JSRuntime*, GetGroupsCallback, void*);

Просмотреть файл

@ -972,7 +972,7 @@ GCRuntime::parseAndSetZeal(const char* str)
{
int frequency = -1;
bool foundFrequency = false;
mozilla::Vector<int> zeals;
mozilla::Vector<int, 0, SystemAllocPolicy> zeals;
static const struct {
const char* const zealMode;
@ -2643,8 +2643,9 @@ GCRuntime::releaseHeldRelocatedArenas()
{
#ifdef DEBUG
unprotectHeldRelocatedArenas();
releaseRelocatedArenas(relocatedArenasToRelease);
Arena* arenas = relocatedArenasToRelease;
relocatedArenasToRelease = nullptr;
releaseRelocatedArenas(arenas);
#endif
}
@ -3134,7 +3135,7 @@ GCRuntime::decommitArenas(AutoLockGC& lock)
// Build a Vector of all current available Chunks. Since we release the
// gc lock while doing the decommit syscall, it is dangerous to iterate
// the available list directly, as concurrent operations can modify it.
mozilla::Vector<Chunk*> toDecommit;
mozilla::Vector<Chunk*, 0, SystemAllocPolicy> toDecommit;
MOZ_ASSERT(availableChunks(lock).verify());
for (ChunkPool::Iter iter(availableChunks(lock)); !iter.done(); iter.next()) {
if (!toDecommit.append(iter.get())) {

Просмотреть файл

@ -152,7 +152,7 @@ PerformanceMonitoring::commit()
return true;
}
GroupVector recentGroups;
PerformanceGroupVector recentGroups;
recentGroups_.swap(recentGroups);
bool success = true;
@ -200,7 +200,7 @@ PerformanceGroupHolder::unlink()
groups_.clear();
}
const GroupVector*
const PerformanceGroupVector*
PerformanceGroupHolder::getGroups(JSContext* cx)
{
if (initialized_)
@ -233,7 +233,7 @@ AutoStopwatch::AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IM
JSRuntime* runtime = cx_->runtime();
iteration_ = runtime->performanceMonitoring.iteration();
const GroupVector* groups = compartment->performanceMonitoring.getGroups(cx);
const PerformanceGroupVector* groups = compartment->performanceMonitoring.getGroups(cx);
if (!groups) {
// Either the embedding has not provided any performance
// monitoring logistics or there was an error that prevents

Просмотреть файл

@ -19,8 +19,6 @@
namespace js {
typedef mozilla::Vector<RefPtr<js::PerformanceGroup>> GroupVector;
/**
* A container for performance groups.
*
@ -43,7 +41,7 @@ struct PerformanceGroupHolder {
* May return `nullptr` if the embedding has not initialized
* support for performance groups.
*/
const GroupVector* getGroups(JSContext*);
const PerformanceGroupVector* getGroups(JSContext*);
explicit PerformanceGroupHolder(JSRuntime* runtime)
: runtime_(runtime)
@ -59,7 +57,7 @@ struct PerformanceGroupHolder {
// The groups to which this compartment belongs. Filled if and only
// if `initialized_` is `true`.
GroupVector groups_;
PerformanceGroupVector groups_;
};
/**
@ -292,7 +290,7 @@ struct PerformanceMonitoring {
/**
* Groups used in the current iteration.
*/
GroupVector recentGroups_;
PerformanceGroupVector recentGroups_;
/**
* The highest value of the timestamp counter encountered
@ -344,7 +342,7 @@ class AutoStopwatch final {
// if `isMonitoringJank_` is `true`.
cpuid_t cpuStart_;
mozilla::Vector<RefPtr<js::PerformanceGroup>> groups_;
PerformanceGroupVector groups_;
public:
// If the stopwatch is active, constructing an instance of

Просмотреть файл

@ -127,7 +127,7 @@ SimpleCount::report(JSContext* cx, CountBase& countBase, MutableHandleValue repo
class BucketCount : public CountType {
struct Count : CountBase {
mozilla::Vector<JS::ubi::Node::Id> ids_;
JS::ubi::Vector<JS::ubi::Node::Id> ids_;
explicit Count(BucketCount& count)
: CountBase(count),
@ -349,7 +349,7 @@ countMapToObject(JSContext* cx, Map& map, GetName getName) {
// that to build the result object. This makes the ordering of entries
// more interesting, and a little less non-deterministic.
mozilla::Vector<typename Map::Entry*> entries;
JS::ubi::Vector<typename Map::Entry*> entries;
if (!entries.reserve(map.count())) {
ReportOutOfMemory(cx);
return nullptr;
@ -570,7 +570,7 @@ ByUbinodeType::report(JSContext* cx, CountBase& countBase, MutableHandleValue re
// Build a vector of pointers to entries; sort by total; and then use
// that to build the result object. This makes the ordering of entries
// more interesting, and a little less non-deterministic.
mozilla::Vector<Entry*> entries;
JS::ubi::Vector<Entry*> entries;
if (!entries.reserve(count.table.count()))
return false;
for (Table::Range r = count.table.all(); !r.empty(); r.popFront())
@ -736,7 +736,7 @@ ByAllocationStack::report(JSContext* cx, CountBase& countBase, MutableHandleValu
// Build a vector of pointers to entries; sort by total; and then use
// that to build the result object. This makes the ordering of entries
// more interesting, and a little less non-deterministic.
mozilla::Vector<Entry*> entries;
JS::ubi::Vector<Entry*> entries;
if (!entries.reserve(count.table.count()))
return false;
for (Table::Range r = count.table.all(); !r.empty(); r.popFront())

Просмотреть файл

@ -1027,13 +1027,18 @@ nsPerformanceStatsService::GetNextId() {
}
/* static*/ bool
nsPerformanceStatsService::GetPerformanceGroupsCallback(JSContext* cx, JSGroupVector& out, void* closure) {
nsPerformanceStatsService::GetPerformanceGroupsCallback(JSContext* cx,
js::PerformanceGroupVector& out,
void* closure)
{
RefPtr<nsPerformanceStatsService> self = reinterpret_cast<nsPerformanceStatsService*>(closure);
return self->GetPerformanceGroups(cx, out);
}
bool
nsPerformanceStatsService::GetPerformanceGroups(JSContext* cx, JSGroupVector& out) {
nsPerformanceStatsService::GetPerformanceGroups(JSContext* cx,
js::PerformanceGroupVector& out)
{
JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
if (!global) {
// While it is possible for a compartment to have no global
@ -1136,13 +1141,17 @@ nsPerformanceStatsService::StopwatchStart(uint64_t iteration) {
}
/*static*/ bool
nsPerformanceStatsService::StopwatchCommitCallback(uint64_t iteration, JSGroupVector& recentGroups, void* closure) {
nsPerformanceStatsService::StopwatchCommitCallback(uint64_t iteration,
js::PerformanceGroupVector& recentGroups,
void* closure)
{
RefPtr<nsPerformanceStatsService> self = reinterpret_cast<nsPerformanceStatsService*>(closure);
return self->StopwatchCommit(iteration, recentGroups);
}
bool
nsPerformanceStatsService::StopwatchCommit(uint64_t iteration, JSGroupVector& recentGroups)
nsPerformanceStatsService::StopwatchCommit(uint64_t iteration,
js::PerformanceGroupVector& recentGroups)
{
MOZ_ASSERT(iteration == mIteration);
MOZ_ASSERT(!recentGroups.empty());

Просмотреть файл

@ -19,7 +19,6 @@
class nsPerformanceGroup;
class nsPerformanceGroupDetails;
typedef mozilla::Vector<RefPtr<js::PerformanceGroup>> JSGroupVector;
typedef mozilla::Vector<RefPtr<nsPerformanceGroup>> GroupVector;
/**
@ -192,8 +191,8 @@ protected:
* calling it more than once may not return the same instances of
* performance groups.
*/
bool GetPerformanceGroups(JSContext* cx, JSGroupVector&);
static bool GetPerformanceGroupsCallback(JSContext* cx, JSGroupVector&, void* closure);
bool GetPerformanceGroups(JSContext* cx, js::PerformanceGroupVector&);
static bool GetPerformanceGroupsCallback(JSContext* cx, js::PerformanceGroupVector&, void* closure);
@ -329,8 +328,10 @@ protected:
* @param recentGroups The groups that have seen activity during this
* event.
*/
static bool StopwatchCommitCallback(uint64_t iteration, JSGroupVector& recentGroups, void* closure);
bool StopwatchCommit(uint64_t iteration, JSGroupVector& recentGroups);
static bool StopwatchCommitCallback(uint64_t iteration,
js::PerformanceGroupVector& recentGroups,
void* closure);
bool StopwatchCommit(uint64_t iteration, js::PerformanceGroupVector& recentGroups);
/**
* The number of times we have started executing JavaScript code.