[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:
pan.deng 2017-01-16 19:12:08 -08:00 committed by Commit bot
parent 738cb6a759
commit 3df428bb92
2 changed files with 41 additions and 1 deletions

View File

@ -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);

View File

@ -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);