Title: [90414] trunk/Source/_javascript_Core
Revision
90414
Author
[email protected]
Date
2011-07-05 16:18:23 -0700 (Tue, 05 Jul 2011)

Log Message

2011-07-05  Filip Pizlo  <[email protected]>

        JSC JIT has code duplication for the handling of call and construct
        https://bugs.webkit.org/show_bug.cgi?id=63957

        Reviewed by Gavin Barraclough.

        * jit/JIT.cpp:
        (JSC::JIT::linkFor):
        * jit/JIT.h:
        * jit/JITStubs.cpp:
        (JSC::jitCompileFor):
        (JSC::DEFINE_STUB_FUNCTION):
        (JSC::arityCheckFor):
        (JSC::lazyLinkFor):
        * runtime/Executable.h:
        (JSC::ExecutableBase::generatedJITCodeFor):
        (JSC::FunctionExecutable::compileFor):
        (JSC::FunctionExecutable::isGeneratedFor):
        (JSC::FunctionExecutable::generatedBytecodeFor):
        (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (90413 => 90414)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-05 23:18:23 UTC (rev 90414)
@@ -1,3 +1,25 @@
+2011-07-05  Filip Pizlo  <[email protected]>
+
+        JSC JIT has code duplication for the handling of call and construct
+        https://bugs.webkit.org/show_bug.cgi?id=63957
+
+        Reviewed by Gavin Barraclough.
+
+        * jit/JIT.cpp:
+        (JSC::JIT::linkFor):
+        * jit/JIT.h:
+        * jit/JITStubs.cpp:
+        (JSC::jitCompileFor):
+        (JSC::DEFINE_STUB_FUNCTION):
+        (JSC::arityCheckFor):
+        (JSC::lazyLinkFor):
+        * runtime/Executable.h:
+        (JSC::ExecutableBase::generatedJITCodeFor):
+        (JSC::FunctionExecutable::compileFor):
+        (JSC::FunctionExecutable::isGeneratedFor):
+        (JSC::FunctionExecutable::generatedBytecodeFor):
+        (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor):
+
 2011-07-05  Gavin Barraclough  <[email protected]>
 
         Build fix following last patch.

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (90413 => 90414)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2011-07-05 23:18:23 UTC (rev 90414)
@@ -609,7 +609,7 @@
     return patchBuffer.finalizeCode();
 }
 
-void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
+void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData, CodeSpecializationKind kind)
 {
     RepatchBuffer repatchBuffer(callerCodeBlock);
 
@@ -622,22 +622,12 @@
     }
 
     // patch the call so we do not continue to try to link.
-    repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
-}
-
-void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
-{
-    RepatchBuffer repatchBuffer(callerCodeBlock);
-
-    // Currently we only link calls with the exact number of arguments.
-    // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
-    if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
-        ASSERT(!callLinkInfo->isLinked());
-        callLinkInfo->callee.set(*globalData, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
-        repatchBuffer.relink(callLinkInfo->hotPathOther, code);
+    if (kind == CodeForCall) {
+        repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
+        return;
     }
 
-    // patch the call so we do not continue to try to link.
+    ASSERT(kind == CodeForConstruct);
     repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());
 }
 

Modified: trunk/Source/_javascript_Core/jit/JIT.h (90413 => 90414)


--- trunk/Source/_javascript_Core/jit/JIT.h	2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2011-07-05 23:18:23 UTC (rev 90414)
@@ -246,8 +246,7 @@
             return jit.privateCompilePatchGetArrayLength(returnAddress);
         }
 
-        static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
-        static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
+        static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*, CodeSpecializationKind);
 
     private:
         struct JSRInfo {

Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (90413 => 90414)


--- trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp	2011-07-05 23:18:23 UTC (rev 90414)
@@ -1902,20 +1902,13 @@
     return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
 }
 
-DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
+inline void* jitCompileFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
 {
-    STUB_INIT_STACK_FRAME(stackFrame);
-
-#if !ASSERT_DISABLED
-    CallData callData;
-    ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
-#endif
-
     JSFunction* function = asFunction(stackFrame.callFrame->callee());
     ASSERT(!function->isHostFunction());
     FunctionExecutable* executable = function->jsExecutable();
     ScopeChainNode* callDataScopeChain = function->scope();
-    JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain);
+    JSObject* error = executable->compileFor(stackFrame.callFrame, callDataScopeChain, kind);
     if (error) {
         stackFrame.callFrame->globalData().exception = error;
         return 0;
@@ -1923,6 +1916,18 @@
     return function;
 }
 
+DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+#if !ASSERT_DISABLED
+    CallData callData;
+    ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
+#endif
+    
+    return jitCompileFor(stackFrame, CodeForCall);
+}
+
 DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
@@ -1931,27 +1936,16 @@
     ConstructData constructData;
     ASSERT(asFunction(stackFrame.callFrame->callee())->getConstructData(constructData) == ConstructTypeJS);
 #endif
-
-    JSFunction* function = asFunction(stackFrame.callFrame->callee());
-    ASSERT(!function->isHostFunction());
-    FunctionExecutable* executable = function->jsExecutable();
-    ScopeChainNode* callDataScopeChain = function->scope();
-    JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain);
-    if (error) {
-        stackFrame.callFrame->globalData().exception = error;
-        return 0;
-    }
-    return function;
+    
+    return jitCompileFor(stackFrame, CodeForConstruct);
 }
 
-DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
+inline void* arityCheckFor(JITStackFrame& stackFrame, CodeSpecializationKind kind, ReturnAddressPtr& stubReturnAddress)
 {
-    STUB_INIT_STACK_FRAME(stackFrame);
-
     CallFrame* callFrame = stackFrame.callFrame;
     JSFunction* callee = asFunction(callFrame->callee());
     ASSERT(!callee->isHostFunction());
-    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForCall();
+    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
     int argCount = callFrame->argumentCountIncludingThis();
     ReturnAddressPtr pc = callFrame->returnPC();
 
@@ -1968,7 +1962,7 @@
             // Rewind to the previous call frame because op_call already optimistically
             // moved the call frame forward.
             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
-            STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
+            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
             return handler.callFrame;
         }
 
@@ -1983,7 +1977,7 @@
             // Rewind to the previous call frame because op_call already optimistically
             // moved the call frame forward.
             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
-            STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
+            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
             return handler.callFrame;
         }
 
@@ -2003,68 +1997,22 @@
     return callFrame;
 }
 
+DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    return arityCheckFor(stackFrame, CodeForCall, STUB_RETURN_ADDRESS);
+}
+
 DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
 
-    CallFrame* callFrame = stackFrame.callFrame;
-    JSFunction* callee = asFunction(callFrame->callee());
-    ASSERT(!callee->isHostFunction());
-    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForConstruct();
-    int argCount = callFrame->argumentCountIncludingThis();
-    ReturnAddressPtr pc = callFrame->returnPC();
-
-    ASSERT(argCount != newCodeBlock->m_numParameters);
-
-    CallFrame* oldCallFrame = callFrame->callerFrame();
-
-    Register* r;
-    if (argCount > newCodeBlock->m_numParameters) {
-        size_t numParameters = newCodeBlock->m_numParameters;
-        r = callFrame->registers() + numParameters;
-        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
-        if (!stackFrame.registerFile->grow(newEnd)) {
-            // Rewind to the previous call frame because op_call already optimistically
-            // moved the call frame forward.
-            ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
-            STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
-            return handler.callFrame;
-        }
-
-        Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
-        for (size_t i = 0; i < numParameters; ++i)
-            argv[i + argCount] = argv[i];
-    } else {
-        size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
-        r = callFrame->registers() + omittedArgCount;
-        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
-        if (!stackFrame.registerFile->grow(newEnd)) {
-            // Rewind to the previous call frame because op_call already optimistically
-            // moved the call frame forward.
-            ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
-            STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
-            return handler.callFrame;
-        }
-
-        Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
-        for (size_t i = 0; i < omittedArgCount; ++i)
-            argv[i] = jsUndefined();
-    }
-
-    callFrame = CallFrame::create(r);
-    callFrame->setCallerFrame(oldCallFrame);
-    callFrame->setArgumentCountIncludingThis(argCount);
-    callFrame->setCallee(callee);
-    callFrame->setScopeChain(callee->scope());
-    callFrame->setReturnPC(pc.value());
-
-    ASSERT((void*)callFrame <= stackFrame.registerFile->end());
-    return callFrame;
+    return arityCheckFor(stackFrame, CodeForConstruct, STUB_RETURN_ADDRESS);
 }
 
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
+inline void* lazyLinkFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
 {
-    STUB_INIT_STACK_FRAME(stackFrame);
     CallFrame* callFrame = stackFrame.callFrame;
     JSFunction* callee = asFunction(callFrame->callee());
     ExecutableBase* executable = callee->executable();
@@ -2072,62 +2020,42 @@
     MacroAssemblerCodePtr codePtr;
     CodeBlock* codeBlock = 0;
     if (executable->isHostFunction())
-        codePtr = executable->generatedJITCodeForCall().addressForCall();
+        codePtr = executable->generatedJITCodeFor(kind).addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope());
+        JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind);
         if (error) {
             callFrame->globalData().exception = createStackOverflowError(callFrame);
             return 0;
         }
-        codeBlock = &functionExecutable->generatedBytecodeForCall();
+        codeBlock = &functionExecutable->generatedBytecodeFor(kind);
         if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
-            codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
+            codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
         else
-            codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
+            codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
     }
     CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
 
     if (!callLinkInfo->seenOnce())
         callLinkInfo->setSeen();
     else
-        JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
+        JIT::linkFor(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData, kind);
 
     return codePtr.executableAddress();
 }
 
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
-    CallFrame* callFrame = stackFrame.callFrame;
-    JSFunction* callee = asFunction(callFrame->callee());
-    ExecutableBase* executable = callee->executable();
+    
+    return lazyLinkFor(stackFrame, CodeForCall);
+}
 
-    MacroAssemblerCodePtr codePtr;
-    CodeBlock* codeBlock = 0;
-    if (executable->isHostFunction())
-        codePtr = executable->generatedJITCodeForConstruct().addressForCall();
-    else {
-        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope());
-        if (error) {
-            throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
-            return 0;
-        }
-        codeBlock = &functionExecutable->generatedBytecodeForConstruct();
-        if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
-            codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall();
-        else
-            codePtr = functionExecutable->generatedJITCodeForConstructWithArityCheck();
-    }
-    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
-
-    if (!callLinkInfo->seenOnce())
-        callLinkInfo->setSeen();
-    else
-        JIT::linkConstruct(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
-
-    return codePtr.executableAddress();
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    return lazyLinkFor(stackFrame, CodeForConstruct);
 }
 
 DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)

Modified: trunk/Source/_javascript_Core/runtime/Executable.h (90413 => 90414)


--- trunk/Source/_javascript_Core/runtime/Executable.h	2011-07-05 23:16:18 UTC (rev 90413)
+++ trunk/Source/_javascript_Core/runtime/Executable.h	2011-07-05 23:18:23 UTC (rev 90414)
@@ -43,6 +43,8 @@
     class ScopeChainNode;
 
     struct ExceptionInfo;
+    
+    enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
 
     class ExecutableBase : public JSCell {
         friend class JIT;
@@ -91,6 +93,14 @@
             ASSERT(m_jitCodeForConstruct);
             return m_jitCodeForConstruct;
         }
+        
+        JITCode& generatedJITCodeFor(CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return generatedJITCodeForCall();
+            ASSERT(kind == CodeForConstruct);
+            return generatedJITCodeForConstruct();
+        }
 
         void clearExecutableCode()
         {
@@ -387,6 +397,30 @@
             ASSERT(m_codeBlockForConstruct);
             return *m_codeBlockForConstruct;
         }
+        
+        JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return compileForCall(exec, scopeChainNode);
+            ASSERT(kind == CodeForConstruct);
+            return compileForConstruct(exec, scopeChainNode);
+        }
+        
+        bool isGeneratedFor(CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return isGeneratedForCall();
+            ASSERT(kind == CodeForConstruct);
+            return isGeneratedForConstruct();
+        }
+        
+        FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return generatedBytecodeForCall();
+            ASSERT(kind == CodeForConstruct);
+            return generatedBytecodeForConstruct();
+        }
 
         const Identifier& name() { return m_name; }
         size_t parameterCount() const { return m_parameters->size(); }
@@ -437,6 +471,14 @@
             ASSERT(m_jitCodeForConstructWithArityCheck);
             return m_jitCodeForConstructWithArityCheck;
         }
+        
+        MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return generatedJITCodeForCallWithArityCheck();
+            ASSERT(kind == CodeForConstruct);
+            return generatedJITCodeForConstructWithArityCheck();
+        }
 #endif
     };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to