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:
Sean Stangl 2017-12-13 15:56:29 -06:00
Родитель df4406437b
Коммит db486799ac
2 изменённых файлов: 19 добавлений и 14 удалений

Просмотреть файл

@ -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;