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

Side by Side Diff: src/execution.h

Issue 359723005: Add mechanism to postpone interrupts selectively. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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 | « no previous file | src/execution.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_EXECUTION_H_ 5 #ifndef V8_EXECUTION_H_
6 #define V8_EXECUTION_H_ 6 #define V8_EXECUTION_H_
7 7
8 #include "src/handles.h" 8 #include "src/handles.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // Get a function delegate (or undefined) for the given non-function 115 // Get a function delegate (or undefined) for the given non-function
116 // object. Used for support calling objects as constructors. 116 // object. Used for support calling objects as constructors.
117 static Handle<Object> GetConstructorDelegate(Isolate* isolate, 117 static Handle<Object> GetConstructorDelegate(Isolate* isolate,
118 Handle<Object> object); 118 Handle<Object> object);
119 static MaybeHandle<Object> TryGetConstructorDelegate(Isolate* isolate, 119 static MaybeHandle<Object> TryGetConstructorDelegate(Isolate* isolate,
120 Handle<Object> object); 120 Handle<Object> object);
121 }; 121 };
122 122
123 123
124 class ExecutionAccess; 124 class ExecutionAccess;
125 class PostponeInterruptsScope;
125 126
126 127
127 // StackGuard contains the handling of the limits that are used to limit the 128 // StackGuard contains the handling of the limits that are used to limit the
128 // number of nested invocations of JavaScript and the stack size used in each 129 // number of nested invocations of JavaScript and the stack size used in each
129 // invocation. 130 // invocation.
130 class StackGuard V8_FINAL { 131 class StackGuard V8_FINAL {
131 public: 132 public:
132 // Pass the address beyond which the stack should not grow. The stack 133 // Pass the address beyond which the stack should not grow. The stack
133 // is assumed to grow downwards. 134 // is assumed to grow downwards.
134 void SetStackLimit(uintptr_t limit); 135 void SetStackLimit(uintptr_t limit);
135 136
136 // Threading support. 137 // Threading support.
137 char* ArchiveStackGuard(char* to); 138 char* ArchiveStackGuard(char* to);
138 char* RestoreStackGuard(char* from); 139 char* RestoreStackGuard(char* from);
139 static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); } 140 static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
140 void FreeThreadResources(); 141 void FreeThreadResources();
141 // Sets up the default stack guard for this thread if it has not 142 // Sets up the default stack guard for this thread if it has not
142 // already been set up. 143 // already been set up.
143 void InitThread(const ExecutionAccess& lock); 144 void InitThread(const ExecutionAccess& lock);
144 // Clears the stack guard for this thread so it does not look as if 145 // Clears the stack guard for this thread so it does not look as if
145 // it has been set up. 146 // it has been set up.
146 void ClearThread(const ExecutionAccess& lock); 147 void ClearThread(const ExecutionAccess& lock);
147 148
148 #define INTERRUPT_LIST(V) \ 149 #define INTERRUPT_LIST(V) \
149 V(DEBUGBREAK, DebugBreak) \ 150 V(DEBUGBREAK, DebugBreak, 0) \
150 V(DEBUGCOMMAND, DebugCommand) \ 151 V(DEBUGCOMMAND, DebugCommand, 1) \
151 V(TERMINATE_EXECUTION, TerminateExecution) \ 152 V(TERMINATE_EXECUTION, TerminateExecution, 2) \
152 V(GC_REQUEST, GC) \ 153 V(GC_REQUEST, GC, 3) \
153 V(INSTALL_CODE, InstallCode) \ 154 V(INSTALL_CODE, InstallCode, 4) \
154 V(API_INTERRUPT, ApiInterrupt) \ 155 V(API_INTERRUPT, ApiInterrupt, 5) \
155 V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites) 156 V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 6)
156 157
157 #define V(NAME, Name) \ 158 #define V(NAME, Name, id) \
158 inline bool Check##Name() { return CheckInterrupt(1 << NAME); } \ 159 inline bool Check##Name() { return CheckInterrupt(NAME); } \
159 inline void Request##Name() { RequestInterrupt(1 << NAME); } \ 160 inline void Request##Name() { RequestInterrupt(NAME); } \
160 inline void Clear##Name() { ClearInterrupt(1 << NAME); } 161 inline void Clear##Name() { ClearInterrupt(NAME); }
161 INTERRUPT_LIST(V) 162 INTERRUPT_LIST(V)
162 #undef V 163 #undef V
163 164
165 // Flag used to set the interrupt causes.
166 enum InterruptFlag {
167 #define V(NAME, Name, id) NAME = (1 << id),
168 INTERRUPT_LIST(V)
169 #undef V
170 #define V(NAME, Name, id) NAME |
171 ALL_INTERRUPTS = INTERRUPT_LIST(V) 0
172 #undef V
173 };
174
164 // This provides an asynchronous read of the stack limits for the current 175 // This provides an asynchronous read of the stack limits for the current
165 // thread. There are no locks protecting this, but it is assumed that you 176 // thread. There are no locks protecting this, but it is assumed that you
166 // have the global V8 lock if you are using multiple V8 threads. 177 // have the global V8 lock if you are using multiple V8 threads.
167 uintptr_t climit() { 178 uintptr_t climit() {
168 return thread_local_.climit_; 179 return thread_local_.climit_;
169 } 180 }
170 uintptr_t real_climit() { 181 uintptr_t real_climit() {
171 return thread_local_.real_climit_; 182 return thread_local_.real_climit_;
172 } 183 }
173 uintptr_t jslimit() { 184 uintptr_t jslimit() {
174 return thread_local_.jslimit_; 185 return thread_local_.jslimit_;
175 } 186 }
176 uintptr_t real_jslimit() { 187 uintptr_t real_jslimit() {
177 return thread_local_.real_jslimit_; 188 return thread_local_.real_jslimit_;
178 } 189 }
179 Address address_of_jslimit() { 190 Address address_of_jslimit() {
180 return reinterpret_cast<Address>(&thread_local_.jslimit_); 191 return reinterpret_cast<Address>(&thread_local_.jslimit_);
181 } 192 }
182 Address address_of_real_jslimit() { 193 Address address_of_real_jslimit() {
183 return reinterpret_cast<Address>(&thread_local_.real_jslimit_); 194 return reinterpret_cast<Address>(&thread_local_.real_jslimit_);
184 } 195 }
185 196
186 // If the stack guard is triggered, but it is not an actual 197 // If the stack guard is triggered, but it is not an actual
187 // stack overflow, then handle the interruption accordingly. 198 // stack overflow, then handle the interruption accordingly.
188 Object* HandleInterrupts(); 199 Object* HandleInterrupts();
189 200
190 private: 201 private:
191 StackGuard(); 202 StackGuard();
192 203
193 // Flag used to set the interrupt causes. 204 bool CheckInterrupt(InterruptFlag flag);
194 enum InterruptFlag { 205 void RequestInterrupt(InterruptFlag flag);
195 #define V(NAME, Name) NAME, 206 void ClearInterrupt(InterruptFlag flag);
196 INTERRUPT_LIST(V)
197 #undef V
198 NUMBER_OF_INTERRUPTS
199 };
200
201 bool CheckInterrupt(int flagbit);
202 void RequestInterrupt(int flagbit);
203 void ClearInterrupt(int flagbit);
204 bool CheckAndClearInterrupt(InterruptFlag flag); 207 bool CheckAndClearInterrupt(InterruptFlag flag);
205 208
206 // You should hold the ExecutionAccess lock when calling this method. 209 // You should hold the ExecutionAccess lock when calling this method.
207 bool has_pending_interrupts(const ExecutionAccess& lock) { 210 bool has_pending_interrupts(const ExecutionAccess& lock) {
208 // Sanity check: We shouldn't be asking about pending interrupts
209 // unless we're not postponing them anymore.
210 ASSERT(!should_postpone_interrupts(lock));
211 return thread_local_.interrupt_flags_ != 0; 211 return thread_local_.interrupt_flags_ != 0;
212 } 212 }
213 213
214 // You should hold the ExecutionAccess lock when calling this method. 214 // You should hold the ExecutionAccess lock when calling this method.
215 bool should_postpone_interrupts(const ExecutionAccess& lock) {
216 return thread_local_.postpone_interrupts_nesting_ > 0;
217 }
218
219 // You should hold the ExecutionAccess lock when calling this method.
220 inline void set_interrupt_limits(const ExecutionAccess& lock); 215 inline void set_interrupt_limits(const ExecutionAccess& lock);
221 216
222 // Reset limits to actual values. For example after handling interrupt. 217 // Reset limits to actual values. For example after handling interrupt.
223 // You should hold the ExecutionAccess lock when calling this method. 218 // You should hold the ExecutionAccess lock when calling this method.
224 inline void reset_limits(const ExecutionAccess& lock); 219 inline void reset_limits(const ExecutionAccess& lock);
225 220
226 // Enable or disable interrupts. 221 // Enable or disable interrupts.
227 void EnableInterrupts(); 222 void EnableInterrupts();
228 void DisableInterrupts(); 223 void DisableInterrupts();
229 224
230 #if V8_TARGET_ARCH_64_BIT 225 #if V8_TARGET_ARCH_64_BIT
231 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe); 226 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
232 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8); 227 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8);
233 #else 228 #else
234 static const uintptr_t kInterruptLimit = 0xfffffffe; 229 static const uintptr_t kInterruptLimit = 0xfffffffe;
235 static const uintptr_t kIllegalLimit = 0xfffffff8; 230 static const uintptr_t kIllegalLimit = 0xfffffff8;
236 #endif 231 #endif
237 232
233 void PushPostponeInterruptsScope(PostponeInterruptsScope* scope);
234 void PopPostponeInterruptsScope();
235
238 class ThreadLocal V8_FINAL { 236 class ThreadLocal V8_FINAL {
239 public: 237 public:
240 ThreadLocal() { Clear(); } 238 ThreadLocal() { Clear(); }
241 // You should hold the ExecutionAccess lock when you call Initialize or 239 // You should hold the ExecutionAccess lock when you call Initialize or
242 // Clear. 240 // Clear.
243 void Clear(); 241 void Clear();
244 242
245 // Returns true if the heap's stack limits should be set, false if not. 243 // Returns true if the heap's stack limits should be set, false if not.
246 bool Initialize(Isolate* isolate); 244 bool Initialize(Isolate* isolate);
247 245
248 // The stack limit is split into a JavaScript and a C++ stack limit. These 246 // The stack limit is split into a JavaScript and a C++ stack limit. These
249 // two are the same except when running on a simulator where the C++ and 247 // two are the same except when running on a simulator where the C++ and
250 // JavaScript stacks are separate. Each of the two stack limits have two 248 // JavaScript stacks are separate. Each of the two stack limits have two
251 // values. The one eith the real_ prefix is the actual stack limit 249 // values. The one eith the real_ prefix is the actual stack limit
252 // set for the VM. The one without the real_ prefix has the same value as 250 // set for the VM. The one without the real_ prefix has the same value as
253 // the actual stack limit except when there is an interruption (e.g. debug 251 // the actual stack limit except when there is an interruption (e.g. debug
254 // break or preemption) in which case it is lowered to make stack checks 252 // break or preemption) in which case it is lowered to make stack checks
255 // fail. Both the generated code and the runtime system check against the 253 // fail. Both the generated code and the runtime system check against the
256 // one without the real_ prefix. 254 // one without the real_ prefix.
257 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM. 255 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM.
258 uintptr_t jslimit_; 256 uintptr_t jslimit_;
259 uintptr_t real_climit_; // Actual C++ stack limit set for the VM. 257 uintptr_t real_climit_; // Actual C++ stack limit set for the VM.
260 uintptr_t climit_; 258 uintptr_t climit_;
261 259
262 int nesting_; 260 PostponeInterruptsScope* postpone_interrupts_;
263 int postpone_interrupts_nesting_;
264 int interrupt_flags_; 261 int interrupt_flags_;
265 }; 262 };
266 263
267 class StackPointer { 264 class StackPointer {
268 public: 265 public:
269 inline uintptr_t address() { return reinterpret_cast<uintptr_t>(this); } 266 inline uintptr_t address() { return reinterpret_cast<uintptr_t>(this); }
270 }; 267 };
271 268
272 // TODO(isolates): Technically this could be calculated directly from a 269 // TODO(isolates): Technically this could be calculated directly from a
273 // pointer to StackGuard. 270 // pointer to StackGuard.
274 Isolate* isolate_; 271 Isolate* isolate_;
275 ThreadLocal thread_local_; 272 ThreadLocal thread_local_;
276 273
277 friend class Isolate; 274 friend class Isolate;
278 friend class StackLimitCheck; 275 friend class StackLimitCheck;
279 friend class PostponeInterruptsScope; 276 friend class PostponeInterruptsScope;
280 277
281 DISALLOW_COPY_AND_ASSIGN(StackGuard); 278 DISALLOW_COPY_AND_ASSIGN(StackGuard);
282 }; 279 };
283 280
284 } } // namespace v8::internal 281 } } // namespace v8::internal
285 282
286 #endif // V8_EXECUTION_H_ 283 #endif // V8_EXECUTION_H_
OLDNEW
« no previous file with comments | « no previous file | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698