Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: src/compiler/load-elimination.cc

Issue 2279213002: [turbofan] Introduce a dedicated ArrayBufferWasNeutered operator. (Closed)
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/load-elimination.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/load-elimination.cc
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc
index 6131fc57d4ec333ef6eac76a01640aac21607d53..2ad21d02ccf1f8b724b3e5cc95cb3561b80308e4 100644
--- a/src/compiler/load-elimination.cc
+++ b/src/compiler/load-elimination.cc
@@ -55,6 +55,8 @@ bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; }
Reduction LoadElimination::Reduce(Node* node) {
switch (node->opcode()) {
+ case IrOpcode::kArrayBufferWasNeutered:
+ return ReduceArrayBufferWasNeutered(node);
case IrOpcode::kCheckMaps:
return ReduceCheckMaps(node);
case IrOpcode::kEnsureWritableFastElements:
@@ -85,6 +87,65 @@ Reduction LoadElimination::Reduce(Node* node) {
return NoChange();
}
+namespace {
+
+bool IsCompatibleCheck(Node const* a, Node const* b) {
+ if (a->op() != b->op()) return false;
+ for (int i = a->op()->ValueInputCount(); --i >= 0;) {
+ if (!MustAlias(a->InputAt(i), b->InputAt(i))) return false;
+ }
+ return true;
+}
+
+} // namespace
+
+Node* LoadElimination::AbstractChecks::Lookup(Node* node) const {
+ for (Node* const check : nodes_) {
+ if (check && IsCompatibleCheck(check, node)) {
+ return check;
+ }
+ }
+ return nullptr;
+}
+
+bool LoadElimination::AbstractChecks::Equals(AbstractChecks const* that) const {
+ if (this == that) return true;
+ for (size_t i = 0; i < arraysize(nodes_); ++i) {
+ if (Node* this_node = this->nodes_[i]) {
+ for (size_t j = 0;; ++j) {
+ if (j == arraysize(nodes_)) return false;
+ if (that->nodes_[j] == this_node) break;
+ }
+ }
+ }
+ for (size_t i = 0; i < arraysize(nodes_); ++i) {
+ if (Node* that_node = that->nodes_[i]) {
+ for (size_t j = 0;; ++j) {
+ if (j == arraysize(nodes_)) return false;
+ if (this->nodes_[j] == that_node) break;
+ }
+ }
+ }
+ return true;
+}
+
+LoadElimination::AbstractChecks const* LoadElimination::AbstractChecks::Merge(
+ AbstractChecks const* that, Zone* zone) const {
+ if (this->Equals(that)) return this;
+ AbstractChecks* copy = new (zone) AbstractChecks(zone);
+ for (Node* const this_node : this->nodes_) {
+ if (this_node == nullptr) continue;
+ for (Node* const that_node : that->nodes_) {
+ if (this_node == that_node) {
+ copy->nodes_[copy->next_index_++] = this_node;
+ break;
+ }
+ }
+ }
+ copy->next_index_ %= arraysize(nodes_);
+ return copy;
+}
+
Node* LoadElimination::AbstractElements::Lookup(Node* object,
Node* index) const {
for (Element const element : elements_) {
@@ -165,6 +226,7 @@ LoadElimination::AbstractElements::Merge(AbstractElements const* that,
this_element.index == that_element.index &&
this_element.value == that_element.value) {
copy->elements_[copy->next_index_++] = this_element;
+ break;
}
}
}
@@ -194,6 +256,13 @@ LoadElimination::AbstractField const* LoadElimination::AbstractField::Kill(
}
bool LoadElimination::AbstractState::Equals(AbstractState const* that) const {
+ if (this->checks_) {
+ if (!that->checks_ || !that->checks_->Equals(this->checks_)) {
+ return false;
+ }
+ } else if (that->checks_) {
+ return false;
+ }
if (this->elements_) {
if (!that->elements_ || !that->elements_->Equals(this->elements_)) {
return false;
@@ -215,6 +284,12 @@ bool LoadElimination::AbstractState::Equals(AbstractState const* that) const {
void LoadElimination::AbstractState::Merge(AbstractState const* that,
Zone* zone) {
+ // Merge the information we have about the checks.
+ if (this->checks_) {
+ this->checks_ =
+ that->checks_ ? that->checks_->Merge(this->checks_, zone) : nullptr;
+ }
+
// Merge the information we have about the elements.
if (this->elements_) {
this->elements_ = that->elements_
@@ -234,6 +309,21 @@ void LoadElimination::AbstractState::Merge(AbstractState const* that,
}
}
+Node* LoadElimination::AbstractState::LookupCheck(Node* node) const {
+ return this->checks_ ? this->checks_->Lookup(node) : nullptr;
+}
+
+LoadElimination::AbstractState const* LoadElimination::AbstractState::AddCheck(
+ Node* node, Zone* zone) const {
+ AbstractState* that = new (zone) AbstractState(*this);
+ if (that->checks_) {
+ that->checks_ = that->checks_->Extend(node, zone);
+ } else {
+ that->checks_ = new (zone) AbstractChecks(node, zone);
+ }
+ return that;
+}
+
Node* LoadElimination::AbstractState::LookupElement(Node* object,
Node* index) const {
if (this->elements_) {
@@ -315,6 +405,18 @@ void LoadElimination::AbstractStateForEffectNodes::Set(
info_for_node_[id] = state;
}
+Reduction LoadElimination::ReduceArrayBufferWasNeutered(Node* node) {
+ Node* const effect = NodeProperties::GetEffectInput(node);
+ AbstractState const* state = node_states_.Get(effect);
+ if (state == nullptr) return NoChange();
+ if (Node* const check = state->LookupCheck(node)) {
+ ReplaceWithValue(node, check, effect);
+ return Replace(check);
+ }
+ state = state->AddCheck(node, zone());
+ return UpdateState(node, state);
+}
+
Reduction LoadElimination::ReduceCheckMaps(Node* node) {
Node* const object = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node);
« no previous file with comments | « src/compiler/load-elimination.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698