зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1393011 - Part 3: Fix a bug where BufferInstructionIterator advances too far. r=nbp
In the case of InstIsGuard(), the BufferInstructionIterator implementation forgot that the underlying AssemblerBufferInstIterator is based on BufferOffsets, the incrementation of which skips pools already. --HG-- extra : histedit_source : c0520c1e7d4ab4a65d4546ee196192f2164c32a3
This commit is contained in:
Родитель
df4406437b
Коммит
db486799ac
|
@ -3289,26 +3289,21 @@ Instruction::maybeSkipAutomaticInstructions()
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Instruction*
|
||||||
BufferInstructionIterator::maybeSkipAutomaticInstructions()
|
BufferInstructionIterator::maybeSkipAutomaticInstructions()
|
||||||
{
|
{
|
||||||
|
const PoolHeader* ph;
|
||||||
// If this is a guard, and the next instruction is a header, always work
|
// If this is a guard, and the next instruction is a header, always work
|
||||||
// around the pool. If it isn't a guard, then start looking ahead.
|
// around the pool. If it isn't a guard, then start looking ahead.
|
||||||
|
|
||||||
const PoolHeader* ph;
|
|
||||||
if (InstIsGuard(*this, &ph)) {
|
if (InstIsGuard(*this, &ph)) {
|
||||||
// Don't skip a natural guard.
|
// Don't skip a natural guard.
|
||||||
if (ph->isNatural())
|
if (ph->isNatural())
|
||||||
return;
|
return cur();
|
||||||
advance(sizeof(Instruction) * (1 + ph->size()));
|
return next();
|
||||||
maybeSkipAutomaticInstructions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InstIsBNop(cur())) {
|
|
||||||
next();
|
|
||||||
maybeSkipAutomaticInstructions();
|
|
||||||
}
|
}
|
||||||
|
if (InstIsBNop(cur()))
|
||||||
|
return next();
|
||||||
|
return cur();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cases to be handled:
|
// Cases to be handled:
|
||||||
|
|
|
@ -1137,7 +1137,6 @@ PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitZoneGroup::Ba
|
||||||
PatchJump(jump_, label);
|
PatchJump(jump_, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
class InstructionIterator;
|
|
||||||
class Assembler;
|
class Assembler;
|
||||||
typedef js::jit::AssemblerBufferWithConstantPools<1024, 4, Instruction, Assembler> ARMBuffer;
|
typedef js::jit::AssemblerBufferWithConstantPools<1024, 4, Instruction, Assembler> ARMBuffer;
|
||||||
|
|
||||||
|
@ -2290,13 +2289,24 @@ class InstructionIterator
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Compile-time iterator over instructions, with a safe interface that
|
||||||
|
// references not-necessarily-linear Instructions by linear BufferOffset.
|
||||||
class BufferInstructionIterator : public ARMBuffer::AssemblerBufferInstIterator
|
class BufferInstructionIterator : public ARMBuffer::AssemblerBufferInstIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BufferInstructionIterator(BufferOffset bo, ARMBuffer* buffer)
|
BufferInstructionIterator(BufferOffset bo, ARMBuffer* buffer)
|
||||||
: ARMBuffer::AssemblerBufferInstIterator(bo, buffer)
|
: ARMBuffer::AssemblerBufferInstIterator(bo, buffer)
|
||||||
{}
|
{}
|
||||||
void maybeSkipAutomaticInstructions();
|
|
||||||
|
// Advances the buffer to the next intentionally-inserted instruction.
|
||||||
|
Instruction* next() {
|
||||||
|
advance(cur()->size());
|
||||||
|
maybeSkipAutomaticInstructions();
|
||||||
|
return cur();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advances the BufferOffset past any automatically-inserted instructions.
|
||||||
|
Instruction* maybeSkipAutomaticInstructions();
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t NumIntArgRegs = 4;
|
static const uint32_t NumIntArgRegs = 4;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче