Title: [90177] trunk/Source/_javascript_Core
Revision
90177
Author
[email protected]
Date
2011-06-30 16:08:11 -0700 (Thu, 30 Jun 2011)

Log Message

2011-06-30  Oliver Hunt  <[email protected]>

        Reviewed by Gavin Barraclough.

        Add optimised paths for a few maths functions
        https://bugs.webkit.org/show_bug.cgi?id=63757

        This adds specialised thunks for Math.abs, Math.round, Math.ceil,
        Math.floor, Math.log, and Math.exp as they are apparently more
        important in real web content than we thought, which is somewhat
        mind-boggling.  On average doubles the performance of the common
        cases (eg. actually passing numbers in).  They're not as efficient
        as they could be, but this way gives them the most portability.

        * assembler/MacroAssemblerARM.h:
        (JSC::MacroAssemblerARM::supportsDoubleBitops):
        (JSC::MacroAssemblerARM::andnotDouble):
        * assembler/MacroAssemblerARMv7.h:
        (JSC::MacroAssemblerARMv7::supportsDoubleBitops):
        (JSC::MacroAssemblerARMv7::andnotDouble):
        * assembler/MacroAssemblerMIPS.h:
        (JSC::MacroAssemblerMIPS::andnotDouble):
        (JSC::MacroAssemblerMIPS::supportsDoubleBitops):
        * assembler/MacroAssemblerSH4.h:
        (JSC::MacroAssemblerSH4::supportsDoubleBitops):
        (JSC::MacroAssemblerSH4::andnotDouble):
        * assembler/MacroAssemblerX86.h:
        (JSC::MacroAssemblerX86::supportsDoubleBitops):
        * assembler/MacroAssemblerX86Common.h:
        (JSC::MacroAssemblerX86Common::andnotDouble):
        * assembler/MacroAssemblerX86_64.h:
        (JSC::MacroAssemblerX86_64::supportsDoubleBitops):
        * assembler/X86Assembler.h:
        (JSC::X86Assembler::andnpd_rr):
        * create_hash_table:
        * jit/SpecializedThunkJIT.h:
        (JSC::SpecializedThunkJIT::finalize):
        (JSC::SpecializedThunkJIT::callDoubleToDouble):
        * jit/ThunkGenerators.cpp:
        (JSC::floorThunkGenerator):
        (JSC::ceilThunkGenerator):
        (JSC::roundThunkGenerator):
        (JSC::expThunkGenerator):
        (JSC::logThunkGenerator):
        (JSC::absThunkGenerator):
        * jit/ThunkGenerators.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (90176 => 90177)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-30 23:08:11 UTC (rev 90177)
@@ -1,3 +1,50 @@
+2011-06-30  Oliver Hunt  <[email protected]>
+
+        Reviewed by Gavin Barraclough.
+
+        Add optimised paths for a few maths functions
+        https://bugs.webkit.org/show_bug.cgi?id=63757
+
+        This adds specialised thunks for Math.abs, Math.round, Math.ceil,
+        Math.floor, Math.log, and Math.exp as they are apparently more
+        important in real web content than we thought, which is somewhat
+        mind-boggling.  On average doubles the performance of the common
+        cases (eg. actually passing numbers in).  They're not as efficient
+        as they could be, but this way gives them the most portability.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::supportsDoubleBitops):
+        (JSC::MacroAssemblerARM::andnotDouble):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::supportsDoubleBitops):
+        (JSC::MacroAssemblerARMv7::andnotDouble):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::andnotDouble):
+        (JSC::MacroAssemblerMIPS::supportsDoubleBitops):
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::supportsDoubleBitops):
+        (JSC::MacroAssemblerSH4::andnotDouble):
+        * assembler/MacroAssemblerX86.h:
+        (JSC::MacroAssemblerX86::supportsDoubleBitops):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::andnotDouble):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::supportsDoubleBitops):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::andnpd_rr):
+        * create_hash_table:
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::finalize):
+        (JSC::SpecializedThunkJIT::callDoubleToDouble):
+        * jit/ThunkGenerators.cpp:
+        (JSC::floorThunkGenerator):
+        (JSC::ceilThunkGenerator):
+        (JSC::roundThunkGenerator):
+        (JSC::expThunkGenerator):
+        (JSC::logThunkGenerator):
+        (JSC::absThunkGenerator):
+        * jit/ThunkGenerators.h:
+
 2011-06-30  Cary Clark  <[email protected]>
 
         Reviewed by James Robinson.

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -789,6 +789,7 @@
     {
         return s_isVFPPresent;
     }
