Changeset 43220 in webkit for trunk/JavaScriptCore/jit
- Timestamp:
- May 5, 2009, 4:34:23 AM (16 years ago)
- Location:
- trunk/JavaScriptCore/jit
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JIT.cpp
r43122 r43220 1765 1765 } 1766 1766 1767 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall)1767 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall, void** ctiNativeCallThunk) 1768 1768 { 1769 1769 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) … … 1814 1814 1815 1815 // Load the callee CodeBlock* into eax 1816 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT 0);1817 loadPtr(Address(regT 0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);1816 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT3); 1817 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0); 1818 1818 Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0); 1819 // If m_code is null and m_jitCode is not, then we have a native function, so arity is irrelevant 1820 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_jitCode)), regT0); 1821 Jump isNativeFunc1 = branchTestPtr(NonZero, regT0); 1819 1822 pop(regT3); 1820 1823 restoreArgumentReference(); … … 1837 1840 push(regT3); 1838 1841 arityCheckOkay1.link(this); 1842 isNativeFunc1.link(this); 1839 1843 1840 1844 compileOpCallInitializeCallFrame(); … … 1844 1848 restoreArgumentReference(); 1845 1849 Call callDontLazyLinkCall = call(); 1850 emitGetJITStubArg(1, regT2); 1846 1851 push(regT3); 1847 1852 … … 1851 1856 1852 1857 // Load the callee CodeBlock* into eax 1853 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT 0);1854 loadPtr(Address(regT 0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);1858 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT3); 1859 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0); 1855 1860 Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0); 1861 // If m_code is null and m_jitCode is not, then we have a native function, so arity is irrelevant 1862 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_jitCode)), regT0); 1863 Jump isNativeFunc2 = branchTestPtr(NonZero, regT0); 1856 1864 pop(regT3); 1857 1865 restoreArgumentReference(); … … 1874 1882 push(regT3); 1875 1883 arityCheckOkay2.link(this); 1884 isNativeFunc2.link(this); 1876 1885 1877 1886 compileOpCallInitializeCallFrame(); … … 1888 1897 1889 1898 // Load the callee CodeBlock* into eax 1890 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT 0);1891 loadPtr(Address(regT 0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);1899 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT3); 1900 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0); 1892 1901 Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0); 1902 // If m_code is null and m_jitCode is not, then we have a native function, so arity is irrelevant 1903 loadPtr(Address(regT3, FIELD_OFFSET(FunctionBodyNode, m_jitCode)), regT0); 1904 Jump isNativeFunc3 = branchTestPtr(NonZero, regT0); 1893 1905 pop(regT3); 1894 1906 restoreArgumentReference(); … … 1911 1923 push(regT3); 1912 1924 arityCheckOkay3.link(this); 1913 1914 compileOpCallInitializeCallFrame();1915 1916 1925 // load ctiCode from the new codeBlock. 1917 1926 loadPtr(Address(regT0, FIELD_OFFSET(CodeBlock, m_jitCode)), regT0); 1918 1927 1928 isNativeFunc3.link(this); 1929 1930 compileOpCallInitializeCallFrame(); 1919 1931 jump(regT0); 1932 1933 1934 Label nativeCallThunk = align(); 1935 pop(regT0); 1936 emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address 1937 1938 // Load caller frame's scope chain into this callframe so that whatever we call can 1939 // get to its global data. 1940 emitGetFromCallFrameHeader(RegisterFile::CallerFrame, regT1); 1941 emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT1, regT1); 1942 emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); 1943 1944 1945 #if PLATFORM(X86_64) 1946 emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86::ecx); 1947 1948 // Allocate stack space for our arglist 1949 subPtr(Imm32(sizeof(ArgList)), stackPointerRegister); 1950 COMPILE_ASSERT((sizeof(ArgList) & 0xf) == 0, ArgList_should_by_16byte_aligned); 1951 1952 // Set up arguments 1953 subPtr(Imm32(1), X86::ecx); // Don't include 'this' in argcount 1954 1955 // Push argcount 1956 storePtr(X86::ecx, Address(stackPointerRegister, FIELD_OFFSET(ArgList, m_argCount))); 1957 1958 // Calculate the start of the callframe header, and store in edx 1959 addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), callFrameRegister, X86::edx); 1960 1961 // Calculate start of arguments as callframe header - sizeof(Register) * argcount (ecx) 1962 mul32(Imm32(sizeof(Register)), X86::ecx, X86::ecx); 1963 subPtr(X86::ecx, X86::edx); 1964 1965 // push pointer to arguments 1966 storePtr(X86::edx, Address(stackPointerRegister, FIELD_OFFSET(ArgList, m_args))); 1967 1968 // ArgList is passed by reference so is stackPointerRegister 1969 move(stackPointerRegister, X86::ecx); 1970 1971 // edx currently points to the first argument, edx-sizeof(Register) points to 'this' 1972 loadPtr(Address(X86::edx, -(int32_t)sizeof(Register)), X86::edx); 1973 1974 emitGetFromCallFrameHeader(RegisterFile::Callee, X86::esi); 1975 1976 move(callFrameRegister, X86::edi); 1977 1978 call(Address(X86::esi, FIELD_OFFSET(JSFunction, m_data))); 1979 1980 addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); 1981 #else 1982 emitGetFromCallFrameHeader(RegisterFile::ArgumentCount, regT0); 1983 1984 struct NativeFunctionSignature { 1985 CallFrame* callFrame; 1986 JSObject* callee; 1987 JSValue thisValue; 1988 ArgList* argPointer; 1989 ArgList args; 1990 }; 1991 const int NativeCallFrameSize = (sizeof(NativeFunctionSignature) + 15) & ~15; 1992 // Allocate system stack frame 1993 subPtr(Imm32(NativeCallFrameSize), stackPointerRegister); 1994 1995 // Set up arguments 1996 subPtr(Imm32(1), regT0); // Don't include 'this' in argcount 1997 1998 // push argcount 1999 storePtr(regT0, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, args) + FIELD_OFFSET(ArgList, m_argCount))); 2000 2001 // Calculate the start of the callframe header, and store in regT1 2002 addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * sizeof(Register)), callFrameRegister, regT1); 2003 2004 // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0) 2005 mul32(Imm32(sizeof(Register)), regT0, regT0); 2006 subPtr(regT0, regT1); 2007 storePtr(regT1, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, args) + FIELD_OFFSET(ArgList, m_args))); 2008 2009 // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) 2010 addPtr(Imm32(FIELD_OFFSET(NativeFunctionSignature, args)), stackPointerRegister, regT0); 2011 storePtr(regT0, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, argPointer))); 2012 2013 // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this' 2014 loadPtr(Address(regT1, -sizeof(Register)), regT1); 2015 poke(regT1, 2); 2016 storePtr(regT1, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, thisValue))); 2017 2018 // Plant callee 2019 emitGetFromCallFrameHeader(RegisterFile::Callee, regT2); 2020 storePtr(regT2, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, callee))); 2021 2022 // Plant callframe 2023 storePtr(callFrameRegister, Address(stackPointerRegister, FIELD_OFFSET(NativeFunctionSignature, callFrame))); 2024 2025 call(Address(regT2, FIELD_OFFSET(JSFunction, m_data))); 2026 addPtr(Imm32(NativeCallFrameSize), stackPointerRegister); 2027 #endif 2028 2029 // Check for an exception 2030 loadPtr(&(globalData->exception), regT2); 2031 Jump exceptionHandler = branchTestPtr(NonZero, regT2); 2032 2033 // Grab the return address. 2034 emitGetFromCallFrameHeader(RegisterFile::ReturnPC, regT1); 2035 2036 // Restore our caller's "r". 2037 emitGetFromCallFrameHeader(RegisterFile::CallerFrame, callFrameRegister); 2038 2039 // Return. 2040 push(regT1); 2041 ret(); 2042 2043 // Handle an exception 2044 exceptionHandler.link(this); 2045 // Grab the return address. 2046 emitGetFromCallFrameHeader(RegisterFile::ReturnPC, regT1); 2047 move(ImmPtr(&globalData->exceptionLocation), regT2); 2048 storePtr(regT1, regT2); 2049 move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2); 2050 emitGetFromCallFrameHeader(RegisterFile::CallerFrame, callFrameRegister); 2051 emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame); 2052 push(regT2); 2053 ret(); 2054 1920 2055 1921 2056 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) … … 1959 2094 *ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin); 1960 2095 *ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin); 2096 *ctiNativeCallThunk = patchBuffer.trampolineAt(nativeCallThunk); 1961 2097 } 1962 2098 -
trunk/JavaScriptCore/jit/JIT.h
r43122 r43220 363 363 } 364 364 365 static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall )365 static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall, void** ctiNativeCallThunk) 366 366 367 367 { 368 368 JIT jit(globalData); 369 jit.privateCompileCTIMachineTrampolines(executablePool, ctiArrayLengthTrampoline, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall);369 jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiArrayLengthTrampoline, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk); 370 370 } 371 371 … … 400 400 void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ProcessorReturnAddress returnAddress); 401 401 402 void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall);402 void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall, void** ctiNativeCallThunk); 403 403 void privateCompilePatchGetArrayLength(ProcessorReturnAddress returnAddress); 404 404 … … 468 468 void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry); 469 469 void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry); 470 void emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to); 470 void emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister); 471 void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to); 471 472 472 473 JSValue getConstantOperand(unsigned src); -
trunk/JavaScriptCore/jit/JITCall.cpp
r43153 r43220 57 57 { 58 58 // Currently we only link calls with the exact number of arguments. 59 if (callerArgCount == calleeCodeBlock->m_numParameters) { 59 // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant 60 if (!calleeCodeBlock || callerArgCount == calleeCodeBlock->m_numParameters) { 60 61 ASSERT(!callLinkInfo->isLinked()); 61 62 62 calleeCodeBlock->addCaller(callLinkInfo); 63 if (calleeCodeBlock) 64 calleeCodeBlock->addCaller(callLinkInfo); 63 65 64 66 callLinkInfo->hotPathBegin.repatch(callee); … … 74 76 store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); 75 77 76 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_ scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain78 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_data) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain 77 79 78 80 storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)))); … … 243 245 storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)))); 244 246 storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)))); 245 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_ scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain247 loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_data) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain 246 248 store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)))); 247 249 storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)))); -
trunk/JavaScriptCore/jit/JITCode.h
r43122 r43220 57 57 } 58 58 59 operator bool() 59 operator bool() const 60 60 { 61 61 return code != 0; -
trunk/JavaScriptCore/jit/JITInlineMethods.h
r43122 r43220 169 169 } 170 170 171 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to) 172 { 173 loadPtr(Address(callFrameRegister, entry * sizeof(Register)), to); 171 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) 172 { 173 loadPtr(Address(from, entry * sizeof(Register)), to); 174 killLastResultRegister(); 175 } 176 177 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to) 178 { 179 load32(Address(callFrameRegister, entry * sizeof(Register)), to); 174 180 killLastResultRegister(); 175 181 } -
trunk/JavaScriptCore/jit/JITStubs.cpp
r43153 r43220 75 75 , m_ctiVirtualCallLink(0) 76 76 , m_ctiVirtualCall(0) 77 { 78 JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiArrayLengthTrampoline, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall); 77 , m_ctiNativeCallThunk(0) 78 { 79 JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiArrayLengthTrampoline, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); 79 80 } 80 81 … … 820 821 #endif 821 822 822 ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->scope().node(); 823 CodeBlock* newCodeBlock = &asFunction(ARG_src1)->body()->bytecode(callDataScopeChain); 824 825 if (!newCodeBlock->jitCode()) 826 JIT::compile(ARG_globalData, newCodeBlock); 827 828 return newCodeBlock; 823 JSFunction* function = asFunction(ARG_src1); 824 FunctionBodyNode* body = function->body(); 825 ScopeChainNode* callDataScopeChain = function->scope().node(); 826 body->jitCode(callDataScopeChain); 827 828 return &(body->generatedBytecode()); 829 829 } 830 830 … … 880 880 JSGlobalData* globalData = ARG_globalData; 881 881 JSFunction* callee = asFunction(ARG_src1); 882 CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node()); 883 if (!codeBlock->jitCode()) 884 JIT::compile(globalData, codeBlock); 882 JITCode jitCode = callee->body()->generatedJITCode(); 883 ASSERT(jitCode); 885 884 886 885 ctiPatchNearCallByReturnAddress(ARG_returnAddress2, globalData->jitStubs.ctiVirtualCallLink()); 887 886 888 return codeBlock->jitCode().addressForCall();887 return jitCode.addressForCall(); 889 888 } 890 889 … … 894 893 895 894 JSFunction* callee = asFunction(ARG_src1); 896 CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node()); 897 if (!codeBlock->jitCode()) 898 JIT::compile(ARG_globalData, codeBlock); 895 JITCode jitCode = callee->body()->generatedJITCode(); 896 ASSERT(jitCode); 897 898 CodeBlock* codeBlock = 0; 899 if (!callee->isHostFunction()) 900 codeBlock = &callee->body()->bytecode(callee->scope().node()); 899 901 900 902 CallLinkInfo* callLinkInfo = &ARG_callFrame->callerFrame()->codeBlock()->getCallLinkInfo(ARG_returnAddress2); 901 JIT::linkCall(callee, codeBlock, codeBlock->jitCode(), callLinkInfo, ARG_int3);902 903 return codeBlock->jitCode().addressForCall();903 JIT::linkCall(callee, codeBlock, jitCode, callLinkInfo, ARG_int3); 904 905 return jitCode.addressForCall(); 904 906 } 905 907 … … 1060 1062 BEGIN_STUB_FUNCTION(); 1061 1063 1064 JSFunction* constructor = asFunction(ARG_src1); 1065 if (constructor->isHostFunction()) { 1066 CallFrame* callFrame = ARG_callFrame; 1067 CodeBlock* codeBlock = callFrame->codeBlock(); 1068 unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); 1069 ARG_globalData->exception = createNotAConstructorError(callFrame, constructor, vPCIndex, codeBlock); 1070 VM_THROW_EXCEPTION(); 1071 } 1072 1062 1073 #ifndef NDEBUG 1063 1074 ConstructData constructData; 1064 ASSERT( asFunction(ARG_src1)->getConstructData(constructData) == ConstructTypeJS);1075 ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS); 1065 1076 #endif 1066 1077 … … 1069 1080 structure = asObject(ARG_src4)->inheritorID(); 1070 1081 else 1071 structure = asFunction(ARG_src1)->scope().node()->globalObject()->emptyObjectStructure();1082 structure = constructor->scope().node()->globalObject()->emptyObjectStructure(); 1072 1083 return new (ARG_globalData) JSObject(structure); 1073 1084 } -
trunk/JavaScriptCore/jit/JITStubs.h
r43122 r43220 211 211 void* ctiVirtualCallLink() { return m_ctiVirtualCallLink; } 212 212 void* ctiVirtualCall() { return m_ctiVirtualCall; } 213 void* ctiNativeCallThunk() { return m_ctiNativeCallThunk; } 213 214 214 215 private: … … 220 221 void* m_ctiVirtualCallLink; 221 222 void* m_ctiVirtualCall; 223 void* m_ctiNativeCallThunk; 222 224 }; 223 225
Note:
See TracChangeset
for help on using the changeset viewer.