Bug 1019322 - Don't serialize asm.js modules with basic block profiling, and allow pointer immediates when compiling such modules, r=luke.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 04 Jun 2014 07:35:32 -0600
changeset 206933 b144d655a179191d81ea678b0ecb7db2d721fbc3
parent 206932 50f9f62bebb226a20dda15339ae5ea85f1cba594
child 206934 310d82551d3b537906f4a74c383c45a92f510881
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1019322
milestone32.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 1019322 - Don't serialize asm.js modules with basic block profiling, and allow pointer immediates when compiling such modules, r=luke.
js/src/jit/AsmJSModule.cpp
js/src/jit/shared/Assembler-shared.h
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -1262,16 +1262,23 @@ struct ScopedCacheEntryOpenedForWrite
     }
 };
 
 bool
 js::StoreAsmJSModuleInCache(AsmJSParser &parser,
                             const AsmJSModule &module,
                             ExclusiveContext *cx)
 {
+    // Don't serialize modules with information about basic block hit counts
+    // compiled in, which both affects code speed and uses absolute addresses
+    // that can't be serialized. (This is separate from normal profiling and
+    // requires an addon to activate).
+    if (module.numFunctionCounts())
+        return false;
+
     MachineId machineId;
     if (!machineId.extractCurrentState(cx))
         return false;
 
     ModuleCharsForStore moduleChars;
     if (!moduleChars.init(parser))
         return false;
 
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -107,63 +107,78 @@ struct ImmWord
 #ifdef DEBUG
 static inline bool
 IsCompilingAsmJS()
 {
     // asm.js compilation pushes an IonContext with a null JSCompartment.
     IonContext *ictx = MaybeGetIonContext();
     return ictx && ictx->compartment == nullptr;
 }
+
+static inline bool
+CanUsePointerImmediates()
+{
+    if (!IsCompilingAsmJS())
+        return true;
+
+    // Pointer immediates can still be used with asm.js when the resulting code
+    // is being profiled; the module will not be serialized in this case.
+    IonContext *ictx = MaybeGetIonContext();
+    if (ictx && ictx->runtime->profilingScripts())
+        return true;
+
+    return false;
+}
 #endif
 
 // Pointer to be embedded as an immediate in an instruction.
 struct ImmPtr
 {
     void *value;
 
     explicit ImmPtr(const void *value) : value(const_cast<void*>(value))
     {
         // To make code serialization-safe, asm.js compilation should only
         // compile pointer immediates using AsmJSImmPtr.
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     template <class R>
     explicit ImmPtr(R (*pf)())
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
     {
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     template <class R, class A1>
     explicit ImmPtr(R (*pf)(A1))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
     {
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     template <class R, class A1, class A2>
     explicit ImmPtr(R (*pf)(A1, A2))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
     {
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     template <class R, class A1, class A2, class A3>
     explicit ImmPtr(R (*pf)(A1, A2, A3))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
     {
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     template <class R, class A1, class A2, class A3, class A4>
     explicit ImmPtr(R (*pf)(A1, A2, A3, A4))
       : value(JS_FUNC_TO_DATA_PTR(void *, pf))
     {
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
 };
 
 // The same as ImmPtr except that the intention is to patch this
 // instruction. The initial value of the immediate is 'addr' and this value is
 // either clobbered or used in the patching process.
 struct PatchedImmPtr {
@@ -212,18 +227,17 @@ struct ImmMaybeNurseryPtr : public ImmGC
 // instruction.
 struct AbsoluteAddress
 {
     void *addr;
 
     explicit AbsoluteAddress(const void *addr)
       : addr(const_cast<void*>(addr))
     {
-        // asm.js shouldn't be creating GC things
-        JS_ASSERT(!IsCompilingAsmJS());
+        JS_ASSERT(CanUsePointerImmediates());
     }
 
     AbsoluteAddress offset(ptrdiff_t delta) {
         return AbsoluteAddress(((uint8_t *) addr) + delta);
     }
 };
 
 // The same as AbsoluteAddress except that the intention is to patch this