+    bool supportsDoubleBitops() const { return false; }
 
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
@@ -855,6 +856,11 @@
     {
         m_assembler.vsqrt_f64_r(dest, src);
     }
+    
+    void andnotDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
 
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -567,6 +567,7 @@
     {
         return false;
     }
+    bool supportsDoubleBitops() const { return false; }
 
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
@@ -646,6 +647,11 @@
     {
         ASSERT_NOT_REACHED();
     }
+    
+    void andnotDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
 
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -460,6 +460,11 @@
     {
         m_assembler.sqrtd(dst, src);
     }
+    
+    void andnotDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
 
     // Memory access operations:
     //
@@ -816,6 +821,7 @@
         return false;
 #endif
     }
+    bool supportsDoubleBitops() const { return false; }
 
     // Stack manipulation operations:
     //

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -762,6 +762,7 @@
     bool supportsFloatingPoint() const { return true; }
     bool supportsFloatingPointTruncate() const { return true; }
     bool supportsFloatingPointSqrt() const { return true; }
+    bool supportsDoubleBitops() const { return false; }
 
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
@@ -1100,6 +1101,11 @@
             m_assembler.dmovRegReg(src, dest);
         m_assembler.dsqrt(dest);
     }
+    
+    void andnotDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
 
     Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
     {

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -166,6 +166,7 @@
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
     bool supportsFloatingPointSqrt() const { return m_isSSE2Present; }
+    bool supportsDoubleBitops() const { return m_isSSE2Present; }
 
 private:
     const bool m_isSSE2Present;

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -423,6 +423,11 @@
         m_assembler.sqrtsd_rr(src, dst);
     }
 
+    void andnotDouble(FPRegisterID src, FPRegisterID dst)
+    {
+        m_assembler.andnpd_rr(src, dst);
+    }
+
     // Memory access operations:
     //
     // Loads are of the form load(address, destination) and stores of the form

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -456,6 +456,7 @@
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return true; }
     bool supportsFloatingPointSqrt() const { return true; }
+    bool supportsDoubleBitops() const { return true; }
 
 private:
     friend class LinkBuffer;

Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (90176 => 90177)


--- trunk/Source/_javascript_Core/assembler/X86Assembler.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -170,6 +170,7 @@
         OP2_SUBSD_VsdWsd    = 0x5C,
         OP2_DIVSD_VsdWsd    = 0x5E,
         OP2_SQRTSD_VsdWsd   = 0x51,
+        OP2_ANDNPD_VpdWpd   = 0x55,
         OP2_XORPD_VpdWpd    = 0x57,
         OP2_MOVD_VdEd       = 0x6E,
         OP2_MOVD_EdVd       = 0x7E,
@@ -1457,6 +1458,12 @@
         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_66);
+        m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_F2);

Modified: trunk/Source/_javascript_Core/create_hash_table (90176 => 90177)


--- trunk/Source/_javascript_Core/create_hash_table	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/create_hash_table	2011-06-30 23:08:11 UTC (rev 90177)
@@ -278,15 +278,35 @@
         if ($key eq "charAt") {
             $thunkGenerator = "charAtThunkGenerator";
         }
-        if ($key eq "sqrt") {
-            $thunkGenerator = "sqrtThunkGenerator";
-        }
-        if ($key eq "pow") {
-            $thunkGenerator = "powThunkGenerator";
-        }
         if ($key eq "fromCharCode") {
             $thunkGenerator = "fromCharCodeThunkGenerator";
         }
+        if ($name eq "mathTable") {
+            if ($key eq "sqrt") {
+                $thunkGenerator = "sqrtThunkGenerator";
+            }
+            if ($key eq "pow") {
+                $thunkGenerator = "powThunkGenerator";
+            }
+            if ($key eq "abs") {
+                $thunkGenerator = "absThunkGenerator";
+            }
+            if ($key eq "floor") {
+                $thunkGenerator = "floorThunkGenerator";
+            }
+            if ($key eq "ceil") {
+                $thunkGenerator = "ceilThunkGenerator";
+            }
+            if ($key eq "round") {
+                $thunkGenerator = "roundThunkGenerator";
+            }
+            if ($key eq "exp") {
+                $thunkGenerator = "expThunkGenerator";
+            }
+            if ($key eq "log") {
+                $thunkGenerator = "logThunkGenerator";
+            }
+        }
         print "   { \"$key\", $attrs[$i], (intptr_t)" . $castStr . "($firstValue), (intptr_t)$secondValue THUNK_GENERATOR($thunkGenerator) },\n";
         $i++;
     }

