Files
v8/test/mjsunit/json-fast-array-objects.js
pthier dcebbb6b6a [json] Guard direct layout fast path against deprecated feedback maps
When a feedback map is deprecated during recursive child property
parsing or prior to ParseJsonObject, Map::Update in BuildJsonObject
may migrate the map to a dictionary mode map or alter its descriptor
count and layout.

Skip the direct layout allocation fast path if the feedback map was
deprecated.

Fixed: 533496238
Change-Id: Ia2a26256d83be6b19e1d11ce9e8ee52d08d49236
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8085684
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#108622}
2026-07-13 06:27:58 -07:00

74 lines
2.5 KiB
JavaScript

// Copyright 2026 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test homogeneous object arrays parse correctly via Direct Layout Allocation fast path.
(function TestHomogeneousObjectArray() {
const items = [
{ id: 1, name: "foo", active: true, score: 95.5 },
{ id: 2, name: "bar", active: false, score: 88.25 },
{ id: 3, name: "baz", active: true, score: 100.0 }
];
const json = JSON.stringify(items);
const parsed = JSON.parse(json);
assertEquals(items.length, parsed.length);
for (let i = 0; i < items.length; i++) {
assertEquals(items[i].id, parsed[i].id);
assertEquals(items[i].name, parsed[i].name);
assertEquals(items[i].active, parsed[i].active);
assertEquals(items[i].score, parsed[i].score);
}
})();
// Test heterogeneous/mismatched object arrays fall back correctly.
(function TestHeterogeneousObjectArray() {
const items = [
{ id: 1, name: "foo" },
{ id: 2, name: "bar", extra: true },
{ id: 3, different: "key" }
];
const json = JSON.stringify(items);
const parsed = JSON.parse(json);
assertEquals(items.length, parsed.length);
assertEquals(items[0], parsed[0]);
assertEquals(items[1], parsed[1]);
assertEquals(items[2], parsed[2]);
})();
// Test reviver with homogeneous array.
(function TestReviverHomogeneousArray() {
const items = [
{ a: 10, b: 20 },
{ a: 30, b: 40 }
];
const json = JSON.stringify(items);
const parsed = JSON.parse(json, (key, val) => {
if (typeof val === "number") return val * 2;
return val;
});
assertEquals(20, parsed[0].a);
assertEquals(40, parsed[0].b);
assertEquals(60, parsed[1].a);
assertEquals(80, parsed[1].b);
})();
// Test that map transitions across child property parsing that deprecate feedback maps
// or normalize maps to dictionary mode do not trigger fast-path DCHECK/memory bugs.
(function TestDeprecatedMapSlowElementsTransition() {
let arr = [];
for (let i = 0; i < 1600; i++) {
arr.push(`{"a":1.1,"p${i}":1}`);
}
let str = `[{"a":1,"b":1},{"a":1,"b":1},{"a":2,"b":[${arr.join(',')}]}]`;
let res = JSON.parse(str);
assertEquals(3, res.length);
assertEquals(1, res[0].a);
assertEquals(1, res[0].b);
assertEquals(2, res[2].a);
assertEquals(1600, res[2].b.length);
assertEquals(1.1, res[2].b[0].a);
assertEquals(1, res[2].b[0].p0);
assertEquals(1.1, res[2].b[1599].a);
assertEquals(1, res[2].b[1599].p1599);
})();