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:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@148639 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index b83393a..f05eb26 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -118,6 +118,17 @@
 }
 #endif
 
+void JIT::emitWatchdogTimerCheck()
+{
+    if (!m_globalData->watchdog.isEnabled())
+        return;
+
+    Jump skipCheck = branchTest8(Zero, AbsoluteAddress(m_globalData->watchdog.timerDidFireAddress()));
+    JITStubCall stubCall(this, cti_handle_watchdog_timer);
+    stubCall.call();
+    skipCheck.link(this);
+}
+
 #define NEXT_OPCODE(name) \
     m_bytecodeOffset += OPCODE_LENGTH(name); \
     break;
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index d9c4436..e9cd1c8 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -858,7 +858,8 @@
 #else
         void emitOptimizationCheck(OptimizationCheckKind) { }
 #endif
-        
+        void emitWatchdogTimerCheck();
+
 #ifndef NDEBUG
         void printBytecodeOperandTypes(unsigned src1, unsigned src2);
 #endif
@@ -945,6 +946,7 @@
 
     inline void JIT::emit_op_loop_hint(Instruction*)
     {
+        emitWatchdogTimerCheck();
         emitOptimizationCheck(LoopOptimizationCheck);
     }
 
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 1712e5e..c6d48b8 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1375,6 +1375,18 @@
     return JSValue::encode(result);
 }
 
+DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+    if (UNLIKELY(globalData->watchdog.didFire(callFrame))) {
+        globalData->exception = createTerminatedExecutionException(globalData);
+        VM_THROW_EXCEPTION_AT_END();
+        return;
+    }
+}
+
 DEFINE_STUB_FUNCTION(void*, stack_check)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index 5240485..2ea4fe5 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -406,6 +406,7 @@
 int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_handle_watchdog_timer(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL;