| Index: src/hydrogen-check-elimination.cc
|
| diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc
|
| index d5715a61ecce5059ded5b5bae02d7368b9c0235a..5fdb3e3f3c48fa1260005eeeab7ec7e6ae537ebd 100644
|
| --- a/src/hydrogen-check-elimination.cc
|
| +++ b/src/hydrogen-check-elimination.cc
|
| @@ -50,7 +50,6 @@ struct HCheckTableEntry {
|
| HValue* object_; // The object being approximated. NULL => invalid entry.
|
| HInstruction* check_; // The last check instruction.
|
| MapSet maps_; // The set of known maps for the object.
|
| - bool is_stable_;
|
| };
|
|
|
|
|
| @@ -104,10 +103,9 @@ class HCheckTable : public ZoneObject {
|
| }
|
| default: {
|
| // If the instruction changes maps uncontrollably, drop everything.
|
| - if (instr->CheckChangesFlag(kOsrEntries)) {
|
| - Reset();
|
| - } else if (instr->CheckChangesFlag(kMaps)) {
|
| - KillUnstableEntries();
|
| + if (instr->CheckChangesFlag(kMaps) ||
|
| + instr->CheckChangesFlag(kOsrEntries)) {
|
| + Kill();
|
| }
|
| }
|
| // Improvements possible:
|
| @@ -156,7 +154,6 @@ class HCheckTable : public ZoneObject {
|
| if (old_entry->check_ != NULL &&
|
| old_entry->check_->block()->Dominates(succ)) {
|
| new_entry->check_ = old_entry->check_;
|
| - new_entry->is_stable_ = old_entry->is_stable_;
|
| } else {
|
| // Leave it NULL till we meet a new check instruction for this object
|
| // in the control flow.
|
| @@ -178,8 +175,7 @@ class HCheckTable : public ZoneObject {
|
| HCheckTableEntry* pred_entry = copy->Find(phi_operand);
|
| if (pred_entry != NULL) {
|
| // Create an entry for a phi in the table.
|
| - copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone()),
|
| - pred_entry->is_stable_);
|
| + copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone()));
|
| }
|
| }
|
| }
|
| @@ -197,13 +193,12 @@ class HCheckTable : public ZoneObject {
|
| if (is_true_branch) {
|
| // Learn on the true branch of if(CompareMap(x)).
|
| if (entry == NULL) {
|
| - copy->Insert(object, cmp, cmp->map(), cmp->is_stable());
|
| + copy->Insert(object, cmp, cmp->map());
|
| } else {
|
| MapSet list = new(phase_->zone()) UniqueSet<Map>();
|
| list->Add(cmp->map(), phase_->zone());
|
| entry->maps_ = list;
|
| entry->check_ = cmp;
|
| - entry->is_stable_ = cmp->is_stable();
|
| }
|
| } else {
|
| // Learn on the false branch of if(CompareMap(x)).
|
| @@ -222,10 +217,10 @@ class HCheckTable : public ZoneObject {
|
| HCheckTableEntry* re = copy->Find(right);
|
| if (le == NULL) {
|
| if (re != NULL) {
|
| - copy->Insert(left, NULL, re->maps_->Copy(zone), re->is_stable_);
|
| + copy->Insert(left, NULL, re->maps_->Copy(zone));
|
| }
|
| } else if (re == NULL) {
|
| - copy->Insert(right, NULL, le->maps_->Copy(zone), le->is_stable_);
|
| + copy->Insert(right, NULL, le->maps_->Copy(zone));
|
| } else {
|
| MapSet intersect = le->maps_->Intersect(re->maps_, zone);
|
| le->maps_ = intersect;
|
| @@ -252,7 +247,8 @@ class HCheckTable : public ZoneObject {
|
| HBasicBlock* pred_block, Zone* zone) {
|
| if (that->size_ == 0) {
|
| // If the other state is empty, simply reset.
|
| - Reset();
|
| + size_ = 0;
|
| + cursor_ = 0;
|
| } else {
|
| int pred_index = succ->PredecessorIndexOf(pred_block);
|
| bool compact = false;
|
| @@ -275,8 +271,6 @@ class HCheckTable : public ZoneObject {
|
| } else {
|
| this_entry->maps_ =
|
| this_entry->maps_->Union(that_entry->maps_, phase_->zone());
|
| - this_entry->is_stable_ =
|
| - this_entry->is_stable_ && that_entry->is_stable_;
|
| if (this_entry->check_ != that_entry->check_) {
|
| this_entry->check_ = NULL;
|
| }
|
| @@ -357,8 +351,7 @@ class HCheckTable : public ZoneObject {
|
| }
|
| } else {
|
| // No entry; insert a new one.
|
| - Insert(object, instr, instr->map_set().Copy(phase_->zone()),
|
| - instr->is_stable());
|
| + Insert(object, instr, instr->map_set().Copy(phase_->zone()));
|
| }
|
| }
|
|
|
| @@ -420,8 +413,7 @@ class HCheckTable : public ZoneObject {
|
| }
|
| } else {
|
| // No prior information.
|
| - // TODO(verwaest): Tag map constants with stability.
|
| - Insert(object, instr, map, false);
|
| + Insert(object, instr, map);
|
| }
|
| }
|
|
|
| @@ -438,14 +430,12 @@ class HCheckTable : public ZoneObject {
|
| if (instr->has_transition()) {
|
| // This store transitions the object to a new map.
|
| Kill(object);
|
| - Insert(object, NULL, MapConstant(instr->transition()),
|
| - instr->is_stable());
|
| + Insert(object, NULL, MapConstant(instr->transition()));
|
| } else if (IsMapAccess(instr->access())) {
|
| // This is a store directly to the map field of the object.
|
| Kill(object);
|
| if (!instr->value()->IsConstant()) return;
|
| - // TODO(verwaest): Tag with stability.
|
| - Insert(object, NULL, MapConstant(instr->value()), false);
|
| + Insert(object, NULL, MapConstant(instr->value()));
|
| } else {
|
| // If the instruction changes maps, it should be handled above.
|
| CHECK(!instr->CheckChangesFlag(kMaps));
|
| @@ -495,26 +485,12 @@ class HCheckTable : public ZoneObject {
|
| }
|
| }
|
|
|
| - // Reset the table.
|
| - void Reset() {
|
| + // Kill everything in the table.
|
| + void Kill() {
|
| size_ = 0;
|
| cursor_ = 0;
|
| }
|
|
|
| - // Kill everything in the table.
|
| - void KillUnstableEntries() {
|
| - bool compact = false;
|
| - for (int i = 0; i < size_; i++) {
|
| - HCheckTableEntry* entry = &entries_[i];
|
| - ASSERT(entry->object_ != NULL);
|
| - if (!entry->is_stable_) {
|
| - entry->object_ = NULL;
|
| - compact = true;
|
| - }
|
| - }
|
| - if (compact) Compact();
|
| - }
|
| -
|
| // Kill everything in the table that may alias {object}.
|
| void Kill(HValue* object) {
|
| bool compact = false;
|
| @@ -596,24 +572,17 @@ class HCheckTable : public ZoneObject {
|
| return entry == NULL ? NULL : entry->maps_;
|
| }
|
|
|
| - void Insert(HValue* object,
|
| - HInstruction* check,
|
| - Unique<Map> map,
|
| - bool is_stable) {
|
| + void Insert(HValue* object, HInstruction* check, Unique<Map> map) {
|
| MapSet list = new(phase_->zone()) UniqueSet<Map>();
|
| list->Add(map, phase_->zone());
|
| - Insert(object, check, list, is_stable);
|
| + Insert(object, check, list);
|
| }
|
|
|
| - void Insert(HValue* object,
|
| - HInstruction* check,
|
| - MapSet maps,
|
| - bool is_stable) {
|
| + void Insert(HValue* object, HInstruction* check, MapSet maps) {
|
| HCheckTableEntry* entry = &entries_[cursor_++];
|
| entry->object_ = object;
|
| entry->check_ = check;
|
| entry->maps_ = maps;
|
| - entry->is_stable_ = is_stable;
|
| // If the table becomes full, wrap around and overwrite older entries.
|
| if (cursor_ == kMaxTrackedObjects) cursor_ = 0;
|
| if (size_ < kMaxTrackedObjects) size_++;
|
| @@ -643,7 +612,8 @@ class HCheckTable : public ZoneObject {
|
| class HCheckMapsEffects : public ZoneObject {
|
| public:
|
| explicit HCheckMapsEffects(Zone* zone)
|
| - : stores_(5, zone) { }
|
| + : maps_stored_(false),
|
| + stores_(5, zone) { }
|
|
|
| inline bool Disabled() {
|
| return false; // Effects are _not_ disabled.
|
| @@ -651,22 +621,27 @@ class HCheckMapsEffects : public ZoneObject {
|
|
|
| // Process a possibly side-effecting instruction.
|
| void Process(HInstruction* instr, Zone* zone) {
|
| - if (instr->IsStoreNamedField()) {
|
| - stores_.Add(HStoreNamedField::cast(instr), zone);
|
| - } else {
|
| - flags_.Add(instr->ChangesFlags());
|
| + switch (instr->opcode()) {
|
| + case HValue::kStoreNamedField: {
|
| + stores_.Add(HStoreNamedField::cast(instr), zone);
|
| + break;
|
| + }
|
| + case HValue::kOsrEntry: {
|
| + // Kill everything. Loads must not be hoisted past the OSR entry.
|
| + maps_stored_ = true;
|
| + }
|
| + default: {
|
| + maps_stored_ |= (instr->CheckChangesFlag(kMaps) |
|
| + instr->CheckChangesFlag(kElementsKind));
|
| + }
|
| }
|
| }
|
|
|
| // Apply these effects to the given check elimination table.
|
| void Apply(HCheckTable* table) {
|
| - if (flags_.Contains(kOsrEntries)) {
|
| - table->Reset();
|
| - return;
|
| - }
|
| - if (flags_.Contains(kMaps) || flags_.Contains(kElementsKind)) {
|
| + if (maps_stored_) {
|
| // Uncontrollable map modifications; kill everything.
|
| - table->KillUnstableEntries();
|
| + table->Kill();
|
| return;
|
| }
|
|
|
| @@ -681,14 +656,14 @@ class HCheckMapsEffects : public ZoneObject {
|
|
|
| // Union these effects with the other effects.
|
| void Union(HCheckMapsEffects* that, Zone* zone) {
|
| - flags_.Add(that->flags_);
|
| + maps_stored_ |= that->maps_stored_;
|
| for (int i = 0; i < that->stores_.length(); i++) {
|
| stores_.Add(that->stores_[i], zone);
|
| }
|
| }
|
|
|
| private:
|
| - GVNFlagSet flags_;
|
| + bool maps_stored_ : 1;
|
| ZoneList<HStoreNamedField*> stores_;
|
| };
|
|
|
| @@ -705,7 +680,7 @@ void HCheckEliminationPhase::Run() {
|
| } else {
|
| // Perform only local analysis.
|
| for (int i = 0; i < graph()->blocks()->length(); i++) {
|
| - table->Reset();
|
| + table->Kill();
|
| engine.AnalyzeOneBlock(graph()->blocks()->at(i), table);
|
| }
|
| }
|
|
|