[INFER] Fail compilation rather than assert if a constant pool is dumped while generating an IC, bug 669715.

This commit is contained in:
Brian Hackett 2011-09-15 12:11:03 -07:00
parent df83129530
commit 42f96c43bb
6 changed files with 26 additions and 56 deletions

View File

@ -947,12 +947,10 @@ namespace JSC {
return m_buffer.sizeOfConstantPool();
}
#ifdef DEBUG
void allowPoolFlush(bool allowFlush)
int flushCount()
{
m_buffer.allowPoolFlush(allowFlush);
return m_buffer.flushCount();
}
#endif
JmpDst label()
{

View File

@ -106,9 +106,7 @@ public:
, m_numConsts(0)
, m_maxDistance(maxPoolSize)
, m_lastConstDelta(0)
#ifdef DEBUG
, m_allowFlush(true)
#endif
, m_flushCount(0)
{
m_pool = static_cast<uint32_t*>(malloc(maxPoolSize));
m_mask = static_cast<char*>(malloc(maxPoolSize / sizeof(uint32_t)));
@ -241,14 +239,10 @@ public:
return m_numConsts;
}
#ifdef DEBUG
// Guard constant pool flushes to ensure that they don't occur during
// regions where offsets into the code have to be maintained (such as PICs).
void allowPoolFlush(bool allowFlush)
int flushCount()
{
m_allowFlush = allowFlush;
return m_flushCount;
}
#endif
private:
void correctDeltas(int insnSize)
@ -273,9 +267,9 @@ private:
{
js::JaegerSpew(js::JSpew_Insns, " -- FLUSHING CONSTANT POOL WITH %d CONSTANTS --\n",
m_numConsts);
ASSERT(m_allowFlush);
if (m_numConsts == 0)
return;
m_flushCount++;
int alignPool = (AssemblerBuffer::size() + (useBarrier ? barrierSize : 0)) & (sizeof(uint64_t) - 1);
if (alignPool)
@ -339,10 +333,7 @@ private:
int m_numConsts;
int m_maxDistance;
int m_lastConstDelta;
#ifdef DEBUG
bool m_allowFlush;
#endif
int m_flushCount;
};
} // namespace JSC

View File

@ -1380,12 +1380,10 @@ public:
m_assembler.forceFlushConstantPool();
}
#ifdef DEBUG
void allowPoolFlush(bool allowFlush)
int flushCount()
{
m_assembler.allowPoolFlush(allowFlush);
return m_assembler.flushCount();
}
#endif
protected:
ARMAssembler::Condition ARMCondition(Condition cond)

View File

@ -228,67 +228,43 @@ class AutoReserveICSpace {
typedef Assembler::Label Label;
Assembler &masm;
#ifdef DEBUG
Label startLabel;
bool didCheck;
#endif
bool *overflowSpace;
int flushCount;
public:
AutoReserveICSpace(Assembler &masm) : masm(masm) {
AutoReserveICSpace(Assembler &masm, bool *overflowSpace)
: masm(masm), didCheck(false), overflowSpace(overflowSpace)
{
masm.ensureSpace(reservedSpace);
#ifdef DEBUG
didCheck = false;
startLabel = masm.label();
/* Assert that the constant pool is not flushed until we reach a safe point. */
masm.allowPoolFlush(false);
JaegerSpew(JSpew_Insns, " -- BEGIN CONSTANT-POOL-FREE REGION -- \n");
#endif
flushCount = masm.flushCount();
}
/* Allow manual IC space checks so that non-patchable code at the end of an IC section can be
* free to use constant pools. */
void check() {
#ifdef DEBUG
JS_ASSERT(!didCheck);
didCheck = true;
Label endLabel = masm.label();
int spaceUsed = masm.differenceBetween(startLabel, endLabel);
/* Spew the space used, to help tuning of reservedSpace. */
JaegerSpew(JSpew_Insns,
" -- END CONSTANT-POOL-FREE REGION: %u bytes used of %u reserved. -- \n",
spaceUsed, reservedSpace);
/* Assert that we didn't emit more code than we protected. */
JS_ASSERT(spaceUsed >= 0);
JS_ASSERT(size_t(spaceUsed) <= reservedSpace);
/* Allow the pool to be flushed. */
masm.allowPoolFlush(true);
#endif
if (masm.flushCount() != flushCount)
*overflowSpace = true;
}
~AutoReserveICSpace() {
#ifdef DEBUG
/* Automatically check the IC space if we didn't already do it manually. */
if (!didCheck) {
check();
}
#endif
}
};
# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<256> arics(__masm)
# define RESERVE_IC_SPACE(__masm) AutoReserveICSpace<256> arics(__masm, &this->overflowICSpace)
# define CHECK_IC_SPACE() arics.check()
/* The OOL path can need a lot of space because we save and restore a lot of registers. The actual
* sequene varies. However, dumping the literal pool before an OOL block is probably a good idea
* anyway, as we branch directly to the start of the block from the fast path. */
# define RESERVE_OOL_SPACE(__masm) AutoReserveICSpace<2048> arics_ool(__masm)
# define RESERVE_OOL_SPACE(__masm) AutoReserveICSpace<2048> arics_ool(__masm, &this->overflowICSpace)
/* Allow the OOL patch to be checked before object destruction. Often, non-patchable epilogues or
* rejoining sequences are emitted, and it isn't necessary to protect these from literal pools. */

View File

@ -133,6 +133,7 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructi
inlining_(false),
hasGlobalReallocation(false),
oomInVector(false),
overflowICSpace(false),
gcNumber(cx->runtime->gcNumber),
applyTricks(NoApplyTricks),
pcLengths(NULL)
@ -894,6 +895,11 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
if (cx->runtime->gcNumber != gcNumber)
return Compile_Retry;
if (overflowICSpace) {
JaegerSpew(JSpew_Scripts, "dumped a constant pool while generating an IC\n");
return Compile_Abort;
}
for (size_t i = 0; i < branchPatches.length(); i++) {
Label label = labelOf(branchPatches[i].pc, branchPatches[i].inlineIndex);
branchPatches[i].jump.linkTo(label, &masm);

View File

@ -472,6 +472,7 @@ class Compiler : public BaseCompiler
bool inlining_;
bool hasGlobalReallocation;
bool oomInVector; // True if we have OOM'd appending to a vector.
bool overflowICSpace; // True if we added a constant pool in a reserved space.
uint32 gcNumber;
enum { NoApplyTricks, LazyArgsObj } applyTricks;
PCLengthEntry *pcLengths;