From 086bacbf22b084741728dab799771b5f7e41dd52 Mon Sep 17 00:00:00 2001 From: win7-7 Date: Mon, 5 Jan 2026 18:04:23 +0200 Subject: [PATCH] 903519 - Register nursery string buffers to be freed 903519 - Register nursery string buffers to be freed, this was missed somehow before. --- js/src/vm/String.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index af46079c2d..036ebba770 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -461,6 +461,9 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) JSExtensibleString& left = leftMostRope->leftChild()->asExtensible(); size_t capacity = left.capacity(); if (capacity >= wholeLength && left.hasTwoByteChars() == IsSame::value) { + wholeChars = const_cast(left.nonInlineChars(nogc)); + wholeCapacity = capacity; + /* * Simulate a left-most traversal from the root to leftMost->leftChild() * via first_visit_node @@ -474,7 +477,7 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) JSString* child = str->d.s.u2.left; js::BarrierMethods::postBarrier(&str->d.s.u2.left, child, nullptr); MOZ_ASSERT(child->isRope()); - str->setNonInlineChars(left.nonInlineChars(nogc)); + str->setNonInlineChars(wholeChars); child->d.u1.flattenData = uintptr_t(str) | Tag_VisitRightChild; str = child; } @@ -482,14 +485,17 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) JSString::writeBarrierPre(str->d.s.u2.left); JSString::writeBarrierPre(str->d.s.u3.right); } - str->setNonInlineChars(left.nonInlineChars(nogc)); - wholeCapacity = capacity; - wholeChars = const_cast(left.nonInlineChars(nogc)); + str->setNonInlineChars(wholeChars); pos = wholeChars + left.d.u1.length; JS_STATIC_ASSERT(!(EXTENSIBLE_FLAGS & DEPENDENT_FLAGS)); left.d.u1.flags ^= (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS); left.d.s.u3.base = (JSLinearString*)this; /* will be true on exit */ BarrierMethods::postBarrier((JSString**)&left.d.s.u3.base, nullptr, this); + Nursery& nursery = zone()->group()->nursery(); + if (isTenured() && !left.isTenured()) + nursery.removeMallocedBuffer(wholeChars); + else if (!isTenured() && left.isTenured()) + nursery.registerMallocedBuffer(wholeChars); goto visit_right_child; } } @@ -500,9 +506,9 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) return nullptr; } - if (!isTenured() && maybecx) { - JSRuntime* rt = maybecx->runtime(); - if (!rt->gc.nursery().registerMallocedBuffer(wholeChars)) { + if (!isTenured()) { + Nursery& nursery = zone()->group()->nursery(); + if (!nursery.registerMallocedBuffer(wholeChars)) { js_free(wholeChars); ReportOutOfMemory(maybecx); return nullptr; @@ -684,6 +690,14 @@ JSDependentString::undependInternal(JSContext* cx) if (!s) return nullptr; + if (!isTenured()) { + if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s)) { + js_free(s); + ReportOutOfMemory(cx); + return nullptr; + } + } + AutoCheckCannotGC nogc; PodCopy(s, nonInlineChars(nogc), n); s[n] = '\0'; @@ -1083,6 +1097,14 @@ JSExternalString::ensureFlat(JSContext* cx) if (!s) return nullptr; + if (!isTenured()) { + if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s)) { + js_free(s); + ReportOutOfMemory(cx); + return nullptr; + } + } + // Copy the chars before finalizing the string. { AutoCheckCannotGC nogc;