Title: [99904] trunk/Source/_javascript_Core
Revision
99904
Author
[email protected]
Date
2011-11-10 15:02:33 -0800 (Thu, 10 Nov 2011)

Log Message

Add ARMv7 support to the DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=72061

Reviewed by Geoff Garen.

* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
(JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
(JSC::DFG::AssemblyHelpers::emitPutImmediateToCallFrameHeader):
(JSC::DFG::AssemblyHelpers::boxDouble):
(JSC::DFG::AssemblyHelpers::unboxDouble):
    - Add CPU(ARM) copies of these functions.
* dfg/DFGJITCodeGenerator.h:
(JSC::DFG::JITCodeGenerator::spill):
    - Fix matching of '}' re #if blocks, makes some tools happy.
(JSC::DFG::JITCodeGenerator::setupArguments):
(JSC::DFG::JITCodeGenerator::setupArgumentsWithExecState):
(JSC::DFG::JITCodeGenerator::appendCallWithExceptionCheckSetResult):
(JSC::DFG::JITCodeGenerator::appendCallSetResult):
    - Add CPU(ARM) / 4 argument register copies of these functions.
* dfg/DFGJITCodeGenerator32_64.cpp:
(JSC::DFG::JITCodeGenerator::nonSpeculativeValueToInt32):
    - Should use callOperation to plant a call to a DFG_OPERATION.
(JSC::DFG::JITCodeGenerator::cachedGetById):
(JSC::DFG::JITCodeGenerator::cachedPutById):
    - These methods need to plant a relinkable jump; we currently do so
      using beginUninterruptedSequence() / endUninterruptedSequence().
* dfg/DFGJITCodeGenerator64.cpp:
(JSC::DFG::JITCodeGenerator::nonSpeculativeValueToInt32):
    - Should use callOperation to plant a call to a DFG_OPERATION.
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
    - This method needs to plant a relinkable jump; we currently do so
      using beginUninterruptedSequence() / endUninterruptedSequence().
(JSC::DFG::JITCompiler::compileBody):
    - Add abstraction to retrieve the pc after a call.
* dfg/DFGOSRExitCompiler.cpp:
    - Fix a bug - CodeLocationLabel needs a data address rather than an
      executable one, but can just take a MacroAssemblerCodePtr instead!
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::compileClampDoubleToByte):
    - Add FIXME comment to come back to! - bug#72054.
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::speculationCheck):
    - Add missing method (ooops, required by bug#72047)
* dfg/DFGSpeculativeJIT32_64.cpp:
    - Need to wrap fmod on ARMv7.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (99903 => 99904)


--- trunk/Source/_javascript_Core/ChangeLog	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-11-10 23:02:33 UTC (rev 99904)
@@ -1,3 +1,55 @@
+2011-11-10  Gavin Barraclough  <[email protected]>
+
+        Add ARMv7 support to the DFG JIT
+        https://bugs.webkit.org/show_bug.cgi?id=72061
+
+        Reviewed by Geoff Garen.
+
+        * dfg/DFGAssemblyHelpers.h:
+        (JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
+        (JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
+        (JSC::DFG::AssemblyHelpers::emitPutImmediateToCallFrameHeader):
+        (JSC::DFG::AssemblyHelpers::boxDouble):
+        (JSC::DFG::AssemblyHelpers::unboxDouble):
+            - Add CPU(ARM) copies of these functions.
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::JITCodeGenerator::spill):
+            - Fix matching of '}' re #if blocks, makes some tools happy.
+        (JSC::DFG::JITCodeGenerator::setupArguments):
+        (JSC::DFG::JITCodeGenerator::setupArgumentsWithExecState):
+        (JSC::DFG::JITCodeGenerator::appendCallWithExceptionCheckSetResult):
+        (JSC::DFG::JITCodeGenerator::appendCallSetResult):
+            - Add CPU(ARM) / 4 argument register copies of these functions.
+        * dfg/DFGJITCodeGenerator32_64.cpp:
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeValueToInt32):
+            - Should use callOperation to plant a call to a DFG_OPERATION.
+        (JSC::DFG::JITCodeGenerator::cachedGetById):
+        (JSC::DFG::JITCodeGenerator::cachedPutById):
+            - These methods need to plant a relinkable jump; we currently do so
+              using beginUninterruptedSequence() / endUninterruptedSequence().
+        * dfg/DFGJITCodeGenerator64.cpp:
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeValueToInt32):
+            - Should use callOperation to plant a call to a DFG_OPERATION.
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::linkOSRExits):
+            - This method needs to plant a relinkable jump; we currently do so
+              using beginUninterruptedSequence() / endUninterruptedSequence().
+        (JSC::DFG::JITCompiler::compileBody):
+            - Add abstraction to retrieve the pc after a call.
+        * dfg/DFGOSRExitCompiler.cpp:
+            - Fix a bug - CodeLocationLabel needs a data address rather than an
+              executable one, but can just take a MacroAssemblerCodePtr instead!
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::compileClampDoubleToByte):
+            - Add FIXME comment to come back to! - bug#72054.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::speculationCheck):
+            - Add missing method (ooops, required by bug#72047)
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+            - Need to wrap fmod on ARMv7.
+
+
 2011-11-10  Filip Pizlo  <[email protected]>
 
         DFG should not reparse code that was just parsed

Modified: trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGAssemblyHelpers.h	2011-11-10 23:02:33 UTC (rev 99904)
@@ -71,6 +71,34 @@
         push(address);
     }
 
