Changeset 149089 in webkit
- Timestamp:
- Apr 24, 2013 7:59:51 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/tests/testapi.c
r148639 r149089 1069 1069 } 1070 1070 1071 static JSValueRef currentCPUTime_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 1072 { 1073 UNUSED_PARAM(functionObject); 1074 UNUSED_PARAM(thisObject); 1075 UNUSED_PARAM(argumentCount); 1076 UNUSED_PARAM(arguments); 1077 UNUSED_PARAM(exception); 1078 1079 ASSERT(JSContextGetGlobalContext(ctx) == context); 1080 return JSValueMakeNumber(ctx, currentCPUTime()); 1081 } 1082 1071 1083 bool shouldTerminateCallbackWasCalled = false; 1072 1084 static bool shouldTerminateCallback(JSContextRef ctx, void* context) … … 1094 1106 if (extendTerminateCallbackCalled == 1) { 1095 1107 JSContextGroupRef contextGroup = JSContextGetGroup(ctx); 1096 JSContextGroupSetExecutionTimeLimit(contextGroup, 2, extendTerminateCallback, 0);1108 JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0); 1097 1109 return false; 1098 1110 } … … 1750 1762 1751 1763 #if PLATFORM(MAC) || PLATFORM(IOS) 1764 JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime"); 1765 JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTime_callAsFunction); 1766 JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, NULL); 1767 JSStringRelease(currentCPUTimeStr); 1768 1752 1769 /* Test script timeout: */ 1753 JSContextGroupSetExecutionTimeLimit(contextGroup, 1, shouldTerminateCallback, 0);1770 JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0); 1754 1771 { 1755 const char* loopForeverScript = "startTime = Date.now(); try { while (true) { if (Date.now() - startTime > 5000) break; } } catch(e) { }"; 1772 const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } "; 1773 JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); 1774 double startTime; 1775 double endTime; 1776 exception = NULL; 1777 shouldTerminateCallbackWasCalled = false; 1778 startTime = currentCPUTime(); 1779 v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); 1780 endTime = currentCPUTime(); 1781 1782 if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled) 1783 printf("PASS: script timed out as expected.\n"); 1784 else { 1785 if (!((endTime - startTime) < .150f)) 1786 printf("FAIL: script did not timed out as expected.\n"); 1787 if (!shouldTerminateCallbackWasCalled) 1788 printf("FAIL: script timeout callback was not called.\n"); 1789 failed = true; 1790 } 1791 1792 if (!exception) { 1793 printf("FAIL: TerminationExecutionException was not thrown.\n"); 1794 failed = true; 1795 } 1796 } 1797 1798 /* Test the script timeout's TerminationExecutionException should NOT be catchable: */ 1799 JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0); 1800 { 1801 const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }"; 1802 JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); 1803 double startTime; 1804 double endTime; 1805 exception = NULL; 1806 shouldTerminateCallbackWasCalled = false; 1807 startTime = currentCPUTime(); 1808 v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); 1809 endTime = currentCPUTime(); 1810 1811 if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) { 1812 if (!((endTime - startTime) < .150f)) 1813 printf("FAIL: script did not timed out as expected.\n"); 1814 if (!shouldTerminateCallbackWasCalled) 1815 printf("FAIL: script timeout callback was not called.\n"); 1816 failed = true; 1817 } 1818 1819 if (exception) 1820 printf("PASS: TerminationExecutionException was not catchable as expected.\n"); 1821 else { 1822 printf("FAIL: TerminationExecutionException was caught.\n"); 1823 failed = true; 1824 } 1825 } 1826 1827 /* Test script timeout cancellation: */ 1828 JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0); 1829 { 1830 const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } "; 1756 1831 JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); 1757 1832 double startTime; … … 1762 1837 endTime = currentCPUTime(); 1763 1838 1764 if (((endTime - startTime) < 2) && shouldTerminateCallbackWasCalled) 1765 printf("PASS: script timed out as expected.\n"); 1766 else { 1767 if (!((endTime - startTime) < 2)) 1768 printf("FAIL: script did not timed out as expected.\n"); 1769 if (!shouldTerminateCallbackWasCalled) 1770 printf("FAIL: script timeout callback was not called.\n"); 1771 failed = true; 1772 } 1773 1774 if (exception) 1775 printf("PASS: TerminationExecutionException was not catchable.\n"); 1776 else { 1777 printf("FAIL: TerminationExecutionException was caught.\n"); 1778 failed = true; 1779 } 1780 } 1781 1782 /* Test script timeout cancellation: */ 1783 JSContextGroupSetExecutionTimeLimit(contextGroup, 1, cancelTerminateCallback, 0); 1784 { 1785 const char* loopForeverScript = "startTime = Date.now(); try { while (true) { if (Date.now() - startTime > 5000) break; } } catch(e) { }"; 1786 JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); 1787 double startTime; 1788 double endTime; 1789 exception = NULL; 1790 startTime = currentCPUTime(); 1791 v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); 1792 endTime = currentCPUTime(); 1793 1794 if (((endTime - startTime) >= 2) && cancelTerminateCallbackWasCalled && !exception) 1839 if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception) 1795 1840 printf("PASS: script timeout was cancelled as expected.\n"); 1796 1841 else { 1797 if (((endTime - startTime) < 2) || exception)1842 if (((endTime - startTime) < .150) || exception) 1798 1843 printf("FAIL: script timeout was not cancelled.\n"); 1799 1844 if (!cancelTerminateCallbackWasCalled) … … 1804 1849 1805 1850 /* Test script timeout extension: */ 1806 JSContextGroupSetExecutionTimeLimit(contextGroup, 1, extendTerminateCallback, 0);1851 JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0); 1807 1852 { 1808 const char* loopForeverScript = " startTime = Date.now(); try { while (true) { if (Date.now() - startTime > 5000) break; } } catch(e) { }";1853 const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } "; 1809 1854 JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript); 1810 1855 double startTime; … … 1817 1862 deltaTime = endTime - startTime; 1818 1863 1819 if ((deltaTime >= 3) && (deltaTime < 5) && (extendTerminateCallbackCalled == 2) && exception)1864 if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception) 1820 1865 printf("PASS: script timeout was extended as expected.\n"); 1821 1866 else { 1822 if (deltaTime < 2)1867 if (deltaTime < .200f) 1823 1868 printf("FAIL: script timeout was not extended as expected.\n"); 1824 else if (deltaTime >= 5)1869 else if (deltaTime >= .500f) 1825 1870 printf("FAIL: script did not timeout.\n"); 1826 1871 … … 1831 1876 1832 1877 if (!exception) 1833 printf("FAIL: TerminationExecutionException was caughtduring timeout extension test.\n");1878 printf("FAIL: TerminationExecutionException was not thrown during timeout extension test.\n"); 1834 1879 1835 1880 failed = true; -
trunk/Source/JavaScriptCore/ChangeLog
r149082 r149089 1 2013-04-24 Mark Lam <mark.lam@apple.com> 2 3 Add watchdog timer polling for the DFG. 4 https://bugs.webkit.org/show_bug.cgi?id=115134. 5 6 Reviewed by Geoffrey Garen. 7 8 The strategy is to add a speculation check to the DFG generated code to 9 test if the watchdog timer has fired or not. If the watchdog timer has 10 fired, the generated code will do an OSR exit to the baseline JIT, and 11 let it handle servicing the watchdog timer. 12 13 If the watchdog is not enabled, this speculation check will not be 14 emitted. 15 16 * API/tests/testapi.c: 17 (currentCPUTime_callAsFunction): 18 (extendTerminateCallback): 19 (main): 20 - removed try/catch statements so that we can test the watchdog on the DFG. 21 - added JS bindings to a native currentCPUTime() function so that the timeout 22 tests can be more accurate. 23 - also shortened the time values so that the tests can complete sooner. 24 25 * bytecode/ExitKind.h: 26 * dfg/DFGAbstractState.cpp: 27 (JSC::DFG::AbstractState::executeEffects): 28 * dfg/DFGByteCodeParser.cpp: 29 (JSC::DFG::ByteCodeParser::parseBlock): 30 * dfg/DFGFixupPhase.cpp: 31 (JSC::DFG::FixupPhase::fixupNode): 32 * dfg/DFGNodeType.h: 33 * dfg/DFGPredictionPropagationPhase.cpp: 34 (JSC::DFG::PredictionPropagationPhase::propagate): 35 * dfg/DFGSpeculativeJIT32_64.cpp: 36 (JSC::DFG::SpeculativeJIT::compile): 37 * dfg/DFGSpeculativeJIT64.cpp: 38 (JSC::DFG::SpeculativeJIT::compile): 39 * runtime/Watchdog.cpp: 40 (JSC::Watchdog::setTimeLimit): 41 1 42 2013-04-24 Filip Pizlo <fpizlo@apple.com> 2 43 -
trunk/Source/JavaScriptCore/bytecode/ExitKind.h
r146089 r149089 47 47 NotStringObject, // We exited because we shouldn't have attempted to optimize string object access. 48 48 Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME. 49 UncountableWatchpoint // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves. 49 UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves. 50 WatchdogTimerFired // We exited because we need to service the watchdog timer. 50 51 }; 51 52 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r149016 r149089 1539 1539 break; 1540 1540 1541 case CheckWatchdogTimer: 1542 node->setCanExit(true); 1543 break; 1544 1541 1545 case Phantom: 1542 1546 case InlineStart: -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r149071 r149089 3286 3286 m_currentBlock->isOSRTarget = true; 3287 3287 3288 // Emit a phantom node to ensure that there is a placeholder node for this bytecode 3289 // op. 3290 addToGraph(Phantom); 3288 if (m_vm->watchdog.isEnabled()) 3289 addToGraph(CheckWatchdogTimer); 3290 else { 3291 // Emit a phantom node to ensure that there is a placeholder 3292 // node for this bytecode op. 3293 addToGraph(Phantom); 3294 } 3291 3295 3292 3296 NEXT_OPCODE(op_loop_hint); -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r149041 r149089 860 860 case CountExecution: 861 861 case ForceOSRExit: 862 case CheckWatchdogTimer: 862 863 break; 863 864 #else -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r147985 r149089 265 265 /* this point, but execution does continue in the basic block - just in a */\ 266 266 /* different compiler. */\ 267 macro(ForceOSRExit, NodeMustGenerate) 267 macro(ForceOSRExit, NodeMustGenerate) \ 268 \ 269 /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \ 270 /* baseline JIT to redo the watchdog timer check, and service the timer. */ \ 271 macro(CheckWatchdogTimer, NodeMustGenerate) \ 268 272 269 273 // This enum generates a monotonically increasing id for all Node types, -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r147985 r149089 527 527 case PutGlobalVar: 528 528 case PutGlobalVarCheck: 529 case CheckWatchdogTimer: 529 530 break; 530 531 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r148696 r149089 4927 4927 } 4928 4928 4929 case CheckWatchdogTimer: 4930 speculationCheck( 4931 WatchdogTimerFired, JSValueRegs(), 0, 4932 m_jit.branchTest8( 4933 JITCompiler::NonZero, 4934 JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog.timerDidFireAddress()))); 4935 break; 4936 4929 4937 case CountExecution: 4930 4938 m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address())); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r148696 r149089 4771 4771 } 4772 4772 4773 case CheckWatchdogTimer: 4774 speculationCheck( 4775 WatchdogTimerFired, JSValueRegs(), 0, 4776 m_jit.branchTest8( 4777 JITCompiler::NonZero, 4778 JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog.timerDidFireAddress()))); 4779 break; 4780 4773 4781 case Phantom: 4774 4782 DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate); -
trunk/Source/JavaScriptCore/runtime/Watchdog.cpp
r148696 r149089 80 80 // polling checks. Hence, there is no need to re-do this flushing. 81 81 if (!wasEnabled) { 82 // For now, we only support this feature when the DFG JIT is disabled. 83 Options::useDFGJIT() = false; 84 85 // And if we've previously compiled any functions, we need to deopt 86 // them because they don't habe the needed polling checks yet. 82 // And if we've previously compiled any functions, we need to revert 83 // them because they don't have the needed polling checks yet. 87 84 vm.releaseExecutableMemory(); 88 85 }
Note: See TracChangeset
for help on using the changeset viewer.