Bug 1523993: Add JitOptions to disable wasm fast paths; r=luke
authorBenjamin Bouvier <benj@benj.me>
Thu, 31 Jan 2019 18:29:02 +0100
changeset 457553 6a66a76627b3c2ee0f01f738010a31ee6d0182c2
parent 457552 b34b924ce9c7f59c10078a5995613c2369a71f3d
child 457554 de9bc20a8ed58c9224319e73d76cc0bec6ed1f22
push id35515
push userrmaries@mozilla.com
push dateThu, 07 Feb 2019 21:44:23 +0000
treeherdermozilla-central@4e98200ee530 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1523993
milestone67.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 1523993: Add JitOptions to disable wasm fast paths; r=luke This adds a new configure option `--enable-wasm-codegen-debug`, which defaults to true in debug builds (disable otherwise). It's a first step so as to be able to use this in both the shell and browser, using the env variables JIT_OPTION_{JitOption field name}. Differential Revision: https://phabricator.services.mozilla.com/D18341
js/moz.configure
js/src/jit/JitOptions.cpp
js/src/jit/JitOptions.h
js/src/jit/MCallOptimize.cpp
js/src/wasm/WasmInstance.cpp
js/src/wasm/WasmJS.cpp
--- a/js/moz.configure
+++ b/js/moz.configure
@@ -510,8 +510,19 @@ def default_cranelift(is_nightly):
     return is_nightly
 
 js_option('--enable-cranelift',
           default=default_cranelift,
           help='{Enable|Disable} Cranelift code generator for wasm')
 
 set_config('ENABLE_WASM_CRANELIFT', depends_if('--enable-cranelift')(lambda x: True))
 set_define('ENABLE_WASM_CRANELIFT', depends_if('--enable-cranelift')(lambda x: True))
+
+
+# Support for debugging code generated by wasm backends
+# =====================================================
+
+js_option('--enable-wasm-codegen-debug',
+          default=depends(when=moz_debug)(lambda: True),
+          help='{Enable|Disable} debugging for wasm codegen')
+
+set_config('WASM_CODEGEN_DEBUG', depends_if('--enable-wasm-codegen-debug')(lambda x: True))
+set_define('WASM_CODEGEN_DEBUG', depends_if('--enable-wasm-codegen-debug')(lambda x: True))
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -268,16 +268,22 @@ DefaultJitOptions::DefaultJitOptions() {
 
 #ifdef JS_TRACE_LOGGING
   // Toggles whether the traceLogger should be on or off.  In either case,
   // some data structures will always be created and initialized such as
   // the traceLoggerState.  However, unless this option is set to true
   // the traceLogger will not be recording any events.
   SET_DEFAULT(enableTraceLogger, false);
 #endif
+
+#ifdef WASM_CODEGEN_DEBUG
+  SET_DEFAULT(enableWasmJitExit, true);
+  SET_DEFAULT(enableWasmJitEntry, true);
+  SET_DEFAULT(enableWasmIonFastCalls, true);
+#endif
 }
 
 bool DefaultJitOptions::isSmallFunction(JSScript* script) const {
   return script->length() <= smallFunctionMaxBytecodeLength_;
 }
 
 void DefaultJitOptions::enableGvn(bool enable) { disableGvn = !enable; }
 
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -70,16 +70,21 @@ struct DefaultJitOptions {
   bool fullDebugChecks;
   bool limitScriptSize;
   bool osr;
   bool wasmFoldOffsets;
   bool wasmDelayTier2;
 #ifdef JS_TRACE_LOGGING
   bool enableTraceLogger;
 #endif
+#ifdef WASM_CODEGEN_DEBUG
+  bool enableWasmJitExit;
+  bool enableWasmJitEntry;
+  bool enableWasmIonFastCalls;
+#endif
   uint32_t baselineWarmUpThreshold;
   uint32_t exceptionBailoutThreshold;
   uint32_t frequentBailoutThreshold;
   uint32_t maxStackArgs;
   uint32_t osrPcMismatchesBeforeRecompile;
   uint32_t smallFunctionMaxBytecodeLength_;
   uint32_t jumpThreshold;
   uint32_t branchPruningHitCountFactor;
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -4049,17 +4049,22 @@ IonBuilder::InliningResult IonBuilder::i
   auto bestTier = inst.code().bestTier();
   const wasm::FuncExport& funcExport =
       inst.metadata(bestTier).lookupFuncExport(funcIndex);
   const wasm::FuncType& sig = funcExport.funcType();
 
   // Check that the function doesn't take or return non-compatible JS
   // argument types before adding nodes to the MIR graph, otherwise they'd be
   // dead code.
-  if (sig.hasI64ArgOrRet() || sig.temporarilyUnsupportedAnyRef()) {
+  if (sig.hasI64ArgOrRet() ||
+      sig.temporarilyUnsupportedAnyRef()
+#ifdef WASM_CODEGEN_DEBUG
+      || !JitOptions.enableWasmIonFastCalls
+#endif
+     ) {
     return InliningStatus_NotInlined;
   }
 
   // If there are too many arguments, don't inline (we won't be able to store
   // the arguments in the LIR node).
   static constexpr size_t MaxNumInlinedArgs = 8;
   static_assert(MaxNumInlinedArgs <= MaxNumLInstructionOperands,
                 "inlined arguments can all be LIR operands");
--- a/js/src/wasm/WasmInstance.cpp
+++ b/js/src/wasm/WasmInstance.cpp
@@ -149,16 +149,22 @@ bool Instance::callImport(JSContext* cx,
   MOZ_ASSERT(cx->realm() == importFun->realm());
 
   RootedValue fval(cx, ObjectValue(*importFun));
   RootedValue thisv(cx, UndefinedValue());
   if (!Call(cx, fval, thisv, args, rval)) {
     return false;
   }
 
+#ifdef WASM_CODEGEN_DEBUG
+  if (!JitOptions.enableWasmJitEntry) {
+    return true;
+  }
+#endif
+
   // The import may already have become optimized.
   for (auto t : code().tiers()) {
     void* jitExitCode = codeBase(t) + fi.jitExitCodeOffset();
     if (import.code == jitExitCode) {
       return true;
     }
   }
 
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -1485,31 +1485,37 @@ static bool EnsureLazyEntryStub(const In
     }
     fun->setAsmJSIndex(funcIndex);
   } else {
     RootedAtom name(cx, NumberToAtom(cx, funcIndex));
     if (!name) {
       return false;
     }
 
+    bool disableJitEntry = funcType.temporarilyUnsupportedAnyRef()
+#ifdef WASM_CODEGEN_DEBUG
+      || !JitOptions.enableWasmJitEntry;
+#endif
+    ;
+
     // Functions with anyref don't have jit entries yet, so they should
     // mostly behave like asm.js functions. Pretend it's the case, until
     // jit entries are implemented.
-    JSFunction::Flags flags = funcType.temporarilyUnsupportedAnyRef()
+    JSFunction::Flags flags = disableJitEntry
                                   ? JSFunction::ASMJS_NATIVE
                                   : JSFunction::WASM_FUN;
 
     fun.set(NewNativeFunction(cx, WasmCall, numArgs, name,
                               gc::AllocKind::FUNCTION_EXTENDED, SingletonObject,
                               flags));
     if (!fun) {
       return false;
     }
 
-    if (funcType.temporarilyUnsupportedAnyRef()) {
+    if (disableJitEntry) {
       fun->setAsmJSIndex(funcIndex);
     } else {
       fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex));
     }
   }
 
   fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT,
                        ObjectValue(*instanceObj));