Commit 6720893e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Do initial-increfs at the done-guarding point

(if the variable is defined before then)
otherwise we would try to incref the variable before guards which would fail the rewrite.
parent cf2b8afb
......@@ -1177,18 +1177,28 @@ RewriterVar* RewriterVar::setType(RefType type) {
assert(this->reftype == RefType::UNKNOWN || this->reftype == type);
if (this->reftype == RefType::UNKNOWN) {
rewriter->addAction([=]() {
int num_needed_refs = this->num_refs_consumed - (this->refHandedOff() ? 1 : 0);
assert(num_needed_refs >= 0);
if (num_needed_refs > 0) {
// XXX do a single add instead of multiple incs
for (int i = 0; i < num_needed_refs; i++) {
this->rewriter->_incref(this);
rewriter->addAction(
[=]() {
int num_needed_refs = this->num_refs_consumed - (this->refHandedOff() ? 1 : 0);
assert(num_needed_refs >= 0);
if (num_needed_refs > 0) {
if (rewriter->isDoneGuarding()) {
assert(num_needed_refs == 1); // not bad just curious
// XXX do a single add instead of multiple incs
for (int i = 0; i < num_needed_refs; i++) {
this->rewriter->_incref(this);
}
} else {
rewriter->pending_increfs.push_back(std::make_pair(this, num_needed_refs));
}
}
}
this->bumpUse();
}, { this }, ActionType::MUTATION);
this->bumpUse();
// Register this as a NORMAL (ie non-MUTATION) action since we will be careful to not do any mutations
// if we are still in the guarding phase.
},
{ this }, ActionType::NORMAL);
this->reftype = type;
}
......@@ -1219,7 +1229,6 @@ void RewriterVar::_release() {
void RewriterVar::refConsumed() {
num_refs_consumed++;
last_refconsumed_numuses = uses.size();
// Maybe emit an incref here to make debugging more clear?
}
void RewriterVar::bumpUse() {
......@@ -1308,6 +1317,13 @@ void Rewriter::commit() {
arg->_release();
}
}
for (auto&& p : pending_increfs) {
// TODO use a single add rather than N inc's
for (int i = 0; i < p.second; i++) {
_incref(p.first);
}
}
assertConsistent();
};
......
......@@ -396,6 +396,9 @@ private:
// This needs to be the first member:
RegionAllocator allocator;
// Increfs that we thought of doing during the guarding phase that we were able to put off.
std::vector<std::pair<RewriterVar*, int>> pending_increfs;
protected:
// Allocates `bytes` bytes of data. The allocation will get freed when the rewriter gets freed.
void* regionAlloc(size_t bytes) { return allocator.alloc(bytes); }
......
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