903519 - Register nursery string buffers to be freed

903519 - Register nursery string buffers to be freed, this was missed somehow before.
This commit is contained in:
win7-7 2026-01-05 18:04:23 +02:00 committed by wuggy
commit 086bacbf22

View file

@ -461,6 +461,9 @@ JSRope::flattenInternal(ExclusiveContext* maybecx)
JSExtensibleString& left = leftMostRope->leftChild()->asExtensible();
size_t capacity = left.capacity();
if (capacity >= wholeLength && left.hasTwoByteChars() == IsSame<CharT, char16_t>::value) {
wholeChars = const_cast<CharT*>(left.nonInlineChars<CharT>(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<JSString*>::postBarrier(&str->d.s.u2.left, child, nullptr);
MOZ_ASSERT(child->isRope());
str->setNonInlineChars(left.nonInlineChars<CharT>(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<CharT>(nogc));
wholeCapacity = capacity;
wholeChars = const_cast<CharT*>(left.nonInlineChars<CharT>(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<JSString*>::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<CharT>(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;