Files
sdk/runtime/vm/bit_vector.cc
T
Samir Jindel eff1a9ff97 Re-land "[vm] Aggressive write-barrier elimination."
The original revision is in Patchset 3.

Four bugs were fixed:

1. JoinEntryInstr::SuccessorCount() is not the correct way to get the
   number of successor blocks from the Join block;
   JoinEntryInstr::last_instruction()->SuccessorCount() must be used
   instead.

2. BitVector::Equals() was non-deterministically returning 'false'
   for equal vectors.

3. All blocks need to be processed at least once during the Analysis
   phase (not only in the SaveResults phase).

4. We were not removing write barriers from StoreIndexed instructions,
   even though we had support for it.

This reverts commit 7fd8ad5a2d.

Fixes https://github.com/dart-lang/sdk/issues/40780

Change-Id: I9650ec2c547ec49cf88ca0524e14f6c245621f6a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138086
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-03-09 14:37:27 +00:00

116 lines
2.9 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/bit_vector.h"
#include "vm/log.h"
#include "vm/os.h"
namespace dart {
void BitVector::Iterator::Advance() {
++bit_index_;
// Skip zero words.
if (current_word_ == 0) {
do {
++word_index_;
if (Done()) return;
current_word_ = target_->data_[word_index_];
} while (current_word_ == 0);
bit_index_ = word_index_ * kBitsPerWord;
}
// Skip zero bytes.
while ((current_word_ & 0xff) == 0) {
current_word_ >>= 8;
bit_index_ += 8;
}
// Skip zero bits.
while ((current_word_ & 0x1) == 0) {
current_word_ >>= 1;
++bit_index_;
}
current_word_ = current_word_ >> 1;
}
bool BitVector::Equals(const BitVector& other) const {
if (length_ != other.length_) return false;
intptr_t i = 0;
for (; i < data_length_ - 1; i++) {
if (data_[i] != other.data_[i]) return false;
}
if (i < data_length_) {
// Don't compare bits beyond length_.
const intptr_t shift_size = kBitsPerWord - (length_ % kBitsPerWord);
const uword mask = static_cast<uword>(-1) >> shift_size;
if ((data_[i] & mask) != (other.data_[i] & mask)) return false;
}
return true;
}
bool BitVector::AddAll(const BitVector* from) {
ASSERT(data_length_ == from->data_length_);
bool changed = false;
for (intptr_t i = 0; i < data_length_; i++) {
const uword before = data_[i];
const uword after = data_[i] | from->data_[i];
if (before != after) {
changed = true;
data_[i] = after;
}
}
return changed;
}
bool BitVector::RemoveAll(const BitVector* from) {
ASSERT(data_length_ == from->data_length_);
bool changed = false;
for (intptr_t i = 0; i < data_length_; i++) {
const uword before = data_[i];
const uword after = data_[i] & ~from->data_[i];
if (before != after) {
changed = true;
data_[i] = after;
}
}
return changed;
}
bool BitVector::KillAndAdd(BitVector* kill, BitVector* gen) {
ASSERT(data_length_ == kill->data_length_);
ASSERT(data_length_ == gen->data_length_);
bool changed = false;
for (intptr_t i = 0; i < data_length_; i++) {
const uword before = data_[i];
const uword after = data_[i] | (gen->data_[i] & ~kill->data_[i]);
if (before != after) changed = true;
data_[i] = after;
}
return changed;
}
void BitVector::Intersect(const BitVector* other) {
ASSERT(other->length() == length());
for (intptr_t i = 0; i < data_length_; i++) {
data_[i] = data_[i] & other->data_[i];
}
}
bool BitVector::IsEmpty() const {
for (intptr_t i = 0; i < data_length_; i++) {
if (data_[i] != 0) {
return false;
}
}
return true;
}
void BitVector::Print() const {
THR_Print("[");
for (intptr_t i = 0; i < length_; i++) {
THR_Print(Contains(i) ? "1" : "0");
}
THR_Print("]");
}
} // namespace dart