Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: src/execution.cc

Issue 242014: Adds an API for setting the stack limit per-thread. (Closed)
Patch Set: Leaves the limits of pending interrupts alone instead of reestablishing them." Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/execution.h ('k') | src/ia32/simulator-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/execution.cc
diff --git a/src/execution.cc b/src/execution.cc
index 04ec9059f34d0311f5219148fdd4470a07ae9214..88e9b6d4631fb5f80a0adc3d560ddea850d7a1fe 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -222,9 +222,7 @@ StackGuard::StackGuard() {
// 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.
+ // Initial StackGuard is being set.
// Ensure that either the stack limits are unset (kIllegalLimit) or that
// they indicate a pending interruption. The interrupt limit will be
@@ -237,17 +235,26 @@ StackGuard::StackGuard() {
(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);
+ if (thread_local_.initial_jslimit_ == kIllegalLimit ||
+ thread_local_.initial_climit_ == kIllegalLimit) {
+ ASSERT(thread_local_.initial_jslimit_ == kIllegalLimit &&
+ thread_local_.initial_climit_ == kIllegalLimit);
+
+ // We will set the stack limits based on the current stack
+ // pointer allowing the stack to grow kLimitSize from here.
+
+ // Compute default limit, checking for underflow.
+ uintptr_t limit =
+ reinterpret_cast<uintptr_t>(this) >= kLimitSize ?
+ reinterpret_cast<uintptr_t>(this) - kLimitSize : 0;
+
+ thread_local_.initial_jslimit_ = GENERATED_CODE_STACK_LIMIT(limit);
+ thread_local_.initial_climit_ = limit;
+ }
+
+ if (thread_local_.interrupt_flags_ == 0) {
+ set_limits(thread_local_.initial_jslimit_, thread_local_.initial_climit_,
+ access);
}
}
// Ensure that proper limits have been set.
@@ -260,8 +267,9 @@ StackGuard::StackGuard() {
StackGuard::~StackGuard() {
ExecutionAccess access;
- if (--thread_local_.nesting_ == 0) {
- set_limits(kIllegalLimit, access);
+ if (--thread_local_.nesting_ == 0 &&
+ thread_local_.interrupt_flags_ == 0) {
+ set_illegal_limit(access);
}
}
@@ -276,24 +284,24 @@ bool StackGuard::IsStackOverflow() {
void StackGuard::EnableInterrupts() {
ExecutionAccess access;
if (IsSet(access)) {
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
}
void StackGuard::SetStackLimit(uintptr_t limit) {
ExecutionAccess access;
- // If the current limits are special (eg due to a pending interrupt) then
- // leave them alone.
- if (thread_local_.jslimit_ == thread_local_.initial_jslimit_) {
- thread_local_.jslimit_ = limit;
- Heap::SetStackLimit(limit);
- }
- if (thread_local_.climit_ == thread_local_.initial_climit_) {
- thread_local_.climit_ = limit;
- }
+ thread_local_.initial_jslimit_ = GENERATED_CODE_STACK_LIMIT(limit);
thread_local_.initial_climit_ = limit;
- thread_local_.initial_jslimit_ = limit;
+
+ // If a StackGuard is active (nesting_ > 0) and not interrupted set
+ // the limit directly. Otherwise the limit will be established by
+ // the first StackGuard.
+ if (thread_local_.nesting_ > 0 &&
+ thread_local_.interrupt_flags_ == 0) {
+ set_limits(thread_local_.initial_jslimit_, thread_local_.initial_climit_,
+ access);
+ }
}
@@ -317,7 +325,7 @@ bool StackGuard::IsInterrupted() {
void StackGuard::Interrupt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= INTERRUPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
@@ -330,7 +338,7 @@ bool StackGuard::IsPreempted() {
void StackGuard::Preempt() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= PREEMPT;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
@@ -343,7 +351,7 @@ bool StackGuard::IsTerminateExecution() {
void StackGuard::TerminateExecution() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= TERMINATE;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
@@ -357,7 +365,7 @@ bool StackGuard::IsDebugBreak() {
void StackGuard::DebugBreak() {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGBREAK;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
@@ -371,7 +379,7 @@ void StackGuard::DebugCommand() {
if (FLAG_debugger_auto_break) {
ExecutionAccess access;
thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
- set_limits(kInterruptLimit, access);
+ set_interrupt_limit(access);
}
}
#endif
@@ -407,6 +415,13 @@ char* StackGuard::RestoreStackGuard(char* from) {
}
+void StackGuard::InitThread(const ExecutionAccess& lock) {
+ // new threads should configure their own stack limits
+ ThreadLocal blank;
+ thread_local_ = blank;
+}
+
+
// --- C a l l s t o n a t i v e s ---
#define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \
« no previous file with comments | « src/execution.h ('k') | src/ia32/simulator-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698