Changeset 90414 in webkit
- Timestamp:
- Jul 5, 2011 4:18:23 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r90404 r90414 1 2011-07-05 Filip Pizlo <fpizlo@apple.com> 2 3 JSC JIT has code duplication for the handling of call and construct 4 https://bugs.webkit.org/show_bug.cgi?id=63957 5 6 Reviewed by Gavin Barraclough. 7 8 * jit/JIT.cpp: 9 (JSC::JIT::linkFor): 10 * jit/JIT.h: 11 * jit/JITStubs.cpp: 12 (JSC::jitCompileFor): 13 (JSC::DEFINE_STUB_FUNCTION): 14 (JSC::arityCheckFor): 15 (JSC::lazyLinkFor): 16 * runtime/Executable.h: 17 (JSC::ExecutableBase::generatedJITCodeFor): 18 (JSC::FunctionExecutable::compileFor): 19 (JSC::FunctionExecutable::isGeneratedFor): 20 (JSC::FunctionExecutable::generatedBytecodeFor): 21 (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor): 22 1 23 2011-07-05 Gavin Barraclough <barraclough@apple.com> 2 24 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r90371 r90414 610 610 } 611 611 612 void JIT::link Call(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)612 void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData, CodeSpecializationKind kind) 613 613 { 614 614 RepatchBuffer repatchBuffer(callerCodeBlock); … … 623 623 624 624 // patch the call so we do not continue to try to link. 625 repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall()); 626 } 627 628 void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData) 629 { 630 RepatchBuffer repatchBuffer(callerCodeBlock); 631 632 // Currently we only link calls with the exact number of arguments. 633 // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant 634 if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) { 635 ASSERT(!callLinkInfo->isLinked()); 636 callLinkInfo->callee.set(*globalData, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee); 637 repatchBuffer.relink(callLinkInfo->hotPathOther, code); 638 } 639 640 // patch the call so we do not continue to try to link. 625 if (kind == CodeForCall) { 626 repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall()); 627 return; 628 } 629 630 ASSERT(kind == CodeForConstruct); 641 631 repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct()); 642 632 } -
trunk/Source/JavaScriptCore/jit/JIT.h
r90371 r90414 247 247 } 248 248 249 static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*); 250 static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*); 249 static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*, CodeSpecializationKind); 251 250 252 251 private: -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r90401 r90414 1903 1903 } 1904 1904 1905 inline void* jitCompileFor(JITStackFrame& stackFrame, CodeSpecializationKind kind) 1906 { 1907 JSFunction* function = asFunction(stackFrame.callFrame->callee()); 1908 ASSERT(!function->isHostFunction()); 1909 FunctionExecutable* executable = function->jsExecutable(); 1910 ScopeChainNode* callDataScopeChain = function->scope(); 1911 JSObject* error = executable->compileFor(stackFrame.callFrame, callDataScopeChain, kind); 1912 if (error) { 1913 stackFrame.callFrame->globalData().exception = error; 1914 return 0; 1915 } 1916 return function; 1917 } 1918 1905 1919 DEFINE_STUB_FUNCTION(void*, op_call_jitCompile) 1906 1920 { … … 1911 1925 ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS); 1912 1926 #endif 1913 1914 JSFunction* function = asFunction(stackFrame.callFrame->callee()); 1915 ASSERT(!function->isHostFunction()); 1916 FunctionExecutable* executable = function->jsExecutable(); 1917 ScopeChainNode* callDataScopeChain = function->scope(); 1918 JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain); 1919 if (error) { 1920 stackFrame.callFrame->globalData().exception = error; 1921 return 0; 1922 } 1923 return function; 1927 1928 return jitCompileFor(stackFrame, CodeForCall); 1924 1929 } 1925 1930 … … 1932 1937 ASSERT(asFunction(stackFrame.callFrame->callee())->getConstructData(constructData) == ConstructTypeJS); 1933 1938 #endif 1934 1935 JSFunction* function = asFunction(stackFrame.callFrame->callee()); 1936 ASSERT(!function->isHostFunction()); 1937 FunctionExecutable* executable = function->jsExecutable(); 1938 ScopeChainNode* callDataScopeChain = function->scope(); 1939 JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain); 1940 if (error) { 1941 stackFrame.callFrame->globalData().exception = error; 1942 return 0; 1943 } 1944 return function; 1945 } 1946 1947 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) 1948 { 1949 STUB_INIT_STACK_FRAME(stackFrame); 1950 1939 1940 return jitCompileFor(stackFrame, CodeForConstruct); 1941 } 1942 1943 inline void* arityCheckFor(JITStackFrame& stackFrame, CodeSpecializationKind kind, ReturnAddressPtr& stubReturnAddress) 1944 { 1951 1945 CallFrame* callFrame = stackFrame.callFrame; 1952 1946 JSFunction* callee = asFunction(callFrame->callee()); 1953 1947 ASSERT(!callee->isHostFunction()); 1954 CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor Call();1948 CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind); 1955 1949 int argCount = callFrame->argumentCountIncludingThis(); 1956 1950 ReturnAddressPtr pc = callFrame->returnPC(); … … 1969 1963 // moved the call frame forward. 1970 1964 ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc); 1971 STUB_SET_RETURN_ADDRESS(handler.catchRoutine);1965 stubReturnAddress = ReturnAddressPtr(handler.catchRoutine); 1972 1966 return handler.callFrame; 1973 1967 } … … 1984 1978 // moved the call frame forward. 1985 1979 ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc); 1986 STUB_SET_RETURN_ADDRESS(handler.catchRoutine);1980 stubReturnAddress = ReturnAddressPtr(handler.catchRoutine); 1987 1981 return handler.callFrame; 1988 1982 } … … 2004 1998 } 2005 1999 2000 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) 2001 { 2002 STUB_INIT_STACK_FRAME(stackFrame); 2003 2004 return arityCheckFor(stackFrame, CodeForCall, STUB_RETURN_ADDRESS); 2005 } 2006 2006 2007 DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) 2007 2008 { 2008 2009 STUB_INIT_STACK_FRAME(stackFrame); 2009 2010 2010 CallFrame* callFrame = stackFrame.callFrame; 2011 JSFunction* callee = asFunction(callFrame->callee()); 2012 ASSERT(!callee->isHostFunction()); 2013 CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForConstruct(); 2014 int argCount = callFrame->argumentCountIncludingThis(); 2015 ReturnAddressPtr pc = callFrame->returnPC(); 2016 2017 ASSERT(argCount != newCodeBlock->m_numParameters); 2018 2019 CallFrame* oldCallFrame = callFrame->callerFrame(); 2020 2021 Register* r; 2022 if (argCount > newCodeBlock->m_numParameters) { 2023 size_t numParameters = newCodeBlock->m_numParameters; 2024 r = callFrame->registers() + numParameters; 2025 Register* newEnd = r + newCodeBlock->m_numCalleeRegisters; 2026 if (!stackFrame.registerFile->grow(newEnd)) { 2027 // Rewind to the previous call frame because op_call already optimistically 2028 // moved the call frame forward. 2029 ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc); 2030 STUB_SET_RETURN_ADDRESS(handler.catchRoutine); 2031 return handler.callFrame; 2032 } 2033 2034 Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; 2035 for (size_t i = 0; i < numParameters; ++i) 2036 argv[i + argCount] = argv[i]; 2037 } else { 2038 size_t omittedArgCount = newCodeBlock->m_numParameters - argCount; 2039 r = callFrame->registers() + omittedArgCount; 2040 Register* newEnd = r + newCodeBlock->m_numCalleeRegisters; 2041 if (!stackFrame.registerFile->grow(newEnd)) { 2042 // Rewind to the previous call frame because op_call already optimistically 2043 // moved the call frame forward. 2044 ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc); 2045 STUB_SET_RETURN_ADDRESS(handler.catchRoutine); 2046 return handler.callFrame; 2047 } 2048 2049 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; 2050 for (size_t i = 0; i < omittedArgCount; ++i) 2051 argv[i] = jsUndefined(); 2052 } 2053 2054 callFrame = CallFrame::create(r); 2055 callFrame->setCallerFrame(oldCallFrame); 2056 callFrame->setArgumentCountIncludingThis(argCount); 2057 callFrame->setCallee(callee); 2058 callFrame->setScopeChain(callee->scope()); 2059 callFrame->setReturnPC(pc.value()); 2060 2061 ASSERT((void*)callFrame <= stackFrame.registerFile->end()); 2062 return callFrame; 2063 } 2064 2065 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall) 2066 { 2067 STUB_INIT_STACK_FRAME(stackFrame); 2011 return arityCheckFor(stackFrame, CodeForConstruct, STUB_RETURN_ADDRESS); 2012 } 2013 2014 inline void* lazyLinkFor(JITStackFrame& stackFrame, CodeSpecializationKind kind) 2015 { 2068 2016 CallFrame* callFrame = stackFrame.callFrame; 2069 2017 JSFunction* callee = asFunction(callFrame->callee()); … … 2073 2021 CodeBlock* codeBlock = 0; 2074 2022 if (executable->isHostFunction()) 2075 codePtr = executable->generatedJITCodeFor Call().addressForCall();2023 codePtr = executable->generatedJITCodeFor(kind).addressForCall(); 2076 2024 else { 2077 2025 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 2078 JSObject* error = functionExecutable->compileFor Call(callFrame, callee->scope());2026 JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind); 2079 2027 if (error) { 2080 2028 callFrame->globalData().exception = createStackOverflowError(callFrame); 2081 2029 return 0; 2082 2030 } 2083 codeBlock = &functionExecutable->generatedBytecodeFor Call();2031 codeBlock = &functionExecutable->generatedBytecodeFor(kind); 2084 2032 if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters)) 2085 codePtr = functionExecutable->generatedJITCodeFor Call().addressForCall();2033 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); 2086 2034 else 2087 codePtr = functionExecutable->generatedJITCode ForCallWithArityCheck();2035 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); 2088 2036 } 2089 2037 CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC()); … … 2092 2040 callLinkInfo->setSeen(); 2093 2041 else 2094 JIT::link Call(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);2042 JIT::linkFor(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData, kind); 2095 2043 2096 2044 return codePtr.executableAddress(); 2097 2045 } 2098 2046 2047 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall) 2048 { 2049 STUB_INIT_STACK_FRAME(stackFrame); 2050 2051 return lazyLinkFor(stackFrame, CodeForCall); 2052 } 2053 2099 2054 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct) 2100 2055 { 2101 2056 STUB_INIT_STACK_FRAME(stackFrame); 2102 CallFrame* callFrame = stackFrame.callFrame; 2103 JSFunction* callee = asFunction(callFrame->callee()); 2104 ExecutableBase* executable = callee->executable(); 2105 2106 MacroAssemblerCodePtr codePtr; 2107 CodeBlock* codeBlock = 0; 2108 if (executable->isHostFunction()) 2109 codePtr = executable->generatedJITCodeForConstruct().addressForCall(); 2110 else { 2111 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 2112 JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope()); 2113 if (error) { 2114 throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS); 2115 return 0; 2116 } 2117 codeBlock = &functionExecutable->generatedBytecodeForConstruct(); 2118 if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters)) 2119 codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall(); 2120 else 2121 codePtr = functionExecutable->generatedJITCodeForConstructWithArityCheck(); 2122 } 2123 CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC()); 2124 2125 if (!callLinkInfo->seenOnce()) 2126 callLinkInfo->setSeen(); 2127 else 2128 JIT::linkConstruct(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData); 2129 2130 return codePtr.executableAddress(); 2057 2058 return lazyLinkFor(stackFrame, CodeForConstruct); 2131 2059 } 2132 2060 -
trunk/Source/JavaScriptCore/runtime/Executable.h
r89973 r90414 44 44 45 45 struct ExceptionInfo; 46 47 enum CodeSpecializationKind { CodeForCall, CodeForConstruct }; 46 48 47 49 class ExecutableBase : public JSCell { … … 91 93 ASSERT(m_jitCodeForConstruct); 92 94 return m_jitCodeForConstruct; 95 } 96 97 JITCode& generatedJITCodeFor(CodeSpecializationKind kind) 98 { 99 if (kind == CodeForCall) 100 return generatedJITCodeForCall(); 101 ASSERT(kind == CodeForConstruct); 102 return generatedJITCodeForConstruct(); 93 103 } 94 104 … … 388 398 return *m_codeBlockForConstruct; 389 399 } 400 401 JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind) 402 { 403 if (kind == CodeForCall) 404 return compileForCall(exec, scopeChainNode); 405 ASSERT(kind == CodeForConstruct); 406 return compileForConstruct(exec, scopeChainNode); 407 } 408 409 bool isGeneratedFor(CodeSpecializationKind kind) 410 { 411 if (kind == CodeForCall) 412 return isGeneratedForCall(); 413 ASSERT(kind == CodeForConstruct); 414 return isGeneratedForConstruct(); 415 } 416 417 FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind) 418 { 419 if (kind == CodeForCall) 420 return generatedBytecodeForCall(); 421 ASSERT(kind == CodeForConstruct); 422 return generatedBytecodeForConstruct(); 423 } 390 424 391 425 const Identifier& name() { return m_name; } … … 437 471 ASSERT(m_jitCodeForConstructWithArityCheck); 438 472 return m_jitCodeForConstructWithArityCheck; 473 } 474 475 MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind) 476 { 477 if (kind == CodeForCall) 478 return generatedJITCodeForCallWithArityCheck(); 479 ASSERT(kind == CodeForConstruct); 480 return generatedJITCodeForConstructWithArityCheck(); 439 481 } 440 482 #endif
Note: See TracChangeset
for help on using the changeset viewer.