diff --git a/js/src/ds/InlineTable.h b/js/src/ds/InlineTable.h index 874efd537052..b1b7f136f419 100644 --- a/js/src/ds/InlineTable.h +++ b/js/src/ds/InlineTable.h @@ -218,11 +218,6 @@ class InlineTable : private AllocPolicy { inlCount_ = 0; } - void clearAndCompact() { - clear(); - table_.clearAndCompact(); - } - MOZ_ALWAYS_INLINE Ptr lookup(const Lookup& l) { MOZ_ASSERT(keyNonZero(l)); @@ -480,8 +475,6 @@ class InlineMap { void clear() { impl_.clear(); } - void clearAndCompact() { impl_.clearAndCompact(); } - Range all() const { return impl_.all(); } MOZ_ALWAYS_INLINE @@ -586,8 +579,6 @@ class InlineSet { void clear() { impl_.clear(); } - void clearAndCompact() { impl_.clearAndCompact(); } - Range all() const { return impl_.all(); } MOZ_ALWAYS_INLINE diff --git a/js/src/jit-test/tests/ion/bug1598784.js b/js/src/jit-test/tests/ion/bug1598784.js new file mode 100644 index 000000000000..20803e2f09fb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1598784.js @@ -0,0 +1,8 @@ +// |jit-test| error:ReferenceError +(function() { + switch (0) { + case 0: + f() = 0; + case -3: + } +})(); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 8d21c6e30d1f..2fdb134afd5d 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -424,7 +424,7 @@ void jit::FreeIonBuilder(IonBuilder* builder) { // destroy the builder and all other data accumulated during compilation, // except any final codegen (which includes an assembler and needs to be // explicitly destroyed). - MOZ_ASSERT(builder->pendingEdges().empty(), "Should not leak malloc memory"); + MOZ_ASSERT(!builder->hasPendingEdgesMap(), "Should not leak malloc memory"); js_delete(builder->backgroundCodegen()); js_delete(builder->alloc().lifoAlloc()); } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index d246d53b43ff..88e81d457b5b 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1623,8 +1623,9 @@ AbortReasonOr IonBuilder::traverseBytecode() { // IonBuilder's destructor is not called, so make sure pendingEdges_ and // GSNCache are not holding onto malloc memory when we return. + pendingEdges_.emplace(); auto freeMemory = mozilla::MakeScopeExit([&] { - pendingEdges_.clearAndCompact(); + pendingEdges_.reset(); gsn.purge(); }); @@ -1748,7 +1749,7 @@ AbortReasonOr IonBuilder::jsop_goto(bool* restarted) { AbortReasonOr IonBuilder::addPendingEdge(const PendingEdge& edge, jsbytecode* target) { - PendingEdgesMap::AddPtr p = pendingEdges_.lookupForAdd(target); + PendingEdgesMap::AddPtr p = pendingEdges_->lookupForAdd(target); if (p) { if (!p->value().append(edge)) { return abort(AbortReason::Alloc); @@ -1761,7 +1762,7 @@ AbortReasonOr IonBuilder::addPendingEdge(const PendingEdge& edge, "Appending one element should be infallible"); MOZ_ALWAYS_TRUE(edges.append(edge)); - if (!pendingEdges_.add(p, target, std::move(edges))) { + if (!pendingEdges_->add(p, target, std::move(edges))) { return abort(AbortReason::Alloc); } return Ok(); @@ -2798,7 +2799,7 @@ AbortReasonOr IonBuilder::restartLoop(MBasicBlock* header) { } // Remove loop header and dead blocks from pendingBlocks. - for (PendingEdgesMap::Range r = pendingEdges_.all(); !r.empty(); + for (PendingEdgesMap::Range r = pendingEdges_->all(); !r.empty(); r.popFront()) { PendingEdges& blocks = r.front().value(); for (size_t i = blocks.length(); i > 0; i--) { @@ -3475,14 +3476,14 @@ AbortReasonOr IonBuilder::visitTry() { } AbortReasonOr IonBuilder::visitJumpTarget(JSOp op) { - PendingEdgesMap::Ptr p = pendingEdges_.lookup(pc); + PendingEdgesMap::Ptr p = pendingEdges_->lookup(pc); if (!p) { // No (reachable) jumps so this is just a no-op. return Ok(); } PendingEdges edges(std::move(p->value())); - pendingEdges_.remove(p); + pendingEdges_->remove(p); MBasicBlock* joinBlock = nullptr; diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index add61831d18b..823ea9d4fa17 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -1255,7 +1255,7 @@ class IonBuilder : public MIRGenerator, uint32_t loopDepth_; - PendingEdgesMap pendingEdges_; + mozilla::Maybe pendingEdges_; LoopStateStack loopStack_; Vector trackedOptimizationSites_; @@ -1438,7 +1438,7 @@ class IonBuilder : public MIRGenerator, void trackInlineSuccessUnchecked(InliningStatus status); public: - const PendingEdgesMap& pendingEdges() const { return pendingEdges_; } + bool hasPendingEdgesMap() const { return pendingEdges_.isSome(); } // This is only valid for IonBuilders that have moved to background size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;