[tbb-commits] [tor-browser] 43/73: Bug 1777604 - wasm: Perform a pipeline flush while creating a module object. r=nbp, a=RyanVM

gitolite role git at cupani.torproject.org
Wed Sep 21 20:17:36 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch geckoview-102.3.0esr-12.0-1
in repository tor-browser.

commit de088a7d3653bce96dd83bb78e0e74954dcea312
Author: Ryan Hunt <rhunt at eqrion.net>
AuthorDate: Thu Jul 28 13:27:02 2022 +0000

    Bug 1777604 - wasm: Perform a pipeline flush while creating a module object. r=nbp, a=RyanVM
    
    Differential Revision: https://phabricator.services.mozilla.com/D152304
---
 js/src/jit/FlushICache.h                | 27 +++++++++++++++++++++++++++
 js/src/jit/arm/Architecture-arm.cpp     | 10 ++++++++++
 js/src/jit/arm64/Architecture-arm64.cpp |  2 ++
 js/src/jit/arm64/vixl/Cpu-vixl.h        |  4 ++++
 js/src/jit/arm64/vixl/MozCpu-vixl.cpp   | 17 +++++++++++++++++
 js/src/wasm/WasmJS.cpp                  | 11 +++++++++++
 6 files changed, 71 insertions(+)

diff --git a/js/src/jit/FlushICache.h b/js/src/jit/FlushICache.h
index 42b1fb045ce6d..6c780e43e8665 100644
--- a/js/src/jit/FlushICache.h
+++ b/js/src/jit/FlushICache.h
@@ -40,6 +40,33 @@ inline void FlushICache(void* code, size_t size,
 #  error "Unknown architecture!"
 #endif
 
+#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) ||       \
+    (defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)) || \
+    defined(JS_CODEGEN_LOONG64)
+
+inline void FlushExecutionContext() {
+  // No-op. Execution context is coherent with instruction cache.
+}
+
+#elif defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_WASM32)
+
+inline void FlushExecutionContext() { MOZ_CRASH(); }
+
+#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
+
+// ARM and ARM64 must flush the instruction pipeline of the current core
+// before executing newly JIT'ed code. This will remove any stale data from
+// the pipeline that may have referenced invalidated instructions.
+//
+// `FlushICache` will perform this for the thread that compiles the code, but
+// other threads that may execute the code are responsible to call
+// this method.
+extern void FlushExecutionContext();
+
+#else
+#  error "Unknown architecture!"
+#endif
+
 }  // namespace jit
 }  // namespace js
 
diff --git a/js/src/jit/arm/Architecture-arm.cpp b/js/src/jit/arm/Architecture-arm.cpp
index 324942f67c264..2491c67350146 100644
--- a/js/src/jit/arm/Architecture-arm.cpp
+++ b/js/src/jit/arm/Architecture-arm.cpp
@@ -527,5 +527,15 @@ void FlushICache(void* code, size_t size, bool codeIsThreadLocal) {
 #endif
 }
 
+void FlushExecutionContext() {
+#ifndef JS_SIMULATOR_ARM
+  // Ensure that any instructions already in the pipeline are discarded and
+  // reloaded from the icache.
+  asm volatile("isb\n" : : : "memory");
+#else
+  // We assume the icache flushing routines on other platforms take care of this
+#endif
+}
+
 }  // namespace jit
 }  // namespace js
diff --git a/js/src/jit/arm64/Architecture-arm64.cpp b/js/src/jit/arm64/Architecture-arm64.cpp
index 3249acc6fb346..f95c0231d84d3 100644
--- a/js/src/jit/arm64/Architecture-arm64.cpp
+++ b/js/src/jit/arm64/Architecture-arm64.cpp
@@ -127,5 +127,7 @@ bool CanFlushICacheFromBackgroundThreads() {
   return vixl::CPU::CanFlushICacheFromBackgroundThreads();
 }
 
+void FlushExecutionContext() { vixl::CPU::FlushExecutionContext(); }
+
 }  // namespace jit
 }  // namespace js
diff --git a/js/src/jit/arm64/vixl/Cpu-vixl.h b/js/src/jit/arm64/vixl/Cpu-vixl.h
index f2bb6f6dbc096..ac709bccbf2a6 100644
--- a/js/src/jit/arm64/vixl/Cpu-vixl.h
+++ b/js/src/jit/arm64/vixl/Cpu-vixl.h
@@ -171,6 +171,10 @@ class CPU {
   // cache on a background thread.
   static bool CanFlushICacheFromBackgroundThreads();
 
+  // Flush the local instruction pipeline, forcing a reload of any instructions
+  // beyond this barrier from the icache.
+  static void FlushExecutionContext();
+
   // Read and interpret the ID registers. This requires
   // CPUFeatures::kIDRegisterEmulation, and therefore cannot be called on
   // non-AArch64 platforms.
diff --git a/js/src/jit/arm64/vixl/MozCpu-vixl.cpp b/js/src/jit/arm64/vixl/MozCpu-vixl.cpp
index 9766bee3b7f9e..ad96098501679 100644
--- a/js/src/jit/arm64/vixl/MozCpu-vixl.cpp
+++ b/js/src/jit/arm64/vixl/MozCpu-vixl.cpp
@@ -294,4 +294,21 @@ void CPU::EnsureIAndDCacheCoherency(void *address, size_t length, bool codeIsThr
 #endif
 }
 
+void CPU::FlushExecutionContext() {
+#if defined(JS_SIMULATOR_ARM64) && defined(JS_CACHE_SIMULATOR_ARM64)
+  // Performing an 'isb' will ensure the current core instruction pipeline is
+  // synchronized with an icache flush executed by another core.
+  using js::jit::SimulatorProcess;
+  js::jit::AutoLockSimulatorCache alsc;
+  Simulator* sim = vixl::Simulator::Current();
+  if (sim) {
+    sim->FlushICache();
+  }
+#elif defined(__aarch64__)
+  // Ensure that any instructions already in the pipeline are discarded and
+  // reloaded from the icache.
+  __asm__ __volatile__("isb\n" : : : "memory");
+#endif
+}
+
 }  // namespace vixl
diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp
index 5e472833bf8da..bb97ef87b3cab 100644
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -31,6 +31,7 @@
 #include "ds/IdValuePair.h"  // js::IdValuePair
 #include "gc/GCContext.h"
 #include "jit/AtomicOperations.h"
+#include "jit/FlushICache.h"
 #include "jit/JitContext.h"
 #include "jit/JitOptions.h"
 #include "jit/Simulator.h"
@@ -1727,6 +1728,16 @@ WasmModuleObject* WasmModuleObject::create(JSContext* cx, const Module& module,
     return nullptr;
   }
 
+  // The pipeline state on some architectures may retain stale instructions
+  // even after we invalidate the instruction cache. There is no generally
+  // available method to broadcast this pipeline flush to all threads after
+  // we've compiled new code, so conservatively perform one here when we're
+  // receiving a module that may have been compiled from another thread.
+  //
+  // The cost of this flush is expected to minimal enough to not be worth
+  // optimizing away in the case the module was compiled on this thread.
+  jit::FlushExecutionContext();
+
   // This accounts for module allocation size (excluding code which is handled
   // separately - see below). This assumes that the size of associated data
   // doesn't change for the life of the WasmModuleObject. The size is counted

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list