f11ba854e5
This adds a new flag --modify-field-representation-inplace (enabled by default), which lets the runtime perform field representation changes for Smi to Tagged or for HeapObject to Tagged in-place instead of creating new maps and marking the previous map tree as deprecated. That means we create (a lot) fewer Maps and DescriptorArrays in the beginning and also need to self-heal fewer objects later (migrating off the deprecated maps). In TurboFan we just take the "field owner dependency" whenever we use the field representation, which is very similar to what we already do for the field types. That means if we change the representation of a field that we used in optimized code, we will simply deoptimize that code and have TurboFan potentially later optimize it again with the new field representation. On the Speedometer2/ElmJS-TodoMVC test, this reduces the total execution time from around 415ms to around 352ms, which corresponds to a **15%** improvement. The overall Speedometer2 score improves from around 74.1 to around 78.3 (on local runs with content_shell), corresponding to a **5.6%** improvement here. 🎉 On the CNN desktop browsing story, it seems that we reduce map space utilization/fragmentation by about 4-5%. But since we allocate a lot less (fewer Maps and DescriptorArrays) we also significantly change the GC timing, which heavily influences the results here. So take this with a grain of salt. 🤷 Note: For Double fields, this doesn't change anything, meaning they still create new maps and deprecate the previous map trees. Bug: v8:8749, v8:8865, v8:9114 Change-Id: Ibd70efcb59be982863905663dbfaa89aa5b31e14 Cq-Include-Trybots: luci.chromium.try:linux-rel,win7-rel Doc: http://bit.ly/v8-in-place-field-representation-changes Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1565891 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#60822}
75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
// 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.
|
|
|
|
// Flags: --allow-natives-syntax --modify-field-representation-inplace
|
|
// Flags: --no-always-opt --opt
|
|
|
|
// Test that code embedding accesses to a Smi field gets properly
|
|
// deoptimized if s->t field representation changes are done in-place.
|
|
(function() {
|
|
function O(x) { this.x = x; }
|
|
|
|
function foo(o) { return o.x; }
|
|
%PrepareFunctionForOptimization(foo);
|
|
foo(new O(1));
|
|
foo(new O(2));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
foo(new O(3));
|
|
assertOptimized(foo);
|
|
|
|
new O(null);
|
|
assertUnoptimized(foo);
|
|
})();
|
|
|
|
// Test that code embedding assignments to a Smi field gets properly
|
|
// deoptimized if s->t field representation changes are done in-place.
|
|
(function() {
|
|
function O(x) { this.x = x; }
|
|
|
|
function foo(o) { o.x = 0; }
|
|
%PrepareFunctionForOptimization(foo);
|
|
foo(new O(1));
|
|
foo(new O(2));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
foo(new O(3));
|
|
assertOptimized(foo);
|
|
|
|
new O(null);
|
|
assertUnoptimized(foo);
|
|
})();
|
|
|
|
// Test that code embedding accesses to a HeapObject field gets properly
|
|
// deoptimized if h->t field representation changes are done in-place.
|
|
(function() {
|
|
function O(x) { this.x = x; }
|
|
|
|
function foo(o) { return o.x; }
|
|
%PrepareFunctionForOptimization(foo);
|
|
foo(new O(null));
|
|
foo(new O("Hello"));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
foo(new O({}));
|
|
assertOptimized(foo);
|
|
|
|
new O(1);
|
|
assertUnoptimized(foo);
|
|
})();
|
|
|
|
// Test that code embedding assignments to a Smi field gets properly
|
|
// deoptimized if s->t field representation changes are done in-place.
|
|
(function() {
|
|
function O(x) { this.x = x; }
|
|
|
|
function foo(o) { o.x = true; }
|
|
%PrepareFunctionForOptimization(foo);
|
|
foo(new O(null));
|
|
foo(new O("Hello"));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
foo(new O({}));
|
|
assertOptimized(foo);
|
|
|
|
new O(1);
|
|
assertUnoptimized(foo);
|
|
})();
|