Bug 913216: Mark the entire heap to be flushed as soon as we start modifing bounds checks. (r=luke)
authorMarty Rosenberg <mrosenberg@mozilla.com>
Fri, 06 Sep 2013 05:14:44 -0400
changeset 158740 2a15f832f616761df9e79935ac1aca88e9ff53f6
parent 158739 547d6f20ecb20ef1301a01188c79adef482031c0
child 158741 10464d3d16cb64e335a154c6709ee0157ef10cf8
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs913216
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 913216: Mark the entire heap to be flushed as soon as we start modifing bounds checks. (r=luke)
js/src/jit/AsmJSModule.cpp
js/src/jit/Ion.cpp
js/src/jit/arm/Assembler-arm.cpp
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -28,21 +28,23 @@ AsmJSModule::patchHeapAccesses(ArrayBuff
 #if defined(JS_CPU_X86)
     void *heapOffset = (void*)heap->dataPointer();
     void *heapLength = (void*)heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchLengthAt(code_), heapLength);
         JSC::X86Assembler::setPointer(heapAccesses_[i].patchOffsetAt(code_), heapOffset);
     }
 #elif defined(JS_CPU_ARM)
-    jit::IonContext ic(cx, NULL);
-    jit::AutoFlushCache afc("patchBoundsCheck");
+
     uint32_t bits = mozilla::CeilingLog2(heap->byteLength());
     for (unsigned i = 0; i < heapAccesses_.length(); i++)
         jit::Assembler::updateBoundsCheck(bits, (jit::Instruction*)(heapAccesses_[i].offset() + code_));
+    // We already know the exact extent of areas that need to be patched, just make sure we
+    // flush all of them at once.
+    jit::AutoFlushCache::updateTop(uintptr_t(code_), pod.codeBytes_);
 #endif
 }
 
 static uint8_t *
 AllocateExecutableMemory(ExclusiveContext *cx, size_t totalBytes)
 {
     JS_ASSERT(totalBytes % AsmJSPageSize == 0);
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2584,17 +2584,17 @@ jit::UsesBeforeIonRecompile(JSScript *sc
     JS_ASSERT(loopDepth > 0);
     return minUses + loopDepth * 100;
 }
 
 void
 AutoFlushCache::updateTop(uintptr_t p, size_t len)
 {
     IonContext *ictx = GetIonContext();
-    IonRuntime *irt = ictx->runtime->ionRuntime();
+    IonRuntime *irt = (ictx != NULL) ? ictx->runtime->ionRuntime() : NULL;
     if (!irt || !irt->flusher())
         JSC::ExecutableAllocator::cacheFlush((void*)p, len);
     else
         irt->flusher()->update(p, len);
 }
 
 AutoFlushCache::AutoFlushCache(const char *nonce, IonRuntime *rt)
   : start_(0),
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -2736,17 +2736,18 @@ void Assembler::updateBoundsCheck(uint32
 
     Op2Reg reg = op.toOp2Reg();
     Register index;
     reg.getRM(&index);
     JS_ASSERT(reg.isO2RegImmShift());
     // O2RegImmShift shift = reg.toO2RegImmShift();
 
     *inst = InstALU(ScratchRegister, InvalidReg, lsr(index, logHeapSize), op_mov, SetCond, Always);
-    AutoFlushCache::updateTop(uintptr_t(inst), 4);
+    // NOTE: we don't update the Auto Flush Cache!  this function is currently only called from
+    // within AsmJSModule::patchHeapAccesses, which does that for us.  Don't call this!
 }
 
 void
 AutoFlushCache::update(uintptr_t newStart, size_t len)
 {
     uintptr_t newStop = newStart + len;
     used_ = true;
     if (!start_) {