本文整理汇总了C++中FrameEntry::setNotCopied方法的典型用法代码示例。如果您正苦于以下问题:C++ FrameEntry::setNotCopied方法的具体用法?C++ FrameEntry::setNotCopied怎么用?C++ FrameEntry::setNotCopied使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FrameEntry
的用法示例。
在下文中一共展示了FrameEntry::setNotCopied方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: local
void
FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange)
{
FrameEntry *localFe = getLocal(n);
bool cacheable = !eval && !escaping[n];
if (!popGuaranteed && !cacheable) {
JS_ASSERT_IF(base[localIndex(n)] && (!eval || n < script->nfixed),
entries[localIndex(n)].type.inMemory() &&
entries[localIndex(n)].data.inMemory());
Address local(JSFrameReg, sizeof(JSStackFrame) + n * sizeof(Value));
storeTo(peek(-1), local, false);
forgetAllRegs(getLocal(n));
localFe->resetSynced();
return;
}
bool wasSynced = localFe->type.synced();
/* Detect something like (x = x) which is a no-op. */
FrameEntry *top = peek(-1);
if (top->isCopy() && top->copyOf() == localFe) {
JS_ASSERT(localFe->isCopied());
return;
}
/* Completely invalidate the local variable. */
if (localFe->isCopied()) {
uncopy(localFe);
if (!localFe->isCopied())
forgetAllRegs(localFe);
} else {
forgetAllRegs(localFe);
}
localFe->resetUnsynced();
/* Constants are easy to propagate. */
if (top->isConstant()) {
localFe->setCopyOf(NULL);
localFe->setNotCopied();
localFe->setConstant(Jsvalify(top->getValue()));
return;
}
/*
* When dealing with copies, there are two important invariants:
*
* 1) The backing store precedes all copies in the tracker.
* 2) The backing store of a local is never a stack slot, UNLESS the local
* variable itself is a stack slot (blocks) that precedes the stack
* slot.
*
* If the top is a copy, and the second condition holds true, the local
* can be rewritten as a copy of the original backing slot. If the first
* condition does not hold, force it to hold by swapping in-place.
*/
FrameEntry *backing = top;
if (top->isCopy()) {
backing = top->copyOf();
JS_ASSERT(backing->trackerIndex() < top->trackerIndex());
uint32 backingIndex = indexOfFe(backing);
uint32 tol = uint32(spBase - base);
if (backingIndex < tol || backingIndex < localIndex(n)) {
/* local.idx < backing.idx means local cannot be a copy yet */
if (localFe->trackerIndex() < backing->trackerIndex())
swapInTracker(backing, localFe);
localFe->setNotCopied();
localFe->setCopyOf(backing);
if (backing->isTypeKnown())
localFe->setType(backing->getKnownType());
else
localFe->type.invalidate();
localFe->data.invalidate();
localFe->isNumber = backing->isNumber;
return;
}
/*
* If control flow lands here, then there was a bytecode sequence like
*
* ENTERBLOCK 2
* GETLOCAL 1
* SETLOCAL 0
*
* The problem is slot N can't be backed by M if M could be popped
* before N. We want a guarantee that when we pop M, even if it was
* copied, it has no outstanding copies.
*
* Because of |let| expressions, it's kind of hard to really know
* whether a region on the stack will be popped all at once. Bleh!
*
* This should be rare except in browser code (and maybe even then),
* but even so there's a quick workaround. We take all copies of the
* backing fe, and redirect them to be copies of the destination.
*/
FrameEntry *tos = tosFe();
for (uint32 i = backing->trackerIndex() + 1; i < tracker.nentries; i++) {
FrameEntry *fe = tracker[i];
//.........这里部分代码省略.........
示例2: tosFe
FrameEntry *
FrameState::uncopy(FrameEntry *original)
{
JS_ASSERT(original->isCopied());
/*
* Copies have two critical invariants:
* 1) The backing store precedes all copies in the tracker.
* 2) The backing store of a copy cannot be popped from the stack
* while the copy is still live.
*
* Maintaining this invariant iteratively is kind of hard, so we choose
* the "lowest" copy in the frame up-front.
*
* For example, if the stack is:
* [A, B, C, D]
* And the tracker has:
* [A, D, C, B]
*
* If B, C, and D are copies of A - we will walk the tracker to the end
* and select D, not B (see bug 583684).
*/
uint32 firstCopy = InvalidIndex;
FrameEntry *tos = tosFe();
FrameEntry *bestFe = NULL;
uint32 ncopies = 0;
for (uint32 i = 0; i < tracker.nentries; i++) {
FrameEntry *fe = tracker[i];
if (fe >= tos)
continue;
if (fe->isCopy() && fe->copyOf() == original) {
if (firstCopy == InvalidIndex) {
firstCopy = i;
bestFe = fe;
} else if (fe < bestFe) {
bestFe = fe;
}
ncopies++;
}
}
if (!ncopies) {
JS_ASSERT(firstCopy == InvalidIndex);
JS_ASSERT(!bestFe);
original->copied = false;
return NULL;
}
JS_ASSERT(firstCopy != InvalidIndex);
JS_ASSERT(bestFe);
/* Mark all extra copies as copies of the new backing index. */
bestFe->setCopyOf(NULL);
if (ncopies > 1) {
bestFe->setCopied();
for (uint32 i = firstCopy; i < tracker.nentries; i++) {
FrameEntry *other = tracker[i];
if (other >= tos || other == bestFe)
continue;
/* The original must be tracked before copies. */
JS_ASSERT(other != original);
if (!other->isCopy() || other->copyOf() != original)
continue;
other->setCopyOf(bestFe);
/*
* This is safe even though we're mutating during iteration. There
* are two cases. The first is that both indexes are <= i, and :.
* will never be observed. The other case is we're placing the
* other FE such that it will be observed later. Luckily, copyOf()
* will return != original, so nothing will happen.
*/
if (other->trackerIndex() < bestFe->trackerIndex())
swapInTracker(bestFe, other);
}
} else {
bestFe->setNotCopied();
}
FrameEntry *fe = bestFe;
/*
* Switch the new backing store to the old backing store. During
* this process we also necessarily make sure the copy can be
* synced.
*/
if (!original->isTypeKnown()) {
/*
* If the copy is unsynced, and the original is in memory,
* give the original a register. We do this below too; it's
* okay if it's spilled.
*/
if (original->type.inMemory() && !fe->type.synced())
tempRegForType(original);
fe->type.inherit(original->type);
if (fe->type.inRegister())
moveOwnership(fe->type.reg(), fe);
//.........这里部分代码省略.........