Changeset 163027 in webkit for trunk/Source/JavaScriptCore/jit/JITOperations.cpp
- Timestamp:
- Jan 29, 2014, 11:18:54 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r161220 r163027 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 #include "ArrayConstructor.h" 32 32 #include "CallFrameInlines.h" 33 #include "CommonSlowPaths.h"34 33 #include "DFGCompilationMode.h" 35 34 #include "DFGDriver.h" … … 37 36 #include "DFGWorklist.h" 38 37 #include "Error.h" 38 #include "ErrorHandlingScope.h" 39 39 #include "GetterSetter.h" 40 40 #include "HostCallReturnValue.h" … … 72 72 73 73 74 void JIT_OPERATION operation StackCheck(ExecState* exec, CodeBlock* codeBlock)74 void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock* codeBlock) 75 75 { 76 76 // We pass in our own code block, because the callframe hasn't been populated. … … 81 81 82 82 NativeCallFrameTracer tracer(vm, callerFrame); 83 84 JSStack& stack = vm->interpreter->stack(); 85 86 if (UNLIKELY(!stack.grow(&exec->registers()[virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset()]))) 87 vm->throwException(callerFrame, createStackOverflowError(callerFrame)); 83 ErrorHandlingScope errorScope(*vm); 84 vm->throwException(callerFrame, createStackOverflowError(callerFrame)); 88 85 } 89 86 … … 98 95 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall); 99 96 if (missingArgCount < 0) 100 vm->throwException(callerFrame, createStackOverflowError(callerFrame));97 throwStackOverflowError(callerFrame); 101 98 102 99 return missingArgCount; … … 113 110 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct); 114 111 if (missingArgCount < 0) 115 vm->throwException(callerFrame, createStackOverflowError(callerFrame));112 throwStackOverflowError(callerFrame); 116 113 117 114 return missingArgCount; … … 613 610 } 614 611 615 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* execCallee) 616 { 617 CallFrame* callerFrame = execCallee->callerFrame(); 618 ASSERT(execCallee->callerFrame()->codeBlock()->codeType() != FunctionCode 619 || !execCallee->callerFrame()->codeBlock()->needsFullScopeChain() 620 || execCallee->callerFrame()->uncheckedR(execCallee->callerFrame()->codeBlock()->activationRegister().offset()).jsValue()); 621 622 execCallee->setScope(callerFrame->scope()); 623 execCallee->setReturnPC(static_cast<Instruction*>(OUR_RETURN_ADDRESS)); 612 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee) 613 { 614 ASSERT(exec->codeBlock()->codeType() != FunctionCode 615 || !exec->codeBlock()->needsFullScopeChain() 616 || exec->uncheckedR(exec->codeBlock()->activationRegister().offset()).jsValue()); 617 618 execCallee->setScope(exec->scope()); 624 619 execCallee->setCodeBlock(0); 625 620 … … 686 681 } 687 682 688 inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) 683 inline char* linkFor( 684 ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers) 689 685 { 690 686 ExecState* exec = execCallee->callerFrame(); … … 705 701 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC()); 706 702 if (executable->isHostFunction()) 707 codePtr = executable-> generatedJITCodeFor(kind)->addressForCall();703 codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, registers); 708 704 else { 709 705 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); 710 706 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); 711 707 if (error) { 712 vm->throwException(exec, createStackOverflowError(exec));708 throwStackOverflowError(exec); 713 709 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); 714 710 } 715 711 codeBlock = functionExecutable->codeBlockFor(kind); 712 ArityCheckMode arity; 716 713 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs) 717 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);714 arity = MustCheckArity; 718 715 else 719 codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall(); 716 arity = ArityCheckNotRequired; 717 codePtr = functionExecutable->entrypointFor(*vm, kind, arity, registers); 720 718 } 721 719 if (!callLinkInfo.seenOnce()) 722 720 callLinkInfo.setSeen(); 723 721 else 724 linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind );722 linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind, registers); 725 723 return reinterpret_cast<char*>(codePtr.executableAddress()); 726 724 } … … 728 726 char* JIT_OPERATION operationLinkCall(ExecState* execCallee) 729 727 { 730 return linkFor(execCallee, CodeForCall );728 return linkFor(execCallee, CodeForCall, RegisterPreservationNotRequired); 731 729 } 732 730 733 731 char* JIT_OPERATION operationLinkConstruct(ExecState* execCallee) 734 732 { 735 return linkFor(execCallee, CodeForConstruct); 736 } 737 738 inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell) 733 return linkFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired); 734 } 735 736 char* JIT_OPERATION operationLinkCallThatPreservesRegs(ExecState* execCallee) 737 { 738 return linkFor(execCallee, CodeForCall, MustPreserveRegisters); 739 } 740 741 char* JIT_OPERATION operationLinkConstructThatPreservesRegs(ExecState* execCallee) 742 { 743 return linkFor(execCallee, CodeForConstruct, MustPreserveRegisters); 744 } 745 746 inline char* virtualForWithFunction( 747 ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers, 748 JSCell*& calleeAsFunctionCell) 739 749 { 740 750 ExecState* exec = execCallee->callerFrame(); … … 758 768 } 759 769 } 760 return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress()); 761 } 762 763 inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) 770 return reinterpret_cast<char*>(executable->entrypointFor( 771 *vm, kind, MustCheckArity, registers).executableAddress()); 772 } 773 774 inline char* virtualFor( 775 ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers) 764 776 { 765 777 JSCell* calleeAsFunctionCellIgnored; 766 return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored); 767 } 768 769 static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo) 778 return virtualForWithFunction(execCallee, kind, registers, calleeAsFunctionCellIgnored); 779 } 780 781 static bool attemptToOptimizeClosureCall( 782 ExecState* execCallee, RegisterPreservationMode registers, JSCell* calleeAsFunctionCell, 783 CallLinkInfo& callLinkInfo) 770 784 { 771 785 if (!calleeAsFunctionCell) … … 781 795 782 796 ASSERT(callee->executable()->hasJITCodeForCall()); 783 MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall()->addressForCall(); 797 MacroAssemblerCodePtr codePtr = 798 callee->executable()->generatedJITCodeForCall()->addressForCall( 799 *execCallee->callerFrame()->codeBlock()->vm(), callee->executable(), 800 ArityCheckNotRequired, registers); 784 801 785 802 CodeBlock* codeBlock; … … 794 811 linkClosureCall( 795 812 execCallee, callLinkInfo, codeBlock, 796 callee->structure(), callee->executable(), codePtr );813 callee->structure(), callee->executable(), codePtr, registers); 797 814 798 815 return true; … … 802 819 { 803 820 JSCell* calleeAsFunctionCell; 804 char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);821 char* result = virtualForWithFunction(execCallee, CodeForCall, RegisterPreservationNotRequired, calleeAsFunctionCell); 805 822 CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC()); 806 823 807 if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))808 linkSlowFor(execCallee, callLinkInfo, CodeForCall );824 if (!attemptToOptimizeClosureCall(execCallee, RegisterPreservationNotRequired, calleeAsFunctionCell, callLinkInfo)) 825 linkSlowFor(execCallee, callLinkInfo, CodeForCall, RegisterPreservationNotRequired); 809 826 810 827 return result; … … 813 830 char* JIT_OPERATION operationVirtualCall(ExecState* execCallee) 814 831 { 815 return virtualFor(execCallee, CodeForCall );832 return virtualFor(execCallee, CodeForCall, RegisterPreservationNotRequired); 816 833 } 817 834 818 835 char* JIT_OPERATION operationVirtualConstruct(ExecState* execCallee) 819 836 { 820 return virtualFor(execCallee, CodeForConstruct); 821 } 822 837 return virtualFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired); 838 } 839 840 char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState* execCallee) 841 { 842 JSCell* calleeAsFunctionCell; 843 char* result = virtualForWithFunction(execCallee, CodeForCall, MustPreserveRegisters, calleeAsFunctionCell); 844 CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC()); 845 846 if (!attemptToOptimizeClosureCall(execCallee, MustPreserveRegisters, calleeAsFunctionCell, callLinkInfo)) 847 linkSlowFor(execCallee, callLinkInfo, CodeForCall, MustPreserveRegisters); 848 849 return result; 850 } 851 852 char* JIT_OPERATION operationVirtualCallThatPreservesRegs(ExecState* execCallee) 853 { 854 return virtualFor(execCallee, CodeForCall, MustPreserveRegisters); 855 } 856 857 char* JIT_OPERATION operationVirtualConstructThatPreservesRegs(ExecState* execCallee) 858 { 859 return virtualFor(execCallee, CodeForConstruct, MustPreserveRegisters); 860 } 823 861 824 862 size_t JIT_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) … … 975 1013 976 1014 #if ENABLE(DFG_JIT) 977 char*JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex)1015 SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex) 978 1016 { 979 1017 VM& vm = exec->vm(); … … 1025 1063 if (Options::verboseOSR()) 1026 1064 dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n"); 1027 return 0;1065 return encodeResult(0, 0); 1028 1066 } 1029 1067 … … 1033 1071 if (Options::verboseOSR()) 1034 1072 dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n"); 1035 return 0;1073 return encodeResult(0, 0); 1036 1074 } 1037 1075 1038 1076 // We cannot be in the process of asynchronous compilation and also have an optimized 1039 1077 // replacement. 1078 DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull(); 1040 1079 ASSERT( 1041 ! vm.worklist1042 || !( vm.worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown1080 !worklist 1081 || !(worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown 1043 1082 && codeBlock->hasOptimizedReplacement())); 1044 1083 1045 1084 DFG::Worklist::State worklistState; 1046 if ( vm.worklist) {1085 if (worklist) { 1047 1086 // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready 1048 1087 // (i.e. compiled) code blocks. But if it completes ours, we also need to know … … 1063 1102 // possible in order to minimize the chances of us executing baseline code after 1064 1103 // optimized code is already available. 1065 worklistState = vm.worklist->completeAllReadyPlansForVM(1104 worklistState = worklist->completeAllReadyPlansForVM( 1066 1105 vm, DFG::CompilationKey(codeBlock, DFG::DFGMode)); 1067 1106 } else … … 1073 1112 RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement()); 1074 1113 codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred); 1075 return 0;1114 return encodeResult(0, 0); 1076 1115 } 1077 1116 … … 1086 1125 if (Options::verboseOSR()) 1087 1126 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n"); 1088 return 0;1127 return encodeResult(0, 0); 1089 1128 } 1090 1129 } else if (codeBlock->hasOptimizedReplacement()) { … … 1111 1150 } 1112 1151 codeBlock->replacement()->jettison(CountReoptimization); 1113 return 0;1152 return encodeResult(0, 0); 1114 1153 } 1115 1154 } else { … … 1120 1159 " because of insufficient profiling.\n"); 1121 1160 } 1122 return 0;1161 return encodeResult(0, 0); 1123 1162 } 1124 1163 … … 1148 1187 1149 1188 CompilationResult result = DFG::compile( 1150 vm, codeBlock->newReplacement().get(), DFG::DFGMode, bytecodeIndex, 1151 mustHandleValues, JITToDFGDeferredCompilationCallback::create(), 1152 vm.ensureWorklist()); 1189 vm, codeBlock->newReplacement().get(), 0, DFG::DFGMode, bytecodeIndex, 1190 mustHandleValues, JITToDFGDeferredCompilationCallback::create()); 1153 1191 1154 1192 if (result != CompilationSuccessful) 1155 return 0;1193 return encodeResult(0, 0); 1156 1194 } 1157 1195 … … 1167 1205 1168 1206 codeBlock->optimizeSoon(); 1169 return static_cast<char*>(address); 1207 ASSERT(exec->codeBlock() == optimizedCodeBlock); 1208 return encodeResult(address, exec->topOfFrame()); 1170 1209 } 1171 1210 … … 1196 1235 } 1197 1236 optimizedCodeBlock->jettison(CountReoptimization); 1198 return 0;1237 return encodeResult(0, 0); 1199 1238 } 1200 1239 … … 1203 1242 codeBlock->optimizeAfterWarmUp(); 1204 1243 1205 return 0;1244 return encodeResult(0, 0); 1206 1245 } 1207 1246 #endif … … 1531 1570 } 1532 1571 1533 CallFrame* JIT_OPERATION operationSize AndAllocFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister)1572 CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister) 1534 1573 { 1535 1574 VM& vm = exec->vm(); … … 1537 1576 JSStack* stack = &exec->interpreter()->stack(); 1538 1577 JSValue arguments = JSValue::decode(encodedArguments); 1539 CallFrame* newCallFrame = size AndAllocFrameForVarargs(exec, stack, arguments, firstFreeRegister);1578 CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, firstFreeRegister); 1540 1579 return newCallFrame; 1541 1580 } … … 1730 1769 } 1731 1770 1732 void JIT_OPERATION lookupExceptionHandler(ExecState* exec) 1733 { 1734 VM* vm = &exec->vm(); 1735 NativeCallFrameTracer tracer(vm, exec); 1736 1737 JSValue exceptionValue = exec->exception(); 1771 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec) 1772 { 1773 NativeCallFrameTracer tracer(vm, exec, NativeCallFrameTracer::VMEntrySentinelOK); 1774 1775 JSValue exceptionValue = vm->exception(); 1738 1776 ASSERT(exceptionValue); 1739 1777 … … 1768 1806 HIDE_SYMBOL(getHostCallReturnValue) "\n" 1769 1807 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1770 "mov 0(%rbp), %rbp\n" // CallerFrameAndPC::callerFrame1771 1808 "mov %rbp, %rdi\n" 1772 1809 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" … … 1779 1816 HIDE_SYMBOL(getHostCallReturnValue) "\n" 1780 1817 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1781 "mov 0(%ebp), %ebp\n" // CallerFrameAndPC::callerFrame 1782 "mov %ebp, 4(%esp)\n" 1818 "mov (%esp), %eax\n" 1819 "push %ebp\n" 1820 "leal -4(%esp), %esp\n" 1821 "push %ebp\n" 1822 "push %eax\n" 1783 1823 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" 1784 1824 ); … … 1793 1833 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n" 1794 1834 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1795 "ldr r7, [r7, #0]" "\n" // CallerFrameAndPC::callerFrame1796 1835 "mov r0, r7" "\n" 1797 1836 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" … … 1805 1844 INLINE_ARM_FUNCTION(getHostCallReturnValue) 1806 1845 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1807 "ldr r11, [r11, #0]" "\n" // CallerFrameAndPC::callerFrame1808 1846 "mov r0, r11" "\n" 1809 1847 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" … … 1817 1855 HIDE_SYMBOL(getHostCallReturnValue) "\n" 1818 1856 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1819 "ldur x29, [x29, #0]" "\n"1820 1857 "mov x0, x29" "\n" 1821 1858 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" … … 1829 1866 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1830 1867 LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState) 1831 "lw $fp, 0($fp)" "\n" // CallerFrameAndPC::callerFrame1832 1868 "move $a0, $fp" "\n" 1833 1869 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" … … 1840 1876 HIDE_SYMBOL(getHostCallReturnValue) "\n" 1841 1877 SYMBOL_STRING(getHostCallReturnValue) ":" "\n" 1842 "mov.l @r14, r14" "\n" // CallerFrameAndPC::callerFrame1843 1878 "mov r14, r4" "\n" 1844 1879 "mov.l 2f, " SH4_SCRATCH_REGISTER "\n" … … 1853 1888 __declspec(naked) EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue() 1854 1889 { 1855 __asm mov ebp, [ebp + 0]; // CallerFrameAndPC::callerFrame1856 1890 __asm mov [esp + 4], ebp; 1857 1891 __asm jmp getHostCallReturnValueWithExecState
Note:
See TracChangeset
for help on using the changeset viewer.