Bug 1763877 - Root elements in TupleType::tuple_with r=jandem

Previously, tuple_with() declared the following pointer to its tuple
argument's elements:
   HeapSlotArray t = tuple->getDenseElements();
Because this wasn't rooted, incremental GC could cause t to be used
after freeing. Since t was only used twice, I inlined it to solve this
problem.

Differential Revision: https://phabricator.services.mozilla.com/D143309
This commit is contained in:
Tim Chevalier 2022-04-14 14:28:30 +00:00
Родитель 222253b8d8
Коммит 624d18e65f
2 изменённых файлов: 14 добавлений и 4 удалений

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

@ -0,0 +1,11 @@
// |jit-test| skip-if: !this.hasOwnProperty("Tuple")
function f() {
var expected = #[1, "monkeys", 3];
assertEq(#[1,2,3].with(1, "monkeys"), expected);
assertEq(Object(#[1,2,3]).with(1, "monkeys"), expected);
}
for (i = 0; i < 500; i++) {
f();
}

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

@ -97,8 +97,6 @@ bool js::tuple_with(JSContext* cx, unsigned argc, Value* vp) {
Rooted<TupleType*> tuple(cx, &(*maybeTuple));
/* Step 2. */
HeapSlotArray t = tuple->getDenseElements();
uint64_t length = tuple->getDenseInitializedLength();
TupleType* list = TupleType::createUninitialized(cx, length);
if (!list) {
@ -126,10 +124,11 @@ bool js::tuple_with(JSContext* cx, unsigned argc, Value* vp) {
/* Step 7 */
uint64_t before = index;
uint64_t after = length - index - 1;
list->copyDenseElements(0, t, before);
list->copyDenseElements(0, tuple->getDenseElements(), before);
list->setDenseInitializedLength(index + 1);
list->initDenseElement(index, value);
list->copyDenseElements(index + 1, t + uint32_t(index + 1), after);
list->copyDenseElements(
index + 1, tuple->getDenseElements() + uint32_t(index + 1), after);
list->setDenseInitializedLength(length);
list->finishInitialization(cx);
/* Step 8 */