Modified: trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h (90176 => 90177)


--- trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -276,7 +276,8 @@
         loadDouble(addressFor(virtualRegisterIndex), dst);
         done.link(this);
         return notInt;
-    }    
+    }
+
 #endif
 
 #if USE(JSVALUE64)
@@ -315,7 +316,7 @@
         done.link(this);
         return notNumber;
     }
-    
+
     ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID)
     {
     }

Modified: trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h (90176 => 90177)


--- trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -127,9 +127,18 @@
         {
             LinkBuffer patchBuffer(globalData, this, m_pool.get());
             patchBuffer.link(m_failures, CodeLocationLabel(fallback));
+            for (unsigned i = 0; i < m_calls.size(); i++)
+                patchBuffer.link(m_calls[i].first, m_calls[i].second);
             return patchBuffer.finalizeCode().m_code;
         }
-        
+
+        // Assumes that the target function uses fpRegister0 as the first argument
+        // and return value. Like any sensible architecture would.
+        void callDoubleToDouble(FunctionPtr function)
+        {
+            m_calls.append(std::make_pair(call(), function));
+        }
+
     private:
         int argumentToVirtualRegister(unsigned argument)
         {
@@ -156,6 +165,7 @@
         JSGlobalData* m_globalData;
         RefPtr<ExecutablePool> m_pool;
         MacroAssembler::JumpList m_failures;
+        Vector<std::pair<Call, FunctionPtr> > m_calls;
     };
 
 }

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (90176 => 90177)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2011-06-30 23:08:11 UTC (rev 90177)
@@ -102,9 +102,196 @@
     return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
 }
 
