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

Side by Side Diff: src/execution.h

Issue 2715004: [Isolates]... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Address comments/make StackGuard::ThreadLocal::Initialize/Clear side-effects visible Created 10 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.cc ('k') | src/execution.cc » ('j') | src/execution.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 // object. Used for support calling objects as functions. 133 // object. Used for support calling objects as functions.
134 static Handle<Object> GetFunctionDelegate(Handle<Object> object); 134 static Handle<Object> GetFunctionDelegate(Handle<Object> object);
135 135
136 // Get a function delegate (or undefined) for the given non-function 136 // Get a function delegate (or undefined) for the given non-function
137 // object. Used for support calling objects as constructors. 137 // object. Used for support calling objects as constructors.
138 static Handle<Object> GetConstructorDelegate(Handle<Object> object); 138 static Handle<Object> GetConstructorDelegate(Handle<Object> object);
139 }; 139 };
140 140
141 141
142 class ExecutionAccess; 142 class ExecutionAccess;
143 class Isolate;
143 144
144 145
145 // StackGuard contains the handling of the limits that are used to limit the 146 // StackGuard contains the handling of the limits that are used to limit the
146 // number of nested invocations of JavaScript and the stack size used in each 147 // number of nested invocations of JavaScript and the stack size used in each
147 // invocation. 148 // invocation.
148 class StackGuard : public AllStatic { 149 class StackGuard {
149 public: 150 public:
150 // Pass the address beyond which the stack should not grow. The stack 151 // Pass the address beyond which the stack should not grow. The stack
151 // is assumed to grow downwards. 152 // is assumed to grow downwards.
152 static void SetStackLimit(uintptr_t limit); 153 void SetStackLimit(uintptr_t limit);
153 154
154 // Threading support. 155 // Threading support.
155 static char* ArchiveStackGuard(char* to); 156 char* ArchiveStackGuard(char* to);
156 static char* RestoreStackGuard(char* from); 157 char* RestoreStackGuard(char* from);
157 static int ArchiveSpacePerThread(); 158 static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
158 static void FreeThreadResources(); 159 void FreeThreadResources();
159 // Sets up the default stack guard for this thread if it has not 160 // Sets up the default stack guard for this thread if it has not
160 // already been set up. 161 // already been set up.
161 static void InitThread(const ExecutionAccess& lock); 162 void InitThread(const ExecutionAccess& lock);
162 // Clears the stack guard for this thread so it does not look as if 163 // Clears the stack guard for this thread so it does not look as if
163 // it has been set up. 164 // it has been set up.
164 static void ClearThread(const ExecutionAccess& lock); 165 void ClearThread(const ExecutionAccess& lock);
165 166
166 static bool IsStackOverflow(); 167 bool IsStackOverflow();
167 static bool IsPreempted(); 168 bool IsPreempted();
168 static void Preempt(); 169 void Preempt();
169 static bool IsInterrupted(); 170 bool IsInterrupted();
170 static void Interrupt(); 171 void Interrupt();
171 static bool IsTerminateExecution(); 172 bool IsTerminateExecution();
172 static void TerminateExecution(); 173 void TerminateExecution();
173 #ifdef ENABLE_DEBUGGER_SUPPORT 174 #ifdef ENABLE_DEBUGGER_SUPPORT
174 static bool IsDebugBreak(); 175 bool IsDebugBreak();
175 static void DebugBreak(); 176 void DebugBreak();
176 static bool IsDebugCommand(); 177 bool IsDebugCommand();
177 static void DebugCommand(); 178 void DebugCommand();
178 #endif 179 #endif
179 static void Continue(InterruptFlag after_what); 180 void Continue(InterruptFlag after_what);
180 181
181 // This provides an asynchronous read of the stack limits for the current 182 // This provides an asynchronous read of the stack limits for the current
182 // thread. There are no locks protecting this, but it is assumed that you 183 // thread. There are no locks protecting this, but it is assumed that you
183 // have the global V8 lock if you are using multiple V8 threads. 184 // have the global V8 lock if you are using multiple V8 threads.
184 static uintptr_t climit() { 185 uintptr_t climit() {
185 return thread_local_.climit_; 186 return thread_local_.climit_;
186 } 187 }
187 static uintptr_t jslimit() { 188 uintptr_t jslimit() {
188 return thread_local_.jslimit_; 189 return thread_local_.jslimit_;
189 } 190 }
190 static uintptr_t real_jslimit() { 191 uintptr_t real_jslimit() {
191 return thread_local_.real_jslimit_; 192 return thread_local_.real_jslimit_;
192 } 193 }
193 static Address address_of_jslimit() { 194 Address address_of_jslimit() {
194 return reinterpret_cast<Address>(&thread_local_.jslimit_); 195 return reinterpret_cast<Address>(&thread_local_.jslimit_);
195 } 196 }
196 static Address address_of_real_jslimit() { 197 Address address_of_real_jslimit() {
197 return reinterpret_cast<Address>(&thread_local_.real_jslimit_); 198 return reinterpret_cast<Address>(&thread_local_.real_jslimit_);
198 } 199 }
199 200
200 private: 201 private:
202 StackGuard();
203
204 Isolate* isolate_; // TODO(isolates): Technically this could be calculated
Vitaly Repeshko 2010/06/09 21:22:38 The comment was formatted correctly. I meant that
205 // directly from a pointer to StackGuard.
206
201 // You should hold the ExecutionAccess lock when calling this method. 207 // You should hold the ExecutionAccess lock when calling this method.
202 static bool has_pending_interrupts(const ExecutionAccess& lock) { 208 bool has_pending_interrupts(const ExecutionAccess& lock) {
203 // Sanity check: We shouldn't be asking about pending interrupts 209 // Sanity check: We shouldn't be asking about pending interrupts
204 // unless we're not postponing them anymore. 210 // unless we're not postponing them anymore.
205 ASSERT(!should_postpone_interrupts(lock)); 211 ASSERT(!should_postpone_interrupts(lock));
206 return thread_local_.interrupt_flags_ != 0; 212 return thread_local_.interrupt_flags_ != 0;
207 } 213 }
208 214
209 // You should hold the ExecutionAccess lock when calling this method. 215 // You should hold the ExecutionAccess lock when calling this method.
210 static bool should_postpone_interrupts(const ExecutionAccess& lock) { 216 bool should_postpone_interrupts(const ExecutionAccess& lock) {
211 return thread_local_.postpone_interrupts_nesting_ > 0; 217 return thread_local_.postpone_interrupts_nesting_ > 0;
212 } 218 }
213 219
214 // You should hold the ExecutionAccess lock when calling this method. 220 // You should hold the ExecutionAccess lock when calling this method.
215 static void set_interrupt_limits(const ExecutionAccess& lock) { 221 inline void set_interrupt_limits(const ExecutionAccess& lock);
216 // Ignore attempts to interrupt when interrupts are postponed.
217 if (should_postpone_interrupts(lock)) return;
218 thread_local_.jslimit_ = kInterruptLimit;
219 thread_local_.climit_ = kInterruptLimit;
220 Heap::SetStackLimits();
221 }
222 222
223 // Reset limits to actual values. For example after handling interrupt. 223 // Reset limits to actual values. For example after handling interrupt.
224 // You should hold the ExecutionAccess lock when calling this method. 224 // You should hold the ExecutionAccess lock when calling this method.
225 static void reset_limits(const ExecutionAccess& lock) { 225 inline void reset_limits(const ExecutionAccess& lock);
226 thread_local_.jslimit_ = thread_local_.real_jslimit_;
227 thread_local_.climit_ = thread_local_.real_climit_;
228 Heap::SetStackLimits();
229 }
230 226
231 // Enable or disable interrupts. 227 // Enable or disable interrupts.
232 static void EnableInterrupts(); 228 void EnableInterrupts();
233 static void DisableInterrupts(); 229 void DisableInterrupts();
234 230
235 static const uintptr_t kLimitSize = kPointerSize * 128 * KB; 231 static const uintptr_t kLimitSize = kPointerSize * 128 * KB;
236 232
237 #ifdef V8_TARGET_ARCH_X64 233 #ifdef V8_TARGET_ARCH_X64
238 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe); 234 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
239 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8); 235 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8);
240 #else 236 #else
241 static const uintptr_t kInterruptLimit = 0xfffffffe; 237 static const uintptr_t kInterruptLimit = 0xfffffffe;
242 static const uintptr_t kIllegalLimit = 0xfffffff8; 238 static const uintptr_t kIllegalLimit = 0xfffffff8;
243 #endif 239 #endif
244 240
245 class ThreadLocal { 241 class ThreadLocal {
246 public: 242 public:
247 ThreadLocal() { Clear(); } 243 ThreadLocal();
248 // You should hold the ExecutionAccess lock when you call Initialize or 244 // You should hold the ExecutionAccess lock when you call Initialize or
249 // Clear. 245 // Clear.
250 void Initialize();
251 void Clear(); 246 void Clear();
247
248 // Returns true if the heap's stack limits should be set, false if not.
249 bool Initialize();
252 250
253 // The stack limit is split into a JavaScript and a C++ stack limit. These 251 // The stack limit is split into a JavaScript and a C++ stack limit. These
254 // two are the same except when running on a simulator where the C++ and 252 // two are the same except when running on a simulator where the C++ and
255 // JavaScript stacks are separate. Each of the two stack limits have two 253 // JavaScript stacks are separate. Each of the two stack limits have two
256 // values. The one eith the real_ prefix is the actual stack limit 254 // values. The one eith the real_ prefix is the actual stack limit
257 // set for the VM. The one without the real_ prefix has the same value as 255 // set for the VM. The one without the real_ prefix has the same value as
258 // the actual stack limit except when there is an interruption (e.g. debug 256 // the actual stack limit except when there is an interruption (e.g. debug
259 // break or preemption) in which case it is lowered to make stack checks 257 // break or preemption) in which case it is lowered to make stack checks
260 // fail. Both the generated code and the runtime system check against the 258 // fail. Both the generated code and the runtime system check against the
261 // one without the real_ prefix. 259 // one without the real_ prefix.
262 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM. 260 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM.
263 uintptr_t jslimit_; 261 uintptr_t jslimit_;
264 uintptr_t real_climit_; // Actual C++ stack limit set for the VM. 262 uintptr_t real_climit_; // Actual C++ stack limit set for the VM.
265 uintptr_t climit_; 263 uintptr_t climit_;
266 264
267 int nesting_; 265 int nesting_;
268 int postpone_interrupts_nesting_; 266 int postpone_interrupts_nesting_;
269 int interrupt_flags_; 267 int interrupt_flags_;
270 }; 268 };
271 269
272 static ThreadLocal thread_local_; 270 ThreadLocal thread_local_;
271 Thread::LocalStorageKey stack_limit_key_;
273 272
273 friend class Isolate;
274 friend class StackLimitCheck; 274 friend class StackLimitCheck;
275 friend class PostponeInterruptsScope; 275 friend class PostponeInterruptsScope;
276 };
277 276
278 277 DISALLOW_COPY_AND_ASSIGN(StackGuard);
279 // Support for checking for stack-overflows in C++ code.
280 class StackLimitCheck BASE_EMBEDDED {
281 public:
282 bool HasOverflowed() const {
283 // Stack has overflowed in C++ code only if stack pointer exceeds the C++
284 // stack guard and the limits are not set to interrupt values.
285 // TODO(214): Stack overflows are ignored if a interrupt is pending. This
286 // code should probably always use the initial C++ limit.
287 return (reinterpret_cast<uintptr_t>(this) < StackGuard::climit()) &&
288 StackGuard::IsStackOverflow();
289 }
290 };
291
292
293 // Support for temporarily postponing interrupts. When the outermost
294 // postpone scope is left the interrupts will be re-enabled and any
295 // interrupts that occurred while in the scope will be taken into
296 // account.
297 class PostponeInterruptsScope BASE_EMBEDDED {
298 public:
299 PostponeInterruptsScope() {
300 StackGuard::thread_local_.postpone_interrupts_nesting_++;
301 StackGuard::DisableInterrupts();
302 }
303
304 ~PostponeInterruptsScope() {
305 if (--StackGuard::thread_local_.postpone_interrupts_nesting_ == 0) {
306 StackGuard::EnableInterrupts();
307 }
308 }
309 }; 278 };
310 279
311 280
312 class GCExtension : public v8::Extension { 281 class GCExtension : public v8::Extension {
313 public: 282 public:
314 GCExtension() : v8::Extension("v8/gc", kSource) {} 283 GCExtension() : v8::Extension("v8/gc", kSource) {}
315 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 284 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
316 v8::Handle<v8::String> name); 285 v8::Handle<v8::String> name);
317 static v8::Handle<v8::Value> GC(const v8::Arguments& args); 286 static v8::Handle<v8::Value> GC(const v8::Arguments& args);
318 private: 287 private:
319 static const char* kSource; 288 static const char* kSource;
320 }; 289 };
321 290
322 291
323 } } // namespace v8::internal 292 } } // namespace v8::internal
324 293
325 #endif // V8_EXECUTION_H_ 294 #endif // V8_EXECUTION_H_
OLDNEW
« no previous file with comments | « src/debug.cc ('k') | src/execution.cc » ('j') | src/execution.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698