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_ |