+    void getPCAfterCall(GPRReg gpr)
+    {
+          peek(gpr, -1);
+    }
+#endif // CPU(X86_64) || CPU(X86)
+
+#if CPU(ARM)
+    ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
+    {
+        move(linkRegister, reg);
+    }
+
+    ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg)
+    {
+        move(reg, linkRegister);
+    }
+
+    ALWAYS_INLINE void restoreReturnAddressBeforeReturn(Address address)
+    {
+        loadPtr(address, linkRegister);
+    }
+
+    ALWAYS_INLINE void getPCAfterCall(GPRReg gpr)
+    {
+        move(ARMRegisters::lr, gpr);
+    }
+#endif
+
     void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, GPRReg to)
     {
         loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
@@ -84,7 +112,6 @@
     {
         storePtr(TrustedImmPtr(value), Address(GPRInfo::callFrameRegister, entry * sizeof(Register)));
     }
-#endif // CPU(X86_64) || CPU(X86)
 
     Jump branchIfNotCell(GPRReg reg)
     {
@@ -132,6 +159,7 @@
 
 #ifndef NDEBUG
     // Add a debug call. This call has no effect on JIT code execution state.
+#if CPU(X86_64) || CPU(X86)
     void debugCall(V_DFGDebugOperation_EP function, void* argument)
     {
         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_globalData->scratchBufferForSize(sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters)));
@@ -160,7 +188,16 @@
         for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
             loadPtr(buffer + i, GPRInfo::toRegister(i));
     }
+#else
+    void debugCall(V_DFGDebugOperation_EP function, void* argument) NO_RETURN_DUE_TO_ASSERT
+    {
+        // debugCall not supported on this platform.
+        UNUSED_PARAM(function);
+        UNUSED_PARAM(argument);
+        ASSERT_NOT_REACHED();
+    }
 #endif
+#endif
 
     // These methods JIT generate dynamic, debug-only checks - akin to ASSERTs.
 #if DFG_ENABLE(JIT_ASSERT)
@@ -192,25 +229,36 @@
         movePtrToDouble(gpr, fpr);
         return fpr;
     }
-#elif USE(JSVALUE32_64)
+#endif
+
+#if USE(JSVALUE32_64) && CPU(X86)
     void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
     {
-#if CPU(X86)
         movePackedToInt32(fpr, payloadGPR);
         rshiftPacked(TrustedImm32(32), fpr);
         movePackedToInt32(fpr, tagGPR);
-#endif
     }
     void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
     {
         jitAssertIsJSDouble(tagGPR);
-#if CPU(X86)
         moveInt32ToPacked(payloadGPR, fpr);
         moveInt32ToPacked(tagGPR, scratchFPR);
         lshiftPacked(TrustedImm32(32), scratchFPR);
         orPacked(scratchFPR, fpr);
+    }
 #endif
