04c8c11ee5
Previously, the species protector was invalidated whenever the __proto__ of an Array instance was manipulated. Then, if the map's new_target_is_base field remained set, it was correct to conclude that GetPrototypeOf(array) was %ArrayPrototype%. However, this choice caused the popular D3 framework to invalidate the species protector, causing many functions to become slower. This patch eliminates that aspect of the species protector. Instead, the check is to look at the instance->map()->prototype(). It is valid to look directly at the map's prototype slot, ignoring hidden prototypes and proxies, because - This is only called on Array instances, so the receiver cannot be a Proxy. - For hidden prototypes, any inaccuracy would only result in conservatively taking the slow path. Theoretically, this patch could make methods applied to arrays from other contexts slower. However, the slowdown would only affect a particular array instance and not have a global spill-over effect. Further, the slowdown could be addressed by tracking, either in the instance's map or in the actual prototype object, whether it is a %ArrayPrototype% from any context, in a way which is cheap to query, and use that rather than comparing to the currently executing native context. In interactive testing, this patch led the OnShape CAD system to experience faster load times (110+s -> 40s). BUG=chromium:606207 LOG=Y Review-Url: https://codereview.chromium.org/1936393002 Cr-Commit-Position: refs/heads/master@{#36033}
29 lines
978 B
JavaScript
29 lines
978 B
JavaScript
// Copyright 2016 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: --harmony-species --allow-natives-syntax
|
|
|
|
// Overwriting Array[Symbol.species] updates the protector
|
|
|
|
let x = [];
|
|
|
|
assertEquals(Array, x.map(()=>{}).constructor);
|
|
assertEquals(Array, x.filter(()=>{}).constructor);
|
|
assertEquals(Array, x.slice().constructor);
|
|
assertEquals(Array, x.splice().constructor);
|
|
assertEquals(Array, x.concat([1]).constructor);
|
|
assertEquals(1, x.concat([1])[0]);
|
|
|
|
class MyArray extends Array { }
|
|
|
|
Object.defineProperty(Array, Symbol.species, {value: MyArray});
|
|
assertFalse(%SpeciesProtector());
|
|
|
|
assertEquals(MyArray, x.map(()=>{}).constructor);
|
|
assertEquals(MyArray, x.filter(()=>{}).constructor);
|
|
assertEquals(MyArray, x.slice().constructor);
|
|
assertEquals(MyArray, x.splice().constructor);
|
|
assertEquals(MyArray, x.concat([1]).constructor);
|
|
assertEquals(1, x.concat([1])[0]);
|