2019-06-24 10:01:56 +00:00
|
|
|
// 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
|
|
|
|
|
|
|
|
// This function was carefully constructed by Clusterfuzz to execute a certain
|
|
|
|
// sequence of transitions. Thus, it may no longer test anything useful if
|
|
|
|
// the transition logic changes.
|
|
|
|
//
|
|
|
|
// The more stable unit test testing the same bug is:
|
|
|
|
// test-field-type-tracking/NormalizeToMigrationTarget
|
|
|
|
var foo = function() {
|
|
|
|
|
|
|
|
function f1(arg) {
|
|
|
|
var ret = { x: arg };
|
|
|
|
ret.__defineGetter__("y", function() { });
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
// Create v1 with a map with properties: {x:Smi, y:AccessorPair}
|
|
|
|
let v1 = f1(10);
|
|
|
|
// Create a map with properties: {x:Double, y:AccessorPair}, deprecating the
|
|
|
|
// previous map.
|
|
|
|
let v2 = f1(10.5);
|
|
|
|
|
|
|
|
// Access x on v1 to a function that reads x, which triggers it to update its
|
|
|
|
// map. This update transitions v1 to slow mode as there is already a "y"
|
|
|
|
// transition with a different accessor.
|
|
|
|
//
|
|
|
|
// Note that the parent function `foo` can't be an IIFE, as then this callsite
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
// would use the NoFeedback version of the GetNamedProperty bytecode, and this
|
2019-06-24 10:01:56 +00:00
|
|
|
// doesn't trigger the map update.
|
|
|
|
v1.x;
|
|
|
|
|
|
|
|
// Create v3 which overwrites a non-accessor with an accessor, triggering it
|
|
|
|
// to normalize, and picking up the same cached normalized map as v1. However,
|
|
|
|
// v3's map is not a migration target and v1's is (as it was migrated to when
|
|
|
|
// updating v1), so the migration target bit doesn't match. This should be
|
|
|
|
// fine and shouldn't trigger any DCHECKs.
|
|
|
|
let v3 = { z:1 };
|
|
|
|
v3.__defineGetter__("z", function() {});
|
|
|
|
};
|
|
|
|
|
|
|
|
%EnsureFeedbackVectorForFunction(foo);
|
|
|
|
foo();
|