+
+#if USE(JSVALUE32_64) && CPU(ARM)
+    void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
+    {
+        m_assembler.vmov(payloadGPR, tagGPR, fpr);
     }
+    void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
+    {
+        jitAssertIsJSDouble(tagGPR);
+        UNUSED_PARAM(scratchFPR);
+        m_assembler.vmov(fpr, payloadGPR, tagGPR);
+    }
 #endif
 
 #if ENABLE(SAMPLING_COUNTERS)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-11-10 23:02:33 UTC (rev 99904)
@@ -592,7 +592,6 @@
             m_jit.storePtr(reg, JITCompiler::addressFor(spillMe));
             info.spill((DataFormat)(spillFormat | DataFormatJS));
             return;
-        }
 #elif USE(JSVALUE32_64)
         case DataFormatDouble:
         case DataFormatJSDouble: {
@@ -621,8 +620,8 @@
             }
             info.spill((DataFormat)(spillFormat | DataFormatJS));
             return;
+#endif
         }
-#endif
     }
     
     bool isStrictInt32(NodeIndex);
@@ -972,7 +971,7 @@
     // On X86 we use cdecl calling conventions, which pass all arguments on the
     // stack. On other architectures we may need to sort values into the
     // correct registers.
-#if CPU(X86)
+#if !NUMBER_OF_ARGUMENT_REGISTERS
     unsigned m_callArgumentIndex;
     void resetCallArguments() { m_callArgumentIndex = 0; }
 
@@ -1128,7 +1127,10 @@
         addCallArgument(arg4);
         addCallArgument(arg5);
     }
-#else
+#endif // !NUMBER_OF_ARGUMENT_REGISTERS
+    // These methods are suitable for any calling convention that provides for
+    // at least 4 argument registers, e.g. X86_64, ARMv7.
+#if NUMBER_OF_ARGUMENT_REGISTERS >= 4
     template<GPRReg destA, GPRReg destB>
     void setupTwoStubArgs(GPRReg srcA, GPRReg srcB)
     {
@@ -1157,6 +1159,7 @@
         } else
             m_jit.swap(destA, destB);
     }
+#if CPU(X86_64)
     template<FPRReg destA, FPRReg destB>
     void setupTwoStubArgs(FPRReg srcA, FPRReg srcB)
     {
@@ -1203,6 +1206,7 @@
         m_jit.moveDouble(destB, destA);
         m_jit.moveDouble(temp, destB);
     }
+#endif
     void setupStubArguments(GPRReg arg1, GPRReg arg2)
     {
         setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
@@ -1259,6 +1263,7 @@
             m_jit.swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3);
     }
 
