Commit db49e223 authored by Maya Lekova's avatar Maya Lekova Committed by Commit Bot

[turbofan] Add serializer support for JSCreate

When the serializer encounters a JSConstruct, it now serializes the
initial map of the new_target to enable further opitmizations in
JSNativeContextSpecialization.

Add regression tests as well.

Bug: v8:7790
Change-Id: Ifab2b58c64a341744e833ed063e9695d74a5cdce
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1900457
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64886}
parent 03d37fc1
...@@ -3909,9 +3909,9 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -3909,9 +3909,9 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
return Changed(node); return Changed(node);
} }
// Otherwise we can only lower to JSCreate if we know that // If {target} is not the same as {new_target} (i.e. the Object
// the value parameter is ignored, which is only the case if // constructor), {value} will be ignored and therefore we can lower
// the {new_target} and {target} are definitely not identical. // to {JSCreate}. See https://tc39.es/ecma262/#sec-object-value.
HeapObjectMatcher mnew_target(new_target); HeapObjectMatcher mnew_target(new_target);
if (mnew_target.HasValue() && if (mnew_target.HasValue() &&
!mnew_target.Ref(broker()).equals(function)) { !mnew_target.Ref(broker()).equals(function)) {
......
...@@ -395,6 +395,7 @@ class SerializerForBackgroundCompilation { ...@@ -395,6 +395,7 @@ class SerializerForBackgroundCompilation {
void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target, void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target,
const HintsVector& arguments, FeedbackSlot slot, const HintsVector& arguments, FeedbackSlot slot,
MissingArgumentsPolicy padding); MissingArgumentsPolicy padding);
void ProcessNewTargetForConstruct(Hints const& new_target);
void ProcessCallVarArgs( void ProcessCallVarArgs(
ConvertReceiverMode receiver_mode, Hints const& callee, ConvertReceiverMode receiver_mode, Hints const& callee,
interpreter::Register first_reg, int reg_count, FeedbackSlot slot, interpreter::Register first_reg, int reg_count, FeedbackSlot slot,
...@@ -1966,6 +1967,38 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct( ...@@ -1966,6 +1967,38 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
ProcessCallOrConstruct(hint.bound_target, new_target, new_arguments, slot, ProcessCallOrConstruct(hint.bound_target, new_target, new_arguments, slot,
padding); padding);
} }
// For JSNativeContextSpecialization::InferReceiverRootMap
if (new_target.has_value()) {
ProcessNewTargetForConstruct(*new_target);
}
}
void SerializerForBackgroundCompilation::ProcessNewTargetForConstruct(
Hints const& new_target_hints) {
for (Handle<Object> target : new_target_hints.constants()) {
if (target->IsJSBoundFunction()) {
// Unroll the bound function
while (target->IsJSBoundFunction()) {
target = handle(
Handle<JSBoundFunction>::cast(target)->bound_target_function(),
broker()->isolate());
}
}
if (target->IsJSFunction()) {
Handle<JSFunction> new_target(Handle<JSFunction>::cast(target));
if (new_target->has_prototype_slot(broker()->isolate()) &&
new_target->has_initial_map()) {
environment()->accumulator_hints().AddMap(
handle(new_target->initial_map(), broker()->isolate()), zone());
}
}
}
for (auto const& virtual_bound_function :
new_target_hints.virtual_bound_functions()) {
ProcessNewTargetForConstruct(virtual_bound_function.bound_target);
}
} }
void SerializerForBackgroundCompilation::ProcessCallVarArgs( void SerializerForBackgroundCompilation::ProcessCallVarArgs(
......
// 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 --opt
class C extends Object {
bla() {}
}
const bla = C.prototype.bla;
function bar(c) {
%TurbofanStaticAssert(c.bla === bla);
}
const boundC = C.bind(null);
function foo() {
let c = new boundC();
bar(c);
}
%PrepareFunctionForOptimization(foo);
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(C);
bar({});
bar({a:1});
bar({aa:1});
bar({aaa:1});
bar({aaaa:1});
bar({aaaaa:1});
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
foo();
// 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 --opt
Object.prototype.bla = function() {}
const bla = Object.prototype.bla;
function bar(c) {
%TurbofanStaticAssert(c.bla === bla);
}
function foo() {
var c = new Object();
bar(c);
}
%PrepareFunctionForOptimization(foo);
%PrepareFunctionForOptimization(bar);
bar({});
bar({a:1});
bar({aa:1});
bar({aaa:1});
bar({aaaa:1});
bar({aaaaa:1});
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
foo();
// 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 --opt
class C extends Object {
bla() {}
}
const bla = C.prototype.bla;
function bar(c) {
%TurbofanStaticAssert(c.bla === bla);
}
function foo() {
let c = new C(...arguments);
bar(c);
}
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(C);
%PrepareFunctionForOptimization(main);
%PrepareFunctionForOptimization(foo);
bar({});
bar({a:1});
bar({aa:1});
bar({aaa:1});
bar({aaaa:1});
bar({aaaaa:1});
function main() {
return foo(1,2,3);
};
main();
main();
%OptimizeFunctionOnNextCall(main);
main();
// 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 --opt
class C extends Object {
bla() {}
}
const bla = C.prototype.bla;
function bar(c) {
%TurbofanStaticAssert(c.bla === bla);
}
function foo() {
var c = new C();
bar(c);
}
%PrepareFunctionForOptimization(foo);
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(C);
bar({});
bar({a:1});
bar({aa:1});
bar({aaa:1});
bar({aaaa:1});
bar({aaaaa:1});
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
foo();
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