From 2331ad205ec29ff0ce4ca5c0478b060ff80288e1 Mon Sep 17 00:00:00 2001 From: Jacob Bramley Date: Mon, 6 Dec 2010 11:07:37 +0000 Subject: [PATCH] Extend the IC protection introduced by bug 614323. [Bug 615875] [r=cdleary] --- js/src/assembler/assembler/ARMAssembler.h | 7 +++++++ .../AssemblerBufferWithConstantPool.h | 18 ++++++++++++++++++ js/src/assembler/assembler/MacroAssemblerARM.h | 7 +++++++ js/src/methodjit/BaseCompiler.h | 17 ++++++++++++++++- 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/js/src/assembler/assembler/ARMAssembler.h b/js/src/assembler/assembler/ARMAssembler.h index 2ac35740b04..1d5a66190d0 100644 --- a/js/src/assembler/assembler/ARMAssembler.h +++ b/js/src/assembler/assembler/ARMAssembler.h @@ -932,6 +932,13 @@ namespace JSC { return m_buffer.sizeOfConstantPool(); } +#ifdef DEBUG + void allowPoolFlush(bool allowFlush) + { + m_buffer.allowPoolFlush(allowFlush); + } +#endif + JmpDst label() { JmpDst label(m_buffer.size()); diff --git a/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h b/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h index 66c927a2655..8b853a16149 100644 --- a/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h +++ b/js/src/assembler/assembler/AssemblerBufferWithConstantPool.h @@ -37,6 +37,7 @@ #include "AssemblerBuffer.h" #include "assembler/wtf/SegmentedVector.h" +#include "assembler/wtf/Assertions.h" #define ASSEMBLER_HAS_CONSTANT_POOL 1 @@ -103,6 +104,9 @@ public: , m_numConsts(0) , m_maxDistance(maxPoolSize) , m_lastConstDelta(0) +#ifdef DEBUG + , m_allowFlush(true) +#endif { m_pool = static_cast(malloc(maxPoolSize)); m_mask = static_cast(malloc(maxPoolSize / sizeof(uint32_t))); @@ -235,6 +239,15 @@ 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) + { + m_allowFlush = allowFlush; + } +#endif + private: void correctDeltas(int insnSize) { @@ -254,6 +267,7 @@ private: void flushConstantPool(bool useBarrier = true) { + ASSERT(m_allowFlush); if (m_numConsts == 0) return; int alignPool = (AssemblerBuffer::size() + (useBarrier ? barrierSize : 0)) & (sizeof(uint64_t) - 1); @@ -313,6 +327,10 @@ private: int m_numConsts; int m_maxDistance; int m_lastConstDelta; + +#ifdef DEBUG + bool m_allowFlush; +#endif }; } // namespace JSC diff --git a/js/src/assembler/assembler/MacroAssemblerARM.h b/js/src/assembler/assembler/MacroAssemblerARM.h index 0f614850d1c..67539e1b1b4 100644 --- a/js/src/assembler/assembler/MacroAssemblerARM.h +++ b/js/src/assembler/assembler/MacroAssemblerARM.h @@ -1078,6 +1078,13 @@ public: m_assembler.forceFlushConstantPool(); } +#ifdef DEBUG + void allowPoolFlush(bool allowFlush) + { + m_assembler.allowPoolFlush(allowFlush); + } +#endif + protected: ARMAssembler::Condition ARMCondition(Condition cond) { diff --git a/js/src/methodjit/BaseCompiler.h b/js/src/methodjit/BaseCompiler.h index 8b10814f0d5..6717e93ed31 100644 --- a/js/src/methodjit/BaseCompiler.h +++ b/js/src/methodjit/BaseCompiler.h @@ -207,7 +207,7 @@ class Repatcher : public JSC::RepatchBuffer #ifdef JS_CPU_ARM class AutoReserveICSpace { typedef Assembler::Label Label; - static const size_t reservedSpace = 64; + static const size_t reservedSpace = 68; Assembler &masm; #ifdef DEBUG @@ -219,6 +219,11 @@ class AutoReserveICSpace { masm.ensureSpace(reservedSpace); #ifdef DEBUG 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 } @@ -226,8 +231,18 @@ class AutoReserveICSpace { #ifdef DEBUG 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 } };