Index: src/execution.cc |
=================================================================== |
--- src/execution.cc (revision 3427) |
+++ src/execution.cc (working copy) |
@@ -38,7 +38,20 @@ |
namespace v8 { |
namespace internal { |
+class StackGuardPrivateData { |
+ public: |
+ Thread::LocalStorageKey stack_limit_key; |
+ StackGuardPrivateData() |
+ :stack_limit_key(internal::Thread::CreateThreadLocalKey()) { |
+ } |
+}; |
+ |
+StackGuardData::StackGuardData() |
+ :thread_local_(0), |
+ stack_guard_private_data_(NULL) { |
+} |
+ |
static Handle<Object> Invoke(bool construct, |
Handle<JSFunction> func, |
Handle<Object> receiver, |
@@ -204,13 +217,14 @@ |
// Static state for stack guards. |
-StackGuard::ThreadLocal StackGuard::thread_local_; |
bool StackGuard::IsStackOverflow() { |
ExecutionAccess access; |
- return (thread_local_.jslimit_ != kInterruptLimit && |
- thread_local_.climit_ != kInterruptLimit); |
+ StackGuardData::ThreadLocal& thread_local = v8_context()-> |
+ stack_guard_data_.thread_local_; |
+ return (thread_local.jslimit_ != kInterruptLimit && |
+ thread_local.climit_ != kInterruptLimit); |
} |
@@ -224,17 +238,19 @@ |
void StackGuard::SetStackLimit(uintptr_t limit) { |
ExecutionAccess access; |
+ StackGuardData::ThreadLocal& thread_local = v8_context()-> |
+ stack_guard_data_.thread_local_; |
// If the current limits are special (eg due to a pending interrupt) then |
// leave them alone. |
uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(limit); |
- if (thread_local_.jslimit_ == thread_local_.real_jslimit_) { |
- thread_local_.jslimit_ = jslimit; |
+ if (thread_local.jslimit_ == thread_local.real_jslimit_) { |
+ thread_local.jslimit_ = jslimit; |
} |
- if (thread_local_.climit_ == thread_local_.real_climit_) { |
- thread_local_.climit_ = limit; |
+ if (thread_local.climit_ == thread_local.real_climit_) { |
+ thread_local.climit_ = limit; |
} |
- thread_local_.real_climit_ = limit; |
- thread_local_.real_jslimit_ = jslimit; |
+ thread_local.real_climit_ = limit; |
+ thread_local.real_jslimit_ = jslimit; |
} |
@@ -245,45 +261,48 @@ |
bool StackGuard::IsSet(const ExecutionAccess& lock) { |
- return thread_local_.interrupt_flags_ != 0; |
+ return v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ != 0; |
} |
bool StackGuard::IsInterrupted() { |
ExecutionAccess access; |
- return thread_local_.interrupt_flags_ & INTERRUPT; |
+ return v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ & INTERRUPT; |
} |
void StackGuard::Interrupt() { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ |= INTERRUPT; |
+ v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= INTERRUPT; |
set_limits(kInterruptLimit, access); |
} |
bool StackGuard::IsPreempted() { |
ExecutionAccess access; |
- return thread_local_.interrupt_flags_ & PREEMPT; |
+ return v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ & PREEMPT; |
} |
void StackGuard::Preempt() { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ |= PREEMPT; |
+ v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= PREEMPT; |
set_limits(kInterruptLimit, access); |
} |
bool StackGuard::IsTerminateExecution() { |
ExecutionAccess access; |
- return thread_local_.interrupt_flags_ & TERMINATE; |
+ return v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ & TERMINATE; |
} |
void StackGuard::TerminateExecution() { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ |= TERMINATE; |
+ v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= TERMINATE; |
set_limits(kInterruptLimit, access); |
} |
@@ -291,27 +310,30 @@ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
bool StackGuard::IsDebugBreak() { |
ExecutionAccess access; |
- return thread_local_.interrupt_flags_ & DEBUGBREAK; |
+ return v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ & DEBUGBREAK; |
} |
void StackGuard::DebugBreak() { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ |= DEBUGBREAK; |
+ v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= DEBUGBREAK; |
set_limits(kInterruptLimit, access); |
} |
bool StackGuard::IsDebugCommand() { |
ExecutionAccess access; |
- return thread_local_.interrupt_flags_ & DEBUGCOMMAND; |
+ return v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ & DEBUGCOMMAND; |
} |
void StackGuard::DebugCommand() { |
if (FLAG_debugger_auto_break) { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ |= DEBUGCOMMAND; |
+ v8_context()-> |
+ stack_guard_data_.thread_local_.interrupt_flags_ |= DEBUGCOMMAND; |
set_limits(kInterruptLimit, access); |
} |
} |
@@ -319,51 +341,69 @@ |
void StackGuard::Continue(InterruptFlag after_what) { |
ExecutionAccess access; |
- thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); |
- if (thread_local_.interrupt_flags_ == 0) { |
+ StackGuardData::ThreadLocal& thread_local = v8_context()-> |
+ stack_guard_data_.thread_local_; |
+ thread_local.interrupt_flags_ &= ~static_cast<int>(after_what); |
+ if (thread_local.interrupt_flags_ == 0) { |
reset_limits(access); |
} |
} |
int StackGuard::ArchiveSpacePerThread() { |
- return sizeof(ThreadLocal); |
+ return sizeof(StackGuardData::ThreadLocal); |
} |
char* StackGuard::ArchiveStackGuard(char* to) { |
ExecutionAccess access; |
- memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); |
- ThreadLocal blank; |
- thread_local_ = blank; |
- return to + sizeof(ThreadLocal); |
+ StackGuardData::ThreadLocal& thread_local = v8_context()-> |
+ stack_guard_data_.thread_local_; |
+ memcpy( |
+ to, |
+ reinterpret_cast<char*>(&thread_local), |
+ sizeof(StackGuardData::ThreadLocal)); |
+ StackGuardData::ThreadLocal blank; |
+ thread_local = blank; |
+ return to + sizeof(StackGuardData::ThreadLocal); |
} |
char* StackGuard::RestoreStackGuard(char* from) { |
ExecutionAccess access; |
- memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); |
+ memcpy( |
+ reinterpret_cast<char*>(&v8_context()->stack_guard_data_.thread_local_), |
+ from, |
+ sizeof(StackGuardData::ThreadLocal)); |
Heap::SetStackLimits(); |
- return from + sizeof(ThreadLocal); |
+ return from + sizeof(StackGuardData::ThreadLocal); |
} |
-static internal::Thread::LocalStorageKey stack_limit_key = |
- internal::Thread::CreateThreadLocalKey(); |
+void StackGuard::PostConstruct() { |
+ V8Context* const v8context = v8_context(); |
+ v8context->stack_guard_data_.thread_local_.Clear(); |
+ v8context->stack_guard_data_.stack_guard_private_data_ = |
+ new StackGuardPrivateData(); |
+} |
+void StackGuard::PreDestroy() { |
+ delete v8_context()->stack_guard_data_.stack_guard_private_data_; |
+} |
void StackGuard::FreeThreadResources() { |
+ StackGuardData& stack_guard_data = v8_context()->stack_guard_data_; |
Thread::SetThreadLocal( |
- stack_limit_key, |
- reinterpret_cast<void*>(thread_local_.real_climit_)); |
+ stack_guard_data.stack_guard_private_data_->stack_limit_key, |
+ reinterpret_cast<void*>(stack_guard_data.thread_local_.real_climit_)); |
} |
-void StackGuard::ThreadLocal::Clear() { |
- real_jslimit_ = kIllegalLimit; |
- jslimit_ = kIllegalLimit; |
- real_climit_ = kIllegalLimit; |
- climit_ = kIllegalLimit; |
+void StackGuardData::ThreadLocal::Clear() { |
+ real_jslimit_ = StackGuard::kIllegalLimit; |
+ jslimit_ = StackGuard::kIllegalLimit; |
+ real_climit_ = StackGuard::kIllegalLimit; |
+ climit_ = StackGuard::kIllegalLimit; |
nesting_ = 0; |
postpone_interrupts_nesting_ = 0; |
interrupt_flags_ = 0; |
@@ -371,12 +411,13 @@ |
} |
-void StackGuard::ThreadLocal::Initialize() { |
- if (real_climit_ == kIllegalLimit) { |
+void StackGuardData::ThreadLocal::Initialize() { |
+ if (real_climit_ == StackGuard::kIllegalLimit) { |
// Takes the address of the limit variable in order to find out where |
// the top of stack is right now. |
- uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; |
- ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); |
+ uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - |
+ StackGuard::kLimitSize; |
+ ASSERT(reinterpret_cast<uintptr_t>(&limit) > StackGuard::kLimitSize); |
real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); |
jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); |
real_climit_ = limit; |
@@ -390,13 +431,15 @@ |
void StackGuard::ClearThread(const ExecutionAccess& lock) { |
- thread_local_.Clear(); |
+ v8_context()->stack_guard_data_.thread_local_.Clear(); |
} |
void StackGuard::InitThread(const ExecutionAccess& lock) { |
- thread_local_.Initialize(); |
- void* stored_limit = Thread::GetThreadLocal(stack_limit_key); |
+ StackGuardData& stack_guard_data = v8_context()->stack_guard_data_; |
+ stack_guard_data.thread_local_.Initialize(); |
+ void* stored_limit = Thread::GetThreadLocal( |
+ stack_guard_data.stack_guard_private_data_->stack_limit_key); |
// You should hold the ExecutionAccess lock when you call this. |
if (stored_limit != NULL) { |
StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit)); |