+#if OS(DARWIN) || (OS(WINDOWS) && CPU(X86))
+#define SYMBOL_STRING(name) "_" #name
+#else
+#define SYMBOL_STRING(name) #name
+#endif
+    
+#if (OS(LINUX) || OS(FREEBSD)) && CPU(X86_64)
+#define SYMBOL_STRING_RELOCATION(name) #name "@plt"
+#elif OS(DARWIN) || (CPU(X86_64) && COMPILER(MINGW) && !GCC_VERSION_AT_LEAST(4, 5, 0))
+#define SYMBOL_STRING_RELOCATION(name) "_" #name
+#elif CPU(X86) && COMPILER(MINGW)
+#define SYMBOL_STRING_RELOCATION(name) "@" #name "@4"
+#else
+#define SYMBOL_STRING_RELOCATION(name) #name
+#endif
+
+#define UnaryDoubleOpWrapper(function) function##Wrapper
+enum MathThunkCallingConvention { };
+typedef MathThunkCallingConvention(*MathThunk)(MathThunkCallingConvention);
+extern "C" {
+
+double jsRound(double);
+double jsRound(double d)
+{
+    double integer = ceil(d);
+    return integer - (integer - d > 0.5);
+}
+
+}
+    
+#if CPU(X86_64) && COMPILER(GCC)
+
+#define defineUnaryDoubleOpWrapper(function) \
+    asm( \
+        ".globl " SYMBOL_STRING(function##Thunk) "\n" \
+        SYMBOL_STRING(function##Thunk) ":" "\n" \
+        "call " SYMBOL_STRING_RELOCATION(function) "\n" \
+        "ret\n" \
+    );\
+    extern "C" { \
+        MathThunkCallingConvention function##Thunk(MathThunkCallingConvention); \
+    } \
+    static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
+
+#elif CPU(X86) && COMPILER(GCC)
+#define defineUnaryDoubleOpWrapper(function) \
+    asm( \
+         ".globl " SYMBOL_STRING(function##Thunk) "\n" \
+         SYMBOL_STRING(function##Thunk) ":" "\n" \
+         "subl $8, %esp\n" \
+         "movsd %xmm0, (%esp) \n" \
+         "call " SYMBOL_STRING_RELOCATION(function) "\n" \
+         "fstpl (%esp) \n" \
+         "movsd (%esp), %xmm0 \n" \
+         "addl $8, %esp\n" \
+         "ret\n" \
+    );\
+    extern "C" { \
+        MathThunkCallingConvention function##Thunk(MathThunkCallingConvention); \
+    } \
+    static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
+
+#else
+
+#define defineUnaryDoubleOpWrapper(function) \
+    static MathThunk UnaryDoubleOpWrapper(function) = 0
+#endif
+
+defineUnaryDoubleOpWrapper(jsRound);
+defineUnaryDoubleOpWrapper(exp);
+defineUnaryDoubleOpWrapper(log);
+defineUnaryDoubleOpWrapper(floor);
+defineUnaryDoubleOpWrapper(ceil);
+
+MacroAssemblerCodePtr floorThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    MacroAssembler::Jump nonIntJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    if (!UnaryDoubleOpWrapper(floor) || !jit.supportsFloatingPoint()) {
+        jit.appendFailure(nonIntJump);
+        return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+    }
+    nonIntJump.link(&jit);
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.callDoubleToDouble(UnaryDoubleOpWrapper(floor));
+    SpecializedThunkJIT::JumpList doubleResult;
+    jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    doubleResult.link(&jit);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
+
+MacroAssemblerCodePtr ceilThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    MacroAssembler::Jump nonIntJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    if (!UnaryDoubleOpWrapper(ceil) || !jit.supportsFloatingPoint()) {
+        jit.appendFailure(nonIntJump);
+        return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+    }
+    nonIntJump.link(&jit);
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.callDoubleToDouble(UnaryDoubleOpWrapper(ceil));
+    SpecializedThunkJIT::JumpList doubleResult;
+    jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    doubleResult.link(&jit);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
+
+static const double negativeZeroConstant = -0.0;
 static const double _oneConstant_ = 1.0;
 static const double negativeHalfConstant = -0.5;
+    
+MacroAssemblerCodePtr roundThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    MacroAssembler::Jump nonIntJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    if (!UnaryDoubleOpWrapper(jsRound) || !jit.supportsFloatingPoint()) {
+        jit.appendFailure(nonIntJump);
+        return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+    }
+    nonIntJump.link(&jit);
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.callDoubleToDouble(UnaryDoubleOpWrapper(jsRound));
+    SpecializedThunkJIT::JumpList doubleResult;
+    jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    doubleResult.link(&jit);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
 
+MacroAssemblerCodePtr expThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    if (!UnaryDoubleOpWrapper(exp))
+        return globalData->jitStubs->ctiNativeCall();
+    SpecializedThunkJIT jit(1, globalData, pool);
+    if (!jit.supportsFloatingPoint())
+        return globalData->jitStubs->ctiNativeCall();
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.callDoubleToDouble(UnaryDoubleOpWrapper(exp));
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
+
+MacroAssemblerCodePtr logThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    if (!UnaryDoubleOpWrapper(log))
+        return globalData->jitStubs->ctiNativeCall();
+    SpecializedThunkJIT jit(1, globalData, pool);
+    if (!jit.supportsFloatingPoint())
+        return globalData->jitStubs->ctiNativeCall();
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.callDoubleToDouble(UnaryDoubleOpWrapper(log));
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
+
+MacroAssemblerCodePtr absThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    MacroAssembler::Jump nonIntJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
+    jit.rshift32(SpecializedThunkJIT::regT0, MacroAssembler::TrustedImm32(31), SpecializedThunkJIT::regT1);
+    jit.add32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT0);
+    jit.xor32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT0);
+    jit.appendFailure(jit.branch32(MacroAssembler::Equal, SpecializedThunkJIT::regT0, MacroAssembler::TrustedImm32(1 << 31)));
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    if (!jit.supportsDoubleBitops()) {
+        jit.appendFailure(nonIntJump);
+        return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+    }
+    nonIntJump.link(&jit);
+    // Shame about the double int conversion here.
+    jit.loadDouble(&negativeZeroConstant, SpecializedThunkJIT::fpRegT1);
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.andnotDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT1);
+    return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+}
+
 MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
 {
     SpecializedThunkJIT jit(2, globalData, pool);

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.h (90176 => 90177)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.h	2011-06-30 23:07:15 UTC (rev 90176)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.h	2011-06-30 23:08:11 UTC (rev 90177)
@@ -37,6 +37,12 @@
     MacroAssemblerCodePtr charCodeAtThunkGenerator(JSGlobalData*, ExecutablePool*);
     MacroAssemblerCodePtr charAtThunkGenerator(JSGlobalData*, ExecutablePool*);
     MacroAssemblerCodePtr fromCharCodeThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr absThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr ceilThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr expThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr floorThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr logThunkGenerator(JSGlobalData*, ExecutablePool*);
+    MacroAssemblerCodePtr roundThunkGenerator(JSGlobalData*, ExecutablePool*);
     MacroAssemblerCodePtr sqrtThunkGenerator(JSGlobalData*, ExecutablePool*);
     MacroAssemblerCodePtr powThunkGenerator(JSGlobalData*, ExecutablePool*);
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to