+#if CPU(X86_64)
     ALWAYS_INLINE void setupArguments(FPRReg arg1)
     {
         m_jit.moveDouble(arg1, FPRInfo::argumentFPR0);
@@ -1268,7 +1273,19 @@
     {
         setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
     }
+#else
+    ALWAYS_INLINE void setupArguments(FPRReg arg1)
+    {
+        m_jit.assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
+    }
 
+    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
+    {
+        m_jit.assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
+        m_jit.assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
+    }
+#endif
+
     ALWAYS_INLINE void setupArgumentsExecState()
     {
         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
@@ -1326,14 +1343,64 @@
         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
+    {
+        setupStubArguments(arg1, arg2);
+        m_jit.move(arg3, GPRInfo::argumentGPR3);
+        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
     {
         setupStubArguments(arg1, arg2);
         m_jit.move(arg3, GPRInfo::argumentGPR3);
         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
-#endif
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
+    {
+        m_jit.move(arg1, GPRInfo::argumentGPR1);
+        m_jit.move(arg2, GPRInfo::argumentGPR2);
+        m_jit.move(arg3, GPRInfo::argumentGPR3);
+        m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
+#endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
+    // These methods are suitable for any calling convention that provides for
+    // exactly 4 argument registers, e.g. ARMv7.
+#if NUMBER_OF_ARGUMENT_REGISTERS == 4
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
+    {
+        m_jit.poke(arg4);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
+    {
+        m_jit.poke(arg4);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
+    {
+        m_jit.poke(arg4);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
+    {
+        m_jit.poke(arg4);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.poke(arg5, 1);
+        m_jit.poke(arg4);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+#endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
+
     // These methods add calls to C++ helper functions.
     // These methods are broadly value representation specific (i.e.
     // deal with the fact that a JSValue may be passed in one or two
@@ -1687,6 +1754,19 @@
         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
         return call;
     }
+#elif CPU(ARM)
+    JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
+    {
+        JITCompiler::Call call = appendCallWithExceptionCheck(function);
+        m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
+        return call;
+    }
+    JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
+    {
+        JITCompiler::Call call = m_jit.appendCall(function);
+        m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
+        return call;
+    }
 #else
     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -421,13 +421,7 @@
         JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
 
         silentSpillAllRegisters(gpr);
-
-        m_jit.subPtr(TrustedImm32(sizeof(double)), JITCompiler::stackPointerRegister);
-        m_jit.storeDouble(fpr, JITCompiler::stackPointerRegister);
-        appendCallWithExceptionCheck(toInt32);
-        m_jit.move(GPRInfo::returnValueGPR, gpr);
-        m_jit.addPtr(TrustedImm32(sizeof(double)), JITCompiler::stackPointerRegister);
-
+        callOperation(toInt32, gpr, fpr);
         silentFillAllRegisters(gpr);
 
         truncatedToInteger.link(&m_jit);
@@ -857,8 +851,10 @@
 {
     ASSERT(nodeType == GetById || nodeType == GetMethod);
 
+    m_jit.beginUninterruptedSequence();
     JITCompiler::DataLabelPtr structureToCompare;
     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+    m_jit.endUninterruptedSequence();
     
     m_jit.loadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfPropertyStorage()), resultPayloadGPR);
     JITCompiler::DataLabelCompact tagLoadWithPatch = m_jit.load32WithCompactAddressOffsetPatch(JITCompiler::Address(resultPayloadGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
@@ -888,8 +884,10 @@
 
 void JITCodeGenerator::cachedPutById(GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
 {
+    m_jit.beginUninterruptedSequence();
     JITCompiler::DataLabelPtr structureToCompare;
     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+    m_jit.endUninterruptedSequence();
 
     writeBarrier(basePayloadGPR, valueTagGPR, valueIndex, WriteBarrierForPropertyAccess, scratchGPR);
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -426,11 +426,7 @@
         JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
         
         silentSpillAllRegisters(gpr);
-        
-        m_jit.moveDouble(fpr, FPRInfo::argumentFPR0);
-        appendCallWithExceptionCheck(toInt32);
-        m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, gpr);
-        
+        callOperation(toInt32, gpr, fpr);
         silentFillAllRegisters(gpr);
         
         truncatedToInteger.link(&m_jit);

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -46,7 +46,9 @@
         OSRExit& exit = codeBlock()->osrExit(i);
         exit.m_check.initialJump().link(this);
         store32(Imm32(i), &globalData()->osrExitIndex);
+        beginUninterruptedSequence();
         exit.m_check.switchToLateJump(jump());
+        endUninterruptedSequence();
     }
 }
 
@@ -98,7 +100,7 @@
         // of the call out from JIT code that threw the exception; this is still
         // available on the stack, just below the stack pointer!
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-        peek(GPRInfo::argumentGPR1, -1);
+        getPCAfterCall(GPRInfo::argumentGPR1);
         m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
         // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
         // and the address of the handler in returnValueGPR2.

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -64,7 +64,7 @@
     
     {
         RepatchBuffer repatchBuffer(codeBlock);
-        repatchBuffer.relink(exit.m_check.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code().executableAddress()));
+        repatchBuffer.relink(exit.m_check.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code()));
     }
     
     globalData->osrExitJumpDestination = exit.m_code.code().executableAddress();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -64,6 +64,47 @@
 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
 
+#elif COMPILER(GCC) && CPU(ARM_THUMB2)
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
+    asm ( \
+    ".text" "\n" \
+    ".align 2" "\n" \
+    ".globl " SYMBOL_STRING(function) "\n" \
+    HIDE_SYMBOL(function) "\n" \
+    ".thumb" "\n" \
+    ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
+    SYMBOL_STRING(function) ":" "\n" \
+        "cpy a2, lr" "\n" \
+        "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
+    );
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
+    asm ( \
+    ".text" "\n" \
+    ".align 2" "\n" \
+    ".globl " SYMBOL_STRING(function) "\n" \
+    HIDE_SYMBOL(function) "\n" \
+    ".thumb" "\n" \
+    ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
+    SYMBOL_STRING(function) ":" "\n" \
+        "cpy a4, lr" "\n" \
+        "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
+    );
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
+    asm ( \
+    ".text" "\n" \
+    ".align 2" "\n" \
+    ".globl " SYMBOL_STRING(function) "\n" \
+    HIDE_SYMBOL(function) "\n" \
+    ".thumb" "\n" \
+    ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
+    SYMBOL_STRING(function) ":" "\n" \
+        "str lr, [sp, #4]" "\n" \
+        "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
+    );
+
 #endif
 
 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
@@ -522,6 +563,19 @@
     "mov %edi, 4(%esp)\n"
     "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
 );
+#elif CPU(ARM_THUMB2)
+asm (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
+HIDE_SYMBOL(getHostCallReturnValue) "\n"
+".thumb" "\n"
+".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
+SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
+    "ldr r5, [r5, #-40]" "\n"
+    "cpy r0, r5" "\n"
+    "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
+);
 #endif
 
 EncodedJSValue DFG_OPERATION getHostCallReturnValueWithExecState(ExecState* exec)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -652,6 +652,8 @@
     MacroAssembler::Jump tooBig = jit.branchDouble(MacroAssembler::DoubleGreaterThan, source, scratch);
     
     jit.loadDouble(&half, scratch);
+    // FIXME: This should probably just use a floating point round!
+    // https://bugs.webkit.org/show_bug.cgi?id=72054
     jit.addDouble(source, scratch);
     jit.truncateDoubleToInt32(scratch, result);   
     MacroAssembler::Jump truncatedInt = jit.jump();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-11-10 23:02:33 UTC (rev 99904)
@@ -228,6 +228,13 @@
             return;
         m_jit.codeBlock()->appendOSRExit(OSRExit(jsValueSource, m_jit.valueProfileFor(nodeIndex), jumpToFail, this));
     }
+    // Add a set of speculation checks without additional recovery.
+    void speculationCheck(JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail)
+    {
+        Vector<MacroAssembler::Jump, 16> JumpVector = jumpsToFail.jumps();
+        for (unsigned i = 0; i < JumpVector.size(); ++i)
+            speculationCheck(jsValueSource, nodeIndex, JumpVector[i]);
+    }
     // Add a speculation check with additional recovery.
     void speculationCheck(JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (99903 => 99904)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2011-11-10 23:01:27 UTC (rev 99903)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2011-11-10 23:02:33 UTC (rev 99904)
@@ -35,7 +35,8 @@
 namespace JSC { namespace DFG {
 
 // On Windows we need to wrap fmod; on other platforms we can call it directly.
-#if CALLING_CONVENTION_IS_STDCALL
+// On ARMv7 we assert that all function pointers have to low bit set (point to thumb code).
+#if CALLING_CONVENTION_IS_STDCALL || CPU(ARM_THUMB2)
 static double DFG_OPERATION fmodAsDFGOperation(double x, double y)
 {
     return fmod(x, y);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to