Title: [98405] trunk/Source/_javascript_Core
Revision
98405
Author
[email protected]
Date
2011-10-25 16:06:13 -0700 (Tue, 25 Oct 2011)

Log Message

Separate out function linking & exception check data structures.
https://bugs.webkit.org/show_bug.cgi?id=70858

Reviewed by Oliver Hunt.

This will make it easier to refactor the callOperation methods to spilt the value
representation specific handling from the cpu/calling-convention implementation.

* dfg/DFGJITCodeGenerator.h:
(JSC::DFG::appendCallWithExceptionCheck):
* dfg/DFGJITCodeGenerator32_64.cpp:
(JSC::DFG::JITCodeGenerator::emitCall):
* dfg/DFGJITCodeGenerator64.cpp:
(JSC::DFG::JITCodeGenerator::emitCall):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::CallLinkRecord::CallLinkRecord):
(JSC::DFG::CallExceptionRecord::CallExceptionRecord):
(JSC::DFG::JITCompiler::JITCompiler):
(JSC::DFG::JITCompiler::notifyCall):
(JSC::DFG::JITCompiler::appendCall):
(JSC::DFG::JITCompiler::addExceptionCheck):
(JSC::DFG::JITCompiler::addFastExceptionCheck):
* dfg/DFGJITCompiler32_64.cpp:
(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (98404 => 98405)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-25 23:06:13 UTC (rev 98405)
@@ -1,3 +1,34 @@
+2011-10-25  Gavin Barraclough  <[email protected]>
+
+        Separate out function linking & exception check data structures.
+        https://bugs.webkit.org/show_bug.cgi?id=70858
+
+        Reviewed by Oliver Hunt.
+
+        This will make it easier to refactor the callOperation methods to spilt the value
+        representation specific handling from the cpu/calling-convention implementation.
+
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::appendCallWithExceptionCheck):
+        * dfg/DFGJITCodeGenerator32_64.cpp:
+        (JSC::DFG::JITCodeGenerator::emitCall):
+        * dfg/DFGJITCodeGenerator64.cpp:
+        (JSC::DFG::JITCodeGenerator::emitCall):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileBody):
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::CallLinkRecord::CallLinkRecord):
+        (JSC::DFG::CallExceptionRecord::CallExceptionRecord):
+        (JSC::DFG::JITCompiler::JITCompiler):
+        (JSC::DFG::JITCompiler::notifyCall):
+        (JSC::DFG::JITCompiler::appendCall):
+        (JSC::DFG::JITCompiler::addExceptionCheck):
+        (JSC::DFG::JITCompiler::addFastExceptionCheck):
+        * dfg/DFGJITCompiler32_64.cpp:
+        (JSC::DFG::JITCompiler::compileBody):
+        (JSC::DFG::JITCompiler::link):
+
 2011-10-25  Filip Pizlo  <[email protected]>
 
         Tiered compilation may introduce dangling pointers in constant buffers

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-10-25 23:06:13 UTC (rev 98405)
@@ -1550,7 +1550,7 @@
 
     JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
     {
-        return m_jit.appendCallWithExceptionCheck(function, at(m_compileIndex).codeOrigin);
+        return m_jit.addExceptionCheck(m_jit.appendCall(function), at(m_compileIndex).codeOrigin);
     }
     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-10-25 23:06:13 UTC (rev 98405)
@@ -1365,7 +1365,7 @@
 
     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     m_jit.poke(GPRInfo::argumentGPR0);
-    JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);
+    JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin);
     m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
     m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), at(m_compileIndex).codeOrigin);

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-10-25 23:06:13 UTC (rev 98405)
@@ -1311,7 +1311,7 @@
     slowPath.link(&m_jit);
     
     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-    JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);
+    JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin);
     m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
     m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), at(m_compileIndex).codeOrigin);

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-10-25 23:06:13 UTC (rev 98405)
@@ -610,17 +610,18 @@
 
     linkOSRExits(speculative);
 
