| Index: src/execution.h
|
| ===================================================================
|
| --- src/execution.h (revision 7267)
|
| +++ src/execution.h (working copy)
|
| @@ -146,71 +146,74 @@
|
|
|
|
|
| class ExecutionAccess;
|
| +class Isolate;
|
|
|
|
|
| // StackGuard contains the handling of the limits that are used to limit the
|
| // number of nested invocations of JavaScript and the stack size used in each
|
| // invocation.
|
| -class StackGuard : public AllStatic {
|
| +class StackGuard {
|
| public:
|
| // Pass the address beyond which the stack should not grow. The stack
|
| // is assumed to grow downwards.
|
| - static void SetStackLimit(uintptr_t limit);
|
| + void SetStackLimit(uintptr_t limit);
|
|
|
| // Threading support.
|
| - static char* ArchiveStackGuard(char* to);
|
| - static char* RestoreStackGuard(char* from);
|
| - static int ArchiveSpacePerThread();
|
| - static void FreeThreadResources();
|
| + char* ArchiveStackGuard(char* to);
|
| + char* RestoreStackGuard(char* from);
|
| + static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
|
| + void FreeThreadResources();
|
| // Sets up the default stack guard for this thread if it has not
|
| // already been set up.
|
| - static void InitThread(const ExecutionAccess& lock);
|
| + void InitThread(const ExecutionAccess& lock);
|
| // Clears the stack guard for this thread so it does not look as if
|
| // it has been set up.
|
| - static void ClearThread(const ExecutionAccess& lock);
|
| + void ClearThread(const ExecutionAccess& lock);
|
|
|
| - static bool IsStackOverflow();
|
| - static bool IsPreempted();
|
| - static void Preempt();
|
| - static bool IsInterrupted();
|
| - static void Interrupt();
|
| - static bool IsTerminateExecution();
|
| - static void TerminateExecution();
|
| - static bool IsRuntimeProfilerTick();
|
| - static void RequestRuntimeProfilerTick();
|
| + bool IsStackOverflow();
|
| + bool IsPreempted();
|
| + void Preempt();
|
| + bool IsInterrupted();
|
| + void Interrupt();
|
| + bool IsTerminateExecution();
|
| + void TerminateExecution();
|
| + bool IsRuntimeProfilerTick();
|
| + void RequestRuntimeProfilerTick();
|
| #ifdef ENABLE_DEBUGGER_SUPPORT
|
| - static bool IsDebugBreak();
|
| - static void DebugBreak();
|
| - static bool IsDebugCommand();
|
| - static void DebugCommand();
|
| + bool IsDebugBreak();
|
| + void DebugBreak();
|
| + bool IsDebugCommand();
|
| + void DebugCommand();
|
| #endif
|
| - static void Continue(InterruptFlag after_what);
|
| + void Continue(InterruptFlag after_what);
|
|
|
| // This provides an asynchronous read of the stack limits for the current
|
| // thread. There are no locks protecting this, but it is assumed that you
|
| // have the global V8 lock if you are using multiple V8 threads.
|
| - static uintptr_t climit() {
|
| + uintptr_t climit() {
|
| return thread_local_.climit_;
|
| }
|
| - static uintptr_t real_climit() {
|
| + uintptr_t real_climit() {
|
| return thread_local_.real_climit_;
|
| }
|
| - static uintptr_t jslimit() {
|
| + uintptr_t jslimit() {
|
| return thread_local_.jslimit_;
|
| }
|
| - static uintptr_t real_jslimit() {
|
| + uintptr_t real_jslimit() {
|
| return thread_local_.real_jslimit_;
|
| }
|
| - static Address address_of_jslimit() {
|
| + Address address_of_jslimit() {
|
| return reinterpret_cast<Address>(&thread_local_.jslimit_);
|
| }
|
| - static Address address_of_real_jslimit() {
|
| + Address address_of_real_jslimit() {
|
| return reinterpret_cast<Address>(&thread_local_.real_jslimit_);
|
| }
|
|
|
| private:
|
| + StackGuard();
|
| +
|
| // You should hold the ExecutionAccess lock when calling this method.
|
| - static bool has_pending_interrupts(const ExecutionAccess& lock) {
|
| + bool has_pending_interrupts(const ExecutionAccess& lock) {
|
| // Sanity check: We shouldn't be asking about pending interrupts
|
| // unless we're not postponing them anymore.
|
| ASSERT(!should_postpone_interrupts(lock));
|
| @@ -218,30 +221,20 @@
|
| }
|
|
|
| // You should hold the ExecutionAccess lock when calling this method.
|
| - static bool should_postpone_interrupts(const ExecutionAccess& lock) {
|
| + bool should_postpone_interrupts(const ExecutionAccess& lock) {
|
| return thread_local_.postpone_interrupts_nesting_ > 0;
|
| }
|
|
|
| // You should hold the ExecutionAccess lock when calling this method.
|
| - static void set_interrupt_limits(const ExecutionAccess& lock) {
|
| - // Ignore attempts to interrupt when interrupts are postponed.
|
| - if (should_postpone_interrupts(lock)) return;
|
| - thread_local_.jslimit_ = kInterruptLimit;
|
| - thread_local_.climit_ = kInterruptLimit;
|
| - Heap::SetStackLimits();
|
| - }
|
| + inline void set_interrupt_limits(const ExecutionAccess& lock);
|
|
|
| // Reset limits to actual values. For example after handling interrupt.
|
| // You should hold the ExecutionAccess lock when calling this method.
|
| - static void reset_limits(const ExecutionAccess& lock) {
|
| - thread_local_.jslimit_ = thread_local_.real_jslimit_;
|
| - thread_local_.climit_ = thread_local_.real_climit_;
|
| - Heap::SetStackLimits();
|
| - }
|
| + inline void reset_limits(const ExecutionAccess& lock);
|
|
|
| // Enable or disable interrupts.
|
| - static void EnableInterrupts();
|
| - static void DisableInterrupts();
|
| + void EnableInterrupts();
|
| + void DisableInterrupts();
|
|
|
| #ifdef V8_TARGET_ARCH_X64
|
| static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
|
| @@ -256,9 +249,11 @@
|
| ThreadLocal() { Clear(); }
|
| // You should hold the ExecutionAccess lock when you call Initialize or
|
| // Clear.
|
| - void Initialize();
|
| void Clear();
|
|
|
| + // Returns true if the heap's stack limits should be set, false if not.
|
| + bool Initialize();
|
| +
|
| // The stack limit is split into a JavaScript and a C++ stack limit. These
|
| // two are the same except when running on a simulator where the C++ and
|
| // JavaScript stacks are separate. Each of the two stack limits have two
|
| @@ -278,45 +273,19 @@
|
| int interrupt_flags_;
|
| };
|
|
|
| - static ThreadLocal thread_local_;
|
| + // TODO(isolates): Technically this could be calculated directly from a
|
| + // pointer to StackGuard.
|
| + Isolate* isolate_;
|
| + ThreadLocal thread_local_;
|
|
|
| + friend class Isolate;
|
| friend class StackLimitCheck;
|
| friend class PostponeInterruptsScope;
|
| -};
|
|
|
| -
|
| -// Support for checking for stack-overflows in C++ code.
|
| -class StackLimitCheck BASE_EMBEDDED {
|
| - public:
|
| - bool HasOverflowed() const {
|
| - // Stack has overflowed in C++ code only if stack pointer exceeds the C++
|
| - // stack guard and the limits are not set to interrupt values.
|
| - // TODO(214): Stack overflows are ignored if a interrupt is pending. This
|
| - // code should probably always use the initial C++ limit.
|
| - return (reinterpret_cast<uintptr_t>(this) < StackGuard::climit()) &&
|
| - StackGuard::IsStackOverflow();
|
| - }
|
| + DISALLOW_COPY_AND_ASSIGN(StackGuard);
|
| };
|
|
|
|
|
| -// Support for temporarily postponing interrupts. When the outermost
|
| -// postpone scope is left the interrupts will be re-enabled and any
|
| -// interrupts that occurred while in the scope will be taken into
|
| -// account.
|
| -class PostponeInterruptsScope BASE_EMBEDDED {
|
| - public:
|
| - PostponeInterruptsScope() {
|
| - StackGuard::thread_local_.postpone_interrupts_nesting_++;
|
| - StackGuard::DisableInterrupts();
|
| - }
|
| -
|
| - ~PostponeInterruptsScope() {
|
| - if (--StackGuard::thread_local_.postpone_interrupts_nesting_ == 0) {
|
| - StackGuard::EnableInterrupts();
|
| - }
|
| - }
|
| -};
|
| -
|
| } } // namespace v8::internal
|
|
|
| #endif // V8_EXECUTION_H_
|
|
|