| Index: src/execution.cc
|
| ===================================================================
|
| --- src/execution.cc (revision 2982)
|
| +++ src/execution.cc (working copy)
|
| @@ -61,9 +61,6 @@
|
| // Entering JavaScript.
|
| VMState state(JS);
|
|
|
| - // Guard the stack against too much recursion.
|
| - StackGuard guard;
|
| -
|
| // Placeholder for return value.
|
| Object* value = reinterpret_cast<Object*>(kZapValue);
|
|
|
| @@ -217,55 +214,6 @@
|
| StackGuard::ThreadLocal StackGuard::thread_local_;
|
|
|
|
|
| -StackGuard::StackGuard() {
|
| - // NOTE: Overall the StackGuard code assumes that the stack grows towards
|
| - // lower addresses.
|
| - ExecutionAccess access;
|
| - if (thread_local_.nesting_++ == 0) {
|
| - // Initial StackGuard is being set. We will set the stack limits based on
|
| - // the current stack pointer allowing the stack to grow kLimitSize from
|
| - // here.
|
| -
|
| - // Ensure that either the stack limits are unset (kIllegalLimit) or that
|
| - // they indicate a pending interruption. The interrupt limit will be
|
| - // temporarily reset through the code below and reestablished if the
|
| - // interrupt flags indicate that an interrupt is pending.
|
| - ASSERT(thread_local_.jslimit_ == kIllegalLimit ||
|
| - (thread_local_.jslimit_ == kInterruptLimit &&
|
| - thread_local_.interrupt_flags_ != 0));
|
| - ASSERT(thread_local_.climit_ == kIllegalLimit ||
|
| - (thread_local_.climit_ == kInterruptLimit &&
|
| - thread_local_.interrupt_flags_ != 0));
|
| -
|
| - uintptr_t limit = GENERATED_CODE_STACK_LIMIT(kLimitSize);
|
| - thread_local_.initial_jslimit_ = thread_local_.jslimit_ = limit;
|
| - Heap::SetStackLimit(limit);
|
| - // NOTE: The check for overflow is not safe as there is no guarantee that
|
| - // the running thread has its stack in all memory up to address 0x00000000.
|
| - thread_local_.initial_climit_ = thread_local_.climit_ =
|
| - reinterpret_cast<uintptr_t>(this) >= kLimitSize ?
|
| - reinterpret_cast<uintptr_t>(this) - kLimitSize : 0;
|
| -
|
| - if (thread_local_.interrupt_flags_ != 0) {
|
| - set_limits(kInterruptLimit, access);
|
| - }
|
| - }
|
| - // Ensure that proper limits have been set.
|
| - ASSERT(thread_local_.jslimit_ != kIllegalLimit &&
|
| - thread_local_.climit_ != kIllegalLimit);
|
| - ASSERT(thread_local_.initial_jslimit_ != kIllegalLimit &&
|
| - thread_local_.initial_climit_ != kIllegalLimit);
|
| -}
|
| -
|
| -
|
| -StackGuard::~StackGuard() {
|
| - ExecutionAccess access;
|
| - if (--thread_local_.nesting_ == 0) {
|
| - set_limits(kIllegalLimit, access);
|
| - }
|
| -}
|
| -
|
| -
|
| bool StackGuard::IsStackOverflow() {
|
| ExecutionAccess access;
|
| return (thread_local_.jslimit_ != kInterruptLimit &&
|
| @@ -285,15 +233,16 @@
|
| ExecutionAccess access;
|
| // 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_.initial_jslimit_) {
|
| - thread_local_.jslimit_ = limit;
|
| - Heap::SetStackLimit(limit);
|
| + thread_local_.jslimit_ = jslimit;
|
| + Heap::SetStackLimit(jslimit);
|
| }
|
| if (thread_local_.climit_ == thread_local_.initial_climit_) {
|
| thread_local_.climit_ = limit;
|
| }
|
| thread_local_.initial_climit_ = limit;
|
| - thread_local_.initial_jslimit_ = limit;
|
| + thread_local_.initial_jslimit_ = jslimit;
|
| }
|
|
|
|
|
| @@ -407,10 +356,61 @@
|
| }
|
|
|
|
|
| +static internal::Thread::LocalStorageKey stack_limit_key =
|
| + internal::Thread::CreateThreadLocalKey();
|
| +
|
| +
|
| void StackGuard::FreeThreadResources() {
|
| + Thread::SetThreadLocal(
|
| + stack_limit_key,
|
| + reinterpret_cast<void*>(thread_local_.initial_climit_));
|
| }
|
|
|
|
|
| +void StackGuard::ThreadLocal::Clear() {
|
| + initial_jslimit_ = kIllegalLimit;
|
| + jslimit_ = kIllegalLimit;
|
| + initial_climit_ = kIllegalLimit;
|
| + climit_ = kIllegalLimit;
|
| + nesting_ = 0;
|
| + postpone_interrupts_nesting_ = 0;
|
| + interrupt_flags_ = 0;
|
| + Heap::SetStackLimit(kIllegalLimit);
|
| +}
|
| +
|
| +
|
| +void StackGuard::ThreadLocal::Initialize() {
|
| + if (initial_climit_ == kIllegalLimit) {
|
| + // Takes the address of the limit variable in order to find out where
|
| + // the top of stack is right now.
|
| + intptr_t limit = reinterpret_cast<intptr_t>(&limit) - kLimitSize;
|
| + initial_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
|
| + jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
|
| + initial_climit_ = limit;
|
| + climit_ = limit;
|
| + Heap::SetStackLimit(SimulatorStack::JsLimitFromCLimit(limit));
|
| + }
|
| + nesting_ = 0;
|
| + postpone_interrupts_nesting_ = 0;
|
| + interrupt_flags_ = 0;
|
| +}
|
| +
|
| +
|
| +void StackGuard::ClearThread(const ExecutionAccess& lock) {
|
| + thread_local_.Clear();
|
| +}
|
| +
|
| +
|
| +void StackGuard::InitThread(const ExecutionAccess& lock) {
|
| + thread_local_.Initialize();
|
| + void* stored_limit = Thread::GetThreadLocal(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));
|
| + }
|
| +}
|
| +
|
| +
|
| // --- C a l l s t o n a t i v e s ---
|
|
|
| #define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \
|
|
|