fourthTier: Have fewer Arrayify's
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:04:20 +0000 (04:04 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2013 04:04:20 +0000 (04:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118335

Reviewed by Mark Hahnenberg.

A lot of Arrayify's arise because some program saw Int32 arrays early on in
execution, but then they all got converted to Double arrays and the program
will never see Int32 arrays ever again. Prior to this change you would always
have an Arrayify in this case. But with this change, the first time that an
ArrayProfile is about to go polymorphic in computeUpdatedPrediction(), it
instead forcibly monomorphises itself to the latest-seen structure.
Thereafter it will never again perform this monomorphisation. This is
controlled by ArrayProfile::m_didPerformFirstRunPruning. This is a 5%
speed-up on Kraken/imaging-gaussian-blur with the FTL enabled, and it
unblocks a bunch of stuff we want to do in the future because it makes a
bunch of loops effect-free.

We will still want to implement Arrayify hoisting in the future, but this is
great anyway because it's better to not have Arrayifications than it is to
have hoisted Arrayifications.

* bytecode/ArrayProfile.cpp:
(JSC::ArrayProfile::computeUpdatedPrediction):
(JSC::ArrayProfile::briefDescription):
(JSC):
(JSC::ArrayProfile::briefDescriptionWithoutUpdating):
* bytecode/ArrayProfile.h:
(JSC::ArrayProfile::ArrayProfile):
(ArrayProfile):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@153264 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/assembler/MacroAssembler.h
Source/JavaScriptCore/bytecode/ArrayProfile.cpp
Source/JavaScriptCore/bytecode/ArrayProfile.h
Source/JavaScriptCore/dfg/DFGBinarySwitch.cpp
Source/JavaScriptCore/dfg/DFGBinarySwitch.h
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h

index 450a9e0..56bcd43 100644 (file)
@@ -1,5 +1,49 @@
 2013-07-02  Filip Pizlo  <fpizlo@apple.com>
 
+        Unreviewed, fix 32-bit build.
+
+        * assembler/MacroAssembler.h:
+        (JSC::MacroAssembler::comparePtr):
+        (MacroAssembler):
+        * dfg/DFGBinarySwitch.cpp:
+        (JSC::DFG::BinarySwitch::advance):
+        * dfg/DFGBinarySwitch.h:
+        (JSC::DFG::BinarySwitch::caseValue):
+
+2013-07-02  Filip Pizlo  <fpizlo@apple.com>
+
+        fourthTier: Have fewer Arrayify's
+        https://bugs.webkit.org/show_bug.cgi?id=118335
+
+        Reviewed by Mark Hahnenberg.
+        
+        A lot of Arrayify's arise because some program saw Int32 arrays early on in
+        execution, but then they all got converted to Double arrays and the program
+        will never see Int32 arrays ever again. Prior to this change you would always
+        have an Arrayify in this case. But with this change, the first time that an
+        ArrayProfile is about to go polymorphic in computeUpdatedPrediction(), it
+        instead forcibly monomorphises itself to the latest-seen structure.
+        Thereafter it will never again perform this monomorphisation. This is
+        controlled by ArrayProfile::m_didPerformFirstRunPruning. This is a 5%
+        speed-up on Kraken/imaging-gaussian-blur with the FTL enabled, and it
+        unblocks a bunch of stuff we want to do in the future because it makes a
+        bunch of loops effect-free.
+        
+        We will still want to implement Arrayify hoisting in the future, but this is
+        great anyway because it's better to not have Arrayifications than it is to
+        have hoisted Arrayifications.
+
+        * bytecode/ArrayProfile.cpp:
+        (JSC::ArrayProfile::computeUpdatedPrediction):
+        (JSC::ArrayProfile::briefDescription):
+        (JSC):
+        (JSC::ArrayProfile::briefDescriptionWithoutUpdating):
+        * bytecode/ArrayProfile.h:
+        (JSC::ArrayProfile::ArrayProfile):
+        (ArrayProfile):
+
+2013-07-02  Filip Pizlo  <fpizlo@apple.com>
+
         fourthTier: add option to disable OSR entry in loops
         https://bugs.webkit.org/show_bug.cgi?id=118329
 
index b54ff57..8c4354f 100644 (file)
@@ -457,6 +457,11 @@ public:
         compare32(cond, left, right, dest);
     }
 
+    void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        compare32(cond, left, right, dest);
+    }
+    
     void storePtr(RegisterID src, ImplicitAddress address)
     {
         store32(src, address);
index ab6a6f4..04e9d69 100644 (file)
@@ -78,6 +78,14 @@ void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker& locker, C
 {
     if (m_lastSeenStructure) {
         m_observedArrayModes |= arrayModeFromStructure(m_lastSeenStructure);
+
+        if (!m_didPerformFirstRunPruning
+            && hasTwoOrMoreBitsSet(m_observedArrayModes)) {
+            m_observedArrayModes = arrayModeFromStructure(m_lastSeenStructure);
+            m_expectedStructure = 0;
+            m_didPerformFirstRunPruning = true;
+        }
+        
         m_mayInterceptIndexedAccesses |=
             m_lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero();
         if (!codeBlock->globalObject()->isOriginalArrayStructure(m_lastSeenStructure))
@@ -103,7 +111,11 @@ void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker& locker, C
 CString ArrayProfile::briefDescription(const ConcurrentJITLocker& locker, CodeBlock* codeBlock)
 {
     computeUpdatedPrediction(locker, codeBlock);
-    
+    return briefDescriptionWithoutUpdating(locker);
+}
+
+CString ArrayProfile::briefDescriptionWithoutUpdating(const ConcurrentJITLocker& locker)
+{
     StringPrintStream out;
     
     bool hasPrinted = false;
index dbc0ce2..715f280 100644 (file)
@@ -136,6 +136,7 @@ public:
         , m_outOfBounds(false)
         , m_mayInterceptIndexedAccesses(false)
         , m_usesOriginalArrayStructures(true)
+        , m_didPerformFirstRunPruning(false)
         , m_observedArrayModes(0)
     {
     }
@@ -148,6 +149,7 @@ public:
         , m_outOfBounds(false)
         , m_mayInterceptIndexedAccesses(false)
         , m_usesOriginalArrayStructures(true)
+        , m_didPerformFirstRunPruning(false)
         , m_observedArrayModes(0)
     {
     }
@@ -189,6 +191,7 @@ public:
     bool usesOriginalArrayStructures(const ConcurrentJITLocker&) const { return m_usesOriginalArrayStructures; }
     
     CString briefDescription(const ConcurrentJITLocker&, CodeBlock*);
+    CString briefDescriptionWithoutUpdating(const ConcurrentJITLocker&);
     
 private:
     friend class LLIntOffsetsExtractor;
@@ -200,8 +203,9 @@ private:
     Structure* m_expectedStructure;
     bool m_mayStoreToHole; // This flag may become overloaded to indicate other special cases that were encountered during array access, as it depends on indexing type. Since we currently have basically just one indexing type (two variants of ArrayStorage), this flag for now just means exactly what its name implies.
     bool m_outOfBounds;
-    bool m_mayInterceptIndexedAccesses;
-    bool m_usesOriginalArrayStructures;
+    bool m_mayInterceptIndexedAccesses : 1;
+    bool m_usesOriginalArrayStructures : 1;
+    bool m_didPerformFirstRunPruning : 1;
     ArrayModes m_observedArrayModes;
 };
 
index 2ca0284..7c35cc1 100644 (file)
@@ -66,7 +66,7 @@ bool BinarySwitch::advance(MacroAssembler& jit)
             case Int32:
                 m_fallThrough.append(jit.branch32(
                     MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::Imm32(m_cases[code.index].value)));
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
                 break;
             case IntPtr:
                 m_fallThrough.append(jit.branchPtr(
@@ -80,7 +80,7 @@ bool BinarySwitch::advance(MacroAssembler& jit)
             case Int32:
                 m_jumpStack.append(jit.branch32(
                     MacroAssembler::NotEqual, m_value,
-                    MacroAssembler::Imm32(m_cases[code.index].value)));
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
                 break;
             case IntPtr:
                 m_jumpStack.append(jit.branchPtr(
@@ -94,7 +94,7 @@ bool BinarySwitch::advance(MacroAssembler& jit)
             case Int32:
                 m_jumpStack.append(jit.branch32(
                     MacroAssembler::LessThan, m_value,
-                    MacroAssembler::Imm32(m_cases[code.index].value)));
+                    MacroAssembler::Imm32(static_cast<int32_t>(m_cases[code.index].value))));
                 break;
             case IntPtr:
                 m_jumpStack.append(jit.branchPtr(
index b702323..f83bc29 100644 (file)
@@ -69,7 +69,7 @@ public:
     BinarySwitch(GPRReg value, const Vector<int64_t>& cases, Type);
     
     unsigned caseIndex() const { return m_cases[m_caseIndex].index; }
-    int caseValue() const { return m_cases[m_caseIndex].value; }
+    int64_t caseValue() const { return m_cases[m_caseIndex].value; }
     
     bool advance(MacroAssembler&);
     
index e1da795..a6f328b 100644 (file)
@@ -1,5 +1,11 @@
 2013-07-02  Filip Pizlo  <fpizlo@apple.com>
 
+        Unreviewed, fix 32-bit build.
+
+        * wtf/Platform.h:
+
+2013-07-02  Filip Pizlo  <fpizlo@apple.com>
+
         fourthTier: FTL should use the equivalent of llvm opt -O2 by default
         https://bugs.webkit.org/show_bug.cgi?id=118311
 
index 01a0637..9870318 100644 (file)
 #endif
 
 /* Do we have LLVM? */
-#if !defined(HAVE_LLVM) && PLATFORM(MAC) && ENABLE(FTL_JIT)
+#if !defined(HAVE_LLVM) && PLATFORM(MAC) && ENABLE(FTL_JIT) && CPU(X86_64)
 #define HAVE_LLVM 1
 #endif