-    // Iterate over the m_calls vector, checking for exception checks,
-    // and linking them to here.
-    for (unsigned i = 0; i < m_calls.size(); ++i) {
-        Jump& exceptionCheck = m_calls[i].m_exceptionCheck;
+    // Iterate over the m_calls vector, checking for jumps to link.
+    bool didLinkExceptionCheck = false;
+    for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
+        Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck;
         if (exceptionCheck.isSet()) {
             exceptionCheck.link(this);
-            ++m_exceptionCheckCount;
+            didLinkExceptionCheck = true;
         }
     }
+
     // If any exception checks were linked, generate code to lookup a handler.
-    if (m_exceptionCheckCount) {
+    if (didLinkExceptionCheck) {
         // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
         // an identifier for the operation that threw the exception, which we can use
         // to look up handler information. The identifier we use is the return address
@@ -628,7 +629,7 @@
         // available on the stack, just below the stack pointer!
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
         peek(GPRInfo::argumentGPR1, -1);
-        m_calls.append(CallRecord(call(), lookupExceptionHandler));
+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
         // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
         // and the address of the handler in returnValueGPR2.
         jump(GPRInfo::returnValueGPR2);
@@ -643,19 +644,15 @@
 #endif
 
     // Link all calls out from the JIT code to their respective functions.
-    for (unsigned i = 0; i < m_calls.size(); ++i) {
-        if (m_calls[i].m_function.value())
-            linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
-    }
+    for (unsigned i = 0; i < m_calls.size(); ++i)
+        linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
 
     if (m_codeBlock->needsCallReturnIndices()) {
-        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount);
-        for (unsigned i = 0; i < m_calls.size(); ++i) {
-            if (m_calls[i].m_handlesExceptions) {
-                unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
-                unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex;
-                m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
-            }
+        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size());
+        for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
+            unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call);
+            unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex;
+            m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
         }
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2011-10-25 23:06:13 UTC (rev 98405)
@@ -63,47 +63,44 @@
 };
 #endif
 
-// === CallRecord ===
+// === CallLinkRecord ===
 //
-// A record of a call out from JIT code to a helper function.
-// Every CallRecord contains a reference to the call instruction & the function
-// that it needs to be linked to. Calls that might throw an exception also record
-// the Jump taken on exception (unset if not present), and ExceptionInfo (presently
-// an unsigned, bytecode index) used to recover handler/source info.
-struct CallRecord {
-    // Constructor for a call with no exception handler.
-    CallRecord(MacroAssembler::Call call, FunctionPtr function)
+// A record of a call out from JIT code that needs linking to a helper function.
+// Every CallLinkRecord contains a reference to the call instruction & the function
+// that it needs to be linked to.
+struct CallLinkRecord {
+    CallLinkRecord(MacroAssembler::Call call, FunctionPtr function)
         : m_call(call)
         , m_function(function)
-        , m_handlesExceptions(false)
     {
     }
 
-    // Constructor for a call with an exception handler.
-    CallRecord(MacroAssembler::Call call, FunctionPtr function, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin)
+    MacroAssembler::Call m_call;
+    FunctionPtr m_function;
+};
+
+// === CallExceptionRecord ===
+//
+// A record of a call out from JIT code that might throw an exception.
+// Calls that might throw an exception also record the Jump taken on exception
+// (unset if not present) and code origin used to recover handler/source info.
+struct CallExceptionRecord {
+    CallExceptionRecord(MacroAssembler::Call call, CodeOrigin codeOrigin)
         : m_call(call)
-        , m_function(function)
-        , m_exceptionCheck(exceptionCheck)
         , m_codeOrigin(codeOrigin)
-        , m_handlesExceptions(true)
     {
     }
 
-    // Constructor for a call that may cause exceptions, but which are handled
-    // through some mechanism other than the in-line exception handler.
-    CallRecord(MacroAssembler::Call call, FunctionPtr function, CodeOrigin codeOrigin)
+    CallExceptionRecord(MacroAssembler::Call call, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin)
         : m_call(call)
-        , m_function(function)
+        , m_exceptionCheck(exceptionCheck)
         , m_codeOrigin(codeOrigin)
-        , m_handlesExceptions(true)
     {
     }
 
     MacroAssembler::Call m_call;
-    FunctionPtr m_function;
     MacroAssembler::Jump m_exceptionCheck;
     CodeOrigin m_codeOrigin;
-    bool m_handlesExceptions;
 };
 
 // === JITCompiler ===
@@ -120,7 +117,6 @@
         : m_globalData(globalData)
         , m_graph(dfg)
         , m_codeBlock(codeBlock)
-        , m_exceptionCheckCount(0)
     {
     }
 
@@ -209,39 +205,36 @@
     }
 
     // Notify the JIT of a call that does not require linking.
