Changeset 148639 in webkit


Ignore:
Timestamp:
Apr 17, 2013 3:37:45 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Source/JavaScriptCore: Add LLINT and baseline JIT support for timing out scripts.
https://bugs.webkit.org/show_bug.cgi?id=114577.

Reviewed by Geoffrey Garen.

Introduces the new Watchdog class which is used to track script
execution time, and initiate script termination if needed.

  • API/JSContextRef.cpp:

(internalScriptTimeoutCallback):
(JSContextGroupSetExecutionTimeLimit):
(JSContextGroupClearExecutionTimeLimit):

  • API/JSContextRefPrivate.h:
  • Added new script execution time limit APIs.
  • API/tests/testapi.c:

(currentCPUTime):
(shouldTerminateCallback):
(cancelTerminateCallback):
(extendTerminateCallback):
(main):

  • Added new API tests for script execution time limit.
  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitLoopHint):

  • loop hints are needed for the llint as well. Hence, it will be emitted unconditionally.
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::addStackTraceIfNecessary):
(JSC::Interpreter::throwException):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):

  • Added checks for script termination before entering script code.
  • jit/JIT.cpp:

(JSC::JIT::emitWatchdogTimerCheck):

  • jit/JIT.h:

(JSC::JIT::emit_op_loop_hint):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)):

  • jit/JITStubs.h:
  • llint/LLIntExceptions.cpp:

(JSC::LLInt::doThrow):

  • Factored out some common code from returnToThrow() and callToThrow().

(JSC::LLInt::returnToThrow):
(JSC::LLInt::callToThrow):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/ExceptionHelpers.cpp:

(JSC::throwTerminatedExecutionException):

  • Also removed the now unused InterruptedExecutionException.
  • runtime/ExceptionHelpers.h:
  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):

  • runtime/JSGlobalData.h:
  • Added watchdog, and removed the now obsolete Terminator.
  • runtime/Terminator.h: Removed.
  • runtime/Watchdog.cpp: Added.

(JSC::Watchdog::Watchdog):
(JSC::Watchdog::~Watchdog):
(JSC::Watchdog::setTimeLimit):
(JSC::Watchdog::didFire):
(JSC::Watchdog::isEnabled):
(JSC::Watchdog::fire):
(JSC::Watchdog::arm):
(JSC::Watchdog::disarm):
(JSC::Watchdog::startCountdownIfNeeded):
(JSC::Watchdog::startCountdown):
(JSC::Watchdog::stopCountdown):
(JSC::Watchdog::Scope::Scope):
(JSC::Watchdog::Scope::~Scope):

  • runtime/Watchdog.h: Added.

(Watchdog):
(JSC::Watchdog::didFire):
(JSC::Watchdog::timerDidFireAddress):
(JSC::Watchdog::isArmed):
(Watchdog::Scope):

  • runtime/WatchdogMac.cpp: Added.

(JSC::Watchdog::initTimer):
(JSC::Watchdog::destroyTimer):
(JSC::Watchdog::startTimer):
(JSC::Watchdog::stopTimer):

  • runtime/WatchdogNone.cpp: Added.

(JSC::Watchdog::initTimer):
(JSC::Watchdog::destroyTimer):
(JSC::Watchdog::startTimer):
(JSC::Watchdog::stopTimer):

Source/WebCore: Add LLINT and baseline JIT support for timing out scripts.
https://bugs.webkit.org/show_bug.cgi?id=114577.

Reviewed by Geoffrey Garen.

Replaced use of the obsolete JSGlobalData.terminator methods with the
JSGlobalData.watchdog equivalents.

  • bindings/js/JSEventListener.cpp:

(WebCore::JSEventListener::handleEvent):

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):

  • bindings/js/WorkerScriptController.cpp:

(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::scheduleExecutionTermination):
(WebCore::WorkerScriptController::isExecutionTerminating):

Source/WTF: Added currentCPUTime() and currentCPUTimeMS().
https://bugs.webkit.org/show_bug.cgi?id=114577.

Reviewed by Geoffrey Garen.

The currentCPUTime() implementation came from the old TimeoutChecker.cpp.

  • wtf/CurrentTime.cpp:

(WTF::currentCPUTime):
(WTF::currentCPUTimeMS):

  • wtf/CurrentTime.h:
Location:
trunk/Source
Files:
4 added
1 deleted
34 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSContextRef.cpp

    r147858 r148639  
    7878
    7979    wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
     80}
     81
     82static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, void* callbackData)
     83{
     84    JSShouldTerminateCallback callback = reinterpret_cast<JSShouldTerminateCallback>(callbackPtr);
     85    JSContextRef contextRef = toRef(exec);
     86    return callback(contextRef, callbackData);
     87}
     88
     89void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* callbackData)
     90{
     91    JSGlobalData& globalData = *toJS(group);
     92    APIEntryShim entryShim(&globalData);
     93    Watchdog& watchdog = globalData.watchdog;
     94    void* callbackPtr = reinterpret_cast<void*>(callback);
     95    watchdog.setTimeLimit(globalData, limit, internalScriptTimeoutCallback, callbackPtr, callbackData);
     96}
     97
     98void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group)
     99{
     100    JSGlobalData& globalData = *toJS(group);
     101    APIEntryShim entryShim(&globalData);
     102    Watchdog& watchdog = globalData.watchdog;
     103    watchdog.setTimeLimit(globalData, std::numeric_limits<double>::infinity());
    80104}
    81105
  • trunk/Source/JavaScriptCore/API/JSContextRefPrivate.h

    r95901 r148639  
    5656JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) AVAILABLE_IN_WEBKIT_VERSION_4_0;
    5757   
     58
     59/*!
     60@typedef JSShouldTerminateCallback
     61@abstract The callback invoked when script execution has exceeded the allowed
     62 time limit previously specified via JSContextGroupSetExecutionTimeLimit.
     63@param ctx The execution context to use.
     64@param context User specified context data previously passed to
     65 JSContextGroupSetExecutionTimeLimit.
     66@discussion If you named your function Callback, you would declare it like this:
     67
     68 bool Callback(JSContextRef ctx, void* context);
     69
     70 If you return true, the timed out script will terminate.
     71 If you return false, the script will run for another period of the allowed
     72 time limit specified via JSContextGroupSetExecutionTimeLimit.
     73
     74 Within this callback function, you may call JSContextGroupSetExecutionTimeLimit
     75 to set a new time limit, or JSContextGroupClearExecutionTimeLimit to cancel the
     76 timeout.
     77*/
     78typedef bool
     79(*JSShouldTerminateCallback) (JSContextRef ctx, void* context);
     80
     81/*!
     82@function
     83@abstract Sets the script execution time limit.
     84@param group The JavaScript context group that this time limit applies to.
     85@param limit The time limit of allowed script execution time in seconds.
     86@param callback The callback function that will be invoked when the time limit
     87 has been reached. This will give you a chance to decide if you want to
     88 terminate the script or not. If you pass a NULL callback, the script will be
     89 terminated unconditionally when the time limit has been reached.
     90@param context User data that you can provide to be passed back to you
     91 in your callback.
     92
     93 In order to guarantee that the execution time limit will take effect, you will
     94 need to call JSContextGroupSetExecutionTimeLimit before you start executing
     95 any scripts.
     96*/
     97JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double limit, JSShouldTerminateCallback, void* context) AVAILABLE_IN_WEBKIT_VERSION_4_0;
     98
     99/*!
     100@function
     101@abstract Clears the script execution time limit.
     102@param group The JavaScript context group that the time limit is cleared on.
     103*/
     104JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef) AVAILABLE_IN_WEBKIT_VERSION_4_0;
     105
    58106#ifdef __cplusplus
    59107}
  • trunk/Source/JavaScriptCore/API/tests/testapi.c

    r148162 r148639  
    3434#include <wtf/UnusedParam.h>
    3535
     36#if PLATFORM(MAC) || PLATFORM(IOS)
     37#include <mach/mach.h>
     38#include <mach/mach_time.h>
     39#include <sys/time.h>
     40#endif
     41
    3642#if OS(WINDOWS)
    3743#include <windows.h>
     
    10451051    val.name = "something";
    10461052}
     1053
     1054#if PLATFORM(MAC) || PLATFORM(IOS)
     1055static double currentCPUTime()
     1056{
     1057    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
     1058    thread_basic_info_data_t info;
     1059
     1060    /* Get thread information */
     1061    mach_port_t threadPort = mach_thread_self();
     1062    thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount);
     1063    mach_port_deallocate(mach_task_self(), threadPort);
     1064   
     1065    double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
     1066    time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
     1067   
     1068    return time;
     1069}
     1070
     1071bool shouldTerminateCallbackWasCalled = false;
     1072static bool shouldTerminateCallback(JSContextRef ctx, void* context)
     1073{
     1074    UNUSED_PARAM(ctx);
     1075    UNUSED_PARAM(context);
     1076    shouldTerminateCallbackWasCalled = true;
     1077    return true;
     1078}
     1079
     1080bool cancelTerminateCallbackWasCalled = false;
     1081static bool cancelTerminateCallback(JSContextRef ctx, void* context)
     1082{
     1083    UNUSED_PARAM(ctx);
     1084    UNUSED_PARAM(context);
     1085    cancelTerminateCallbackWasCalled = true;
     1086    return false;
     1087}
     1088
     1089int extendTerminateCallbackCalled = 0;
     1090static bool extendTerminateCallback(JSContextRef ctx, void* context)
     1091{
     1092    UNUSED_PARAM(context);
     1093    extendTerminateCallbackCalled++;
     1094    if (extendTerminateCallbackCalled == 1) {
     1095        JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
     1096        JSContextGroupSetExecutionTimeLimit(contextGroup, 2, extendTerminateCallback, 0);
     1097        return false;
     1098    }
     1099    return true;
     1100}
     1101#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
     1102
    10471103
    10481104int main(int argc, char* argv[])
     
    16931749    }
    16941750
     1751#if PLATFORM(MAC) || PLATFORM(IOS)
     1752    /* Test script timeout: */
     1753    JSContextGroupSetExecutionTimeLimit(contextGroup, 1, shouldTerminateCallback, 0);
     1754    {
     1755        const char* loopForeverScript = "startTime = Date.now(); try { while (true) { if (Date.now() - startTime > 5000) break; } } catch(e) { }";
     1756        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
     1757        double startTime;
     1758        double endTime;
     1759        exception = NULL;
     1760        startTime = currentCPUTime();
     1761        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
     1762        endTime = currentCPUTime();
     1763
     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)
     1795            printf("PASS: script timeout was cancelled as expected.\n");
     1796        else {
     1797            if (((endTime - startTime) < 2) || exception)
     1798                printf("FAIL: script timeout was not cancelled.\n");
     1799            if (!cancelTerminateCallbackWasCalled)
     1800                printf("FAIL: script timeout callback was not called.\n");
     1801            failed = true;
     1802        }
     1803    }
     1804
     1805    /* Test script timeout extension: */
     1806    JSContextGroupSetExecutionTimeLimit(contextGroup, 1, extendTerminateCallback, 0);
     1807    {
     1808        const char* loopForeverScript = "startTime = Date.now(); try { while (true) { if (Date.now() - startTime > 5000) break; } } catch(e) { }";
     1809        JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
     1810        double startTime;
     1811        double endTime;
     1812        double deltaTime;
     1813        exception = NULL;
     1814        startTime = currentCPUTime();
     1815        v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
     1816        endTime = currentCPUTime();
     1817        deltaTime = endTime - startTime;
     1818
     1819        if ((deltaTime >= 3) && (deltaTime < 5) && (extendTerminateCallbackCalled == 2) && exception)
     1820            printf("PASS: script timeout was extended as expected.\n");
     1821        else {
     1822            if (deltaTime < 2)
     1823                printf("FAIL: script timeout was not extended as expected.\n");
     1824            else if (deltaTime >= 5)
     1825                printf("FAIL: script did not timeout.\n");
     1826
     1827            if (extendTerminateCallbackCalled < 1)
     1828                printf("FAIL: script timeout callback was not called.\n");
     1829            if (extendTerminateCallbackCalled < 2)
     1830                printf("FAIL: script timeout callback was not called after timeout extension.\n");
     1831
     1832            if (!exception)
     1833                printf("FAIL: TerminationExecutionException was caught during timeout extension test.\n");
     1834
     1835            failed = true;
     1836        }
     1837    }
     1838#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
     1839
    16951840    // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
    16961841    function = NULL;
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r148571 r148639  
    306306    runtime/StructureChain.cpp
    307307    runtime/SymbolTable.cpp
     308    runtime/Watchdog.cpp
     309    runtime/WatchdogNone.cpp
    308310
    309311    tools/CodeProfile.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r148638 r148639  
     12013-04-17  Mark Lam  <mark.lam@apple.com>
     2
     3        Add LLINT and baseline JIT support for timing out scripts.
     4        https://bugs.webkit.org/show_bug.cgi?id=114577.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Introduces the new Watchdog class which is used to track script
     9        execution time, and initiate script termination if needed.
     10
     11        * API/JSContextRef.cpp:
     12        (internalScriptTimeoutCallback):
     13        (JSContextGroupSetExecutionTimeLimit):
     14        (JSContextGroupClearExecutionTimeLimit):
     15        * API/JSContextRefPrivate.h:
     16        - Added new script execution time limit APIs.
     17        * API/tests/testapi.c:
     18        (currentCPUTime):
     19        (shouldTerminateCallback):
     20        (cancelTerminateCallback):
     21        (extendTerminateCallback):
     22        (main):
     23        - Added new API tests for script execution time limit.
     24        * CMakeLists.txt:
     25        * GNUmakefile.list.am:
     26        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
     27        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     28        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     29        * JavaScriptCore.xcodeproj/project.pbxproj:
     30        * Target.pri:
     31        * bytecompiler/BytecodeGenerator.cpp:
     32        (JSC::BytecodeGenerator::emitLoopHint):
     33        - loop hints are needed for the llint as well. Hence, it will be
     34          emitted unconditionally.
     35        * interpreter/Interpreter.cpp:
     36        (JSC::Interpreter::addStackTraceIfNecessary):
     37        (JSC::Interpreter::throwException):
     38        (JSC::Interpreter::execute):
     39        (JSC::Interpreter::executeCall):
     40        (JSC::Interpreter::executeConstruct):
     41        - Added checks for script termination before entering script code.
     42        * jit/JIT.cpp:
     43        (JSC::JIT::emitWatchdogTimerCheck):
     44        * jit/JIT.h:
     45        (JSC::JIT::emit_op_loop_hint):
     46        * jit/JITStubs.cpp:
     47        (JSC::DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)):
     48        * jit/JITStubs.h:
     49        * llint/LLIntExceptions.cpp:
     50        (JSC::LLInt::doThrow):
     51        - Factored out some common code from returnToThrow() and callToThrow().
     52        (JSC::LLInt::returnToThrow):
     53        (JSC::LLInt::callToThrow):
     54        * llint/LLIntSlowPaths.cpp:
     55        (JSC::LLInt::LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)):
     56        * llint/LLIntSlowPaths.h:
     57        * llint/LowLevelInterpreter.asm:
     58        * llint/LowLevelInterpreter32_64.asm:
     59        * llint/LowLevelInterpreter64.asm:
     60        * runtime/ExceptionHelpers.cpp:
     61        (JSC::throwTerminatedExecutionException):
     62        - Also removed the now unused InterruptedExecutionException.
     63        * runtime/ExceptionHelpers.h:
     64        * runtime/JSGlobalData.cpp:
     65        (JSC::JSGlobalData::JSGlobalData):
     66        * runtime/JSGlobalData.h:
     67        - Added watchdog, and removed the now obsolete Terminator.
     68        * runtime/Terminator.h: Removed.
     69        * runtime/Watchdog.cpp: Added.
     70        (JSC::Watchdog::Watchdog):
     71        (JSC::Watchdog::~Watchdog):
     72        (JSC::Watchdog::setTimeLimit):
     73        (JSC::Watchdog::didFire):
     74        (JSC::Watchdog::isEnabled):
     75        (JSC::Watchdog::fire):
     76        (JSC::Watchdog::arm):
     77        (JSC::Watchdog::disarm):
     78        (JSC::Watchdog::startCountdownIfNeeded):
     79        (JSC::Watchdog::startCountdown):
     80        (JSC::Watchdog::stopCountdown):
     81        (JSC::Watchdog::Scope::Scope):
     82        (JSC::Watchdog::Scope::~Scope):
     83        * runtime/Watchdog.h: Added.
     84        (Watchdog):
     85        (JSC::Watchdog::didFire):
     86        (JSC::Watchdog::timerDidFireAddress):
     87        (JSC::Watchdog::isArmed):
     88        (Watchdog::Scope):
     89        * runtime/WatchdogMac.cpp: Added.
     90        (JSC::Watchdog::initTimer):
     91        (JSC::Watchdog::destroyTimer):
     92        (JSC::Watchdog::startTimer):
     93        (JSC::Watchdog::stopTimer):
     94        * runtime/WatchdogNone.cpp: Added.
     95        (JSC::Watchdog::initTimer):
     96        (JSC::Watchdog::destroyTimer):
     97        (JSC::Watchdog::startTimer):
     98        (JSC::Watchdog::stopTimer):
     99
    11002013-04-14  Roger Fong  <roger_fong@apple.com>
    2101
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r148479 r148639  
    783783        Source/JavaScriptCore/runtime/SymbolTable.cpp \
    784784        Source/JavaScriptCore/runtime/SymbolTable.h \
    785         Source/JavaScriptCore/runtime/Terminator.h \
    786785        Source/JavaScriptCore/runtime/Tracing.h \
    787786        Source/JavaScriptCore/runtime/TypedArrayDescriptor.h \
    788787        Source/JavaScriptCore/runtime/Uint16WithFraction.h \
     788        Source/JavaScriptCore/runtime/Watchdog.cpp \
     789        Source/JavaScriptCore/runtime/Watchdog.h \
     790        Source/JavaScriptCore/runtime/WatchdogNone.cpp \
    789791        Source/JavaScriptCore/runtime/WeakGCMap.h \
    790792        Source/JavaScriptCore/runtime/WeakRandom.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r148479 r148639  
    13711371                        </File>
    13721372                        <File
    1373                                 RelativePath="..\..\runtime\Terminator.h"
    1374                                 >
    1375                         </File>
    1376                         <File
    13771373                                RelativePath="..\..\runtime\TypedArrayDescriptor.h"
     1374                                >
     1375                        </File>
     1376                        <File
     1377                                RelativePath="..\..\runtime\Watchdog.cpp"
     1378                                >
     1379                        </File>
     1380                        <File
     1381                                RelativePath="..\..\runtime\Watchdog.h"
     1382                                >
     1383                        </File>
     1384                        <File
     1385                                RelativePath="..\..\runtime\WatchdogNone.cpp"
    13781386                                >
    13791387                        </File>
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r148479 r148639  
    371371    <ClCompile Include="..\runtime\StructureRareData.cpp" />
    372372    <ClCompile Include="..\runtime\SymbolTable.cpp" />
     373    <ClCompile Include="..\runtime\Watchdog.cpp" />
     374    <ClCompile Include="..\runtime\WatchdogNone.cpp" />
    373375    <ClCompile Include="..\tools\CodeProfile.cpp" />
    374376    <ClCompile Include="..\tools\CodeProfiling.cpp" />
     
    753755    <ClInclude Include="..\runtime\StructureTransitionTable.h" />
    754756    <ClInclude Include="..\runtime\SymbolTable.h" />
    755     <ClInclude Include="..\runtime\Terminator.h" />
    756757    <ClInclude Include="..\runtime\Tracing.h" />
    757758    <ClInclude Include="..\runtime\TypedArrayDescriptor.h" />
    758759    <ClInclude Include="..\runtime\Uint16WithFraction.h" />
     760    <ClInclude Include="..\runtime\Watchdog.h" />
    759761    <ClInclude Include="..\runtime\WeakGCMap.h" />
    760762    <ClInclude Include="..\runtime\WeakRandom.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r148479 r148639  
    718718      <Filter>runtime</Filter>
    719719    </ClCompile>
     720    <ClCompile Include="..\runtime\Watchdog.cpp">
     721      <Filter>runtime</Filter>
     722    </ClCompile>
     723    <ClCompile Include="..\runtime\WatchdogNone.cpp">
     724      <Filter>runtime</Filter>
     725    </ClCompile>
    720726    <ClCompile Include="..\tools\CodeProfile.cpp">
    721727      <Filter>tools</Filter>
     
    17911797      <Filter>runtime</Filter>
    17921798    </ClInclude>
    1793     <ClInclude Include="..\runtime\Terminator.h">
    1794       <Filter>runtime</Filter>
    1795     </ClInclude>
    17961799    <ClInclude Include="..\runtime\Tracing.h">
    17971800      <Filter>runtime</Filter>
     
    18011804    </ClInclude>
    18021805    <ClInclude Include="..\runtime\Uint16WithFraction.h">
     1806      <Filter>runtime</Filter>
     1807    </ClInclude>
     1808    <ClInclude Include="..\runtime\Watchdog.h">
    18031809      <Filter>runtime</Filter>
    18041810    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r148479 r148639  
    661661                969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07940ED1D3AE00F1F681 /* Opcode.cpp */; };
    662662                969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    663                 971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    664663                978801401471AD920041B016 /* JSDateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */; };
    665664                978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    872871                FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
    873872                FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
     873                FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
     874                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); };};
     875                FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */; };
    874876/* End PBXBuildFile section */
    875877
     
    15831585                9788FC221471AD0C0068CE2D /* JSDateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDateMath.cpp; sourceTree = "<group>"; };
    15841586                9788FC231471AD0C0068CE2D /* JSDateMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDateMath.h; sourceTree = "<group>"; };
    1585                 97F6903A1169DF7F00A6BB46 /* Terminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminator.h; sourceTree = "<group>"; };
    15861587                A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
    15871588                A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
     
    18141815                FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
    18151816                FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
     1817                FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Watchdog.cpp; sourceTree = "<group>"; };
     1818                FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = "<group>"; };
     1819                FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WatchdogMac.cpp; sourceTree = "<group>"; };
    18161820/* End PBXFileReference section */
    18171821
     
    25952599                                0F919D2715856770004A4E7D /* SymbolTable.cpp */,
    25962600                                14A396A60CD2933100B5B4FF /* SymbolTable.h */,
    2597                                 97F6903A1169DF7F00A6BB46 /* Terminator.h */,
    25982601                                5D53726D0E1C546B0021E549 /* Tracing.d */,
    25992602                                5D53726E0E1C54880021E549 /* Tracing.h */,
    26002603                                0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */,
    26012604                                866739D113BFDE710023D87C /* Uint16WithFraction.h */,
     2605                                FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */,
     2606                                FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
     2607                                FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
    26022608                                14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
    26032609                                1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
     
    30953101                                0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
    30963102                                0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
     3103                                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
    30973104                                0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
    30983105                                0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
     
    33773384                                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
    33783385                                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
    3379                                 971EDEA61169E0D3005E4262 /* Terminator.h in Headers */,
    33803386                                0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
    33813387                                A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
     
    40244030                                14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
    40254031                                A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
     4032                                FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */,
    40264033                                8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
    40274034                                14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
     
    40614068                                A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
    40624069                                FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */,
     4070                                FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
    40634071                                0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */,
    40644072                                0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
  • trunk/Source/JavaScriptCore/Target.pri

    r148479 r148639  
    325325    runtime/StructureRareData.cpp \
    326326    runtime/SymbolTable.cpp \
     327    runtime/Watchdog.cpp \
     328    runtime/WatchdogNone.cpp \
    327329    tools/CodeProfile.cpp \
    328330    tools/CodeProfiling.cpp \
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r147892 r148639  
    656656void BytecodeGenerator::emitLoopHint()
    657657{
    658 #if ENABLE(DFG_JIT)
    659658    emitOpcode(op_loop_hint);
    660 #endif
    661659}
    662660
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r147872 r148639  
    768768    JSObject* errorObject = asObject(error);
    769769    JSGlobalObject* globalObject = 0;
    770     if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error))
     770    if (isTerminatedExecutionException(error))
    771771        globalObject = globalData->dynamicGlobalObject;
    772772    else
     
    789789{
    790790    CodeBlock* codeBlock = callFrame->codeBlock();
    791     bool isInterrupt = false;
     791    bool isTermination = false;
    792792
    793793    ASSERT(!exceptionValue.isEmpty());
     
    811811        }
    812812
    813         isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
     813        isTermination = isTerminatedExecutionException(exception);
    814814    } else {
    815815        if (!callFrame->globalData().exceptionStack.size()) {
     
    828828    // Calculate an exception handler vPC, unwinding call frames as necessary.
    829829    HandlerInfo* handler = 0;
    830     while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
     830    while (isTermination || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
    831831        if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
    832832            if (LegacyProfiler* profiler = callFrame->globalData().enabledProfiler())
     
    10311031    // Execute the code:
    10321032    JSValue result;
    1033     {
     1033    if (LIKELY(!globalData.watchdog.didFire(newCallFrame))) {
    10341034        SamplingTool::CallRecord callRecord(m_sampler.get());
     1035        Watchdog::Scope watchdogScope(globalData.watchdog);
    10351036
    10361037#if ENABLE(LLINT_C_LOOP)
     
    10391040        result = program->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
    10401041#endif // ENABLE(JIT)
    1041     }
     1042    } else
     1043        result = throwTerminatedExecutionException(newCallFrame);
    10421044
    10431045    if (LegacyProfiler* profiler = globalData.enabledProfiler())
     
    11011103
    11021104    JSValue result;
    1103     {
     1105    if (LIKELY(!globalData.watchdog.didFire(newCallFrame))) {
    11041106        SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
     1107        Watchdog::Scope watchdogScope(globalData.watchdog);
    11051108
    11061109        // Execute the code:
     
    11131116        } else
    11141117            result = JSValue::decode(callData.native.function(newCallFrame));
    1115     }
     1118    } else
     1119        result = throwTerminatedExecutionException(newCallFrame);
    11161120
    11171121    if (LegacyProfiler* profiler = globalData.enabledProfiler())
     
    11761180
    11771181    JSValue result;
    1178     {
     1182    if (LIKELY(!globalData.watchdog.didFire(newCallFrame))) {
    11791183        SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
     1184        Watchdog::Scope watchdogScope(globalData.watchdog);
    11801185
    11811186        // Execute the code.
     
    11861191            result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, &globalData);
    11871192#endif // ENABLE(JIT)
    1188         } else {
     1193        } else
    11891194            result = JSValue::decode(constructData.native.function(newCallFrame));
    1190         }
    1191     }
     1195    } else
     1196        result = throwTerminatedExecutionException(newCallFrame);
    11921197
    11931198    if (LegacyProfiler* profiler = globalData.enabledProfiler())
     
    12731278    // Execute the code:
    12741279    JSValue result;
    1275     {
     1280    if (LIKELY(!globalData.watchdog.didFire(closure.newCallFrame))) {
    12761281        SamplingTool::CallRecord callRecord(m_sampler.get());
    1277        
     1282        Watchdog::Scope watchdogScope(globalData.watchdog);
     1283
    12781284#if ENABLE(LLINT_C_LOOP)
    12791285        result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
     
    12811287        result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, &globalData);
    12821288#endif // ENABLE(JIT)
    1283     }
     1289    } else
     1290        result = throwTerminatedExecutionException(closure.newCallFrame);
    12841291
    12851292    if (LegacyProfiler* profiler = globalData.enabledProfiler())
     
    13691376    // Execute the code:
    13701377    JSValue result;
    1371     {
     1378    if (LIKELY(!globalData.watchdog.didFire(newCallFrame))) {
    13721379        SamplingTool::CallRecord callRecord(m_sampler.get());
    1373        
     1380        Watchdog::Scope watchdogScope(globalData.watchdog);
     1381
    13741382#if ENABLE(LLINT_C_LOOP)
    13751383        result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
     
    13771385        result = eval->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
    13781386#endif // ENABLE(JIT)
    1379     }
     1387    } else
     1388        result = throwTerminatedExecutionException(newCallFrame);
    13801389
    13811390    if (LegacyProfiler* profiler = globalData.enabledProfiler())
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r148119 r148639  
    118118}
    119119#endif
     120
     121void JIT::emitWatchdogTimerCheck()
     122{
     123    if (!m_globalData->watchdog.isEnabled())
     124        return;
     125
     126    Jump skipCheck = branchTest8(Zero, AbsoluteAddress(m_globalData->watchdog.timerDidFireAddress()));
     127    JITStubCall stubCall(this, cti_handle_watchdog_timer);
     128    stubCall.call();
     129    skipCheck.link(this);
     130}
    120131
    121132#define NEXT_OPCODE(name) \
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r148119 r148639  
    859859        void emitOptimizationCheck(OptimizationCheckKind) { }
    860860#endif
    861        
     861        void emitWatchdogTimerCheck();
     862
    862863#ifndef NDEBUG
    863864        void printBytecodeOperandTypes(unsigned src1, unsigned src2);
     
    946947    inline void JIT::emit_op_loop_hint(Instruction*)
    947948    {
     949        emitWatchdogTimerCheck();
    948950        emitOptimizationCheck(LoopOptimizationCheck);
    949951    }
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r148474 r148639  
    13741374    CHECK_FOR_EXCEPTION_AT_END();
    13751375    return JSValue::encode(result);
     1376}
     1377
     1378DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)
     1379{
     1380    STUB_INIT_STACK_FRAME(stackFrame);
     1381    CallFrame* callFrame = stackFrame.callFrame;
     1382    JSGlobalData* globalData = stackFrame.globalData;
     1383    if (UNLIKELY(globalData->watchdog.didFire(callFrame))) {
     1384        globalData->exception = createTerminatedExecutionException(globalData);
     1385        VM_THROW_EXCEPTION_AT_END();
     1386        return;
     1387    }
    13761388}
    13771389
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r148119 r148639  
    407407int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    408408void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL;
     409void JIT_STUB cti_handle_watchdog_timer(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    409410int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    410411void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/llint/LLIntExceptions.cpp

    r139541 r148639  
    6666}
    6767
    68 Instruction* returnToThrow(ExecState* exec, Instruction* pc)
     68static void doThrow(ExecState* exec, Instruction* pc)
    6969{
    7070    JSGlobalData* globalData = &exec->globalData();
    7171    NativeCallFrameTracer tracer(globalData, exec);
     72    fixupPCforExceptionIfNeeded(exec);
     73    genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
     74}
     75
     76Instruction* returnToThrow(ExecState* exec, Instruction* pc)
     77{
    7278#if LLINT_SLOW_PATH_TRACING
     79    JSGlobalData* globalData = &exec->globalData();
    7380    dataLog("Throwing exception ", globalData->exception, " (returnToThrow).\n");
    7481#endif
    75     fixupPCforExceptionIfNeeded(exec);
    76     genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
    77    
     82    doThrow(exec, pc);
    7883    return LLInt::exceptionInstructions();
    7984}
     
    8186void* callToThrow(ExecState* exec, Instruction* pc)
    8287{
     88#if LLINT_SLOW_PATH_TRACING
    8389    JSGlobalData* globalData = &exec->globalData();
    84     NativeCallFrameTracer tracer(globalData, exec);
    85 #if LLINT_SLOW_PATH_TRACING
    8690    dataLog("Throwing exception ", globalData->exception, " (callToThrow).\n");
    8791#endif
    88     fixupPCforExceptionIfNeeded(exec);
    89     genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
    90 
     92    doThrow(exec, pc);
    9193    return LLInt::getCodePtr(llint_throw_during_call_trampoline);
    9294}
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r147947 r148639  
    16291629}
    16301630
     1631LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
     1632{
     1633    LLINT_BEGIN_NO_SET_PC();
     1634    if (UNLIKELY(globalData.watchdog.didFire(exec)))
     1635        LLINT_THROW(createTerminatedExecutionException(&globalData));
     1636    LLINT_RETURN_TWO(0, exec);
     1637}
     1638
    16311639LLINT_SLOW_PATH_DECL(slow_path_debug)
    16321640{
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r147184 r148639  
    205205LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
    206206LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
     207LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_watchdog_timer);
    207208LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
    208209LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_will_call);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r148474 r148639  
    10581058_llint_op_loop_hint:
    10591059    traceExecution()
     1060    loadp JITStackFrame::globalData[sp], t1
     1061    loadb JSGlobalData::watchdog+Watchdog::m_timerDidFire[t1], t0
     1062    btbnz t0, .handleWatchdogTimer
     1063.afterWatchdogTimerCheck:
    10601064    checkSwitchToJITForLoop()
    10611065    dispatch(1)
    1062 
     1066.handleWatchdogTimer:
     1067    callWatchdogTimerHandler()
     1068    jmp .afterWatchdogTimerCheck
    10631069
    10641070_llint_op_switch_string:
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r148474 r148639  
    184184    move t1, cfr
    185185    action(t0)
     186end
     187
     188macro callWatchdogTimerHandler()
     189    storei PC, ArgumentCount + TagOffset[cfr]
     190    cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
     191    move t1, cfr
     192    btpnz t0, _llint_throw_from_slow_path_trampoline
     193    loadi ArgumentCount + TagOffset[cfr], PC
    186194end
    187195
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r147190 r148639  
    125125    move t1, cfr
    126126    action(t0)
     127end
     128
     129macro callWatchdogTimerHandler()
     130    storei PC, ArgumentCount + TagOffset[cfr]
     131    prepareStateForCCall()
     132    cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
     133    move t1, cfr
     134    btpnz t0, _llint_throw_from_slow_path_trampoline
     135    move t3, PB
     136    loadi ArgumentCount + TagOffset[cfr], PC
    127137end
    128138
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r139541 r148639  
    4141
    4242namespace JSC {
    43 
    44 ASSERT_HAS_TRIVIAL_DESTRUCTOR(InterruptedExecutionError);
    45 
    46 const ClassInfo InterruptedExecutionError::s_info = { "InterruptedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InterruptedExecutionError) };
    47 
    48 JSValue InterruptedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint)
    49 {
    50     if (hint == PreferString)
    51         return jsNontrivialString(exec, String(ASCIILiteral("JavaScript execution exceeded timeout.")));
    52     return JSValue(QNaN);
    53 }
    54 
    55 JSObject* createInterruptedExecutionException(JSGlobalData* globalData)
    56 {
    57     return InterruptedExecutionError::create(*globalData);
    58 }
    59 
    60 bool isInterruptedExecutionException(JSObject* object)
    61 {
    62     return object->inherits(&InterruptedExecutionError::s_info);
    63 }
    64 
    65 bool isInterruptedExecutionException(JSValue value)
    66 {
    67     return value.inherits(&InterruptedExecutionError::s_info);
    68 }
    69 
    7043
    7144ASSERT_HAS_TRIVIAL_DESTRUCTOR(TerminatedExecutionError);
     
    169142}
    170143
     144JSObject* throwTerminatedExecutionException(ExecState* exec)
     145{
     146    Interpreter::ErrorHandlingMode mode(exec);
     147    return throwError(exec, createTerminatedExecutionException(&exec->globalData()));
     148}
     149
    171150} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.h

    r127191 r148639  
    3434namespace JSC {
    3535
    36 JS_EXPORT_PRIVATE JSObject* createInterruptedExecutionException(JSGlobalData*);
    37 bool isInterruptedExecutionException(JSObject*);
    38 bool isInterruptedExecutionException(JSValue);
    39 
    4036JSObject* createTerminatedExecutionException(JSGlobalData*);
    4137bool isTerminatedExecutionException(JSObject*);
     
    5450JSObject* throwOutOfMemoryError(ExecState*);
    5551JSObject* throwStackOverflowError(ExecState*);
     52JSObject* throwTerminatedExecutionException(ExecState*);
    5653
    57 
    58 class InterruptedExecutionError : public JSNonFinalObject {
    59 private:
    60     InterruptedExecutionError(JSGlobalData& globalData)
    61         : JSNonFinalObject(globalData, globalData.interruptedExecutionErrorStructure.get())
    62     {
    63     }
    64 
    65     static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
    66 
    67 public:
    68     typedef JSNonFinalObject Base;
    69 
    70     static InterruptedExecutionError* create(JSGlobalData& globalData)
    71     {
    72         InterruptedExecutionError* error = new (NotNull, allocateCell<InterruptedExecutionError>(globalData.heap)) InterruptedExecutionError(globalData);
    73         error->finishCreation(globalData);
    74         return error;
    75     }
    76 
    77     static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
    78     {
    79         return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
    80     }
    81 
    82     static const ClassInfo s_info;
    83 };
    8454
    8555class TerminatedExecutionError : public JSNonFinalObject {
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r148616 r148639  
    205205    structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
    206206    debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull()));
    207     interruptedExecutionErrorStructure.set(*this, InterruptedExecutionError::createStructure(*this, 0, jsNull()));
    208207    terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
    209208    stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r148568 r148639  
    4747#include "SmallStrings.h"
    4848#include "Strong.h"
    49 #include "Terminator.h"
    5049#include "ThunkGenerators.h"
    5150#include "TypedArrayDescriptor.h"
     51#include "Watchdog.h"
    5252#include "WeakRandom.h"
    5353#include <wtf/BumpPointerAllocator.h>
     
    212212        ClientData* clientData;
    213213        ExecState* topCallFrame;
     214        Watchdog watchdog;
    214215
    215216        const HashTable* arrayConstructorTable;
     
    234235        Strong<Structure> structureRareDataStructure;
    235236        Strong<Structure> debuggerActivationStructure;
    236         Strong<Structure> interruptedExecutionErrorStructure;
    237237        Strong<Structure> terminatedExecutionErrorStructure;
    238238        Strong<Structure> stringStructure;
     
    325325#endif
    326326        NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
    327 
    328         Terminator terminator;
    329327
    330328        JSValue exception;
  • trunk/Source/WTF/ChangeLog

    r148625 r148639  
     12013-04-17  Mark Lam  <mark.lam@apple.com>
     2
     3        Added currentCPUTime() and currentCPUTimeMS().
     4        https://bugs.webkit.org/show_bug.cgi?id=114577.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The currentCPUTime() implementation came from the old TimeoutChecker.cpp.
     9
     10        * wtf/CurrentTime.cpp:
     11        (WTF::currentCPUTime):
     12        (WTF::currentCPUTimeMS):
     13        * wtf/CurrentTime.h:
     14
    1152013-04-17  Ryosuke Niwa  <rniwa@webkit.org>
    216
  • trunk/Source/WTF/wtf/CurrentTime.cpp

    r147910 r148639  
    11/*
    2  * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Google Inc. All rights reserved.
    44 * Copyright (C) 2007-2009 Torch Mobile, Inc.
     5 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    56 *
    67 * Redistribution and use in source and binary forms, with or without
     
    3536
    3637#if PLATFORM(MAC)
     38#include <mach/mach.h>
    3739#include <mach/mach_time.h>
    3840#include <sys/time.h>
     
    332334#endif
    333335
     336double currentCPUTime()
     337{
     338#if OS(DARWIN)
     339    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
     340    thread_basic_info_data_t info;
     341
     342    // Get thread information
     343    mach_port_t threadPort = mach_thread_self();
     344    thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
     345    mach_port_deallocate(mach_task_self(), threadPort);
     346   
     347    double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
     348    time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
     349   
     350    return time;
     351#elif OS(WINDOWS)
     352    union {
     353        FILETIME fileTime;
     354        unsigned long long fileTimeAsLong;
     355    } userTime, kernelTime;
     356   
     357    // GetThreadTimes won't accept null arguments so we pass these even though
     358    // they're not used.
     359    FILETIME creationTime, exitTime;
     360   
     361    GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
     362   
     363    return userTime.fileTimeAsLong / 10000000. + kernelTime.fileTimeAsLong / 10000000.;
     364#elif OS(QNX)
     365    struct timespec time;
     366    if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time))
     367        CRASH();
     368    return time.tv_sec + time.tv_nsec / 1.0e9;
     369#else
     370    // FIXME: We should return the time the current thread has spent executing.
     371
     372    // use a relative time from first call in order to avoid an overflow
     373    static double firstTime = currentTime();
     374    return currentTime() - firstTime;
     375#endif
     376}
     377
     378double currentCPUTimeMS()
     379{
     380    return currentCPUTime() * 1000;
     381}
     382
    334383} // namespace WTF
  • trunk/Source/WTF/wtf/CurrentTime.h

    r124560 r148639  
    5252WTF_EXPORT_PRIVATE double monotonicallyIncreasingTime();
    5353
     54// Returns the current CPU time of the current thread in seconds.
     55// Precision varies depending on platform but is usually as good or better
     56// than a millisecond.
     57WTF_EXPORT_PRIVATE double currentCPUTime();
     58
     59// Returns the current CPU time of the current thread in milliseconds.
     60WTF_EXPORT_PRIVATE double currentCPUTimeMS();
     61
    5462} // namespace WTF
    5563
     
    5765using WTF::currentTimeMS;
    5866using WTF::monotonicallyIncreasingTime;
     67using WTF::currentCPUTime;
    5968
    6069#endif // CurrentTime_h
  • trunk/Source/WebCore/ChangeLog

    r148636 r148639  
     12013-04-17  Mark Lam  <mark.lam@apple.com>
     2
     3        Add LLINT and baseline JIT support for timing out scripts.
     4        https://bugs.webkit.org/show_bug.cgi?id=114577.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Replaced use of the obsolete JSGlobalData.terminator methods with the
     9        JSGlobalData.watchdog equivalents.
     10
     11        * bindings/js/JSEventListener.cpp:
     12        (WebCore::JSEventListener::handleEvent):
     13        * bindings/js/SerializedScriptValue.cpp:
     14        (WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):
     15        * bindings/js/WorkerScriptController.cpp:
     16        (WebCore::WorkerScriptController::evaluate):
     17        (WebCore::WorkerScriptController::scheduleExecutionTermination):
     18        (WebCore::WorkerScriptController::isExecutionTerminating):
     19
    1202013-04-16  Jer Noble <jer.noble@apple.com>
    221
  • trunk/Source/WebCore/bindings/js/JSEventListener.cpp

    r148373 r148639  
    137137        if (scriptExecutionContext->isWorkerContext()) {
    138138            bool terminatorCausedException = (exec->hadException() && isTerminatedExecutionException(exec->exception()));
    139             if (terminatorCausedException || globalData.terminator.shouldTerminate())
     139            if (terminatorCausedException || globalData.watchdog.didFire())
    140140                static_cast<WorkerContext*>(scriptExecutionContext)->script()->forbidExecution();
    141141        }
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r148119 r148639  
    19031903        throwError(exec, createStackOverflowError(exec));
    19041904        break;
    1905     case InterruptedExecutionError:
    1906         throwError(exec, createInterruptedExecutionException(&exec->globalData()));
    1907         break;
    19081905    case ValidationError:
    19091906        throwError(exec, createTypeError(exec, "Unable to deserialize data."));
  • trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp

    r148119 r148639  
    138138    JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerContextWrapper.get(), &evaluationException);
    139139
    140     if ((evaluationException && isTerminatedExecutionException(evaluationException)) ||  m_workerContextWrapper->globalData().terminator.shouldTerminate()) {
     140    if ((evaluationException && isTerminatedExecutionException(evaluationException)) ||  m_workerContextWrapper->globalData().watchdog.didFire()) {
    141141        forbidExecution();
    142142        return;
     
    165165    // accurately reflect that state when called from another thread.
    166166    MutexLocker locker(m_scheduledTerminationMutex);
    167     m_globalData->terminator.terminateSoon();
     167    m_globalData->watchdog.fire();
    168168}
    169169
     
    172172    // See comments in scheduleExecutionTermination regarding mutex usage.
    173173    MutexLocker locker(m_scheduledTerminationMutex);
    174     return m_globalData->terminator.shouldTerminate();
     174    return m_globalData->watchdog.didFire();
    175175}
    176176
Note: See TracChangeset for help on using the changeset viewer.