Commit 864cacd6 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[json] Don't consume sibling feedback from objects with detached maps

By marking maps detached from the transition tree as prototypes, we'll
automatically stop tracking transitions from those detached fast maps. That
allows us to quickly check whether a map is detached (or the initial map
anyway); and saves memory. We can use this information to ignore sibling type
feedback when parsing a JSON array with many distinctly shaped json objects.

Bug: chromium:993980
Change-Id: I86d493ac2cabec2c31c6e322ad5c5a7ace059dfc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1771778Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63403}
parent 7e1fbe8f
......@@ -825,8 +825,12 @@ MaybeHandle<Object> JsonParser<Char>::ParseJsonValue() {
cont_stack.back().type() == JsonContinuation::kArrayElement &&
cont_stack.back().index < element_stack.size() &&
element_stack.back()->IsJSObject()) {
feedback =
handle(JSObject::cast(*element_stack.back()).map(), isolate_);
Map maybe_feedback = JSObject::cast(*element_stack.back()).map();
// Don't consume feedback from objects with a map that's detached
// from the transition tree.
if (!maybe_feedback.GetBackPointer().IsUndefined(isolate_)) {
feedback = handle(maybe_feedback, isolate_);
}
}
value = BuildJsonObject(cont, property_stack, feedback);
property_stack.resize(cont.index);
......
......@@ -1730,6 +1730,12 @@ Handle<Map> Map::CopyReplaceDescriptors(
descriptors->GeneralizeAllFields();
result->InitializeDescriptors(isolate, *descriptors,
LayoutDescriptor::FastPointerLayout());
// If we were trying to insert a transition but failed because there are
// too many transitions already, mark the object as a prototype to avoid
// tracking transitions from the detached map.
if (flag == INSERT_TRANSITION) {
result->set_is_prototype_map(true);
}
}
} else {
result->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
......
// Copyright 2019 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.
(function () {
// generate some sample data
let data = new Array(1600).fill(null).map((e, i) => ({
invariantKey: 'v',
['randomKey' + i]: 'w',
}));
// use json parser
data = JSON.parse(JSON.stringify(data))
// look for undefined values
for (const t of data) {
assertFalse(Object.keys(t).some(k => !t[k]));
}
})()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment