1f3f8f3e69
Add support to the JSCallReducer to recognize JSConstruct nodes where the target is the Object constructor, and reduce them to JSCreate nodes if either (a) no value is passed to the Object constructor, or (b) the target and new.target are definitely not identical, by checking whether both target and new.target are different HeapConstants (if they are not, then the JSCreateLowering will not be able to do a lot with the JSCreate anyways). This should cover the relevant cases for subclassing appropriately. It fixes the 3-4x slowdown on the micro-benchmark mentioned in the linked bug, baseNoExtends: 752 ms. baseExtendsObject: 752 ms. baseExtendsViaFactory: 751 ms. and thus removes the performance cliff. R=jarin@chromium.org Bug: v8:6801 Change-Id: Id265fd1399302a67b5790a6d0156679920c58bdd Reviewed-on: https://chromium-review.googlesource.com/657019 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#47913}
52 lines
1.4 KiB
JavaScript
52 lines
1.4 KiB
JavaScript
// Copyright 2017 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
|
|
|
|
// Common pattern in Webpack 3 generated bundles, see
|
|
// https://github.com/webpack/webpack/issues/5600 for details.
|
|
(function ObjectConstructorWithKnownFunction() {
|
|
"use strict";
|
|
class A {
|
|
bar() { return this; }
|
|
};
|
|
function foo(a) {
|
|
return Object(a.bar)();
|
|
}
|
|
assertEquals(undefined, foo(new A));
|
|
assertEquals(undefined, foo(new A));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(undefined, foo(new A));
|
|
})();
|
|
|
|
(function ObjectConstructorWithString() {
|
|
"use strict";
|
|
function foo() {
|
|
return Object("a");
|
|
}
|
|
assertEquals('object', typeof foo());
|
|
assertEquals('object', typeof foo());
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals('object', typeof foo());
|
|
})();
|
|
|
|
// Object constructor subclassing via Class Factories, see
|
|
// https://twitter.com/FremyCompany/status/905977048006402048
|
|
// for the hint.
|
|
(function ObjectConstructorSubClassing() {
|
|
"use strict";
|
|
const Factory = Base => class A extends Base {};
|
|
const A = Factory(Object);
|
|
function foo() {
|
|
return new A(1, 2, 3);
|
|
}
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), Object);
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), Object);
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertInstanceof(foo(), A);
|
|
assertInstanceof(foo(), Object);
|
|
})();
|