-    void notifyCall(Call call, CodeOrigin codeOrigin)
+    void notifyCall(Call functionCall, CodeOrigin codeOrigin)
     {
-        m_calls.append(CallRecord(call, FunctionPtr(), codeOrigin));
+        m_exceptionChecks.append(CallExceptionRecord(functionCall, codeOrigin));
     }
 
     // Add a call out from JIT code, without an exception check.
     Call appendCall(const FunctionPtr& function)
     {
         Call functionCall = call();
-        m_calls.append(CallRecord(functionCall, function));
-        // FIXME: should be able to JIT_ASSERT here that globalData->exception is null on return back to JIT code.
+        m_calls.append(CallLinkRecord(functionCall, function));
         return functionCall;
     }
 
     // Add a call out from JIT code, with an exception check.
-    Call appendCallWithExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin)
+    Call addExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
     {
-        Call functionCall = call();
 #if USE(JSVALUE64)
         Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception));
 #elif USE(JSVALUE32_64)
         Jump exceptionCheck = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
 #endif
-        m_calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));
+        m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
         return functionCall;
     }
     
     // Add a call out from JIT code, with a fast exception check that tests if the return value is zero.
-    Call appendCallWithFastExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin)
+    Call addFastExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
     {
-        Call functionCall = call();
         Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR);
-        m_calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));
+        m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
         return functionCall;
     }
     
@@ -466,8 +459,8 @@
     
     // Vector of calls out from JIT code, including exception handler information.
     // Count of the number of CallRecords with exception handlers.
-    Vector<CallRecord> m_calls;
-    unsigned m_exceptionCheckCount;
+    Vector<CallLinkRecord> m_calls;
+    Vector<CallExceptionRecord> m_exceptionChecks;
     
     // JIT code map for OSR entrypoints.
     Label m_startOfCode;

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp (98404 => 98405)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp	2011-10-25 23:02:53 UTC (rev 98404)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp	2011-10-25 23:06:13 UTC (rev 98405)
@@ -568,26 +568,26 @@
 
     linkOSRExits(speculative);
 
-    // Iterate over the m_calls vector, checking for exception checks,
-    // and linking them to here.
-    for (unsigned i = 0; i < m_calls.size(); ++i) {
-        Jump& exceptionCheck = m_calls[i].m_exceptionCheck;
+    // Iterate over the m_calls vector, checking for jumps to link.
+    bool didLinkExceptionCheck = false;
+    for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
+        Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck;
         if (exceptionCheck.isSet()) {
             exceptionCheck.link(this);
-            ++m_exceptionCheckCount;
+            didLinkExceptionCheck = true;
         }
     }
+
     // If any exception checks were linked, generate code to lookup a handler.
-    if (m_exceptionCheckCount) {
+    if (didLinkExceptionCheck) {
         // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
         // an identifier for the operation that threw the exception, which we can use
         // to look up handler information. The identifier we use is the return address
         // 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);
-        poke(GPRInfo::callFrameRegister);
-        poke(GPRInfo::argumentGPR1, 1);
-        m_calls.append(CallRecord(call(), lookupExceptionHandler));
+        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
         // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
         // and the address of the handler in returnValueGPR2.
         jump(GPRInfo::returnValueGPR2);
@@ -602,19 +602,15 @@
 #endif
 
     // Link all calls out from the JIT code to their respective functions.
-    for (unsigned i = 0; i < m_calls.size(); ++i) {
-        if (m_calls[i].m_function.value())
-            linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
-    }
+    for (unsigned i = 0; i < m_calls.size(); ++i)
+        linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
 
     if (m_codeBlock->needsCallReturnIndices()) {
-        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount);
-        for (unsigned i = 0; i < m_calls.size(); ++i) {
-            if (m_calls[i].m_handlesExceptions) {
-                unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
-                unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex;
-                m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
-            }
+        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size());
+        for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
+            unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call);
+            unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex;
+            m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
         }
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to