Commit 47a15c62 authored by Alexandre Talon's avatar Alexandre Talon Committed by Commit Bot

[Turbofan] New DCHECK to ensure no use is mutated when iterating through them

This CL adds a DCHECK to make the uses() function safer: we store what
the next pointer should be to comparing with the next use (from the 
current element in the linked list). This helps detect code which 
invalidates the use-list iterator, which would otherwise cause 
hard-to-debug errors.

Bug: 
Change-Id: I3875361809ffd55fb8be2cbb15af3250e3fd4c12
Reviewed-on: https://chromium-review.googlesource.com/596030Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Alexandre Talon <alexandret@google.com>
Cr-Commit-Position: refs/heads/master@{#47074}
parent d721a9d4
...@@ -63,7 +63,7 @@ class V8_EXPORT_PRIVATE Node final { ...@@ -63,7 +63,7 @@ class V8_EXPORT_PRIVATE Node final {
: inputs_.outline_->count_; : inputs_.outline_->count_;
} }
#if DEBUG #ifdef DEBUG
void Verify(); void Verify();
#define BOUNDS_CHECK(index) \ #define BOUNDS_CHECK(index) \
do { \ do { \
...@@ -593,7 +593,14 @@ class Node::Uses::const_iterator final { ...@@ -593,7 +593,14 @@ class Node::Uses::const_iterator final {
typedef Node** pointer; typedef Node** pointer;
typedef Node*& reference; typedef Node*& reference;
const_iterator(const const_iterator& other) : current_(other.current_) {} const_iterator(const const_iterator& other)
: current_(other.current_)
#ifdef DEBUG
,
next_(other.next_)
#endif
{
}
Node* operator*() const { return current_->from(); } Node* operator*() const { return current_->from(); }
bool operator==(const const_iterator& other) const { bool operator==(const const_iterator& other) const {
...@@ -604,7 +611,13 @@ class Node::Uses::const_iterator final { ...@@ -604,7 +611,13 @@ class Node::Uses::const_iterator final {
} }
const_iterator& operator++() { const_iterator& operator++() {
DCHECK_NOT_NULL(current_); DCHECK_NOT_NULL(current_);
// Checking no use gets mutated while iterating through them, a potential
// very tricky cause of bug.
current_ = current_->next; current_ = current_->next;
#ifdef DEBUG
DCHECK_EQ(current_, next_);
next_ = current_ ? current_->next : nullptr;
#endif
return *this; return *this;
} }
const_iterator operator++(int); const_iterator operator++(int);
...@@ -613,9 +626,19 @@ class Node::Uses::const_iterator final { ...@@ -613,9 +626,19 @@ class Node::Uses::const_iterator final {
friend class Node::Uses; friend class Node::Uses;
const_iterator() : current_(nullptr) {} const_iterator() : current_(nullptr) {}
explicit const_iterator(Node* node) : current_(node->first_use_) {} explicit const_iterator(Node* node)
: current_(node->first_use_)
#ifdef DEBUG
,
next_(current_ ? current_->next : nullptr)
#endif
{
}
Node::Use* current_; Node::Use* current_;
#ifdef DEBUG
Node::Use* next_;
#endif
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment