Bug 1518565 - Flush the instruction cache when patching OSIPoints. r=sstangl
authorNicolas B. Pierron <nicolas.b.pierron@nbp.name>
Thu, 10 Jan 2019 19:42:11 +0100
changeset 514188 68c3af3df20efad7faab88f7852b5842fb97f5f8
parent 514187 1e7a80d93de52175695270169634e3a51134b9d7
child 514189 706add84af1aefd035b2450d08ac1d7c0d658b4f
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstangl
bugs1518565
milestone66.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 1518565 - Flush the instruction cache when patching OSIPoints. r=sstangl
js/src/jit/arm64/Assembler-arm64.cpp
js/src/jit/arm64/Assembler-arm64.h
js/src/jit/arm64/MacroAssembler-arm64.cpp
--- a/js/src/jit/arm64/Assembler-arm64.cpp
+++ b/js/src/jit/arm64/Assembler-arm64.cpp
@@ -372,16 +372,30 @@ void PatchJump(CodeLocationJump& jump_, 
   // FIXME: That assumption implies that the branch target is always in-range.
   if (branch->IsTargetReachable((Instruction*)label.raw())) {
     branch->SetImmPCOffsetTarget((Instruction*)label.raw());
   } else {
     MOZ_CRASH("PatchJump target not reachable");
   }
 }
 
+void Assembler::PatchWrite_NearCall(CodeLocationLabel start,
+                                    CodeLocationLabel toCall) {
+  Instruction* dest = (Instruction*)start.raw();
+  ptrdiff_t relTarget = (Instruction*)toCall.raw() - dest;
+  ptrdiff_t relTarget00 = relTarget >> 2;
+  MOZ_RELEASE_ASSERT((relTarget & 0x3) == 0);
+  MOZ_RELEASE_ASSERT(vixl::is_int26(relTarget00));
+
+  // printf("patching %p with call to %p\n", start.raw(), toCall.raw());
+  bl(dest, relTarget00);
+
+  AutoFlushICache::flush(uintptr_t(dest), 4);
+}
+
 void Assembler::PatchDataWithValueCheck(CodeLocationLabel label,
                                         PatchedImmPtr newValue,
                                         PatchedImmPtr expected) {
   Instruction* i = (Instruction*)label.raw();
   void** pValue = i->LiteralAddress<void**>();
   MOZ_ASSERT(*pValue == expected.value);
   *pValue = newValue.value;
 }
--- a/js/src/jit/arm64/Assembler-arm64.h
+++ b/js/src/jit/arm64/Assembler-arm64.h
@@ -314,21 +314,17 @@ class Assembler : public vixl::Assembler
   size_t addPatchableJump(BufferOffset src, RelocationKind kind);
 
  public:
   static uint32_t PatchWrite_NearCallSize() { return 4; }
 
   static uint32_t NopSize() { return 4; }
 
   static void PatchWrite_NearCall(CodeLocationLabel start,
-                                  CodeLocationLabel toCall) {
-    Instruction* dest = (Instruction*)start.raw();
-    // printf("patching %p with call to %p\n", start.raw(), toCall.raw());
-    bl(dest, ((Instruction*)toCall.raw() - dest) >> 2);
-  }
+                                  CodeLocationLabel toCall);
   static void PatchDataWithValueCheck(CodeLocationLabel label,
                                       PatchedImmPtr newValue,
                                       PatchedImmPtr expected);
 
   static void PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
                                       ImmPtr expected);
 
   static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm) {
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -661,17 +661,22 @@ void MacroAssembler::call(JitCode* c) {
 
 CodeOffset MacroAssembler::callWithPatch() {
   bl(0, LabelDoc());
   return CodeOffset(currentOffset());
 }
 void MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset) {
   Instruction* inst = getInstructionAt(BufferOffset(callerOffset - 4));
   MOZ_ASSERT(inst->IsBL());
-  bl(inst, ((int)calleeOffset - ((int)callerOffset - 4)) >> 2);
+  ptrdiff_t relTarget = (int)calleeOffset - ((int)callerOffset - 4);
+  ptrdiff_t relTarget00 = relTarget >> 2;
+  MOZ_RELEASE_ASSERT((relTarget & 0x3) == 0);
+  MOZ_RELEASE_ASSERT(vixl::is_int26(relTarget00));
+  bl(inst, relTarget00);
+  AutoFlushICache::flush(uintptr_t(inst), 4);
 }
 
 CodeOffset MacroAssembler::farJumpWithPatch() {
   vixl::UseScratchRegisterScope temps(this);
   const ARMRegister scratch = temps.AcquireX();
   const ARMRegister scratch2 = temps.AcquireX();
 
   AutoForbidPools afp(this, /* max number of instructions in scope = */ 7);