[turbofan] A bug fix of loadElimination.
KillFields of an object should remove its cache from all the fields. Currently, the cache in the front field is kept which is not expected. This patch fixes it. Review-Url: https://codereview.chromium.org/2618273002 Cr-Commit-Position: refs/heads/master@{#42388}
This commit is contained in:
parent
738cb6a759
commit
3df428bb92
@ -535,7 +535,7 @@ LoadElimination::AbstractState::KillFields(Node* object, Zone* zone) const {
|
|||||||
AbstractField const* that_field = this_field->Kill(object, zone);
|
AbstractField const* that_field = this_field->Kill(object, zone);
|
||||||
if (that_field != this_field) {
|
if (that_field != this_field) {
|
||||||
AbstractState* that = new (zone) AbstractState(*this);
|
AbstractState* that = new (zone) AbstractState(*this);
|
||||||
that->fields_[i] = this_field;
|
that->fields_[i] = that_field;
|
||||||
while (++i < arraysize(fields_)) {
|
while (++i < arraysize(fields_)) {
|
||||||
if (this->fields_[i] != nullptr) {
|
if (this->fields_[i] != nullptr) {
|
||||||
that->fields_[i] = this->fields_[i]->Kill(object, zone);
|
that->fields_[i] = this->fields_[i]->Kill(object, zone);
|
||||||
|
@ -174,6 +174,46 @@ TEST_F(LoadEliminationTest, StoreFieldAndLoadField) {
|
|||||||
EXPECT_EQ(value, r.replacement());
|
EXPECT_EQ(value, r.replacement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LoadEliminationTest, StoreFieldAndKillFields) {
|
||||||
|
Node* object = Parameter(Type::Any(), 0);
|
||||||
|
Node* value = Parameter(Type::Any(), 1);
|
||||||
|
Node* effect = graph()->start();
|
||||||
|
Node* control = graph()->start();
|
||||||
|
|
||||||
|
FieldAccess access1 = {kTaggedBase, kPointerSize,
|
||||||
|
MaybeHandle<Name>(), MaybeHandle<Map>(),
|
||||||
|
Type::Any(), MachineType::AnyTagged(),
|
||||||
|
kNoWriteBarrier};
|
||||||
|
|
||||||
|
// Offset that out of field cache size.
|
||||||
|
FieldAccess access2 = {kTaggedBase, 2048 * kPointerSize,
|
||||||
|
MaybeHandle<Name>(), MaybeHandle<Map>(),
|
||||||
|
Type::Any(), MachineType::AnyTagged(),
|
||||||
|
kNoWriteBarrier};
|
||||||
|
|
||||||
|
StrictMock<MockAdvancedReducerEditor> editor;
|
||||||
|
LoadElimination load_elimination(&editor, jsgraph(), zone());
|
||||||
|
|
||||||
|
load_elimination.Reduce(graph()->start());
|
||||||
|
|
||||||
|
Node* store1 = effect = graph()->NewNode(simplified()->StoreField(access1),
|
||||||
|
object, value, effect, control);
|
||||||
|
load_elimination.Reduce(store1);
|
||||||
|
|
||||||
|
// Invalidate caches of object.
|
||||||
|
Node* store2 = effect = graph()->NewNode(simplified()->StoreField(access2),
|
||||||
|
object, value, effect, control);
|
||||||
|
load_elimination.Reduce(store2);
|
||||||
|
|
||||||
|
Node* store3 = graph()->NewNode(simplified()->StoreField(access1),
|
||||||
|
object, value, effect, control);
|
||||||
|
|
||||||
|
Reduction r = load_elimination.Reduce(store3);
|
||||||
|
|
||||||
|
// store3 shall not be replaced, since caches were invalidated.
|
||||||
|
EXPECT_EQ(store3, r.replacement());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(LoadEliminationTest, StoreFieldAndStoreElementAndLoadField) {
|
TEST_F(LoadEliminationTest, StoreFieldAndStoreElementAndLoadField) {
|
||||||
Node* object = Parameter(Type::Any(), 0);
|
Node* object = Parameter(Type::Any(), 0);
|
||||||
Node* value = Parameter(Type::Any(), 1);
|
Node* value = Parameter(Type::Any(), 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user